diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-20 02:17:21 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-20 02:17:21 +0000 |
commit | 625ccb3f7897cb056c44808c6352d93378ac94a3 (patch) | |
tree | ce4511d24f37c1ab9703410cb73f1e3a6fcbb98f /clang/lib/Sema/SemaLookup.cpp | |
parent | 41a1546ebcd07c27ac46bc9858159e7ba6532d1d (diff) | |
download | bcm5719-llvm-625ccb3f7897cb056c44808c6352d93378ac94a3.tar.gz bcm5719-llvm-625ccb3f7897cb056c44808c6352d93378ac94a3.zip |
[modules] Remove some redundant work when building a lookup table for a DeclContext.
When we need to build the lookup table for a DeclContext, we used to pull in
all lexical declarations for the context; instead, just build a lookup table
for the local lexical declarations. We previously didn't guarantee that the
imported declarations would be in the returned map, but in some cases we'd
happen to put them all in there regardless. Now we're even lazier about this.
This unnecessary work was papering over some other bugs:
- LookupVisibleDecls would use the DC for name lookups in the TU in C, and
this was not guaranteed to find all imported names (generally, the DC for
the TU in C is not a reliable place to perform lookups). We now use an
identifier-based lookup mechanism for this.
- We didn't actually load in the list of eagerly-deserialized declarations
when importing a module (so external definitions in a module wouldn't be
emitted by users of those modules unless they happened to be deserialized
by the user of the module).
llvm-svn: 232793
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index e15e532be19..0b406184058 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3021,17 +3021,45 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, if (Visited.visitedContext(Ctx->getPrimaryContext())) return; + // Outside C++, lookup results for the TU live on identifiers. + if (isa<TranslationUnitDecl>(Ctx) && + !Result.getSema().getLangOpts().CPlusPlus) { + auto &S = Result.getSema(); + auto &Idents = S.Context.Idents; + + // Ensure all external identifiers are in the identifier table. + if (IdentifierInfoLookup *External = Idents.getExternalIdentifierLookup()) { + std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers()); + for (StringRef Name = Iter->Next(); !Name.empty(); Name = Iter->Next()) + Idents.get(Name); + } + + // Walk all lookup results in the TU for each identifier. + for (const auto &Ident : Idents) { + for (auto I = S.IdResolver.begin(Ident.getValue()), + E = S.IdResolver.end(); + I != E; ++I) { + if (S.IdResolver.isDeclInScope(*I, Ctx)) { + if (NamedDecl *ND = Result.getAcceptableDecl(*I)) { + Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); + Visited.add(ND); + } + } + } + } + + return; + } + if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) Result.getSema().ForceDeclarationOfImplicitMembers(Class); // Enumerate all of the results in this context. for (const auto &R : Ctx->lookups()) { - for (auto *I : R) { - if (NamedDecl *ND = dyn_cast<NamedDecl>(I)) { - if ((ND = Result.getAcceptableDecl(ND))) { - Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); - Visited.add(ND); - } + for (auto *D : R) { + if (auto *ND = Result.getAcceptableDecl(D)) { + Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); + Visited.add(ND); } } } |