Skip to content

Commit 5ea5594

Browse files
authored
Merge pull request #66387 from DougGregor/silgen-freestanding-local-vars
2 parents 5d03a72 + 7082074 commit 5ea5594

File tree

10 files changed

+70
-31
lines changed

10 files changed

+70
-31
lines changed

include/swift/AST/Decl.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,13 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
911911
///
912912
/// Auxiliary declarations can be property wrapper backing variables,
913913
/// backing variables for 'lazy' vars, or peer macro expansions.
914-
void visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const;
914+
///
915+
/// When \p visitFreestandingExpanded is true (the default), this will also
916+
/// visit the declarations produced by a freestanding macro expansion.
917+
void visitAuxiliaryDecls(
918+
AuxiliaryDeclCallback callback,
919+
bool visitFreestandingExpanded = true
920+
) const;
915921

916922
using MacroCallback = llvm::function_ref<void(CustomAttr *, MacroDecl *)>;
917923

@@ -8621,8 +8627,9 @@ class MacroExpansionDecl : public Decl, public FreestandingMacroExpansion {
86218627
return getExpansionInfo()->getSourceRange();
86228628
}
86238629
SourceLoc getLocFromSource() const { return getExpansionInfo()->SigilLoc; }
8624-
using ExprOrStmtExpansionCallback = llvm::function_ref<void(ASTNode)>;
8625-
void forEachExpandedExprOrStmt(ExprOrStmtExpansionCallback) const;
8630+
8631+
/// Enumerate the nodes produced by expanding this macro expansion.
8632+
void forEachExpandedNode(llvm::function_ref<void(ASTNode)> callback) const;
86268633

86278634
/// Returns a discriminator which determines this macro expansion's index
86288635
/// in the sequence of macro expansions within the current function.

