Skip to content

Commit 98c2a83

Browse files
committedMar 5, 2023
[Macros] Always visit macro-produced decls as auxiliary decls
Always use `Decl::visitAuxiliaryDecls` to visit decls produced by macros, including peer macros and declaration macros. Use name-driven expansion for peer macros. Remove `MacroExpansionDecl::getRewritten()`. Also make `ExpandMacroExpansionDeclRequest` cache the buffer ID (similar to other macros) instead of an array of decls.

16 files changed

+172
-132
lines changed
 

‎include/swift/AST/ASTWalker.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ enum class MacroWalking {
9595

9696
/// Walk into both the arguments of the macro as written in the source code
9797
/// and also the macro expansion.
98-
ArgumentsAndExpansion
98+
ArgumentsAndExpansion,
99+
100+
/// Don't walk into macros.
101+
None
99102
};
100103

101104
/// An abstract class used to traverse an AST.
@@ -545,6 +548,9 @@ class ASTWalker {
545548

546549
case MacroWalking::ArgumentsAndExpansion:
547550
return std::make_pair(true, true);
551+
552+
case MacroWalking::None:
553+
return std::make_pair(false, false);
548554
}
549555
}
550556

‎include/swift/AST/Decl.h

-1
Original file line numberDiff line numberDiff line change
@@ -8527,7 +8527,6 @@ class MacroExpansionDecl : public Decl {
85278527
DeclNameLoc getMacroNameLoc() const { return MacroNameLoc; }
85288528
DeclNameRef getMacroName() const { return MacroName; }
85298529
ArgumentList *getArgs() const { return ArgList; }
8530-
ArrayRef<Decl *> getRewritten() const;
85318530
ConcreteDeclRef getMacroRef() const { return macroRef; }
85328531
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
85338532

‎include/swift/AST/TypeCheckRequests.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -3835,16 +3835,16 @@ class MacroDefinitionRequest
38353835
/// Find the definition of a given macro.
38363836
class ExpandMacroExpansionDeclRequest
38373837
: public SimpleRequest<ExpandMacroExpansionDeclRequest,
3838-
ArrayRef<Decl *>(MacroExpansionDecl *),
3838+
Optional<unsigned>(MacroExpansionDecl *),
38393839
RequestFlags::Cached> {
38403840
public:
38413841
using SimpleRequest::SimpleRequest;
38423842

38433843
private:
38443844
friend SimpleRequest;
38453845

3846-
ArrayRef<Decl *> evaluate(Evaluator &evaluator,
3847-
MacroExpansionDecl *med) const;
3846+
Optional<unsigned>
3847+
evaluate(Evaluator &evaluator, MacroExpansionDecl *med) const;
38483848

38493849
public:
38503850
bool isCached() const { return true; }

‎include/swift/AST/TypeMemberVisitor.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,17 @@ class TypeMemberVisitor : public DeclVisitor<ImplClass, RetTy> {
5454
return RetTy();
5555
}
5656

57+
RetTy visitMacroExpansionDecl(MacroExpansionDecl *D) {
58+
// Expansion already visited as auxiliary decls.
59+
return RetTy();
60+
}
61+
5762
/// A convenience method to visit all the members.
5863
void visitMembers(NominalTypeDecl *D) {
5964
for (Decl *member : D->getMembers()) {
65+
member->visitAuxiliaryDecls([&](Decl *decl) {
66+
asImpl().visit(decl);
67+
});
6068
asImpl().visit(member);
6169
}
6270
}
@@ -78,12 +86,6 @@ class TypeMemberVisitor : public DeclVisitor<ImplClass, RetTy> {
7886
asImpl().visit(dd);
7987
}
8088
}
81-
82-
/// Visit expanded macros.
83-
void visitMacroExpansionDecl(MacroExpansionDecl *D) {
84-
for (auto *decl : D->getRewritten())
85-
asImpl().visit(decl);
86-
}
8789
};
8890

8991
template<typename ImplClass, typename RetTy = void>

‎lib/AST/ASTVerifier.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class Verifier : public ASTWalker {
272272
}
273273

