@@ -1534,75 +1534,129 @@ static DeclName adjustLazyMacroExpansionNameKey(
1534
1534
return name;
1535
1535
}
1536
1536
1537
+ // / Call the given function body with each macro declaration and its associated
1538
+ // / role attribute for the given role.
1539
+ // /
1540
+ // / This routine intentionally avoids calling `forEachAttachedMacro`, which
1541
+ // / triggers request cycles.
1542
+ static void forEachPotentialResolvedMacro (
1543
+ DeclContext *moduleScopeCtx, DeclNameRef macroName, MacroRole role,
1544
+ llvm::function_ref<void (MacroDecl *, const MacroRoleAttr *)> body
1545
+ ) {
1546
+ ASTContext &ctx = moduleScopeCtx->getASTContext ();
1547
+ UnqualifiedLookupDescriptor lookupDesc{macroName, moduleScopeCtx};
1548
+ auto lookup = evaluateOrDefault (
1549
+ ctx.evaluator , UnqualifiedLookupRequest{lookupDesc}, {});
1550
+ for (auto result : lookup.allResults ()) {
1551
+ auto *vd = result.getValueDecl ();
1552
+ auto *macro = dyn_cast<MacroDecl>(vd);
1553
+ if (!macro)
1554
+ continue ;
1555
+
1556
+ auto *macroRoleAttr = macro->getMacroRoleAttr (role);
1557
+ if (!macroRoleAttr)
1558
+ continue ;
1559
+
1560
+ body (macro, macroRoleAttr);
1561
+ }
1562
+ }
1563
+
1564
+ // / For each macro with the given role that might be attached to the given
1565
+ // / declaration, call the body.
1566
+ static void forEachPotentialAttachedMacro (
1567
+ Decl *decl, MacroRole role,
1568
+ llvm::function_ref<void (MacroDecl *macro, const MacroRoleAttr *)> body
1569
+ ) {
1570
+ // We intentionally avoid calling `forEachAttachedMacro` in order to avoid
1571
+ // a request cycle.
1572
+ auto moduleScopeCtx = decl->getDeclContext ()->getModuleScopeContext ();
1573
+ for (auto attrConst : decl->getSemanticAttrs ().getAttributes <CustomAttr>()) {
1574
+ auto *attr = const_cast <CustomAttr *>(attrConst);
1575
+ UnresolvedMacroReference macroRef (attr);
1576
+ auto macroName = macroRef.getMacroName ();
1577
+ forEachPotentialResolvedMacro (moduleScopeCtx, macroName, role, body);
1578
+ }
1579
+ }
1580
+
1581
+ namespace {
1582
+ // / Function object that tracks macro-introduced names.
1583
+ struct MacroIntroducedNameTracker {
1584
+ ValueDecl *attachedTo = nullptr ;
1585
+
1586
+ llvm::SmallSet<DeclName, 4 > allIntroducedNames;
1587
+ bool introducesArbitraryNames = false ;
1588
+
1589
+ // / Augment the set of names with those introduced by the given macro.
1590
+ void operator ()(MacroDecl *macro, const MacroRoleAttr *attr) {
1591
+ // First check for arbitrary names.
1592
+ if (attr->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary)) {
1593
+ introducesArbitraryNames = true ;
1594
+ }
1595
+
1596
+ // If this introduces arbitrary names, there's nothing more to do.
1597
+ if (introducesArbitraryNames)
1598
+ return ;
1599
+
1600
+ SmallVector<DeclName, 4 > introducedNames;
1601
+ macro->getIntroducedNames (
1602
+ attr->getMacroRole (), attachedTo, introducedNames);
1603
+ for (auto name : introducedNames)
1604
+ allIntroducedNames.insert (name.getBaseName ());
1605
+ }
1606
+
1607
+ bool shouldExpandForName (DeclName name) const {
1608
+ return introducesArbitraryNames ||
1609
+ allIntroducedNames.contains (name.getBaseName ());
1610
+ }
1611
+ };
1612
+ }
1613
+
1537
1614
static void
1538
1615
populateLookupTableEntryFromMacroExpansions (ASTContext &ctx,
1539
1616
MemberLookupTable &table,
1540
1617
DeclName name,
1541
- NominalTypeDecl *dc) {
1542
- auto *moduleScopeCtx = dc->getModuleScopeContext ();
1543
- auto *module = dc->getModuleContext ();
1544
- for (auto *member : dc->getCurrentMembersWithoutLoading ()) {
1618
+ TypeOrExtensionDecl container) {
1619
+
1620
+ // Trigger the expansion of member macros on the container, if any of the
1621
+ // names match.
1622
+ {
1623
+ MacroIntroducedNameTracker nameTracker;
1624
+ auto decl = container.getAsDecl ();
1625
+ forEachPotentialAttachedMacro (decl, MacroRole::Member, nameTracker);
1626
+ if (nameTracker.shouldExpandForName (name)) {
1627
+ (void )evaluateOrDefault (
1628
+ ctx.evaluator ,
1629
+ ExpandSynthesizedMemberMacroRequest{decl},
1630
+ false );
1631
+ }
1632
+ }
1633
+
1634
+ auto dc = container.getAsDeclContext ();
1635
+ auto *module = dc->getParentModule ();
1636
+ auto idc = container.getAsIterableDeclContext ();
1637
+ for (auto *member : idc->getCurrentMembersWithoutLoading ()) {
1545
1638
// Collect all macro introduced names, along with its corresponding macro
1546
1639
// reference. We need the macro reference to prevent adding auxiliary decls
1547
1640
// that weren't introduced by the macro.
1548
- llvm::SmallSet<DeclName, 4 > allIntroducedNames;
1549
- bool introducesArbitraryNames = false ;
1641
+ MacroIntroducedNameTracker nameTracker;
1550
1642
if (auto *med = dyn_cast<MacroExpansionDecl>(member)) {
1551
- auto declRef = evaluateOrDefault (
1552
- ctx.evaluator , ResolveMacroRequest{med, dc},
1553
- nullptr );
1554
- if (!declRef)
1555
- continue ;
1556
- auto *macro = dyn_cast<MacroDecl>(declRef.getDecl ());
1557
- if (macro->getMacroRoleAttr (MacroRole::Declaration)
1558
- ->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary))
1559
- introducesArbitraryNames = true ;
1560
- else {
1561
- SmallVector<DeclName, 4 > introducedNames;
1562
- macro->getIntroducedNames (MacroRole::Declaration, nullptr ,
1563
- introducedNames);
1564
- for (auto name : introducedNames)
1565
- allIntroducedNames.insert (name);
1566
- }
1643
+ forEachPotentialResolvedMacro (
1644
+ member->getModuleContext (), med->getMacroName (),
1645
+ MacroRole::Declaration, nameTracker);
1567
1646
} else if (auto *vd = dyn_cast<ValueDecl>(member)) {
1568
- // We intentionally avoid calling `forEachAttachedMacro` in order to avoid
1569
- // a request cycle.
1570
- for (auto attrConst : member->getSemanticAttrs ().getAttributes <CustomAttr>()) {
1571
- auto *attr = const_cast <CustomAttr *>(attrConst);
1572
- UnresolvedMacroReference macroRef (attr);
1573
- auto macroName = macroRef.getMacroName ();
1574
- UnqualifiedLookupDescriptor lookupDesc{macroName, moduleScopeCtx};
1575
- auto lookup = evaluateOrDefault (
1576
- ctx.evaluator , UnqualifiedLookupRequest{lookupDesc}, {});
1577
- for (auto result : lookup.allResults ()) {
1578
- auto *vd = result.getValueDecl ();
1579
- auto *macro = dyn_cast<MacroDecl>(vd);
1580
- if (!macro)
1581
- continue ;
1582
- auto *macroRoleAttr = macro->getMacroRoleAttr (MacroRole::Peer);
1583
- if (!macroRoleAttr)
1584
- continue ;
1585
- if (macroRoleAttr->hasNameKind (
1586
- MacroIntroducedDeclNameKind::Arbitrary))
1587
- introducesArbitraryNames = true ;
1588
- else {
1589
- SmallVector<DeclName, 4 > introducedNames;
1590
- macro->getIntroducedNames (
1591
- MacroRole::Peer, dyn_cast<ValueDecl>(member), introducedNames);
1592
- for (auto name : introducedNames)
1593
- allIntroducedNames.insert (name);
1594
- }
1595
- }
1596
- }
1647
+ nameTracker.attachedTo = dyn_cast<ValueDecl>(member);
1648
+ forEachPotentialAttachedMacro (member, MacroRole::Peer, nameTracker);
1597
1649
}
1598
- // Expand macros based on the name.
1599
- if (introducesArbitraryNames || allIntroducedNames.contains (name))
1650
+
1651
+ // Expand macros on this member.
1652
+ if (nameTracker.shouldExpandForName (name)) {
1600
1653
member->visitAuxiliaryDecls ([&](Decl *decl) {
1601
1654
auto *sf = module ->getSourceFileContainingLocation (decl->getLoc ());
1602
1655
// Bail out if the auxiliary decl was not produced by a macro.
1603
1656
if (!sf || sf->Kind != SourceFileKind::MacroExpansion) return ;
1604
1657
table.addMember (decl);
1605
1658
});
1659
+ }
1606
1660
}
1607
1661
}
1608
1662
@@ -1773,6 +1827,10 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
1773
1827
if (!Table.isLazilyCompleteForMacroExpansion (macroExpansionKey)) {
1774
1828
populateLookupTableEntryFromMacroExpansions (
1775
1829
ctx, Table, macroExpansionKey, decl);
1830
+ for (auto ext : decl->getExtensions ()) {
1831
+ populateLookupTableEntryFromMacroExpansions (
1832
+ ctx, Table, macroExpansionKey, ext);
1833
+ }
1776
1834
Table.markLazilyCompleteForMacroExpansion (macroExpansionKey);
1777
1835
}
1778
1836
@@ -2134,12 +2192,6 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
2134
2192
// Make sure we've resolved property wrappers, if we need them.
2135
2193
installPropertyWrapperMembersIfNeeded (current, member);
2136
2194
2137
- // Expand synthesized member macros.
2138
- auto &ctx = current->getASTContext ();
2139
- (void )evaluateOrDefault (ctx.evaluator ,
2140
- ExpandSynthesizedMemberMacroRequest{current},
2141
- false );
2142
-
2143
2195
// Look for results within the current nominal type and its extensions.
2144
2196
bool currentIsProtocol = isa<ProtocolDecl>(current);
2145
2197
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();
0 commit comments