Skip to content

Commit b111ea4

Browse files
authored
Merge pull request #26825 from slavapestov/new-shadowing-rule-part-0
Few more small name lookup cleanups
2 parents c773364 + 9e18f2a commit b111ea4

File tree

5 files changed

+46
-71
lines changed

5 files changed

+46
-71
lines changed

lib/AST/ASTContext.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -868,15 +868,14 @@ StructDecl *ASTContext::getObjCBoolDecl() const {
868868
ClassDecl *ASTContext::get##NAME##Decl() const { \
869869
if (!getImpl().NAME##Decl) { \
870870
if (ModuleDecl *M = getLoadedModule(Id_Foundation)) { \
871-
/* Note: use unqualified lookup so we find NSError regardless of */ \
872-
/* whether it's defined in the Foundation module or the Clang */ \
873-
/* Foundation module it imports. */ \
874-
UnqualifiedLookup lookup(getIdentifier(#NAME), M); \
875-
if (auto type = lookup.getSingleTypeResult()) { \
876-
if (auto classDecl = dyn_cast<ClassDecl>(type)) { \
877-
if (classDecl->getGenericParams() == nullptr) { \
878-
getImpl().NAME##Decl = classDecl; \
879-
} \
871+
/* Note: lookupQualified() will search both the Foundation module \
872+
* and the Clang Foundation module it imports. */ \
873+
SmallVector<ValueDecl *, 1> decls; \
874+
M->lookupQualified(M, getIdentifier(#NAME), NL_OnlyTypes, decls); \
875+
if (decls.size() == 1 && isa<ClassDecl>(decls[0])) { \
876+
auto classDecl = cast<ClassDecl>(decls[0]); \
877+
if (classDecl->getGenericParams() == nullptr) { \
878+
getImpl().NAME##Decl = classDecl; \
880879
} \
881880
} \
882881
} \

lib/AST/NameLookup.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,14 +1613,16 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclName member,
16131613
bool isLookupCascading;
16141614
configureLookup(this, options, tracker, isLookupCascading);
16151615

1616+
auto kind = (options & NL_OnlyTypes
1617+
? ResolutionKind::TypesOnly
1618+
: ResolutionKind::Overloadable);
16161619
auto topLevelScope = getModuleScopeContext();
16171620
if (module == topLevelScope->getParentModule()) {
16181621
if (tracker) {
16191622
recordLookupOfTopLevelName(topLevelScope, member, isLookupCascading);
16201623
}
16211624
lookupInModule(module, /*accessPath=*/{}, member, decls,
1622-
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
1623-
topLevelScope);
1625+
NLKind::QualifiedLookup, kind, topLevelScope);
16241626
} else {
16251627
// Note: This is a lookup into another module. Unless we're compiling
16261628
// multiple modules at once, or if the other module re-exports this one,
@@ -1633,8 +1635,7 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclName member,
16331635
if (import.second != module)
16341636
return true;
16351637
lookupInModule(import.second, import.first, member, decls,
1636-
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
1637-
topLevelScope);
1638+
NLKind::QualifiedLookup, kind, topLevelScope);
16381639
// If we're able to do an unscoped lookup, we see everything. No need
16391640
// to keep going.
16401641
return !import.first.empty();
@@ -1644,10 +1645,6 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclName member,
16441645
llvm::SmallPtrSet<ValueDecl *, 4> knownDecls;
16451646
decls.erase(std::remove_if(decls.begin(), decls.end(),
16461647
[&](ValueDecl *vd) -> bool {
1647-
// If we're performing a type lookup, skip non-types.
1648-
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(vd))
1649-
return true;
1650-
16511648
return !knownDecls.insert(vd).second;
16521649
}), decls.end());
16531650

lib/ParseSIL/ParseSIL.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,14 +1170,19 @@ bool SILParser::performTypeLocChecking(TypeLoc &T, bool IsSILType,
11701170

11711171
/// Find the top-level ValueDecl or Module given a name.
11721172
static llvm::PointerUnion<ValueDecl *, ModuleDecl *>
1173-
lookupTopDecl(Parser &P, DeclBaseName Name) {
1173+
lookupTopDecl(Parser &P, DeclBaseName Name, bool typeLookup) {
11741174
// Use UnqualifiedLookup to look through all of the imports.
11751175
// We have to lie and say we're done with parsing to make this happen.
11761176
assert(P.SF.ASTStage == SourceFile::Parsing &&
11771177
"Unexpected stage during parsing!");
11781178
llvm::SaveAndRestore<SourceFile::ASTStage_t> ASTStage(P.SF.ASTStage,
11791179
SourceFile::Parsed);
1180-
UnqualifiedLookup DeclLookup(Name, &P.SF);
1180+
1181+
UnqualifiedLookup::Options options;
1182+
if (typeLookup)
1183+
options |= UnqualifiedLookup::Flags::TypeLookup;
1184+
1185+
UnqualifiedLookup DeclLookup(Name, &P.SF, SourceLoc(), options);
11811186
assert(DeclLookup.isSuccess() && DeclLookup.Results.size() == 1);
11821187
ValueDecl *VD = DeclLookup.Results.back().getValueDecl();
11831188
return VD;
@@ -1358,9 +1363,11 @@ bool SILParser::parseSILDottedPathWithoutPound(ValueDecl *&Decl,
13581363
}
13591364
} while (P.consumeIf(tok::period));
13601365

1361-
// Look up ValueDecl from a dotted path.
1366+
// Look up ValueDecl from a dotted path. If there are multiple components,
1367+
// the first one must be a type declaration.
13621368
ValueDecl *VD;
1363-
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res = lookupTopDecl(P, FullName[0]);
1369+
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res = lookupTopDecl(
1370+
P, FullName[0], /*typeLookup=*/FullName.size() > 1);
13641371
// It is possible that the last member lookup can return multiple lookup
13651372
// results. One example is the overloaded member functions.
13661373
if (Res.is<ModuleDecl*>()) {
@@ -5749,7 +5756,8 @@ bool SILParserTUState::parseSILVTable(Parser &P) {
57495756
return true;
57505757

57515758
// Find the class decl.
5752-
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res = lookupTopDecl(P, Name);
5759+
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res =
5760+
lookupTopDecl(P, Name, /*typeLookup=*/true);
57535761
assert(Res.is<ValueDecl*>() && "Class look-up should return a Decl");
57545762
ValueDecl *VD = Res.get<ValueDecl*>();
57555763
if (!VD) {
@@ -5836,7 +5844,8 @@ static ProtocolDecl *parseProtocolDecl(Parser &P, SILParser &SP) {
58365844
return nullptr;
58375845

58385846
// Find the protocol decl. The protocol can be imported.
5839-
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res = lookupTopDecl(P, DeclName);
5847+
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res =
5848+
lookupTopDecl(P, DeclName, /*typeLookup=*/true);
58405849
assert(Res.is<ValueDecl*>() && "Protocol look-up should return a Decl");
58415850
ValueDecl *VD = Res.get<ValueDecl*>();
58425851
if (!VD) {

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -950,11 +950,14 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
950950
if (!renamedParsedDeclName.ContextName.empty()) {
951951
return nullptr;
952952
}
953-
UnqualifiedLookup lookup(renamedDeclName.getBaseIdentifier(),
954-
declContext->getModuleScopeContext(),
955-
SourceLoc(),
956-
UnqualifiedLookup::Flags::TypeLookup);
957-
return lookup.getSingleTypeResult();
953+
SmallVector<ValueDecl *, 1> decls;
954+
declContext->lookupQualified(declContext->getParentModule(),
955+
renamedDeclName.getBaseIdentifier(),
956+
NL_OnlyTypes,
957+
decls);
958+
if (decls.size() == 1)
959+
return decls[0];
960+
return nullptr;
958961
}
959962

960963
TypeDecl *typeDecl = declContext->getSelfNominalTypeDecl();
@@ -1439,10 +1442,12 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
14391442
isNSObjectOrAnyHashable(ctx, typeArgs[0])) {
14401443
if (ModuleDecl *M = ctx.getLoadedModule(ctx.Id_Foundation)) {
14411444
if (!NSCopyingType) {
1442-
UnqualifiedLookup lookup(ctx.getIdentifier("NSCopying"), M);
1443-
auto type = lookup.getSingleTypeResult();
1444-
if (type && isa<ProtocolDecl>(type)) {
1445-
NSCopyingType = type->getDeclaredInterfaceType();
1445+
SmallVector<ValueDecl *, 1> decls;
1446+
M->lookupQualified(M, ctx.getIdentifier("NSCopying"),
1447+
NL_OnlyTypes, decls);
1448+
if (decls.size() == 1 && isa<ProtocolDecl>(decls[0])) {
1449+
NSCopyingType = cast<ProtocolDecl>(decls[0])
1450+
->getDeclaredInterfaceType();
14461451
} else {
14471452
NSCopyingType = Type();
14481453
}

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ namespace {
7474
LookupResult &Result;
7575
DeclContext *DC;
7676
NameLookupOptions Options;
77-
bool IsMemberLookup;
7877

7978
/// The vector of found declarations.
8079
SmallVector<ValueDecl *, 4> FoundDecls;
@@ -86,46 +85,13 @@ namespace {
8685

8786
public:
8887
LookupResultBuilder(LookupResult &result, DeclContext *dc,
89-
NameLookupOptions options,
90-
bool isMemberLookup)
91-
: Result(result), DC(dc), Options(options),
92-
IsMemberLookup(isMemberLookup) {
88+
NameLookupOptions options)
89+
: Result(result), DC(dc), Options(options) {
9390
if (dc->getASTContext().isAccessControlDisabled())
9491
Options |= NameLookupFlags::IgnoreAccessControl;
9592
}
9693

97-
/// Determine whether we should filter out the results by removing
98-
/// overridden and shadowed declarations.
99-
/// FIXME: We should *always* do this, but there are weird assumptions
100-
/// about the results of unqualified name lookup, e.g., that a local
101-
/// variable not having a type indicates that it hasn't been seen yet.
102-
bool shouldFilterResults() const {
103-
// Member lookups always filter results.
104-
if (IsMemberLookup) return true;
105-
106-
bool allAreInOtherModules = true;
107-
auto currentModule = DC->getParentModule();
108-
for (const auto &found : Result) {
109-
// We found a member, so we need to filter.
110-
if (found.getBaseDecl() != nullptr)
111-
return true;
112-
113-
// We found something in our own module.
114-
if (found.getValueDecl()->getDeclContext()->getParentModule() ==
115-
currentModule)
116-
allAreInOtherModules = false;
117-
}
118-
119-
// FIXME: Only perform shadowing if we found things from other modules.
120-
// This prevents us from introducing additional type-checking work
121-
// during name lookup.
122-
return allAreInOtherModules;
123-
}
124-
12594
~LookupResultBuilder() {
126-
// Check whether we should do this filtering aat all.
127-
if (!shouldFilterResults()) return;
128-
12995
// Remove any overridden declarations from the found-declarations set.
13096
removeOverriddenDecls(FoundDecls);
13197
removeOverriddenDecls(FoundOuterDecls);
@@ -305,7 +271,7 @@ LookupResult TypeChecker::lookupUnqualified(DeclContext *dc, DeclName name,
305271
convertToUnqualifiedLookupOptions(options));
306272

307273
LookupResult result;
308-
LookupResultBuilder builder(result, dc, options, /*memberLookup*/false);
274+
LookupResultBuilder builder(result, dc, options);
309275
for (auto idx : indices(lookup.Results)) {
310276
const auto &found = lookup.Results[idx];
311277
// Determine which type we looked through to find this result.
@@ -381,8 +347,7 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc,
381347
subOptions &= ~NL_RemoveOverridden;
382348
subOptions &= ~NL_RemoveNonVisible;
383349

384-
LookupResultBuilder builder(result, dc, options,
385-
/*memberLookup*/true);
350+
LookupResultBuilder builder(result, dc, options);
386351
SmallVector<ValueDecl *, 4> lookupResults;
387352
dc->lookupQualified(type, name, subOptions, lookupResults);
388353

0 commit comments

Comments
 (0)