[PATCH] D24803: [change-namespace] fix qualifier of function references.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 21 08:39:44 PDT 2016
ioeric created this revision.
ioeric added a reviewer: hokein.
ioeric added a subscriber: cfe-commits.
https://reviews.llvm.org/D24803
Files:
change-namespace/ChangeNamespace.cpp
unittests/change-namespace/ChangeNamespaceTests.cpp
Index: unittests/change-namespace/ChangeNamespaceTests.cpp
===================================================================
--- unittests/change-namespace/ChangeNamespaceTests.cpp
+++ unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -314,6 +314,29 @@
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
+TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) {
+ std::string Code =
+ "namespace na {\n"
+ "void a_f() {}\n"
+ "namespace nb {\n"
+ "void f() { a_f(); }\n"
+ "void g() { f(); }\n"
+ "} // namespace nb\n"
+ "} // namespace na\n";
+ std::string Expected =
+ "namespace na {\n"
+ "void a_f() {}\n"
+ "\n"
+ "} // namespace na\n"
+ "namespace x {\n"
+ "namespace y {\n"
+ "void f() { na::a_f(); }\n"
+ "void g() { f(); }\n"
+ "} // namespace y\n"
+ "} // namespace x\n";
+ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
} // anonymous namespace
} // namespace change_namespace
} // namespace clang
Index: change-namespace/ChangeNamespace.cpp
===================================================================
--- change-namespace/ChangeNamespace.cpp
+++ change-namespace/ChangeNamespace.cpp
@@ -231,7 +231,6 @@
}
// FIXME: handle the following symbols:
-// - Function references.
// - Variable references.
void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
// Match old namespace blocks.
@@ -283,6 +282,22 @@
hasDeclaration(DeclMatcher.bind("from_decl"))))))
.bind("nested_specifier_loc"),
this);
+
+ // Handle function.
+ // Only handle functions that are defined in a namespace excluding static
+ // methods (qualified by nested specifier) and functions defined in the global
+ // namespace.
+ // Note that the matcher does not exlude calls to out-of-line static method
+ // definitions, so we need to exclude them in the callback handler.
+ auto FuncMatcher = functionDecl(
+ hasParent(namespaceDecl()),
+ unless(anyOf(IsInMovedNs, hasAncestor(namespaceDecl(isAnonymous())),
+ hasAncestor(cxxRecordDecl()))));
+ Finder->addMatcher(
+ decl(forEachDescendant(callExpr(callee(FuncMatcher)).bind("call")),
+ IsInMovedNs)
+ .bind("dc"),
+ this);
}
void ChangeNamespaceTool::run(
@@ -301,11 +316,25 @@
SourceLocation Start = Specifier->getBeginLoc();
SourceLocation End = EndLocationForType(Specifier->getTypeLoc());
fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
- } else {
- const auto *TLoc = Result.Nodes.getNodeAs<TypeLoc>("type");
- assert(TLoc != nullptr && "Expecting callback for TypeLoc");
+ } else if (const auto *TLoc = Result.Nodes.getNodeAs<TypeLoc>("type")) {
fixTypeLoc(Result, startLocationForType(*TLoc), EndLocationForType(*TLoc),
*TLoc);
+ } else {
+ 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);
+ // Ignore static methods since they will be handled by nested name
+ // specifiers.
+ if (Func->getCanonicalDecl()->getStorageClass() ==
+ clang::StorageClass::SC_Static)
+ return;
+ std::string Name = Func->getQualifiedNameAsString();
+ const clang::Decl *Context = Result.Nodes.getNodeAs<clang::Decl>("dc");
+ assert(Context && "Empty decl context.");
+ clang::SourceRange CalleeRange = Call->getCallee()->getSourceRange();
+ replaceQualifiedSymbolInDeclContext(Result, Context, CalleeRange.getBegin(),
+ CalleeRange.getEnd(), Name);
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24803.72054.patch
Type: text/x-patch
Size: 3819 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160921/b7024608/attachment-0001.bin>
More information about the cfe-commits
mailing list