Skip to content

Commit 1707e76

Browse files
authored
[Macros] Expand nested macros in qualified name lookup. (#71407)
1 parent 7e9fee0 commit 1707e76

File tree

3 files changed

+75
-17
lines changed

3 files changed

+75
-17
lines changed

lib/AST/NameLookup.cpp

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,24 +1903,37 @@ populateLookupTableEntryFromMacroExpansions(ASTContext &ctx,
19031903
// Collect all macro introduced names, along with its corresponding macro
19041904
// reference. We need the macro reference to prevent adding auxiliary decls
19051905
// that weren't introduced by the macro.
1906-
MacroIntroducedNameTracker nameTracker;
1907-
if (auto *med = dyn_cast<MacroExpansionDecl>(member)) {
1908-
forEachPotentialResolvedMacro(
1909-
dc->getModuleScopeContext(), med->getMacroName(),
1910-
MacroRole::Declaration, nameTracker);
1911-
} else if (auto *vd = dyn_cast<ValueDecl>(member)) {
1912-
nameTracker.attachedTo = dyn_cast<ValueDecl>(member);
1913-
forEachPotentialAttachedMacro(member, MacroRole::Peer, nameTracker);
1914-
}
19151906

1916-
// Expand macros on this member.
1917-
if (nameTracker.shouldExpandForName(name)) {
1918-
member->visitAuxiliaryDecls([&](Decl *decl) {
1919-
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
1920-
// Bail out if the auxiliary decl was not produced by a macro.
1921-
if (!sf || sf->Kind != SourceFileKind::MacroExpansion) return;
1922-
table.addMember(decl);
1923-
});
1907+
std::deque<Decl *> mightIntroduceNames;
1908+
mightIntroduceNames.push_back(member);
1909+
1910+
while (!mightIntroduceNames.empty()) {
1911+
auto *member = mightIntroduceNames.front();
1912+
1913+
MacroIntroducedNameTracker nameTracker;
1914+
if (auto *med = dyn_cast<MacroExpansionDecl>(member)) {
1915+
forEachPotentialResolvedMacro(
1916+
dc->getModuleScopeContext(), med->getMacroName(),
1917+
MacroRole::Declaration, nameTracker);
1918+
} else if (auto *vd = dyn_cast<ValueDecl>(member)) {
1919+
nameTracker.attachedTo = dyn_cast<ValueDecl>(member);
1920+
forEachPotentialAttachedMacro(member, MacroRole::Peer, nameTracker);
1921+
}
1922+
1923+
// Expand macros on this member.
1924+
if (nameTracker.shouldExpandForName(name)) {
1925+
member->visitAuxiliaryDecls([&](Decl *decl) {
1926+
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
1927+
// Bail out if the auxiliary decl was not produced by a macro.
1928+
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
1929+
return;
1930+
1931+
mightIntroduceNames.push_back(decl);
1932+
table.addMember(decl);
1933+
});
1934+
}
1935+
1936+
mightIntroduceNames.pop_front();
19241937
}
19251938
}
19261939
}

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,35 @@ public struct SendableMacro: ExtensionMacro {
20912091
}
20922092
}
20932093

2094+
public struct GenerateStubMemberMacro: MemberMacro {
2095+
public static func expansion(
2096+
of node: AttributeSyntax,
2097+
providingMembersOf declaration: some DeclGroupSyntax,
2098+
conformingTo protocols: [TypeSyntax],
2099+
in context: some MacroExpansionContext
2100+
) throws -> [DeclSyntax] {
2101+
return ["#generateMemberStubs"]
2102+
}
2103+
}
2104+
2105+
public struct GenerateStubsFreestandingMacro: DeclarationMacro {
2106+
public static func expansion(
2107+
of node: some FreestandingMacroExpansionSyntax,
2108+
in context: some MacroExpansionContext
2109+
) throws -> [DeclSyntax] {
2110+
return ["#generateMember"]
2111+
}
2112+
}
2113+
2114+
public struct SingleMemberStubMacro: DeclarationMacro {
2115+
public static func expansion(
2116+
of node: some FreestandingMacroExpansionSyntax,
2117+
in context: some MacroExpansionContext
2118+
) throws -> [DeclSyntax] {
2119+
return ["static func member() {}"]
2120+
}
2121+
}
2122+
20942123
public struct FakeCodeItemMacro: DeclarationMacro, PeerMacro {
20952124
public static func expansion(
20962125
of node: some FreestandingMacroExpansionSyntax,

test/Macros/macro_expand_synthesized_members.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,19 @@ func testC2() {
141141
// CHECK: deinit was called
142142
}
143143
testC2()
144+
145+
@attached(member, names: arbitrary)
146+
macro GenerateStubs() = #externalMacro(module: "MacroDefinition", type: "GenerateStubMemberMacro")
147+
148+
@freestanding(declaration, names: arbitrary)
149+
macro generateMemberStubs() = #externalMacro(module: "MacroDefinition", type: "GenerateStubsFreestandingMacro")
150+
151+
@freestanding(declaration, names: named(member()))
152+
macro generateMember() = #externalMacro(module: "MacroDefinition", type: "SingleMemberStubMacro")
153+
154+
@GenerateStubs
155+
struct NestedMacroExpansion {}
156+
157+
func callNestedExpansionMember() {
158+
NestedMacroExpansion.member()
159+
}

0 commit comments

Comments
 (0)