diff options
author | Eric Liu <ioeric@google.com> | 2016-07-26 14:53:05 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-07-26 14:53:05 +0000 |
commit | df5bcea08806580cd2a99b12c9fd7d428fd60004 (patch) | |
tree | 35f4379f188b1b644589a9aca630491640d9215c /clang/lib/Tooling/Core/Lookup.cpp | |
parent | 94ed30a40132764010bf721d9136bd0e15b06c23 (diff) | |
download | bcm5719-llvm-df5bcea08806580cd2a99b12c9fd7d428fd60004.tar.gz bcm5719-llvm-df5bcea08806580cd2a99b12c9fd7d428fd60004.zip |
[Tooling] skip anonymous namespaces when checking if typeLoc references a type decl from a different canonical namespace.
Summary:
[Tooling] skip anonymous namespaces when checking if typeLoc
references a type decl from a different canonical namespace.
Reviewers: bkramer
Subscribers: cfe-commits, klimek
Differential Revision: https://reviews.llvm.org/D22808
llvm-svn: 276754
Diffstat (limited to 'clang/lib/Tooling/Core/Lookup.cpp')
-rw-r--r-- | clang/lib/Tooling/Core/Lookup.cpp | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/clang/lib/Tooling/Core/Lookup.cpp b/clang/lib/Tooling/Core/Lookup.cpp index 697eeb46ce4..84135f441d2 100644 --- a/clang/lib/Tooling/Core/Lookup.cpp +++ b/clang/lib/Tooling/Core/Lookup.cpp @@ -16,33 +16,46 @@ using namespace clang; using namespace clang::tooling; -static bool isInsideDifferentNamespaceWithSameName(const DeclContext *DeclA, - const DeclContext *DeclB) { +// Returns true if the context in which the type is used and the context in +// which the type is declared are the same semantical namespace but different +// lexical namespaces. +static bool +usingFromDifferentCanonicalNamespace(const DeclContext *FromContext, + const DeclContext *UseContext) { while (true) { - // Look past non-namespaces on DeclA. - while (DeclA && !isa<NamespaceDecl>(DeclA)) - DeclA = DeclA->getParent(); + // Look past non-namespaces and anonymous namespaces on FromContext. + // We can skip anonymous namespace because: + // 1. `FromContext` and `UseContext` must be in the same anonymous + // namespaces since referencing across anonymous namespaces is not possible. + // 2. If `FromContext` and `UseContext` are in the same anonymous namespace, + // the function will still return `false` as expected. + while (FromContext && + (!isa<NamespaceDecl>(FromContext) || + cast<NamespaceDecl>(FromContext)->isAnonymousNamespace())) + FromContext = FromContext->getParent(); - // Look past non-namespaces on DeclB. - while (DeclB && !isa<NamespaceDecl>(DeclB)) - DeclB = DeclB->getParent(); + // Look past non-namespaces and anonymous namespaces on UseContext. + while (UseContext && + (!isa<NamespaceDecl>(UseContext) || + cast<NamespaceDecl>(UseContext)->isAnonymousNamespace())) + UseContext = UseContext->getParent(); // We hit the root, no namespace collision. - if (!DeclA || !DeclB) + if (!FromContext || !UseContext) return false; // Literally the same namespace, not a collision. - if (DeclA == DeclB) + if (FromContext == UseContext) return false; // Now check the names. If they match we have a different namespace with the // same name. - if (cast<NamespaceDecl>(DeclA)->getDeclName() == - cast<NamespaceDecl>(DeclB)->getDeclName()) + if (cast<NamespaceDecl>(FromContext)->getDeclName() == + cast<NamespaceDecl>(UseContext)->getDeclName()) return true; - DeclA = DeclA->getParent(); - DeclB = DeclB->getParent(); + FromContext = FromContext->getParent(); + UseContext = UseContext->getParent(); } } @@ -98,8 +111,8 @@ std::string tooling::replaceNestedName(const NestedNameSpecifier *Use, const bool in_global_namespace = isa<TranslationUnitDecl>(FromDecl->getDeclContext()); if (class_name_only && !in_global_namespace && - !isInsideDifferentNamespaceWithSameName(FromDecl->getDeclContext(), - UseContext)) { + !usingFromDifferentCanonicalNamespace(FromDecl->getDeclContext(), + UseContext)) { auto Pos = ReplacementString.rfind("::"); return Pos != StringRef::npos ? ReplacementString.substr(Pos + 2) : ReplacementString; |