summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/change-namespace/ChangeNamespace.cpp10
-rw-r--r--clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp41
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"
OpenPOWER on IntegriCloud