diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 21 |
2 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1a415b01dac..3345a1bbecb 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14826,6 +14826,9 @@ void Sema::ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod) { VisibleModules = std::move(VisibleModulesStack.back()); VisibleModulesStack.pop_back(); VisibleModules.setVisible(Mod, DirectiveLoc); + // Leaving a module hides namespace names, so our visible namespace cache + // is now out of date. + VisibleNamespaceCache.clear(); } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 3efcf5a3e41..a35c7600ab5 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1566,6 +1566,10 @@ static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); for (auto RD : D->redecls()) { + // Don't bother with extra checks if we already know this one isn't visible. + if (RD == D) + continue; + if (auto ND = dyn_cast<NamedDecl>(RD)) { // FIXME: This is wrong in the case where the previous declaration is not // visible in the same scope as D. This needs to be done much more @@ -1579,6 +1583,23 @@ static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { } NamedDecl *LookupResult::getAcceptableDeclSlow(NamedDecl *D) const { + if (auto *ND = dyn_cast<NamespaceDecl>(D)) { + // Namespaces are a bit of a special case: we expect there to be a lot of + // redeclarations of some namespaces, all declarations of a namespace are + // essentially interchangeable, all declarations are found by name lookup + // if any is, and namespaces are never looked up during template + // instantiation. So we benefit from caching the check in this case, and + // it is correct to do so. + auto *Key = ND->getCanonicalDecl(); + if (auto *Acceptable = getSema().VisibleNamespaceCache.lookup(Key)) + return Acceptable; + auto *Acceptable = + isVisible(getSema(), Key) ? Key : findAcceptableDecl(getSema(), Key); + if (Acceptable) + getSema().VisibleNamespaceCache.insert(std::make_pair(Key, Acceptable)); + return Acceptable; + } + return findAcceptableDecl(getSema(), D); } |

