r276754 - [Tooling] skip anonymous namespaces when checking if typeLoc references a type decl from a different canonical namespace.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 26 07:53:06 PDT 2016
Author: ioeric
Date: Tue Jul 26 09:53:05 2016
New Revision: 276754
URL: http://llvm.org/viewvc/llvm-project?rev=276754&view=rev
Log:
[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
Modified:
cfe/trunk/lib/Tooling/Core/Lookup.cpp
cfe/trunk/unittests/Tooling/LookupTest.cpp
Modified: cfe/trunk/lib/Tooling/Core/Lookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Core/Lookup.cpp?rev=276754&r1=276753&r2=276754&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Core/Lookup.cpp (original)
+++ cfe/trunk/lib/Tooling/Core/Lookup.cpp Tue Jul 26 09:53:05 2016
@@ -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 on DeclB.
- while (DeclB && !isa<NamespaceDecl>(DeclB))
- DeclB = DeclB->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 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(c
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;
Modified: cfe/trunk/unittests/Tooling/LookupTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/LookupTest.cpp?rev=276754&r1=276753&r2=276754&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/LookupTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/LookupTest.cpp Tue Jul 26 09:53:05 2016
@@ -103,6 +103,14 @@ TEST(LookupTest, replaceNestedName) {
};
Visitor.runOver(
"namespace a { int foo(); }\nusing a::foo;\nauto f = foo();\n");
+
+ Visitor.OnCall = [&](CallExpr *Expr) {
+ EXPECT_EQ("c::bar", replaceCallExpr(Expr, "::a::c::bar"));
+ };
+ Visitor.runOver("namespace a { namespace b { void foo(); } }\n"
+ "namespace a { namespace b { namespace {"
+ "void f() { foo(); }"
+ "} } }\n");
}
} // end anonymous namespace
More information about the cfe-commits
mailing list