@@ -1206,6 +1206,10 @@ class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
12061206 // / parent nominal type.
12071207 llvm::DenseSet<DeclBaseName> LazilyCompleteNames;
12081208
1209+ // / The set of names for which we have expanded relevant macros for in the
1210+ // / parent nominal type.
1211+ llvm::DenseSet<DeclName> LazilyCompleteNamesForMacroExpansion;
1212+
12091213public:
12101214 // / Create a new member lookup table.
12111215 explicit MemberLookupTable (ASTContext &ctx);
@@ -1234,6 +1238,23 @@ class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
12341238 LazilyCompleteNames.clear ();
12351239 }
12361240
1241+ bool isLazilyCompleteForMacroExpansion (DeclName name) const {
1242+ // If we've already expanded macros for a simple name, we must have expanded
1243+ // all macros that produce names with the same base identifier.
1244+ bool isBaseNameComplete = name.isCompoundName () &&
1245+ isLazilyCompleteForMacroExpansion (DeclName (name.getBaseName ()));
1246+ return isBaseNameComplete ||
1247+ LazilyCompleteNamesForMacroExpansion.contains (name);
1248+ }
1249+
1250+ void markLazilyCompleteForMacroExpansion (DeclName name) {
1251+ LazilyCompleteNamesForMacroExpansion.insert (name);
1252+ }
1253+
1254+ void clearLazilyCompleteForMacroExpansionCache () {
1255+ LazilyCompleteNamesForMacroExpansion.clear ();
1256+ }
1257+
12371258 // / Iterator into the lookup table.
12381259 typedef LookupTable::iterator iterator;
12391260
@@ -1356,6 +1377,7 @@ void NominalTypeDecl::addedExtension(ExtensionDecl *ext) {
13561377 if (ext->hasLazyMembers ()) {
13571378 table->addMembers (ext->getCurrentMembersWithoutLoading ());
13581379 table->clearLazilyCompleteCache ();
1380+ table->clearLazilyCompleteForMacroExpansionCache ();
13591381 } else {
13601382 table->addMembers (ext->getMembers ());
13611383 }
@@ -1483,6 +1505,55 @@ populateLookupTableEntryFromExtensions(ASTContext &ctx,
14831505 }
14841506}
14851507
1508+ static void
1509+ populateLookupTableEntryFromMacroExpansions (ASTContext &ctx,
1510+ MemberLookupTable &table,
1511+ DeclName name,
1512+ 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+
1521+ for (auto *member : dc->getCurrentMembersWithoutLoading ()) {
1522+ auto *med = dyn_cast<MacroExpansionDecl>(member);
1523+ if (!med)
1524+ continue ;
1525+ auto macro = evaluateOrDefault (
1526+ ctx.evaluator , ResolveMacroRequest{med, MacroRole::Declaration, dc},
1527+ nullptr );
1528+ if (!macro)
1529+ continue ;
1530+ auto *attr = macro->getMacroRoleAttr (MacroRole::Declaration);
1531+ // If a macro produces arbitrary names, we have to expand it to factor its
1532+ // expansion results into name lookup.
1533+ if (attr->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary)) {
1534+ expandAndPopulate (med);
1535+ }
1536+ // Otherwise, we expand the macro if it has the same decl base name being
1537+ // looked for.
1538+ else {
1539+ auto it = llvm::find_if (attr->getNames (),
1540+ [&](const MacroIntroducedDeclName &introName) {
1541+ // FIXME: The `Named` kind of `MacroIntroducedDeclName` should store a
1542+ // `DeclName` instead of `Identifier`. This is so that we can compare
1543+ // base identifiers when the macro specifies a compound name.
1544+ // Currently only simple names are allowed in a `MacroRoleAttr`.
1545+ if (!name.isSpecial ())
1546+ return introName.getIdentifier () == name.getBaseIdentifier ();
1547+ else
1548+ return introName.getIdentifier ().str () ==
1549+ name.getBaseName ().userFacingName ();
1550+ });
1551+ if (it != attr->getNames ().end ())
1552+ expandAndPopulate (med);
1553+ }
1554+ }
1555+ }
1556+
14861557MemberLookupTable *NominalTypeDecl::getLookupTable () {
14871558 if (!LookupTable.getPointer ()) {
14881559 auto &ctx = getASTContext ();
@@ -1646,6 +1717,11 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
16461717 Table.markLazilyComplete (baseName);
16471718 }
16481719
1720+ if (!Table.isLazilyCompleteForMacroExpansion (name)) {
1721+ populateLookupTableEntryFromMacroExpansions (ctx, Table, name, decl);
1722+ Table.markLazilyCompleteForMacroExpansion (name);
1723+ }
1724+
16491725 // Look for a declaration with this name.
16501726 auto known = Table.find (name);
16511727 if (known == Table.end ()) {
0 commit comments