Skip to content

Commit 57cca85

Browse files
committed
[Macros] Avoid unqualified lookup requests for macro names in the source lookup
cache, which obviously can cause request cycles.
1 parent be558d9 commit 57cca85

File tree

1 file changed

+30
-36
lines changed

1 file changed

+30
-36
lines changed

lib/AST/Module.cpp

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ class swift::SourceLookupCache {
171171
template<typename Range>
172172
void addToMemberCache(Range decls);
173173

174+
using MacroDeclMap = llvm::DenseMap<Identifier, TinyPtrVector<MacroDecl *>>;
175+
MacroDeclMap MacroDecls;
176+
174177
using AuxiliaryDeclMap = llvm::DenseMap<DeclName, TinyPtrVector<MissingDecl *>>;
175178
AuxiliaryDeclMap TopLevelAuxiliaryDecls;
176179
SmallVector<ValueDecl *, 4> MayHaveAuxiliaryDecls;
@@ -266,6 +269,9 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
266269

267270
if (auto *PG = dyn_cast<PrecedenceGroupDecl>(D))
268271
PrecedenceGroups[PG->getName()].push_back(PG);
272+
273+
if (auto *macro = dyn_cast<MacroDecl>(D))
274+
MacroDecls[macro->getBaseIdentifier()].push_back(macro);
269275
}
270276
}
271277

@@ -321,8 +327,6 @@ void SourceLookupCache::addToMemberCache(Range decls) {
321327

322328
void SourceLookupCache::populateAuxiliaryDeclCache() {
323329
for (auto *decl : MayHaveAuxiliaryDecls) {
324-
auto *dc = decl->getDeclContext();
325-
326330
// Gather macro-introduced peer names.
327331
llvm::SmallDenseMap<CustomAttr *, llvm::SmallVector<DeclName, 2>> introducedNames;
328332

@@ -341,16 +345,15 @@ void SourceLookupCache::populateAuxiliaryDeclCache() {
341345
for (auto attrConst : decl->getSemanticAttrs().getAttributes<CustomAttr>()) {
342346
auto *attr = const_cast<CustomAttr *>(attrConst);
343347
UnresolvedMacroReference macroRef(attr);
344-
auto moduleScopeDC = dc->getModuleScopeContext();
345-
ASTContext &ctx = moduleScopeDC->getASTContext();
346-
UnqualifiedLookupDescriptor descriptor(macroRef.getMacroName(), moduleScopeDC);
347-
auto lookup = evaluateOrDefault(
348-
ctx.evaluator, UnqualifiedLookupRequest{descriptor}, {});
349-
for (const auto &found : lookup.allResults()) {
350-
if (auto macro = dyn_cast<MacroDecl>(found.getValueDecl())) {
351-
macro->getIntroducedNames(MacroRole::Peer,
352-
decl, introducedNames[attr]);
353-
}
348+
auto macroName = macroRef.getMacroName().getBaseIdentifier();
349+
350+
auto found = MacroDecls.find(macroName);
351+
if (found == MacroDecls.end())
352+
continue;
353+
354+
for (const auto *macro : found->second) {
355+
macro->getIntroducedNames(MacroRole::Peer,
356+
decl, introducedNames[attr]);
354357
}
355358
}
356359

@@ -396,34 +399,25 @@ void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,
396399
auto I = TopLevelValues.find(Name);
397400
if (I == TopLevelValues.end()) return;
398401

399-
bool foundMacros = false;
400402
Result.reserve(I->second.size());
401-
for (ValueDecl *Elt : I->second) {
403+
for (ValueDecl *Elt : I->second)
402404
Result.push_back(Elt);
403-
foundMacros = isa<MacroDecl>(Elt);
404-
}
405405

406-
// If none of the results are macro decls, look into peers.
407-
//
408-
// FIXME: This approach is an approximation for whether lookup is attempting
409-
// to find macro declarations, and it may cause cycles for invalid macro
410-
// references. We need a more principled way to determine whether we're looking
411-
// for a macro and should not look into auxiliary decls during lookup.
406+
// Add top-level auxiliary decls to the result.
412407
//
413-
// We also need to not consider auxiliary decls if we're doing lookup from
414-
// inside a macro argument at module scope.
415-
if (!foundMacros) {
416-
populateAuxiliaryDeclCache();
417-
auto I = TopLevelAuxiliaryDecls.find(Name);
418-
if (I == TopLevelAuxiliaryDecls.end()) return;
419-
420-
for (auto *unexpandedDecl : I->second) {
421-
// Add expanded peers to the result.
422-
unexpandedDecl->forEachExpandedPeer(
423-
[&](ValueDecl *expandedPeer) {
424-
Result.push_back(expandedPeer);
425-
});
426-
}
408+
// FIXME: We need to not consider auxiliary decls if we're doing lookup
409+
// from inside a macro argument at module scope.
410+
populateAuxiliaryDeclCache();
411+
auto auxDecls = TopLevelAuxiliaryDecls.find(Name);
412+
if (auxDecls == TopLevelAuxiliaryDecls.end())
413+
return;
414+
415+
for (auto *unexpandedDecl : auxDecls->second) {
416+
// Add expanded peers to the result.
417+
unexpandedDecl->forEachExpandedPeer(
418+
[&](ValueDecl *expandedPeer) {
419+
Result.push_back(expandedPeer);
420+
});
427421
}
428422
}
429423

0 commit comments

Comments
 (0)