Skip to content

Commit f4b2b60

Browse files
committed
[Macros] Enable global peer macros.
Global peer macro expansions are not injected into the AST. Instead, they are visited as "auxiliary declarations" when needed, such as in the decl checker and during SILGen. This is the same mechanism used for local property wrappers and local lazy variables.
1 parent 937afa3 commit f4b2b60

File tree

13 files changed

+150
-12
lines changed

13 files changed

+150
-12
lines changed

include/swift/AST/Decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,15 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
867867
/// attribute macro expansion.
868868
DeclAttributes getSemanticAttrs() const;
869869

870+
using AuxiliaryDeclCallback = llvm::function_ref<void(Decl *)>;
871+
872+
/// Iterate over the auxiliary declarations for this declaration,
873+
/// invoking the given callback with each auxiliary decl.
874+
///
875+
/// Auxiliary declarations can be property wrapper backing variables,
876+
/// backing variables for 'lazy' vars, or peer macro expansions.
877+
void visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const;
878+
870879
using MacroCallback = llvm::function_ref<void(CustomAttr *, MacroDecl *)>;
871880

872881
/// Iterate over each attached macro with the given role, invoking the

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ SWIFT_REQUEST(TypeChecker, ExpandSynthesizedMemberMacroRequest,
441441
ArrayRef<unsigned>(Decl *),
442442
Cached, NoLocationInfo)
443443
SWIFT_REQUEST(TypeChecker, ExpandPeerMacroRequest,
444-
bool(Decl *),
444+
ArrayRef<unsigned>(Decl *),
445445
Cached, NoLocationInfo)
446446
SWIFT_REQUEST(TypeChecker, SynthesizeRuntimeMetadataAttrGenerator,
447447
Expr *(CustomAttr *, ValueDecl *),

lib/AST/Decl.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,27 @@ DeclAttributes Decl::getSemanticAttrs() const {
376376
return getAttrs();
377377
}
378378

379+
void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
380+
auto &ctx = getASTContext();
381+
auto *mutableThis = const_cast<Decl *>(this);
382+
auto peerBuffers =
383+
evaluateOrDefault(ctx.evaluator,
384+
ExpandPeerMacroRequest{mutableThis},
385+
{});
386+
387+
SourceManager &sourceMgr = ctx.SourceMgr;
388+
auto *moduleDecl = getModuleContext();
389+
for (auto bufferID : peerBuffers) {
390+
auto startLoc = sourceMgr.getLocForBufferStart(bufferID);
391+
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
392+
for (auto *peer : sourceFile->getTopLevelDecls()) {
393+
callback(peer);
394+
}
395+
}
396+
397+
// FIXME: fold VarDecl::visitAuxiliaryDecls into this.
398+
}
399+
379400
void Decl::forEachAttachedMacro(MacroRole role,
380401
MacroCallback macroCallback) const {
381402
auto *dc = getDeclContext();

lib/Parse/ParseRequests.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,12 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator,
200200
}
201201

202202
case GeneratedSourceInfo::PeerMacroExpansion: {
203-
// FIXME: this does not work for top-level or local peer expansions.
204-
parser.parseExpandedMemberList(items);
203+
if (parser.CurDeclContext->isTypeContext()) {
204+
parser.parseExpandedMemberList(items);
205+
} else {
206+
parser.parseTopLevelItems(items);
207+
}
208+
205209
break;
206210
}
207211
}

lib/SILGen/SILGen.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,6 +2188,13 @@ class SILGenModuleRAII {
21882188

21892189
SourceFileScope scope(SGM, sf);
21902190
for (auto *D : sf->getTopLevelDecls()) {
2191+
// Emit auxiliary decls.
2192+
D->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
2193+
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
2194+
"SILgen-decl", auxiliaryDecl);
2195+
SGM.visit(auxiliaryDecl);
2196+
});
2197+
21912198
FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
21922199
"SILgen-decl", D);
21932200
SGM.visit(D);

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ static void synthesizeMemberDeclsForLookup(NominalTypeDecl *NTD,
616616
(void)evaluateOrDefault(
617617
ctx.evaluator,
618618
ExpandPeerMacroRequest{member},
619-
false);
619+
{});
620620
}
621621

622622
synthesizePropertyWrapperVariables(NTD);

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2806,7 +2806,7 @@ static ArrayRef<Decl *> evaluateMembersRequest(
28062806
(void)evaluateOrDefault(
28072807
ctx.evaluator,
28082808
ExpandPeerMacroRequest{member},
2809-
false);
2809+
{});
28102810

28112811
if (auto *var = dyn_cast<VarDecl>(member)) {
28122812
// The projected storage wrapper ($foo) might have

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
18521852
}
18531853

18541854
void visit(Decl *decl) {
1855+
// Visit auxiliary decls first.
1856+
decl->visitAuxiliaryDecls([&](Decl *auxiliaryDecl) {
1857+
this->visit(auxiliaryDecl);
1858+
});
1859+
18551860
if (auto *Stats = getASTContext().Stats)
18561861
++Stats->getFrontendCounters().NumDeclsTypechecked;
18571862

lib/Sema/TypeCheckMacros.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,9 +1194,6 @@ swift::expandPeers(CustomAttr *attr, MacroDecl *macro, Decl *decl) {
11941194
nominal->addMember(peer);
11951195
} else if (auto *extension = dyn_cast<ExtensionDecl>(parent)) {
11961196
extension->addMember(peer);
1197-
} else {
1198-
// TODO: Add peers to global or local contexts.
1199-
continue;
12001197
}
12011198
}
12021199

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static void computeLoweredStoredProperties(NominalTypeDecl *decl,
121121
(void)evaluateOrDefault(
122122
ctx.evaluator,
123123
ExpandPeerMacroRequest{member},
124-
false);
124+
{});
125125

126126
auto *var = dyn_cast<VarDecl>(member);
127127
if (!var || var->isStatic())

0 commit comments

Comments
 (0)