274274
MacroWalking getMacroWalkingBehavior() const override {
275-
return MacroWalking::Expansion;
275+
return MacroWalking::None;
276276
}
277277

278278
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {

‎lib/AST/ASTWalker.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -433,15 +433,17 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
433433
bool shouldWalkArguments, shouldWalkExpansion;
434434
std::tie(shouldWalkArguments, shouldWalkExpansion) =
435435
Walker.shouldWalkMacroArgumentsAndExpansion();
436-
if (shouldWalkArguments && MED->getArgs() && doIt(MED->getArgs()))
436+
if (shouldWalkArguments && MED->getArgs() && !doIt(MED->getArgs()))
437437
return true;
438-
438+
// Visit auxiliary decls, which may be decls from macro expansions.
439+
bool alreadyFailed = false;
439440
if (shouldWalkExpansion) {
440-
for (auto *decl : MED->getRewritten())
441-
if (doIt(decl))
442-
return true;
441+
MED->visitAuxiliaryDecls([&](Decl *decl) {
442+
if (alreadyFailed) return;
443+
alreadyFailed = inherited::visit(decl);
444+
});
443445
}
444-
return false;
446+
return alreadyFailed;
445447
}
446448

447449
bool visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {

‎lib/AST/Decl.cpp

+13-8
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,16 @@ void Decl::visitAuxiliaryDecls(AuxiliaryDeclCallback callback) const {
413413
}
414414
}
415415

416+
else if (auto *med = dyn_cast<MacroExpansionDecl>(mutableThis)) {
417+
if (auto bufferID = evaluateOrDefault(
418+
ctx.evaluator, ExpandMacroExpansionDeclRequest{med}, {})) {
419+
auto startLoc = sourceMgr.getLocForBufferStart(*bufferID);
420+
auto *sourceFile = moduleDecl->getSourceFileContainingLocation(startLoc);
421+
for (auto *decl : sourceFile->getTopLevelDecls())
422+
callback(decl);
423+
}
424+
}
425+
416426
// FIXME: fold VarDecl::visitAuxiliaryDecls into this.
417427
}
418428

