@@ -1534,77 +1534,132 @@ 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);
1605
+ }
1606
+
1607
+ bool shouldExpandForName (DeclName name) const {
1608
+ return introducesArbitraryNames || allIntroducedNames.contains (name);
1609
+ }
1610
+ };
1611
+ }
1612
+
1537
1613
static void
1538
1614
populateLookupTableEntryFromMacroExpansions (ASTContext &ctx,
1539
1615
MemberLookupTable &table,
1540
1616
DeclName name,
1541
1617
TypeOrExtensionDecl container) {
1618
+
1619
+ // Trigger the expansion of member macros on the container, if any of the
1620
+ // names match.
1621
+ {
1622
+ MacroIntroducedNameTracker nameTracker;
1623
+ auto decl = container.getAsDecl ();
1624
+ forEachPotentialAttachedMacro (decl, MacroRole::Member, nameTracker);
1625
+ if (nameTracker.shouldExpandForName (name)) {
1626
+ (void )evaluateOrDefault (
1627
+ ctx.evaluator ,
1628
+ ExpandSynthesizedMemberMacroRequest{decl},
1629
+ false );
1630
+ }
1631
+ }
1632
+
1542
1633
auto dc = container.getAsDeclContext ();
1543
- auto *moduleScopeCtx = dc->getModuleScopeContext ();
1544
1634
auto *module = dc->getParentModule ();
1545
1635
auto idc = container.getAsIterableDeclContext ();
1546
1636
for (auto *member : idc->getCurrentMembersWithoutLoading ()) {
1547
1637
// Collect all macro introduced names, along with its corresponding macro
1548
1638
// reference. We need the macro reference to prevent adding auxiliary decls
1549
1639
// that weren't introduced by the macro.
1550
- llvm::SmallSet<DeclName, 4 > allIntroducedNames;
1551
- bool introducesArbitraryNames = false ;
1640
+ MacroIntroducedNameTracker nameTracker;
1552
1641
if (auto *med = dyn_cast<MacroExpansionDecl>(member)) {
1553
1642
auto declRef = evaluateOrDefault (
1554
1643
ctx.evaluator , ResolveMacroRequest{med, dc},
1555
1644
nullptr );
1556
1645
if (!declRef)
1557
1646
continue ;
1558
1647
auto *macro = dyn_cast<MacroDecl>(declRef.getDecl ());
1559
- if (macro->getMacroRoleAttr (MacroRole::Declaration)
1560
- ->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary))
1561
- introducesArbitraryNames = true ;
1562
- else {
1563
- SmallVector<DeclName, 4 > introducedNames;
1564
- macro->getIntroducedNames (MacroRole::Declaration, nullptr ,
1565
- introducedNames);
1566
- for (auto name : introducedNames)
1567
- allIntroducedNames.insert (name);
1568
- }
1648
+ nameTracker (macro, macro->getMacroRoleAttr (MacroRole::Declaration));
1569
1649
} else if (auto *vd = dyn_cast<ValueDecl>(member)) {
1570
- // We intentionally avoid calling `forEachAttachedMacro` in order to avoid
1571
- // a request cycle.
1572
- for (auto attrConst : member->getSemanticAttrs ().getAttributes <CustomAttr>()) {
1573
- auto *attr = const_cast <CustomAttr *>(attrConst);
1574
- UnresolvedMacroReference macroRef (attr);
1575
- auto macroName = macroRef.getMacroName ();
1576
- UnqualifiedLookupDescriptor lookupDesc{macroName, moduleScopeCtx};
1577
- auto lookup = evaluateOrDefault (
1578
- ctx.evaluator , UnqualifiedLookupRequest{lookupDesc}, {});
1579
- for (auto result : lookup.allResults ()) {
1580
- auto *vd = result.getValueDecl ();
1581
- auto *macro = dyn_cast<MacroDecl>(vd);
1582
- if (!macro)
1583
- continue ;
1584
- auto *macroRoleAttr = macro->getMacroRoleAttr (MacroRole::Peer);
1585
- if (!macroRoleAttr)
1586
- continue ;
1587
- if (macroRoleAttr->hasNameKind (
1588
- MacroIntroducedDeclNameKind::Arbitrary))
1589
- introducesArbitraryNames = true ;
1590
- else {
1591
- SmallVector<DeclName, 4 > introducedNames;
1592
- macro->getIntroducedNames (
1593
- MacroRole::Peer, dyn_cast<ValueDecl>(member), introducedNames);
1594
- for (auto name : introducedNames)
1595
- allIntroducedNames.insert (name);
1596
- }
1597
- }
1598
- }
1650
+ nameTracker.attachedTo = dyn_cast<ValueDecl>(member);
1651
+ forEachPotentialAttachedMacro (member, MacroRole::Peer, nameTracker);
1599
1652
}
1600
- // Expand macros based on the name.
1601
- if (introducesArbitraryNames || allIntroducedNames.contains (name))
1653
+
1654
+ // Expand macros on this member.
1655
+ if (nameTracker.shouldExpandForName (name)) {
1602
1656
member->visitAuxiliaryDecls ([&](Decl *decl) {
1603
1657
auto *sf = module ->getSourceFileContainingLocation (decl->getLoc ());
1604
1658
// Bail out if the auxiliary decl was not produced by a macro.
1605
1659
if (!sf || sf->Kind != SourceFileKind::MacroExpansion) return ;
1606
1660
table.addMember (decl);
1607
1661
});
1662
+ }
1608
1663
}
1609
1664
}
1610
1665
@@ -2140,17 +2195,6 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
2140
2195
// Make sure we've resolved property wrappers, if we need them.
2141
2196
installPropertyWrapperMembersIfNeeded (current, member);
2142
2197
2143
- // Expand synthesized member macros.
2144
- auto &ctx = current->getASTContext ();
2145
- (void )evaluateOrDefault (ctx.evaluator ,
2146
- ExpandSynthesizedMemberMacroRequest{current},
2147
- false );
2148
- for (auto ext : current->getExtensions ()) {
2149
- (void )evaluateOrDefault (ctx.evaluator ,
2150
- ExpandSynthesizedMemberMacroRequest{ext},
2151
- false );
2152
- }
2153
-
2154
2198
// Look for results within the current nominal type and its extensions.
2155
2199
bool currentIsProtocol = isa<ProtocolDecl>(current);
2156
2200
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();
0 commit comments