Skip to content

Commit da77b15

Browse files
authored
Merge pull request #66224 from DougGregor/visit-var-decls-in-freestanding-expansions-once-5.9
2 parents b924163 + e6ec9b5 commit da77b15

File tree

7 files changed

+76
-22
lines changed

7 files changed

+76
-22
lines changed

include/swift/AST/ASTContext.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,6 @@ class ASTContext final {
335335
/// The # of times we have performed typo correction.
336336
unsigned NumTypoCorrections = 0;
337337

338-
/// The next auto-closure discriminator. This needs to be preserved
339-
/// across invocations of both the parser and the type-checker.
340-
unsigned NextAutoClosureDiscriminator = 0;
341-
342338
/// Cached mapping from types to their associated tangent spaces.
343339
llvm::DenseMap<Type, Optional<TangentSpace>> AutoDiffTangentSpaces;
344340

@@ -1107,6 +1103,13 @@ class ASTContext final {
11071103
unsigned getNextMacroDiscriminator(MacroDiscriminatorContext context,
11081104
DeclBaseName baseName);
11091105

1106+
/// Get the next discriminator within the given declaration context.
1107+
unsigned getNextDiscriminator(const DeclContext *dc);
1108+
1109+
/// Set the maximum assigned discriminator within the given declaration context.
1110+
void setMaxAssignedDiscriminator(
1111+
const DeclContext *dc, unsigned discriminator);
1112+
11101113
/// Retrieve the Clang module loader for this ASTContext.
11111114
///
11121115
/// If there is no Clang module loader, returns a null pointer.

lib/AST/ASTContext.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ struct ASTContext::Implementation {
401401
llvm::DenseMap<std::pair<const void *, Identifier>, unsigned>
402402
NextMacroDiscriminator;
403403

404+
/// Local and closure discriminators per context.
405+
llvm::DenseMap<const DeclContext *, unsigned> NextDiscriminator;
406+
404407
/// Structure that captures data that is segregated into different
405408
/// arenas.
406409
struct Arena {
@@ -2170,6 +2173,18 @@ unsigned ASTContext::getNextMacroDiscriminator(
21702173
return getImpl().NextMacroDiscriminator[key]++;
21712174
}
21722175

2176+
/// Get the next discriminator within the given declaration context.
2177+
unsigned ASTContext::getNextDiscriminator(const DeclContext *dc) {
2178+
return getImpl().NextDiscriminator[dc];
2179+
}
2180+
2181+
/// Set the maximum assigned discriminator within the given declaration context.
2182+
void ASTContext::setMaxAssignedDiscriminator(
2183+
const DeclContext *dc, unsigned discriminator) {
2184+
assert(discriminator >= getImpl().NextDiscriminator[dc]);
2185+
getImpl().NextDiscriminator[dc] = discriminator;
2186+
}
2187+
21732188
void ASTContext::verifyAllLoadedModules() const {
21742189
#ifndef NDEBUG
21752190
FrontendStatsTracer tracer(Stats, "verify-all-loaded-modules");

lib/AST/ASTWalker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
460460
if (shouldWalkExpansion) {
461461
MED->visitAuxiliaryDecls([&](Decl *decl) {
462462
if (alreadyFailed) return;
463-
alreadyFailed = inherited::visit(decl);
463+
if (!isa<VarDecl>(decl))
464+
alreadyFailed = inherited::visit(decl);
464465
});
465466
MED->forEachExpandedExprOrStmt([&](ASTNode expandedNode) {
466467
if (alreadyFailed) return;

lib/AST/Decl.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2934,10 +2934,26 @@ unsigned ValueDecl::getLocalDiscriminator() const {
29342934
return 0;
29352935

29362936
// Assign local discriminators in this context.
2937+
ASTContext &ctx = getASTContext();
29372938
evaluateOrDefault(
2938-
getASTContext().evaluator,
2939+
ctx.evaluator,
29392940
LocalDiscriminatorsRequest{getDeclContext()}, InvalidDiscriminator);
29402941

2942+
// If we don't have a discriminator, and either
2943+
// 1. We have ill-formed code and we're able to assign a discriminator, or
2944+
// 2. We are in a macro expansion buffer
2945+
//
2946+
// then assign the next discriminator now.
2947+
if (LocalDiscriminator == InvalidDiscriminator &&
2948+
(ctx.Diags.hadAnyError() ||
2949+
(getLoc().isValid() &&
2950+
getModuleContext()->getSourceFileContainingLocation(getLoc())
2951+
->getFulfilledMacroRole() != None))) {
2952+
auto discriminator = ctx.getNextDiscriminator(getDeclContext());
2953+
ctx.setMaxAssignedDiscriminator(getDeclContext(), discriminator + 1);
2954+
const_cast<ValueDecl *>(this)->LocalDiscriminator = discriminator;
2955+
}
2956+
29412957
assert(LocalDiscriminator != InvalidDiscriminator);
29422958

29432959
return LocalDiscriminator;

lib/AST/Expr.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,16 +1901,22 @@ unsigned AbstractClosureExpr::getDiscriminator() const {
19011901
if (raw != InvalidDiscriminator)
19021902
return raw;
19031903

1904+
ASTContext &ctx = getASTContext();
19041905
evaluateOrDefault(
1905-
getASTContext().evaluator, LocalDiscriminatorsRequest{getParent()}, 0);
1906+
ctx.evaluator, LocalDiscriminatorsRequest{getParent()}, 0);
19061907

1907-
// Ill-formed code might not be able to assign discriminators, so assign
1908-
// a new one now.
1908+
// If we don't have a discriminator, and either
1909+
// 1. We have ill-formed code and we're able to assign a discriminator, or
1910+
// 2. We are in a macro expansion buffer
1911+
//
1912+
// then assign the next discriminator now.
19091913
if (getRawDiscriminator() == InvalidDiscriminator &&
1910-
getASTContext().Diags.hadAnyError()) {
1914+
(ctx.Diags.hadAnyError() ||
1915+
getParentSourceFile()->getFulfilledMacroRole() != None)) {
1916+
auto discriminator = ctx.getNextDiscriminator(getParent());
1917+
ctx.setMaxAssignedDiscriminator(getParent(), discriminator + 1);
19111918
const_cast<AbstractClosureExpr *>(this)->
1912-
Bits.AbstractClosureExpr.Discriminator =
1913-
getASTContext().NextAutoClosureDiscriminator++;
1919+
Bits.AbstractClosureExpr.Discriminator = discriminator;
19141920
}
19151921

19161922
assert(getRawDiscriminator() != InvalidDiscriminator);

lib/Sema/TypeCheckStmt.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ namespace {
255255
}
256256

257257
MacroWalking getMacroWalkingBehavior() const override {
258-
return MacroWalking::ArgumentsAndExpansion;
258+
return MacroWalking::Arguments;
259259
}
260260

261261
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
@@ -410,7 +410,6 @@ unsigned LocalDiscriminatorsRequest::evaluate(
410410
LocalDiscriminatorsRequest{dc->getParent()}, 0);
411411
}
412412

413-
Optional<unsigned> expectedNextAutoclosureDiscriminator = None;
414413
ASTNode node;
415414
ParameterList *params = nullptr;
416415
ParamDecl *selfParam = nullptr;
@@ -436,7 +435,7 @@ unsigned LocalDiscriminatorsRequest::evaluate(
436435
params = closure->getParameters();
437436
} else if (auto topLevel = dyn_cast<TopLevelCodeDecl>(dc)) {
438437
node = topLevel->getBody();
439-
expectedNextAutoclosureDiscriminator = ctx.NextAutoClosureDiscriminator;
438+
dc = topLevel->getParentModule();
440439
} else if (auto patternBindingInit = dyn_cast<PatternBindingInitializer>(dc)){
441440
auto patternBinding = patternBindingInit->getBinding();
442441
node = patternBinding->getInit(patternBindingInit->getBindingIndex());
@@ -472,12 +471,11 @@ unsigned LocalDiscriminatorsRequest::evaluate(
472471
params = getParameterList(dc);
473472
}
474473

474+
auto startDiscriminator = ctx.getNextDiscriminator(dc);
475475
if (!node && !params && !selfParam)
476-
return 0;
476+
return startDiscriminator;
477477

478-
SetLocalDiscriminators visitor(
479-
expectedNextAutoclosureDiscriminator.value_or(0)
480-
);
478+
SetLocalDiscriminators visitor(startDiscriminator);
481479

482480
// Set local discriminator for the 'self' parameter.
483481
if (selfParam)
@@ -494,9 +492,7 @@ unsigned LocalDiscriminatorsRequest::evaluate(
494492
node.walk(visitor);
495493

496494
unsigned nextDiscriminator = visitor.maxAssignedDiscriminator();
497-
if (expectedNextAutoclosureDiscriminator) {
498-
ctx.NextAutoClosureDiscriminator = nextDiscriminator;
499-
}
495+
ctx.setMaxAssignedDiscriminator(dc, nextDiscriminator);
500496

501497
// Return the next discriminator.
502498
return nextDiscriminator;

test/Macros/macro_expand.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ macro freestandingWithClosure<T>(_ value: T, body: (T) -> T) = #externalMacro(mo
5252
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
5353

5454
@freestanding(declaration, names: arbitrary) macro bitwidthNumberedStructs(_ baseName: String, blah: Bool) = #externalMacro(module: "MacroDefinition", type: "DefineBitwidthNumberedStructsMacro")
55+
56+
@freestanding(declaration, names: named(value)) macro varValue() = #externalMacro(module: "MacroDefinition", type: "VarValueMacro")
57+
5558
#endif
5659

5760
#if TEST_DIAGNOSTICS
@@ -400,3 +403,17 @@ func testFreestandingWithClosure(i: Int) {
400403
return x
401404
}
402405
}
406+
407+
// Nested macros with closures
408+
@freestanding(expression) macro coerceToInt<T>(_ value: T) -> Int = #externalMacro(module: "MacroDefinition", type: "CoerceToIntMacro")
409+
410+
func testFreestandingClosureNesting() {
411+
_ = #stringify({ () -> Int in
412+
#coerceToInt(2)
413+
})
414+
}
415+
416+
// Freestanding declaration macros that produce local variables
417+
func testLocalVarsFromDeclarationMacros() {
418+
#varValue
419+
}

0 commit comments

Comments
 (0)