hokein updated this revision to Diff 120199.
hokein added a comment.

improve the code and add more tests.


https://reviews.llvm.org/D39241

Files:
  lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
  test/clang-rename/TemplatedClassFunction.cpp


Index: test/clang-rename/TemplatedClassFunction.cpp
===================================================================
--- test/clang-rename/TemplatedClassFunction.cpp
+++ test/clang-rename/TemplatedClassFunction.cpp
@@ -6,17 +6,22 @@
 
 int main(int argc, char **argv) {
   A<int> a;
-  a.foo();   /* Test 2 */     // CHECK: a.bar()   /* Test 2 */
+  A<double> b;
+  A<float> c;
+  a.foo();   /* Test 2 */     // CHECK: a.bar();   /* Test 2 */
+  b.foo();   /* Test 3 */     // CHECK: b.bar();   /* Test 3 */
+  c.foo();   /* Test 4 */     // CHECK: c.bar();   /* Test 4 */
   return 0;
 }
 
 // Test 1.
-// RUN: clang-refactor rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' 
| FileCheck %s
+// RUN: clang-rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' | 
FileCheck %s
 // Test 2.
-// RUN: clang-refactor rename -offset=162 -new-name=bar %s -- | sed 's,//.*,,' 
| FileCheck %s
-//
-// Currently unsupported test.
-// XFAIL: *
+// RUN: clang-rename -offset=191 -new-name=bar %s -- | sed 's,//.*,,' | 
FileCheck %s
+// Test 3.
+// RUN: clang-rename -offset=255 -new-name=bar %s -- | sed 's,//.*,,' | 
FileCheck %s
+// Test 4.
+// RUN: clang-rename -offset=319 -new-name=bar %s -- | sed 's,//.*,,' | 
FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'foo.*' <file>
Index: lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
===================================================================
--- lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -73,6 +73,7 @@
         if (checkIfOverriddenFunctionAscends(OverriddenMethod))
           USRSet.insert(getUSRForDecl(OverriddenMethod));
       }
+      addUSRsOfInstantiatedMethods(MethodDecl);
     } else if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
       handleCXXRecordDecl(RecordDecl);
     } else if (const auto *TemplateDecl =
@@ -84,9 +85,13 @@
     return std::vector<std::string>(USRSet.begin(), USRSet.end());
   }
 
+  bool shouldVisitTemplateInstantiations() const { return true; }
+
   bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
     if (MethodDecl->isVirtual())
       OverriddenMethods.push_back(MethodDecl);
+    if (MethodDecl->getInstantiatedFromMemberFunction())
+      InstantiatedMethods.push_back(MethodDecl);
     return true;
   }
 
@@ -137,6 +142,20 @@
       addUSRsOfOverridenFunctions(OverriddenMethod);
   }
 
+  void addUSRsOfInstantiatedMethods(const CXXMethodDecl *MethodDecl) {
+    // For renaming a class template method, all references of the instantiated
+    // member methods should be renamed too, so add USRs of the instantiated
+    // methods to the USR set.
+    USRSet.insert(getUSRForDecl(MethodDecl));
+    if (const auto *FT = MethodDecl->getInstantiatedFromMemberFunction())
+      USRSet.insert(getUSRForDecl(FT));
+    for (const auto *Method : InstantiatedMethods) {
+      if (USRSet.find(getUSRForDecl(
+              Method->getInstantiatedFromMemberFunction())) != USRSet.end())
+        USRSet.insert(getUSRForDecl(Method));
+    }
+  }
+
   bool checkIfOverriddenFunctionAscends(const CXXMethodDecl *MethodDecl) {
     for (const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
       if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end())
@@ -150,6 +169,7 @@
   ASTContext &Context;
   std::set<std::string> USRSet;
   std::vector<const CXXMethodDecl *> OverriddenMethods;
+  std::vector<const CXXMethodDecl *> InstantiatedMethods;
   std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs;
 };
 } // namespace


Index: test/clang-rename/TemplatedClassFunction.cpp
===================================================================
--- test/clang-rename/TemplatedClassFunction.cpp
+++ test/clang-rename/TemplatedClassFunction.cpp
@@ -6,17 +6,22 @@
 
 int main(int argc, char **argv) {
   A<int> a;
-  a.foo();   /* Test 2 */     // CHECK: a.bar()   /* Test 2 */
+  A<double> b;
+  A<float> c;
+  a.foo();   /* Test 2 */     // CHECK: a.bar();   /* Test 2 */
+  b.foo();   /* Test 3 */     // CHECK: b.bar();   /* Test 3 */
+  c.foo();   /* Test 4 */     // CHECK: c.bar();   /* Test 4 */
   return 0;
 }
 
 // Test 1.
-// RUN: clang-refactor rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-refactor rename -offset=162 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
-//
-// Currently unsupported test.
-// XFAIL: *
+// RUN: clang-rename -offset=191 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// Test 3.
+// RUN: clang-rename -offset=255 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// Test 4.
+// RUN: clang-rename -offset=319 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'foo.*' <file>
Index: lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
===================================================================
--- lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -73,6 +73,7 @@
         if (checkIfOverriddenFunctionAscends(OverriddenMethod))
           USRSet.insert(getUSRForDecl(OverriddenMethod));
       }
+      addUSRsOfInstantiatedMethods(MethodDecl);
     } else if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
       handleCXXRecordDecl(RecordDecl);
     } else if (const auto *TemplateDecl =
@@ -84,9 +85,13 @@
     return std::vector<std::string>(USRSet.begin(), USRSet.end());
   }
 
+  bool shouldVisitTemplateInstantiations() const { return true; }
+
   bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
     if (MethodDecl->isVirtual())
       OverriddenMethods.push_back(MethodDecl);
+    if (MethodDecl->getInstantiatedFromMemberFunction())
+      InstantiatedMethods.push_back(MethodDecl);
     return true;
   }
 
@@ -137,6 +142,20 @@
       addUSRsOfOverridenFunctions(OverriddenMethod);
   }
 
+  void addUSRsOfInstantiatedMethods(const CXXMethodDecl *MethodDecl) {
+    // For renaming a class template method, all references of the instantiated
+    // member methods should be renamed too, so add USRs of the instantiated
+    // methods to the USR set.
+    USRSet.insert(getUSRForDecl(MethodDecl));
+    if (const auto *FT = MethodDecl->getInstantiatedFromMemberFunction())
+      USRSet.insert(getUSRForDecl(FT));
+    for (const auto *Method : InstantiatedMethods) {
+      if (USRSet.find(getUSRForDecl(
+              Method->getInstantiatedFromMemberFunction())) != USRSet.end())
+        USRSet.insert(getUSRForDecl(Method));
+    }
+  }
+
   bool checkIfOverriddenFunctionAscends(const CXXMethodDecl *MethodDecl) {
     for (const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
       if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end())
@@ -150,6 +169,7 @@
   ASTContext &Context;
   std::set<std::string> USRSet;
   std::vector<const CXXMethodDecl *> OverriddenMethods;
+  std::vector<const CXXMethodDecl *> InstantiatedMethods;
   std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs;
 };
 } // namespace
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D39241: [clang-rename] ... Haojian Wu via Phabricator via cfe-commits

Reply via email to