[clang-tools-extra] r282837 - [change-namespace] fix namespace specifier of global variables.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 29 21:32:40 PDT 2016
Author: ioeric
Date: Thu Sep 29 23:32:39 2016
New Revision: 282837
URL: http://llvm.org/viewvc/llvm-project?rev=282837&view=rev
Log:
[change-namespace] fix namespace specifier of global variables.
Reviewers: hokein
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D24963
Modified:
clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp?rev=282837&r1=282836&r2=282837&view=diff
==============================================================================
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp (original)
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp Thu Sep 29 23:32:39 2016
@@ -230,8 +230,6 @@ ChangeNamespaceTool::ChangeNamespaceTool
DiffNewNamespace = joinNamespaces(NewNsSplitted);
}
-// FIXME: handle the following symbols:
-// - Variable references.
void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
// Match old namespace blocks.
std::string FullOldNs = "::" + OldNamespace;
@@ -303,6 +301,14 @@ void ChangeNamespaceTool::registerMatche
IsInMovedNs, unless(isImplicit()))
.bind("dc"),
this);
+
+ auto GlobalVarMatcher = varDecl(
+ hasGlobalStorage(), hasParent(namespaceDecl()),
+ unless(anyOf(IsInMovedNs, hasAncestor(namespaceDecl(isAnonymous())))));
+ Finder->addMatcher(declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")),
+ to(GlobalVarMatcher.bind("var_decl")))
+ .bind("var_ref"),
+ this);
}
void ChangeNamespaceTool::run(
@@ -324,8 +330,19 @@ void ChangeNamespaceTool::run(
} else if (const auto *TLoc = Result.Nodes.getNodeAs<TypeLoc>("type")) {
fixTypeLoc(Result, startLocationForType(*TLoc), EndLocationForType(*TLoc),
*TLoc);
+ } else if (const auto *VarRef = Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")){
+ const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
+ assert(Var);
+ if (Var->getCanonicalDecl()->isStaticDataMember())
+ return;
+ std::string Name = Var->getQualifiedNameAsString();
+ const clang::Decl *Context = Result.Nodes.getNodeAs<clang::Decl>("dc");
+ assert(Context && "Empty decl context.");
+ clang::SourceRange VarRefRange = VarRef->getSourceRange();
+ replaceQualifiedSymbolInDeclContext(Result, Context, VarRefRange.getBegin(),
+ VarRefRange.getEnd(), Name);
} else {
- const auto* Call = Result.Nodes.getNodeAs<clang::CallExpr>("call");
+ const auto *Call = Result.Nodes.getNodeAs<clang::CallExpr>("call");
assert(Call != nullptr &&"Expecting callback for CallExpr.");
const clang::FunctionDecl* Func = Call->getDirectCallee();
assert(Func != nullptr);
Modified: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp?rev=282837&r1=282836&r2=282837&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Thu Sep 29 23:32:39 2016
@@ -447,6 +447,72 @@ TEST_F(ChangeNamespaceTest, FixFunctionN
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
+TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
+ std::string Code = "namespace na {\n"
+ "int GlobA;\n"
+ "static int GlobAStatic = 0;\n"
+ "namespace nc { int GlobC; }\n"
+ "namespace nb {\n"
+ "int GlobB;\n"
+ "void f() {\n"
+ " int a = GlobA;\n"
+ " int b = GlobAStatic;\n"
+ " int c = nc::GlobC;\n"
+ "}\n"
+ "} // namespace nb\n"
+ "} // namespace na\n";
+
+ std::string Expected = "namespace na {\n"
+ "int GlobA;\n"
+ "static int GlobAStatic = 0;\n"
+ "namespace nc { int GlobC; }\n"
+ "\n"
+ "} // namespace na\n"
+ "namespace x {\n"
+ "namespace y {\n"
+ "int GlobB;\n"
+ "void f() {\n"
+ " int a = na::GlobA;\n"
+ " int b = na::GlobAStatic;\n"
+ " int c = na::nc::GlobC;\n"
+ "}\n"
+ "} // namespace y\n"
+ "} // namespace x\n";
+
+ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
+TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) {
+ std::string Code = "namespace na {\n"
+ "class A {\n"
+ "public:\n"
+ "static int A1;\n"
+ "static int A2;\n"
+ "}\n"
+ "static int A::A1 = 0;\n"
+ "namespace nb {\n"
+ "void f() { int a = A::A1; int b = A::A2; }"
+ "} // namespace nb\n"
+ "} // namespace na\n";
+
+ std::string Expected = "namespace na {\n"
+ "class A {\n"
+ "public:\n"
+ "static int A1;\n"
+ "static int A2;\n"
+ "}\n"
+ "static int A::A1 = 0;\n"
+ "\n"
+ "} // namespace na\n"
+ "namespace x {\n"
+ "namespace y {\n"
+ "void f() { int a = na::A::A1; int b = na::A::A2; }"
+ "} // namespace y\n"
+ "} // namespace x\n";
+
+ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
} // anonymous namespace
} // namespace change_namespace
} // namespace clang
More information about the cfe-commits
mailing list