@@ -1534,75 +1534,129 @@ static DeclName adjustLazyMacroExpansionNameKey(
15341534 return name;
15351535}
15361536
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+
15371614static void
15381615populateLookupTableEntryFromMacroExpansions (ASTContext &ctx,
15391616 MemberLookupTable &table,
15401617 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 ()) {
15451638 // Collect all macro introduced names, along with its corresponding macro
15461639 // reference. We need the macro reference to prevent adding auxiliary decls
15471640 // that weren't introduced by the macro.
1548- llvm::SmallSet<DeclName, 4 > allIntroducedNames;
1549- bool introducesArbitraryNames = false ;
1641+ MacroIntroducedNameTracker nameTracker;
15501642 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);
15671646 } 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);
15971649 }
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)) {
16001653 member->visitAuxiliaryDecls ([&](Decl *decl) {
16011654 auto *sf = module ->getSourceFileContainingLocation (decl->getLoc ());
16021655 // Bail out if the auxiliary decl was not produced by a macro.
16031656 if (!sf || sf->Kind != SourceFileKind::MacroExpansion) return ;
16041657 table.addMember (decl);
16051658 });
1659+ }
16061660 }
16071661}
16081662
@@ -1773,6 +1827,10 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
17731827 if (!Table.isLazilyCompleteForMacroExpansion (macroExpansionKey)) {
17741828 populateLookupTableEntryFromMacroExpansions (
17751829 ctx, Table, macroExpansionKey, decl);
1830+ for (auto ext : decl->getExtensions ()) {
1831+ populateLookupTableEntryFromMacroExpansions (
1832+ ctx, Table, macroExpansionKey, ext);
1833+ }
17761834 Table.markLazilyCompleteForMacroExpansion (macroExpansionKey);
17771835 }
17781836
@@ -2134,12 +2192,6 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
21342192 // Make sure we've resolved property wrappers, if we need them.
21352193 installPropertyWrapperMembersIfNeeded (current, member);
21362194
2137- // Expand synthesized member macros.
2138- auto &ctx = current->getASTContext ();
2139- (void )evaluateOrDefault (ctx.evaluator ,
2140- ExpandSynthesizedMemberMacroRequest{current},
2141- false );
2142-
21432195 // Look for results within the current nominal type and its extensions.
21442196 bool currentIsProtocol = isa<ProtocolDecl>(current);
21452197 auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();
0 commit comments