ioeric created this revision.
ioeric added a reviewer: hokein.
ioeric added a subscriber: cfe-commits.

https://reviews.llvm.org/D27208

Files:
  change-namespace/ChangeNamespace.cpp
  change-namespace/ChangeNamespace.h
  unittests/change-namespace/ChangeNamespaceTests.cpp

Index: unittests/change-namespace/ChangeNamespaceTests.cpp
===================================================================
--- unittests/change-namespace/ChangeNamespaceTests.cpp
+++ unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -457,6 +457,41 @@
   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"
Index: change-namespace/ChangeNamespace.h
===================================================================
--- change-namespace/ChangeNamespace.h
+++ change-namespace/ChangeNamespace.h
@@ -76,6 +76,10 @@
   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
Index: change-namespace/ChangeNamespace.cpp
===================================================================
--- change-namespace/ChangeNamespace.cpp
+++ change-namespace/ChangeNamespace.cpp
@@ -369,11 +369,13 @@
                                 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 @@
     assert(Var);
     if (Var->getCanonicalDecl()->isStaticDataMember())
       return;
-    const clang::Decl *Context = Result.Nodes.getNodeAs<clang::Decl>("dc");
+    const Decl *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 Decl *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 Decl *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 @@
     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) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to