lib/AST/ASTWalker.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -455,22 +455,20 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
455455
else
456456
return true;
457457
}
458-
// Visit auxiliary decls, which may be decls from macro expansions.
459458
bool alreadyFailed = false;
460459
if (shouldWalkExpansion) {
461-
MED->visitAuxiliaryDecls([&](Decl *decl) {
462-
if (alreadyFailed) return;
463-
if (!isa<VarDecl>(decl))
464-
alreadyFailed = inherited::visit(decl);
465-
});
466-
MED->forEachExpandedExprOrStmt([&](ASTNode expandedNode) {
460+
MED->forEachExpandedNode([&](ASTNode expandedNode) {
467461
if (alreadyFailed) return;
468462
if (auto *expr = expandedNode.dyn_cast<Expr *>()) {
469463
if (!doIt(expr))
470464
alreadyFailed = true;
471465
} else if (auto *stmt = expandedNode.dyn_cast<Stmt *>()) {
472466
if (!doIt(stmt))
473467
alreadyFailed = true;
468+
} else {
469+
auto decl = expandedNode.get<Decl *>();
470+
if (!isa<VarDecl>(decl))
471+
alreadyFailed = inherited::visit(decl);
474472
}
475473
});
476474
}

lib/AST/Decl.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,10 @@ DeclAttributes Decl::getSemanticAttrs() const {
381381
return getAttrs();
382382
}
383383

384-
void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
384+
void Decl::visitAuxiliaryDecls(
385+
AuxiliaryDeclCallback callback,
386+
bool visitFreestandingExpanded
387+
) const {
385388
auto &ctx = getASTContext();
386389
auto *mutableThis = const_cast<Decl *>(this);
387390
SourceManager &sourceMgr = ctx.SourceMgr;
@@ -414,13 +417,15 @@ void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
414417
}
415418
}
416419

417-
else if (auto *med = dyn_cast<MacroExpansionDecl>(mutableThis)) {
418-
if (auto bufferID = evaluateOrDefault(
419-
ctx.evaluator, ExpandMacroExpansionDeclRequest{med}, {})) {
420-
auto startLoc = sourceMgr.getLocForBufferStart(*bufferID);
421-
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
422-
for (auto *decl : sourceFile->getTopLevelDecls())
423-
callback(decl);
420+
if (visitFreestandingExpanded) {
421+
if (auto *med = dyn_cast<MacroExpansionDecl>(mutableThis)) {
422+
if (auto bufferID = evaluateOrDefault(
423+
ctx.evaluator, ExpandMacroExpansionDeclRequest{med}, {})) {
424+
auto startLoc = sourceMgr.getLocForBufferStart(*bufferID);
425+
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
426+
for (auto *decl : sourceFile->getTopLevelDecls())
427+
callback(decl);
428+
}
424429
}
425430
}
426431

@@ -10637,8 +10642,9 @@ unsigned MacroExpansionDecl::getDiscriminator() const {
1063710642
return getRawDiscriminator();
1063810643
}
1063910644

10640-
void MacroExpansionDecl::forEachExpandedExprOrStmt(
10641-
ExprOrStmtExpansionCallback callback) const {
10645+
void MacroExpansionDecl::forEachExpandedNode(
10646+
llvm::function_ref<void(ASTNode)> callback
10647+
) const {
1064210648
auto mutableThis = const_cast<MacroExpansionDecl *>(this);
1064310649
auto bufferID = evaluateOrDefault(
1064410650
getASTContext().evaluator,
@@ -10650,8 +10656,7 @@ void MacroExpansionDecl::forEachExpandedExprOrStmt(
1065010656
auto startLoc = sourceMgr.getLocForBufferStart(*bufferID);
1065110657
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
1065210658
for (auto node : sourceFile->getTopLevelItems())
10653-
if (node.is<Expr *>() || node.is<Stmt *>())
10654-
callback(node);
10659+
callback(node);
1065510660
}
1065610661

1065710662
NominalTypeDecl *

lib/SILGen/SILGenDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,11 +1625,13 @@ void SILGenFunction::visitVarDecl(VarDecl *D) {
16251625
}
16261626

16271627
void SILGenFunction::visitMacroExpansionDecl(MacroExpansionDecl *D) {
1628-
D->forEachExpandedExprOrStmt([&](ASTNode node) {
1628+
D->forEachExpandedNode([&](ASTNode node) {
16291629
if (auto *expr = node.dyn_cast<Expr *>())
16301630
emitIgnoredExpr(expr);
16311631
else if (auto *stmt = node.dyn_cast<Stmt *>())
16321632
emitStmt(stmt);
1633+
else
1634+
visit(node.get<Decl *>());
16331635
});
16341636
}
16351637

lib/SILGen/SILGenExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6294,11 +6294,13 @@ RValue RValueEmitter::visitMacroExpansionExpr(MacroExpansionExpr *E,
62946294
}
62956295
else if (auto *MED = E->getSubstituteDecl()) {
62966296
Mangle::ASTMangler mangler;
6297-
MED->forEachExpandedExprOrStmt([&](ASTNode node) {
6297+
MED->forEachExpandedNode([&](ASTNode node) {
62986298
if (auto *expr = node.dyn_cast<Expr *>())
62996299
visit(expr, C);
63006300
else if (auto *stmt = node.dyn_cast<Stmt *>())
63016301
SGF.emitStmt(stmt);
6302+
else
6303+
SGF.visit(node.get<Decl *>());
63026304
});
63036305
return RValue();
63046306
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
18501850
if (!isa<ClassDecl>(decl->getDeclContext())) {
18511851
decl->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
18521852
this->visit(auxiliaryDecl);
1853-
});
1853+
}, /*visitFreestandingExpanded=*/false);
18541854
}
18551855

18561856
if (auto *Stats = getASTContext().Stats)
@@ -2066,8 +2066,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20662066
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {
20672067
// Assign a discriminator.
20682068
(void)MED->getDiscriminator();
2069-
// Decls in expansion already visited as auxiliary decls.
2070-
MED->forEachExpandedExprOrStmt([&](ASTNode node) {
2069+
MED->forEachExpandedNode([&](ASTNode node) {
20712070
TypeChecker::typeCheckASTNode(node, MED->getDeclContext());
20722071
});
20732072
}

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,25 @@ public struct DefineDeclsWithKnownNamesMacro: DeclarationMacro {
299299
}
300300
}
301301

302+
public struct VarDeclMacro: CodeItemMacro {
303+
public static func expansion(
304+
of node: some FreestandingMacroExpansionSyntax,
305+
in context: some MacroExpansionContext
306+
) throws -> [CodeBlockItemSyntax] {
307+
let name = context.makeUniqueName("fromMacro")
308+
return [
309+
"let \(name) = 23",
310+
"use(\(name))",
311+
"""
312+
if true {
313+
let \(name) = "string"
314+
use(\(name))
315+
}
316+
"""
317+
]
318+
}
319+
}
320+
302321
public struct WarningMacro: ExpressionMacro {
303322
public static func expansion(
304323
of macro: some FreestandingMacroExpansionSyntax,

test/Macros/macro_expand_codeitems.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,10 @@ func testFreestandingMacroExpansion() {
3333
#codeItems
3434
}
3535
testFreestandingMacroExpansion()
36+
37+
@freestanding(codeItem) macro varDecl() = #externalMacro(module: "MacroDefinition", type: "VarDeclMacro")
38+
39+
func testVarDecl() {
40+
func use<T>(_ t: T) {}
41+
#varDecl()
42+
}

test/Macros/top_level_freestanding.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func lookupGlobalFreestandingExpansion() {
5050

5151
#anonymousTypes(public: true) { "hello" }
5252

53-
// CHECK-SIL: sil @$s9MacroUser03$s9A71User33_082AE7CFEFA6960C804A9FE7366EB5A0Ll14anonymousTypesfMf0_4namefMu_C5helloSSyF
53+
// CHECK-SIL: sil @$s9MacroUser03$s9A70User33_082AE7CFEFA6960C804A9FE7366EB5A0Ll14anonymousTypesfMf_4namefMu_C5helloSSyF
5454

5555
@main
5656
struct Main {

test/SourceKit/Macros/macro_basic.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition"
131131
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=57:1 %s -- ${COMPILER_ARGS[@]} -parse-as-library | %FileCheck -check-prefix=EXPAND_MACRO_DECL %s
132132
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=57:2 %s -- ${COMPILER_ARGS[@]} -parse-as-library | %FileCheck -check-prefix=EXPAND_MACRO_DECL %s
133133
// EXPAND_MACRO_DECL: source.edit.kind.active:
134-
// EXPAND_MACRO_DECL-NEXT: 57:1-57:28 (@__swiftmacro_9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf0_.swift) "class $s9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf0_4namefMu_ {
134+
// EXPAND_MACRO_DECL-NEXT: 57:1-57:28 (@__swiftmacro_9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf_.swift) "class $s9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf_4namefMu_ {
135135
// EXPAND_MACRO_DECL-NEXT: func hello() -> String {
136136
// EXPAND_MACRO_DECL-NEXT: "hello"
137137
// EXPAND_MACRO_DECL-NEXT: }
@@ -140,15 +140,15 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition"
140140
// EXPAND_MACRO_DECL-NEXT: return Self.self
141141
// EXPAND_MACRO_DECL-NEXT: }
142142
// EXPAND_MACRO_DECL-NEXT: }
143-
// EXPAND_MACRO_DECL-NEXT: enum $s9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf0_4namefMu0_ {
143+
// EXPAND_MACRO_DECL-NEXT: enum $s9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf_4namefMu0_ {
144144
// EXPAND_MACRO_DECL-NEXT: case apple
145145
// EXPAND_MACRO_DECL-NEXT: case banana
146146
// EXPAND_MACRO_DECL-EMPTY:
147147
// EXPAND_MACRO_DECL-NEXT: func hello() -> String {
148148
// EXPAND_MACRO_DECL-NEXT: "hello"
149149
// EXPAND_MACRO_DECL-NEXT: }
150150
// EXPAND_MACRO_DECL-NEXT: }
151-
// EXPAND_MACRO_DECL-NEXT: struct $s9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf0_4namefMu1_: Equatable {
151+
// EXPAND_MACRO_DECL-NEXT: struct $s9MacroUser33_70D4178875715FB9B8B50C58F66F8D53Ll14anonymousTypesfMf_4namefMu1_: Equatable {
152152
// EXPAND_MACRO_DECL-NEXT: static func == (lhs: Self, rhs: Self) -> Bool {
153153
// EXPAND_MACRO_DECL-NEXT: false
154154
// EXPAND_MACRO_DECL-NEXT: }

0 commit comments

Comments
 (0)