[clang-tools-extra] r288139 - [change-namespace] fix non-calling function references.
Eric Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 29 06:15:15 PST 2016
Author: ioeric
Date: Tue Nov 29 08:15:14 2016
New Revision: 288139
URL: http://llvm.org/viewvc/llvm-project?rev=288139&view=rev
Log:
[change-namespace] fix non-calling function references.
Reviewers: hokein
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D27208
Modified:
clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
clang-tools-extra/trunk/change-namespace/ChangeNamespace.h
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=288139&r1=288138&r2=288139&view=diff
==============================================================================
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp (original)
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp Tue Nov 29 08:15:14 2016
@@ -369,11 +369,13 @@ void ChangeNamespaceTool::registerMatche
hasAncestor(namespaceDecl(isAnonymous())),
hasAncestor(cxxRecordDecl()))),
hasParent(namespaceDecl()));
- Finder->addMatcher(
- decl(forEachDescendant(callExpr(callee(FuncMatcher)).bind("call")),
- IsInMovedNs, unless(isImplicit()))
- .bind("dc"),
- this);
+ Finder->addMatcher(decl(forEachDescendant(expr(anyOf(
+ callExpr(callee(FuncMatcher)).bind("call"),
+ declRefExpr(to(FuncMatcher.bind("func_decl")))
+ .bind("func_ref")))),
+ IsInMovedNs, unless(isImplicit()))
+ .bind("dc"),
+ this);
auto GlobalVarMatcher = varDecl(
hasGlobalStorage(), hasParent(namespaceDecl()),
@@ -421,26 +423,32 @@ void ChangeNamespaceTool::run(
assert(Var);
if (Var->getCanonicalDecl()->isStaticDataMember())
return;
- const clang::Decl *Context = Result.Nodes.getNodeAs<clang::Decl>("dc");
+ const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
assert(Context && "Empty decl context.");
- clang::SourceRange VarRefRange = VarRef->getSourceRange();
- replaceQualifiedSymbolInDeclContext(
- Result, Context->getDeclContext(), VarRefRange.getBegin(),
- VarRefRange.getEnd(), llvm::cast<NamedDecl>(Var));
+ fixDeclRefExpr(Result, Context->getDeclContext(),
+ llvm::cast<NamedDecl>(Var), VarRef);
+ } else if (const auto *FuncRef =
+ Result.Nodes.getNodeAs<DeclRefExpr>("func_ref")) {
+ const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func_decl");
+ assert(Func);
+ const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
+ assert(Context && "Empty decl context.");
+ fixDeclRefExpr(Result, Context->getDeclContext(),
+ llvm::cast<NamedDecl>(Func), FuncRef);
} else {
- const auto *Call = Result.Nodes.getNodeAs<clang::CallExpr>("call");
+ const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
assert(Call != nullptr && "Expecting callback for CallExpr.");
- const clang::FunctionDecl *Func = Call->getDirectCallee();
+ const FunctionDecl *Func = Call->getDirectCallee();
assert(Func != nullptr);
// Ignore out-of-line static methods since they will be handled by nested
// name specifiers.
if (Func->getCanonicalDecl()->getStorageClass() ==
- clang::StorageClass::SC_Static &&
+ StorageClass::SC_Static &&
Func->isOutOfLine())
return;
- const clang::Decl *Context = Result.Nodes.getNodeAs<clang::Decl>("dc");
+ const auto *Context = Result.Nodes.getNodeAs<Decl>("dc");
assert(Context && "Empty decl context.");
- clang::SourceRange CalleeRange = Call->getCallee()->getSourceRange();
+ SourceRange CalleeRange = Call->getCallee()->getSourceRange();
replaceQualifiedSymbolInDeclContext(
Result, Context->getDeclContext(), CalleeRange.getBegin(),
CalleeRange.getEnd(), llvm::cast<NamedDecl>(Func));
@@ -698,6 +706,15 @@ void ChangeNamespaceTool::fixUsingShadow
llvm_unreachable(llvm::toString(std::move(Err)).c_str());
}
+void ChangeNamespaceTool::fixDeclRefExpr(
+ const ast_matchers::MatchFinder::MatchResult &Result,
+ const DeclContext *UseContext, const NamedDecl *From,
+ const DeclRefExpr *Ref) {
+ SourceRange RefRange = Ref->getSourceRange();
+ replaceQualifiedSymbolInDeclContext(Result, UseContext, RefRange.getBegin(),
+ RefRange.getEnd(), From);
+}
+
void ChangeNamespaceTool::onEndOfTranslationUnit() {
// Move namespace blocks and insert forward declaration to old namespace.
for (const auto &FileAndNsMoves : MoveNamespaces) {
Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/change-namespace/ChangeNamespace.h?rev=288139&r1=288138&r2=288139&view=diff
==============================================================================
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.h (original)
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.h Tue Nov 29 08:15:14 2016
@@ -76,6 +76,10 @@ private:
void fixUsingShadowDecl(const ast_matchers::MatchFinder::MatchResult &Result,
const UsingDecl *UsingDeclaration);
+ void fixDeclRefExpr(const ast_matchers::MatchFinder::MatchResult &Result,
+ const DeclContext *UseContext, const NamedDecl *From,
+ const DeclRefExpr *Ref);
+
// Information about moving an old namespace.
struct MoveNamespace {
// The start offset of the namespace block being moved in the original
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=288139&r1=288138&r2=288139&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Tue Nov 29 08:15:14 2016
@@ -457,6 +457,40 @@ TEST_F(ChangeNamespaceTest, FixFunctionN
EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
}
+TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) {
+ std::string Code = "namespace na {\n"
+ "class A {\n"
+ "public:\n"
+ " static void f() {}\n"
+ "};\n"
+ "void a_f() {}\n"
+ "static void s_f() {}\n"
+ "namespace nb {\n"
+ "void f() {\n"
+ "auto *ref1 = A::f; auto *ref2 = a_f; auto *ref3 = s_f;\n"
+ "}\n"
+ "} // namespace nb\n"
+ "} // namespace na\n";
+ std::string Expected =
+ "namespace na {\n"
+ "class A {\n"
+ "public:\n"
+ " static void f() {}\n"
+ "};\n"
+ "void a_f() {}\n"
+ "static void s_f() {}\n"
+ "\n"
+ "} // namespace na\n"
+ "namespace x {\n"
+ "namespace y {\n"
+ "void f() {\n"
+ "auto *ref1 = na::A::f; auto *ref2 = na::a_f; auto *ref3 = na::s_f;\n"
+ "}\n"
+ "} // namespace y\n"
+ "} // namespace x\n";
+ EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
+
TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) {
std::string Code = "namespace na {\n"
"int GlobA;\n"
More information about the cfe-commits
mailing list