[change-namespace] check using shadow decl correctly when shortening namespace specifiers.

Summary:
This fixes mismatch between template decls and template specialization decls.

Also added a few more test cases.

Reviewers: bkramer

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D29447

llvm-svn: 293897
This commit is contained in:
Eric Liu 2017-02-02 15:29:54 +00:00
parent 180bc5a021
commit ae7de7117a
2 changed files with 71 additions and 2 deletions

View File

@ -761,7 +761,8 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext(
if (isDeclVisibleAtLocation(*Result.SourceManager, Using, DeclCtx, Start)) {
for (const auto *UsingShadow : Using->shadows()) {
const auto *TargetDecl = UsingShadow->getTargetDecl();
if (TargetDecl == FromDecl) {
if (TargetDecl->getQualifiedNameAsString() ==
FromDecl->getQualifiedNameAsString()) {
ReplaceName = FromDecl->getNameAsString();
Matched = true;
break;

View File

@ -1255,7 +1255,7 @@ TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) {
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
TEST_F(ChangeNamespaceTest, UsingDeclInTheParentOfOldNamespace) {
TEST_F(ChangeNamespaceTest, UsingShadowDeclInTheParentOfOldNamespace) {
OldNamespace = "nb::nc";
NewNamespace = "nb::nd";
std::string Code = "namespace na { class A {}; }\n"
@ -1277,6 +1277,74 @@ TEST_F(ChangeNamespaceTest, UsingDeclInTheParentOfOldNamespace) {
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
TEST_F(ChangeNamespaceTest, UsingShadowDeclInOldNamespace) {
OldNamespace = "nb";
NewNamespace = "nc";
std::string Code = "namespace na { class A {}; }\n"
"namespace nb {\n"
"using na::A;\n"
"void d() { A a; }\n"
"struct X { A a; };\n"
"} // nb\n";
std::string Expected = "namespace na { class A {}; }\n"
"\n"
"namespace nc {\n"
"using ::na::A;\n"
"void d() { A a; }\n"
"struct X { A a; };\n"
"} // namespace nc\n";
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateClass) {
OldNamespace = "nb";
NewNamespace = "nc";
std::string Code = "namespace na {\n"
"template <typename T>\n"
"class A { T t; };\n"
"} // namespace na\n"
"namespace nb {\n"
"using na::A;\n"
"void d() { A<int> a; }\n"
"} // nb\n";
std::string Expected = "namespace na {\n"
"template <typename T>\n"
"class A { T t; };\n"
"} // namespace na\n"
"\n"
"namespace nc {\n"
"using ::na::A;\n"
"void d() { A<int> a; }\n"
"} // namespace nc\n";
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateFunction) {
OldNamespace = "nb";
NewNamespace = "nc";
std::string Code = "namespace na {\n"
"template <typename T>\n"
"void f() { T t; };\n"
"} // namespace na\n"
"namespace nb {\n"
"using na::f;\n"
"void d() { f<int>(); }\n"
"} // nb\n";
std::string Expected = "namespace na {\n"
"template <typename T>\n"
"void f() { T t; };\n"
"} // namespace na\n"
"\n"
"namespace nc {\n"
"using ::na::f;\n"
"void d() { f<int>(); }\n"
"} // namespace nc\n";
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
TEST_F(ChangeNamespaceTest, UsingAliasDecl) {
std::string Code =
"namespace nx { namespace ny { class X {}; } }\n"