@@ -1915,7 +1925,9 @@ StringRef PatternBindingEntry::getInitStringRepresentation(
19151925

19161926
SourceRange PatternBindingDecl::getSourceRange() const {
19171927
SourceLoc startLoc = getStartLoc();
1918-
SourceLoc endLoc = getPatternList().back().getSourceRange().End;
1928+
SourceLoc endLoc = getPatternList().empty()
1929+
? SourceLoc()
1930+
: getPatternList().back().getSourceRange().End;
19191931
if (startLoc.isValid() != endLoc.isValid()) return SourceRange();
19201932
return { startLoc, endLoc };
19211933
}
@@ -10159,13 +10171,6 @@ unsigned MacroExpansionDecl::getDiscriminator() const {
1015910171
return getRawDiscriminator();
1016010172
}
1016110173

10162-
ArrayRef<Decl *> MacroExpansionDecl::getRewritten() const {
10163-
auto mutableThis = const_cast<MacroExpansionDecl *>(this);
10164-
return evaluateOrDefault(
10165-
getASTContext().evaluator,
10166-
ExpandMacroExpansionDeclRequest{mutableThis}, {});
10167-
}
10168-
1016910174
NominalTypeDecl *
1017010175
ValueDecl::getRuntimeDiscoverableAttrTypeDecl(CustomAttr *attr) const {
1017110176
auto &ctx = getASTContext();

‎lib/AST/NameLookup.cpp

+62-40
Original file line numberDiff line numberDiff line change
@@ -1510,48 +1510,70 @@ populateLookupTableEntryFromMacroExpansions(ASTContext &ctx,
15101510
MemberLookupTable &table,
15111511
DeclName name,
15121512
NominalTypeDecl *dc) {
1513-
auto expandAndPopulate = [&](MacroExpansionDecl *med) {
1514-
auto expanded = evaluateOrDefault(med->getASTContext().evaluator,
1515-
ExpandMacroExpansionDeclRequest{med},
1516-
nullptr);
1517-
for (auto *decl : expanded)
1518-
table.addMember(decl);
1519-
};
1520-
1513+
auto *moduleScopeCtx = dc->getModuleScopeContext();
1514+
auto *module = dc->getModuleContext();
15211515
for (auto *member : dc->getCurrentMembersWithoutLoading()) {
1522-
auto *med = dyn_cast<MacroExpansionDecl>(member);
1523-
if (!med)
1524-
continue;
1525-
auto declRef = evaluateOrDefault(
1526-
ctx.evaluator, ResolveMacroRequest{med, dc},
1527-
nullptr);
1528-
auto *macro = dyn_cast_or_null<MacroDecl>(declRef.getDecl());
1529-
if (!macro)
1530-
continue;
1531-
auto *attr = macro->getMacroRoleAttr(MacroRole::Declaration);
1532-
// If a macro produces arbitrary names, we have to expand it to factor its
1533-
// expansion results into name lookup.
1534-
if (attr->hasNameKind(MacroIntroducedDeclNameKind::Arbitrary)) {
1535-
expandAndPopulate(med);
1536-
}
1537-
// Otherwise, we expand the macro if it has the same decl base name being
1538-
// looked for.
1539-
else {
1540-
auto it = llvm::find_if(attr->getNames(),
1541-
[&](const MacroIntroducedDeclName &introName) {
1542-
// FIXME: The `Named` kind of `MacroIntroducedDeclName` should store a
1543-
// `DeclName` instead of `Identifier`. This is so that we can compare
1544-
// base identifiers when the macro specifies a compound name.
1545-
// Currently only simple names are allowed in a `MacroRoleAttr`.
1546-
if (!name.isSpecial())
1547-
return introName.getIdentifier() == name.getBaseIdentifier();
1548-
else
1549-
return introName.getIdentifier().str() ==
1550-
name.getBaseName().userFacingName();
1551-
});
1552-
if (it != attr->getNames().end())
1553-
expandAndPopulate(med);
1516+
// Collect all macro introduced names, along with its corresponding macro
1517+
// reference. We need the macro reference to prevent adding auxiliary decls
1518+
// that weren't introduced by the macro.
1519+
llvm::SmallSet<DeclName, 4> allIntroducedNames;
1520+
bool introducesArbitraryNames = false;
1521+
if (auto *med = dyn_cast<MacroExpansionDecl>(member)) {
1522+
auto declRef = evaluateOrDefault(
1523+
ctx.evaluator, ResolveMacroRequest{med, dc},
1524+
nullptr);
1525+
if (!declRef)
1526+
continue;
1527+
auto *macro = dyn_cast<MacroDecl>(declRef.getDecl());
1528+
if (macro->getMacroRoleAttr(MacroRole::Declaration)
1529+
->hasNameKind(MacroIntroducedDeclNameKind::Arbitrary))
1530+
introducesArbitraryNames = true;
1531+
else {
1532+
SmallVector<DeclName, 4> introducedNames;
1533+
macro->getIntroducedNames(MacroRole::Declaration, nullptr,
1534+
introducedNames);
1535+
for (auto name : introducedNames)
1536+
allIntroducedNames.insert(name);
1537+
}
1538+
} else if (auto *vd = dyn_cast<ValueDecl>(member)) {
1539+
// We intentionally avoid calling `forEachAttachedMacro` in order to avoid
1540+
// a request cycle.
1541+
for (auto attrConst : member->getSemanticAttrs().getAttributes<CustomAttr>()) {
1542+
auto *attr = const_cast<CustomAttr *>(attrConst);
1543+
UnresolvedMacroReference macroRef(attr);
1544+
auto macroName = macroRef.getMacroName();
1545+
UnqualifiedLookupDescriptor lookupDesc{macroName, moduleScopeCtx};
1546+
auto lookup = evaluateOrDefault(
1547+
ctx.evaluator, UnqualifiedLookupRequest{lookupDesc}, {});
1548+
for (auto result : lookup.allResults()) {
1549+
auto *vd = result.getValueDecl();
1550+
auto *macro = dyn_cast<MacroDecl>(vd);
1551+
if (!macro)
1552+
continue;
1553+
auto *macroRoleAttr = macro->getMacroRoleAttr(MacroRole::Peer);
1554+
if (!macroRoleAttr)
1555+
continue;
1556+
if (macroRoleAttr->hasNameKind(
1557+
MacroIntroducedDeclNameKind::Arbitrary))
1558+
introducesArbitraryNames = true;
1559+
else {
1560+
SmallVector<DeclName, 4> introducedNames;
1561+
macro->getIntroducedNames(
1562+
MacroRole::Peer, dyn_cast<ValueDecl>(member), introducedNames);
1563+
for (auto name : introducedNames)
1564+
allIntroducedNames.insert(name);
1565+
}
1566+
}
1567+
}
15541568
}
1569+
// Expand macros based on the name.
1570+
if (introducesArbitraryNames || allIntroducedNames.contains(name))
1571+
member->visitAuxiliaryDecls([&](Decl *decl) {
1572+
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
1573+
// Bail out if the auxiliary decl was not produced by a macro.
1574+
if (!sf || sf->Kind != SourceFileKind::MacroExpansion) return;
1575+
table.addMember(decl);
1576+
});
15551577
}
15561578
}
15571579

‎lib/IRGen/GenDecl.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -2441,6 +2441,9 @@ void swift::irgen::disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariabl
24412441

24422442
/// Emit a global declaration.
24432443
void IRGenModule::emitGlobalDecl(Decl *D) {
2444+
D->visitAuxiliaryDecls([&](Decl *decl) {
2445+
emitGlobalDecl(decl);
2446+
});
24442447
switch (D->getKind()) {
24452448
case DeclKind::Extension:
24462449
return emitExtension(cast<ExtensionDecl>(D));
@@ -2526,8 +2529,7 @@ void IRGenModule::emitGlobalDecl(Decl *D) {
25262529
return;
25272530

25282531
case DeclKind::MacroExpansion:
2529-
for (auto *rewritten : cast<MacroExpansionDecl>(D)->getRewritten())
2530-
emitGlobalDecl(rewritten);
2532+
// Expansion already visited as auxiliary decls.
25312533
return;
25322534
}
25332535

@@ -5452,6 +5454,9 @@ Address IRGenModule::getAddrOfEnumCase(EnumElementDecl *Case,
54525454

54535455
void IRGenModule::emitNestedTypeDecls(DeclRange members) {
54545456
for (Decl *member : members) {
5457+
member->visitAuxiliaryDecls([&](Decl *decl) {
5458+
emitNestedTypeDecls({decl, nullptr});
5459+
});
54555460
switch (member->getKind()) {
54565461
case DeclKind::Import:
54575462
case DeclKind::TopLevelCode:
@@ -5512,8 +5517,7 @@ void IRGenModule::emitNestedTypeDecls(DeclRange members) {
55125517
emitClassDecl(cast<ClassDecl>(member));
55135518
continue;
55145519
case DeclKind::MacroExpansion:
5515-
for (auto *decl : cast<MacroExpansionDecl>(member)->getRewritten())
5516-
emitNestedTypeDecls({decl, nullptr});
5520+
// Expansion already visited as auxiliary decls.
55175521
continue;
55185522
}
55195523
}

‎lib/SILGen/SILGen.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1792,8 +1792,9 @@ void SILGenModule::visitMacroDecl(MacroDecl *d) {
17921792
}
17931793

17941794
void SILGenModule::visitMacroExpansionDecl(MacroExpansionDecl *d) {
1795-
// Expanded declaration macros were already added to the parent decl context
1796-
// for name lookup to work. Nothing to be done here.
1795+
d->visitAuxiliaryDecls([&](Decl *decl) {
1796+
visit(decl);
1797+
});
17971798
}
17981799

17991800
bool

‎lib/Sema/MiscDiagnostics.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3805,7 +3805,7 @@ void VarDeclUsageChecker::handleIfConfig(IfConfigDecl *ICD) {
38053805
: VDUC(VDUC), SF(VDUC.DC->getParentSourceFile()) {}
38063806

38073807
MacroWalking getMacroWalkingBehavior() const override {
3808-
return MacroWalking::ArgumentsAndExpansion;
3808+
return MacroWalking::Arguments;
38093809
}
38103810

38113811
PostWalkResult<Expr *> walkToExprPost(Expr *E) override {

‎lib/Sema/TypeCheckDecl.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -2829,12 +2829,6 @@ static ArrayRef<Decl *> evaluateMembersRequest(
28292829
nullptr);
28302830

28312831
for (auto *member : idc->getMembers()) {
2832-
// Expand peer macros.
2833-
(void)evaluateOrDefault(
2834-
ctx.evaluator,
2835-
ExpandPeerMacroRequest{member},
2836-
{});
2837-
28382832
if (auto *var = dyn_cast<VarDecl>(member)) {
28392833
// The projected storage wrapper ($foo) might have
28402834
// dynamically-dispatched accessors, so force them to be synthesized.
@@ -2847,17 +2841,22 @@ static ArrayRef<Decl *> evaluateMembersRequest(
28472841

28482842
SortedDeclList synthesizedMembers;
28492843

2850-
for (auto *member : idc->getMembers()) {
2844+
std::function<void(Decl *)> addResult;
2845+
addResult = [&](Decl *member) {
2846+
member->visitAuxiliaryDecls(addResult);
28512847
if (auto *vd = dyn_cast<ValueDecl>(member)) {
28522848
// Add synthesized members to a side table and sort them by their mangled
28532849
// name, since they could have been added to the class in any order.
28542850
if (vd->isSynthesized()) {
28552851
synthesizedMembers.add(vd);
2856-
continue;
2852+
return;
28572853
}
28582854
}
2859-
28602855
result.push_back(member);
2856+
};
2857+
2858+
for (auto *member : idc->getMembers()) {
2859+
addResult(member);
28612860
}
28622861

28632862
if (!synthesizedMembers.empty()) {

‎lib/Sema/TypeCheckDeclPrimary.cpp

+3-11
Original file line numberDiff line numberDiff line change
@@ -2063,12 +2063,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20632063
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {
20642064
// Assign a discriminator.
20652065
(void)MED->getDiscriminator();
2066-
2067-
auto rewritten = evaluateOrDefault(
2068-
Ctx.evaluator, ExpandMacroExpansionDeclRequest{MED}, {});
2069-
2070-
for (auto *decl : rewritten)
2071-
visit(decl);
2066+
// Expansion already visited as auxiliary decls.
20722067
}
20732068

20742069
void visitBoundVariable(VarDecl *VD) {
@@ -3763,7 +3758,7 @@ void TypeChecker::checkParameterList(ParameterList *params,
37633758
}
37643759
}
37653760

3766-
ArrayRef<Decl *>
3761+
Optional<unsigned>
37673762
ExpandMacroExpansionDeclRequest::evaluate(Evaluator &evaluator,
37683763
MacroExpansionDecl *MED) const {
37693764
auto &ctx = MED->getASTContext();
@@ -3785,8 +3780,5 @@ ExpandMacroExpansionDeclRequest::evaluate(Evaluator &evaluator,
37853780
MED->setMacroRef(macro);
37863781

37873782
// Expand the macro.
3788-
SmallVector<Decl *, 2> expandedTemporary;
3789-
if (!expandFreestandingDeclarationMacro(MED, expandedTemporary))
3790-
return {};
3791-
return ctx.AllocateCopy(expandedTemporary);
3783+
return expandFreestandingDeclarationMacro(MED);
37923784
}

‎lib/Sema/TypeCheckMacros.cpp

+14-26
Original file line numberDiff line numberDiff line change
@@ -676,17 +676,17 @@ Expr *swift::expandMacroExpr(
676676
return expandedExpr;
677677
}
678678

679-
/// Expands the given macro expansion declaration and type-check the result.
680-
bool swift::expandFreestandingDeclarationMacro(
681-
MacroExpansionDecl *med, SmallVectorImpl<Decl *> &results) {
679+
/// Expands the given macro expansion declaration.
680+
Optional<unsigned>
681+
swift::expandFreestandingDeclarationMacro(MacroExpansionDecl *med) {
682682
auto *dc = med->getDeclContext();
683683
ASTContext &ctx = dc->getASTContext();
684684
SourceManager &sourceMgr = ctx.SourceMgr;
685685

686686
auto moduleDecl = dc->getParentModule();
687687
auto sourceFile = moduleDecl->getSourceFileContainingLocation(med->getLoc());
688688
if (!sourceFile)
689-
return false;
689+
return None;
690690

691691
// Evaluate the macro.
692692
NullTerminatedStringRef evaluatedSource;
@@ -697,21 +697,21 @@ bool swift::expandFreestandingDeclarationMacro(
697697

698698
if (isFromExpansionOfMacro(sourceFile, macro, MacroRole::Declaration)) {
699699
med->diagnose(diag::macro_recursive, macro->getName());
700-
return false;
700+
return None;
701701
}
702702

703703
auto macroDef = macro->getDefinition();
704704
switch (macroDef.kind) {
705705
case MacroDefinition::Kind::Undefined:
706706
case MacroDefinition::Kind::Invalid:
707707
// Already diagnosed as an error elsewhere.
708-
return false;
708+
return None;
709709

710710
case MacroDefinition::Kind::Builtin: {
711711
switch (macroDef.getBuiltinKind()) {
712712
case BuiltinMacroKind::ExternalMacro:
713713
// FIXME: Error here.
714-
return false;
714+
return None;
715715
}
716716
}
717717

@@ -729,15 +729,15 @@ bool swift::expandFreestandingDeclarationMacro(
729729
macro->getName()
730730
);
731731
macro->diagnose(diag::decl_declared_here, macro->getName());
732-
return false;
732+
return None;
733733
}
734734

735735
// Make sure freestanding macros are enabled before we expand.
736736
if (!ctx.LangOpts.hasFeature(Feature::FreestandingMacros) &&
737737
!macro->getMacroRoles().contains(MacroRole::Expression)) {
738738
med->diagnose(
739739
diag::macro_experimental, "freestanding", "FreestandingMacros");
740-
return false;
740+
return None;
741741
}
742742

743743
#if SWIFT_SWIFT_PARSER
@@ -746,7 +746,7 @@ bool swift::expandFreestandingDeclarationMacro(
746746
// Builtin macros are handled via ASTGen.
747747
auto astGenSourceFile = sourceFile->exportedSourceFile;
748748
if (!astGenSourceFile)
749-
return false;
749+
return None;
750750

751751
Mangle::ASTMangler mangler;
752752
auto discriminator = mangler.mangleMacroExpansion(med);
@@ -760,13 +760,13 @@ bool swift::expandFreestandingDeclarationMacro(
760760
med->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
761761
&evaluatedSourceLength);
762762
if (!evaluatedSourceAddress)
763-
return false;
763+
return None;
764764
evaluatedSource = NullTerminatedStringRef(evaluatedSourceAddress,
765765
(size_t)evaluatedSourceLength);
766766
break;
767767
#else
768768
med->diagnose(diag::macro_unsupported);
769-
return false;
769+
return None;
770770
#endif
771771
}
772772
}
@@ -820,12 +820,11 @@ bool swift::expandFreestandingDeclarationMacro(
820820
if (!decl) {
821821
ctx.Diags.diagnose(
822822
macroBufferRange.getStart(), diag::expected_macro_expansion_decls);
823-
return false;
823+
return None;
824824
}
825825
decl->setDeclContext(dc);
826-
results.push_back(decl);
827826
}
828-
return true;
827+
return macroBufferID;
829828
}
830829

831830
// If this storage declaration is a variable with an explicit initializer,
@@ -1219,17 +1218,6 @@ swift::expandPeers(CustomAttr *attr, MacroDecl *macro, Decl *decl) {
12191218
return None;
12201219

12211220
PrettyStackTraceDecl debugStack("applying expanded peer macro", decl);
1222-
1223-
auto *parent = decl->getDeclContext();
1224-
auto topLevelDecls = macroSourceFile->getTopLevelDecls();
1225-
for (auto peer : topLevelDecls) {
1226-
if (auto *nominal = dyn_cast<NominalTypeDecl>(parent)) {
1227-
nominal->addMember(peer);
1228-
} else if (auto *extension = dyn_cast<ExtensionDecl>(parent)) {
1229-
extension->addMember(peer);
1230-
}
1231-
}
1232-
12331221
return macroSourceFile->getBufferID();
12341222
}
12351223

‎lib/Sema/TypeCheckMacros.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ Expr *expandMacroExpr(
4343
/// Expands the given macro expansion declaration, type-checks the replacement
4444
/// declarations, and adds them to \p results.
4545
///
46-
/// \returns true if expansion succeeded, false if failed.
47-
bool expandFreestandingDeclarationMacro(
48-
MacroExpansionDecl *med, SmallVectorImpl<Decl *> &results);
46+
/// \returns Expansion buffer ID if expansion succeeded, \p None if failed.
47+
Optional<unsigned> expandFreestandingDeclarationMacro(MacroExpansionDecl *med);
4948

5049
/// Expand the accessors for the given storage declaration based on the
5150
/// custom attribute that references the given macro.

‎test/Macros/macro_expand_peers.swift

+31-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-build-swift -swift-version 5 -I %swift-host-lib-dir -L %swift-host-lib-dir -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
3-
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -disable-availability-checking
4-
// RUN: %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir %s -disable-availability-checking -dump-macro-expansions > %t/expansions-dump.txt 2>&1
2+
// RUN: %target-build-swift -swift-version 5 -I %swift-host-lib-dir -L %swift-host-lib-dir -emit-library -o %t/%target-library-name(MacroDefinition) -parse-as-library -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
3+
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -I %swift-host-lib-dir -disable-availability-checking
4+
// RUN: %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -I %swift-host-lib-dir %s -disable-availability-checking -dump-macro-expansions > %t/expansions-dump.txt 2>&1
55
// RUN: %FileCheck -check-prefix=CHECK-DUMP %s < %t/expansions-dump.txt
66

7+
// RUN: %target-build-swift -swift-version 5 -Xfrontend -disable-availability-checking -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -I %swift-host-lib-dir -L %swift-host-lib-dir %s -o %t/main -module-name MacroUser
8+
// RUN: %target-run %t/main | %FileCheck %s -check-prefix=CHECK-EXEC
79

810
// FIXME: Swift parser is not enabled on Linux CI yet.
911
// REQUIRES: OS=macosx
@@ -24,9 +26,9 @@ struct S {
2426
// CHECK-DUMP: }
2527
// CHECK-DUMP: }
2628

27-
func useOverload() {
28-
f(a: 1, for: "", 2.0) {
29-
print($0)
29+
func useOverload(_ body: @escaping (String) -> Void) {
30+
self.f(a: 1, for: "hahaha local", 2.0) {
31+
body($0)
3032
}
3133
}
3234
}
@@ -43,13 +45,12 @@ func f(a: Int, for b: String, _ value: Double) async -> String {
4345
return b
4446
}
4547

46-
func useOverload() {
47-
f(a: 1, for: "", 2.0) {
48-
print($0)
48+
func useOverload(_ body: @escaping (String) -> Void) {
49+
f(a: 1, for: "hahaha global", 2.0) {
50+
body($0)
4951
}
5052
}
5153

52-
5354
@attached(peer)
5455
macro wrapInType() = #externalMacro(module: "MacroDefinition", type: "WrapInType")
5556

@@ -64,3 +65,23 @@ func global(a: Int, b: String) {
6465
// CHECK-DUMP: global(a: a, b: b)
6566
// CHECK-DUMP: }
6667
// CHECK-DUMP: }
68+
69+
@main
70+
struct Main {
71+
static func main() async {
72+
let result1 = await withCheckedContinuation { cont in
73+
S().useOverload {
74+
cont.resume(returning: $0)
75+
}
76+
}
77+
print(result1)
78+
// CHECK-EXEC: hahaha local
79+
let result2 = await withCheckedContinuation { cont in
80+
useOverload {
81+
cont.resume(returning: $0)
82+
}
83+
}
84+
print(result2)
85+
// CHECK-EXEC: hahaha global
86+
}
87+
}

0 commit comments

Comments
 (0)
Please sign in to comment.