Skip to content

Commit 081a6af

Browse files
committed
[Name lookup] Factor out qualified lookup into a module.
The “name lookup into a module” lookup is completely different from performing name lookup into a type. Factor it out into its own utility routine.
1 parent 1cf6ef1 commit 081a6af

File tree

2 files changed

+64
-48
lines changed

2 files changed

+64
-48
lines changed

include/swift/AST/DeclContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,10 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
486486
LazyResolver *typeResolver,
487487
SmallVectorImpl<ValueDecl *> &decls) const;
488488

489+
/// Perform qualified lookup for the given member in the given module.
490+
bool lookupQualified(ModuleDecl *module, DeclName member, NLOptions options,
491+
SmallVectorImpl<ValueDecl *> &decls) const;
492+
489493
/// Perform \c AnyObject lookup for the given member.
490494
bool lookupAnyObject(DeclName member, NLOptions options,
491495
SmallVectorImpl<ValueDecl *> &decls) const;

lib/AST/NameLookup.cpp

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,10 @@ bool DeclContext::lookupQualified(Type type,
16341634
if (type->isAnyObject())
16351635
return lookupAnyObject(member, options, decls);
16361636

1637+
// Handle lookup in a module.
1638+
if (auto moduleTy = type->getAs<ModuleType>())
1639+
return lookupQualified(moduleTy->getModule(), member, options, decls);
1640+
16371641
if (!typeResolver)
16381642
typeResolver = getASTContext().getLazyResolver();
16391643

@@ -1642,54 +1646,6 @@ bool DeclContext::lookupQualified(Type type,
16421646
bool isLookupCascading;
16431647
configureLookup(this, options, tracker, isLookupCascading);
16441648

1645-
// Look for module references.
1646-
if (auto moduleTy = type->getAs<ModuleType>()) {
1647-
ModuleDecl *module = moduleTy->getModule();
1648-
auto topLevelScope = getModuleScopeContext();
1649-
if (module == topLevelScope->getParentModule()) {
1650-
if (tracker) {
1651-
recordLookupOfTopLevelName(topLevelScope, member, isLookupCascading);
1652-
}
1653-
lookupInModule(module, /*accessPath=*/{}, member, decls,
1654-
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
1655-
typeResolver, topLevelScope);
1656-
} else {
1657-
// Note: This is a lookup into another module. Unless we're compiling
1658-
// multiple modules at once, or if the other module re-exports this one,
1659-
// it shouldn't be possible to have a dependency from that module on
1660-
// anything in this one.
1661-
1662-
// Perform the lookup in all imports of this module.
1663-
forAllVisibleModules(this,
1664-
[&](const ModuleDecl::ImportedModule &import) -> bool {
1665-
if (import.second != module)
1666-
return true;
1667-
lookupInModule(import.second, import.first, member, decls,
1668-
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
1669-
typeResolver, topLevelScope);
1670-
// If we're able to do an unscoped lookup, we see everything. No need
1671-
// to keep going.
1672-
return !import.first.empty();
1673-
});
1674-
}
1675-
1676-
llvm::SmallPtrSet<ValueDecl *, 4> knownDecls;
1677-
decls.erase(std::remove_if(decls.begin(), decls.end(),
1678-
[&](ValueDecl *vd) -> bool {
1679-
// If we're performing a type lookup, don't even attempt to validate
1680-
// the decl if its not a type.
1681-
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(vd))
1682-
return true;
1683-
1684-
return !knownDecls.insert(vd).second;
1685-
}), decls.end());
1686-
1687-
if (auto *debugClient = topLevelScope->getParentModule()->getDebugClient())
1688-
filterForDiscriminator(decls, debugClient);
1689-
1690-
return !decls.empty();
1691-
}
1692-
16931649
// The set of nominal type declarations we should (and have) visited.
16941650
SmallVector<NominalTypeDecl *, 4> stack;
16951651
llvm::SmallPtrSet<NominalTypeDecl *, 4> visited;
@@ -1828,8 +1784,64 @@ bool DeclContext::lookupQualified(Type type,
18281784
return finishLookup(this, options, decls);
18291785
}
18301786

1787+
bool DeclContext::lookupQualified(ModuleDecl *module, DeclName member,
1788+
NLOptions options,
1789+
SmallVectorImpl<ValueDecl *> &decls) const {
1790+
using namespace namelookup;
1791+
assert(decls.empty() && "additive lookup not supported");
1792+
1793+
// Configure lookup and dig out the tracker.
1794+
ReferencedNameTracker *tracker = nullptr;
1795+
bool isLookupCascading;
1796+
configureLookup(this, options, tracker, isLookupCascading);
1797+
1798+
ASTContext &ctx = getASTContext();
1799+
auto topLevelScope = getModuleScopeContext();
1800+
if (module == topLevelScope->getParentModule()) {
1801+
if (tracker) {
1802+
recordLookupOfTopLevelName(topLevelScope, member, isLookupCascading);
1803+
}
1804+
lookupInModule(module, /*accessPath=*/{}, member, decls,
1805+
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
1806+
ctx.getLazyResolver(), topLevelScope);
1807+
} else {
1808+
// Note: This is a lookup into another module. Unless we're compiling
1809+
// multiple modules at once, or if the other module re-exports this one,
1810+
// it shouldn't be possible to have a dependency from that module on
1811+
// anything in this one.
1812+
1813+
// Perform the lookup in all imports of this module.
1814+
forAllVisibleModules(this,
1815+
[&](const ModuleDecl::ImportedModule &import) -> bool {
1816+
if (import.second != module)
1817+
return true;
1818+
lookupInModule(import.second, import.first, member, decls,
1819+
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
1820+
ctx.getLazyResolver(), topLevelScope);
1821+
// If we're able to do an unscoped lookup, we see everything. No need
1822+
// to keep going.
1823+
return !import.first.empty();
1824+
});
1825+
}
1826+
1827+
llvm::SmallPtrSet<ValueDecl *, 4> knownDecls;
1828+
decls.erase(std::remove_if(decls.begin(), decls.end(),
1829+
[&](ValueDecl *vd) -> bool {
1830+
// If we're performing a type lookup, skip non-types.
1831+
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(vd))
1832+
return true;
1833+
1834+
return !knownDecls.insert(vd).second;
1835+
}), decls.end());
1836+
1837+
return finishLookup(this, options, decls);
1838+
}
1839+
18311840
bool DeclContext::lookupAnyObject(DeclName member, NLOptions options,
18321841
SmallVectorImpl<ValueDecl *> &decls) const {
1842+
using namespace namelookup;
1843+
assert(decls.empty() && "additive lookup not supported");
1844+
18331845
// Configure lookup and dig out the tracker.
18341846
ReferencedNameTracker *tracker = nullptr;
18351847
bool isLookupCascading;

0 commit comments

Comments
 (0)