Skip to content

Commit b0ea22c

Browse files
DougGregorbnbarham
authored andcommitted
[Macros] Teach SILGen to visit declartions produced by freestanding macros
Fixes a crash where local variables introduced by a freestanding declaration macro would not get SIL emitted for them, rdar://109721114. (cherry picked from commit 0caa453)
1 parent 46dc2be commit b0ea22c

File tree

8 files changed

+48
-16
lines changed

8 files changed

+48
-16
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8639,8 +8639,9 @@ class MacroExpansionDecl : public Decl, public FreestandingMacroExpansion {
86398639
return getExpansionInfo()->getSourceRange();
86408640
}
86418641
SourceLoc getLocFromSource() const { return getExpansionInfo()->SigilLoc; }
8642-
using ExprOrStmtExpansionCallback = llvm::function_ref<void(ASTNode)>;
8643-
void forEachExpandedExprOrStmt(ExprOrStmtExpansionCallback) const;
8642+
8643+
/// Enumerate the nodes produced by expanding this macro expansion.
8644+
void forEachExpandedNode(llvm::function_ref<void(ASTNode)> callback) const;
86448645

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

lib/AST/ASTWalker.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -458,19 +458,18 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
458458
// Visit auxiliary decls, which may be decls from macro expansions.
459459
bool alreadyFailed = false;
460460
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) {
461+
MED->forEachExpandedNode([&](ASTNode expandedNode) {
467462
if (alreadyFailed) return;
468463
if (auto *expr = expandedNode.dyn_cast<Expr *>()) {
469464
if (!doIt(expr))
470465
alreadyFailed = true;
471466
} else if (auto *stmt = expandedNode.dyn_cast<Stmt *>()) {
472467
if (!doIt(stmt))
473468
alreadyFailed = true;
469+
} else {
470+
auto decl = expandedNode.get<Decl *>();
471+
if (!isa<VarDecl>(decl))
472+
alreadyFailed = inherited::visit(decl);
474473
}
475474
});
476475
}

lib/AST/Decl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10680,8 +10680,9 @@ unsigned MacroExpansionDecl::getDiscriminator() const {
1068010680
return getRawDiscriminator();
1068110681
}
1068210682

10683-
void MacroExpansionDecl::forEachExpandedExprOrStmt(
10684-
ExprOrStmtExpansionCallback callback) const {
10683+
void MacroExpansionDecl::forEachExpandedNode(
10684+
llvm::function_ref<void(ASTNode)> callback
10685+
) const {
1068510686
auto mutableThis = const_cast<MacroExpansionDecl *>(this);
1068610687
auto bufferID = evaluateOrDefault(
1068710688
getASTContext().evaluator,
@@ -10693,8 +10694,7 @@ void MacroExpansionDecl::forEachExpandedExprOrStmt(
1069310694
auto startLoc = sourceMgr.getLocForBufferStart(*bufferID);
1069410695
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
1069510696
for (auto node : sourceFile->getTopLevelItems())
10696-
if (node.is<Expr *>() || node.is<Stmt *>())
10697-
callback(node);
10697+
callback(node);
1069810698
}
1069910699

1070010700
NominalTypeDecl *

lib/SILGen/SILGenDecl.cpp

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

16231623
void SILGenFunction::visitMacroExpansionDecl(MacroExpansionDecl *D) {
1624-
D->forEachExpandedExprOrStmt([&](ASTNode node) {
1624+
D->forEachExpandedNode([&](ASTNode node) {
16251625
if (auto *expr = node.dyn_cast<Expr *>())
16261626
emitIgnoredExpr(expr);
16271627
else if (auto *stmt = node.dyn_cast<Stmt *>())
16281628
emitStmt(stmt);
1629+
else
1630+
visit(node.get<Decl *>());
16291631
});
16301632
}
16311633

lib/SILGen/SILGenExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6298,11 +6298,13 @@ RValue RValueEmitter::visitMacroExpansionExpr(MacroExpansionExpr *E,
62986298
}
62996299
else if (auto *MED = E->getSubstituteDecl()) {
63006300
Mangle::ASTMangler mangler;
6301-
MED->forEachExpandedExprOrStmt([&](ASTNode node) {
6301+
MED->forEachExpandedNode([&](ASTNode node) {
63026302
if (auto *expr = node.dyn_cast<Expr *>())
63036303
visit(expr, C);
63046304
else if (auto *stmt = node.dyn_cast<Stmt *>())
63056305
SGF.emitStmt(stmt);
6306+
else
6307+
SGF.visit(node.get<Decl *>());
63066308
});
63076309
return RValue();
63086310
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,8 +2066,11 @@ 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) {
2070+
// Decls in expansion already visited as auxiliary decls.
2071+
if (node.is<Decl *>())
2072+
return;
2073+
20712074
TypeChecker::typeCheckASTNode(node, MED->getDeclContext());
20722075
});
20732076
}

test/Macros/Inputs/syntax_macro_definitions.swift

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

302+
public struct VarDeclMacro: DeclarationMacro {
303+
public static func expansion(
304+
of node: some FreestandingMacroExpansionSyntax,
305+
in context: some MacroExpansionContext
306+
) throws -> [DeclSyntax] {
307+
return [
308+
"""
309+
let fromMacro = 23
310+
use(fromMacro)
311+
if true {
312+
let fromMacro = "string"
313+
use(fromMacro)
314+
}
315+
"""
316+
]
317+
}
318+
}
319+
302320
public struct WarningMacro: ExpressionMacro {
303321
public static func expansion(
304322
of macro: some FreestandingMacroExpansionSyntax,

test/Macros/macro_expand.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ func testFileID(a: Int, b: Int) {
150150

151151
testFileID(a: 1, b: 2)
152152

153+
@freestanding(declaration, names: named(fromMacro)) macro varDecl() = #externalMacro(module: "MacroDefinition", type: "VarDeclMacro")
154+
155+
func testVarDecl() {
156+
func use<T>(_ t: T) {}
157+
#varDecl()
158+
}
159+
153160
@freestanding(expression) macro stringifyAndTry<T>(_ value: T) -> (T, String) =
154161
#externalMacro(module: "MacroDefinition", type: "StringifyAndTryMacro")
155162

0 commit comments

Comments
 (0)