[change-namespace] fix a case references to templated using alias are qualified types.
authorEric Liu <ioeric@google.com>
Thu, 15 Dec 2016 13:02:41 +0000 (13:02 +0000)
committerEric Liu <ioeric@google.com>
Thu, 15 Dec 2016 13:02:41 +0000 (13:02 +0000)
llvm-svn: 289816

clang-tools-extra/change-namespace/ChangeNamespace.cpp
clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp

index b620b42..6c04a40 100644 (file)
@@ -457,16 +457,18 @@ void ChangeNamespaceTool::run(
     // This avoids fixing types with record types as qualifier, which is not
     // filtered by matchers in some cases, e.g. the type is templated. We should
     // handle the record type qualifier instead.
-    if (TLoc->getTypeLocClass() == TypeLoc::Elaborated) {
+    TypeLoc Loc = *TLoc;
+    while (Loc.getTypeLocClass() == TypeLoc::Qualified)
+      Loc = Loc.getNextTypeLoc();
+    if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
       NestedNameSpecifierLoc NestedNameSpecifier =
-          TLoc->castAs<ElaboratedTypeLoc>().getQualifierLoc();
+          Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
       const Type *SpecifierType =
           NestedNameSpecifier.getNestedNameSpecifier()->getAsType();
       if (SpecifierType && SpecifierType->isRecordType())
         return;
     }
-    fixTypeLoc(Result, startLocationForType(*TLoc), endLocationForType(*TLoc),
-               *TLoc);
+    fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
   } else if (const auto *VarRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
index caaeae8..8deed04 100644 (file)
@@ -1365,6 +1365,8 @@ TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) {
                      "public:\n"
                      "  template<typename P>\n"
                      "  using GG = some_ns::G<int, P>;\n"
+                     "\n"
+                     "  struct Nested {};\n"
                      "};\n"
                      "class Derived : public Base {};\n"
                      "} // namespace na\n"
@@ -1372,6 +1374,10 @@ TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) {
                      "namespace nb {\n"
                      "void f() {\n"
                      "  Derived::GG<float> g;\n"
+                     "  const Derived::GG<int> gg;\n"
+                     "  const Derived::GG<int>* gg_ptr;\n"
+                     "  struct Derived::Nested nested;\n"
+                     "  const struct Derived::Nested *nested_ptr;\n"
                      "}\n"
                      "} // namespace nb\n"
                      "} // namespace na\n";
@@ -1384,6 +1390,8 @@ TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) {
                          "public:\n"
                          "  template<typename P>\n"
                          "  using GG = some_ns::G<int, P>;\n"
+                         "\n"
+                         "  struct Nested {};\n"
                          "};\n"
                          "class Derived : public Base {};\n"
                          "} // namespace na\n"
@@ -1392,6 +1400,10 @@ TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) {
                          "namespace nc {\n"
                          "void f() {\n"
                          "  Derived::GG<float> g;\n"
+                         "  const Derived::GG<int> gg;\n"
+                         "  const Derived::GG<int>* gg_ptr;\n"
+                         "  struct Derived::Nested nested;\n"
+                         "  const struct Derived::Nested *nested_ptr;\n"
                          "}\n"
                          "} // namespace nc\n\n"
                          "} // namespace nb\n"