Skip to content

Commit 82de47c

Browse files
committed
[Macros] Fix name lookup in macro expansion declaration arguments.
Teach ASTScope to create child nodes for each of the arguments of a macro expansion declaration, so that we can perform name lookup into them. Otherwise, we cannot have nontrivial closures in arguments to a macro expansion declaration. Fixes rdar://107388151.
1 parent dd2d851 commit 82de47c

8 files changed

+81
-1
lines changed

include/swift/AST/ASTScope.h

+26
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,32 @@ class MacroDefinitionScope final : public ASTScopeImpl {
12371237
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
12381238
};
12391239

1240+
class MacroExpansionDeclScope final : public ASTScopeImpl {
1241+
public:
1242+
MacroExpansionDecl *const decl;
1243+
1244+
MacroExpansionDeclScope(MacroExpansionDecl *e) : decl(e) {}
1245+
virtual ~MacroExpansionDeclScope() {}
1246+
1247+
protected:
1248+
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
1249+
1250+
private:
1251+
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
1252+
1253+
public:
1254+
std::string getClassName() const override;
1255+
SourceRange
1256+
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1257+
1258+
protected:
1259+
void printSpecifics(llvm::raw_ostream &out) const override;
1260+
1261+
public:
1262+
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
1263+
Decl *getDecl() const { return decl; }
1264+
};
1265+
12401266
class AbstractStmtScope : public ASTScopeImpl {
12411267
public:
12421268
SourceRange

lib/AST/ASTScope.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ DEFINE_GET_CLASS_NAME(SubscriptDeclScope)
152152
DEFINE_GET_CLASS_NAME(EnumElementScope)
153153
DEFINE_GET_CLASS_NAME(MacroDeclScope)
154154
DEFINE_GET_CLASS_NAME(MacroDefinitionScope)
155+
DEFINE_GET_CLASS_NAME(MacroExpansionDeclScope)
155156
DEFINE_GET_CLASS_NAME(IfStmtScope)
156157
DEFINE_GET_CLASS_NAME(WhileStmtScope)
157158
DEFINE_GET_CLASS_NAME(GuardStmtScope)

lib/AST/ASTScopeCreation.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ class NodeAdder
317317
VISIT_AND_IGNORE(PoundDiagnosticDecl)
318318
VISIT_AND_IGNORE(MissingDecl)
319319
VISIT_AND_IGNORE(MissingMemberDecl)
320-
VISIT_AND_IGNORE(MacroExpansionDecl)
321320

322321
// Only members of the active clause are in scope, and those
323322
// are visited separately.
@@ -353,6 +352,7 @@ class NodeAdder
353352
VISIT_AND_CREATE(CaseStmt, CaseStmtScope)
354353
VISIT_AND_CREATE(AbstractFunctionDecl, AbstractFunctionDeclScope)
355354
VISIT_AND_CREATE(MacroDecl, MacroDeclScope)
355+
VISIT_AND_CREATE(MacroExpansionDecl, MacroExpansionDeclScope)
356356

357357
#undef VISIT_AND_CREATE
358358

@@ -724,6 +724,7 @@ NO_NEW_INSERTION_POINT(RepeatWhileScope)
724724
NO_NEW_INSERTION_POINT(SubscriptDeclScope)
725725
NO_NEW_INSERTION_POINT(MacroDeclScope)
726726
NO_NEW_INSERTION_POINT(MacroDefinitionScope)
727+
NO_NEW_INSERTION_POINT(MacroExpansionDeclScope)
727728
NO_NEW_INSERTION_POINT(SwitchStmtScope)
728729
NO_NEW_INSERTION_POINT(WhileStmtScope)
729730

@@ -1131,6 +1132,16 @@ MacroDefinitionScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
11311132
scopeCreator.addToScopeTree(ASTNode(definition), this);
11321133
}
11331134

1135+
void MacroExpansionDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
1136+
ScopeCreator &scopeCreator) {
1137+
// FIXME: If we get attributes on macro expansions, visit them here.
1138+
if (auto argList = decl->getArgs()) {
1139+
for (const auto &arg : *argList) {
1140+
scopeCreator.addExprToScopeTree(arg.getExpr(), this);
1141+
}
1142+
}
1143+
}
1144+
11341145
void CaptureListScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
11351146
ScopeCreator &scopeCreator) {
11361147
auto *closureExpr = expr->getClosureBody();

lib/AST/ASTScopePrinting.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ void MacroDeclScope::printSpecifics(llvm::raw_ostream &out) const {
182182
decl->dumpRef(out);
183183
}
184184

185+
void MacroExpansionDeclScope::printSpecifics(llvm::raw_ostream &out) const {
186+
out << decl->getMacroName();
187+
}
188+
185189
void ConditionalClausePatternUseScope::printSpecifics(
186190
llvm::raw_ostream &out) const {
187191
sec.getPattern()->print(out);

lib/AST/ASTScopeSourceRange.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ SourceRange MacroDefinitionScope::getSourceRangeOfThisASTNode(
148148
return definition->getSourceRange();
149149
}
150150

151+
SourceRange MacroExpansionDeclScope::getSourceRangeOfThisASTNode(
152+
const bool omitAssertions) const {
153+
return decl->getSourceRangeIncludingAttrs();
154+
}
155+
151156
SourceRange
152157
EnumElementScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
153158
return decl->getSourceRange();

test/Macros/Inputs/syntax_macro_definitions.swift

+9
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ enum CustomError: Error, CustomStringConvertible {
208208
}
209209
}
210210

211+
public struct EmptyDeclarationMacro: DeclarationMacro {
212+
public static func expansion(
213+
of node: some FreestandingMacroExpansionSyntax,
214+
in context: some MacroExpansionContext
215+
) throws -> [DeclSyntax] {
216+
return []
217+
}
218+
}
219+
211220
public struct DefineBitwidthNumberedStructsMacro: DeclarationMacro {
212221
public static func expansion(
213222
of node: some FreestandingMacroExpansionSyntax,

test/Macros/macro_expand.swift

+13
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,16 @@ func testFreestandingMacroExpansion() {
334334
#anonymousTypes { "hello" }
335335
}
336336
testFreestandingMacroExpansion()
337+
338+
// Avoid re-type-checking declaration macro arguments.
339+
@freestanding(declaration)
340+
macro freestandingWithClosure<T>(_ value: T, body: (T) -> T) = #externalMacro(module: "MacroDefinition", type: "EmptyDeclarationMacro")
341+
342+
func testFreestandingWithClosure(i: Int) {
343+
#freestandingWithClosure(i) { x in x }
344+
345+
#freestandingWithClosure(i) {
346+
let x = $0
347+
return x
348+
}
349+
}

test/Macros/top_level_freestanding.swift

+11
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,14 @@ struct Main {
3535
lookupGlobalFreestandingExpansion()
3636
}
3737
}
38+
39+
@freestanding(declaration)
40+
macro freestandingWithClosure<T>(_ value: T, body: (T) -> T) = #externalMacro(module: "MacroDefinition", type: "EmptyDeclarationMacro")
41+
42+
// Unqualified lookup for names defined within macro arguments.
43+
#freestandingWithClosure(0) { x in x }
44+
45+
#freestandingWithClosure(1) {
46+
let x = $0
47+
return x
48+
}

0 commit comments

Comments
 (0)