diff options
Diffstat (limited to 'clang-tools-extra')
| -rw-r--r-- | clang-tools-extra/change-namespace/ChangeNamespace.cpp | 10 | ||||
| -rw-r--r-- | clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp | 41 |
2 files changed, 47 insertions, 4 deletions
diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.cpp b/clang-tools-extra/change-namespace/ChangeNamespace.cpp index 40eb36ba4ef..4157e4df4ca 100644 --- a/clang-tools-extra/change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/change-namespace/ChangeNamespace.cpp @@ -272,13 +272,15 @@ void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) { allOf(IsInMovedNs, unless(cxxRecordDecl(unless(isDefinition()))))))); // Match TypeLocs on the declaration. Carefully match only the outermost - // TypeLoc that's directly linked to the old class and don't handle nested - // name specifier locs. + // TypeLoc and template specialization arguments (which are not outermost) + // that are directly linked to types matching `DeclMatcher`. Nested name + // specifier locs are handled separately below. Finder->addMatcher( typeLoc(IsInMovedNs, loc(qualType(hasDeclaration(DeclMatcher.bind("from_decl")))), - unless(anyOf(hasParent(typeLoc( - loc(qualType(hasDeclaration(DeclMatcher))))), + unless(anyOf(hasParent(typeLoc(loc(qualType( + allOf(hasDeclaration(DeclMatcher), + unless(templateSpecializationType())))))), hasParent(nestedNameSpecifierLoc()))), hasAncestor(decl().bind("dc"))) .bind("type"), diff --git a/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp b/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp index a608289e9bf..17528e962bf 100644 --- a/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp +++ b/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp @@ -190,6 +190,47 @@ TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) { EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) { + std::string Code = "namespace na {\n" + "class A {};\n" + "template <typename T>\n" + "class B {};\n" + "template <typename T1, typename T2>\n" + "class Two {};\n" + "namespace nc { class C {}; }\n" + "} // na\n" + "\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " B<A> b;\n" + " B<nc::C> b_c;\n" + " Two<A, nc::C> two;\n" + "}\n" + "} // nb\n" + "} // na\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "template <typename T>\n" + "class B {};\n" + "template <typename T1, typename T2>\n" + "class Two {};\n" + "namespace nc { class C {}; }\n" + "} // na\n" + "\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " na::B<na::A> b;\n" + " na::B<na::nc::C> b_c;\n" + " na::Two<na::A, na::nc::C> two;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) { std::string Code = "namespace na {\n" "namespace nb {\n" |

