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

https://reviews.llvm.org/D26423

Files:
  clang-move/ClangMove.cpp
  test/clang-move/Inputs/template_class_test.cpp
  test/clang-move/Inputs/template_class_test.h
  test/clang-move/move-template-class.cpp

Index: test/clang-move/move-template-class.cpp
===================================================================
--- /dev/null
+++ test/clang-move/move-template-class.cpp
@@ -0,0 +1,86 @@
+// RUN: mkdir -p %T/move-template-class
+// RUN: cp %S/Inputs/template_class_test*  %T/move-template-class
+// RUN: cd %T/move-template-class
+// RUN: clang-move -names="A,B" -new_cc=%T/move-template-class/new_template_class_test.cpp -new_header=%T/move-template-class/new_template_class_test.h -old_cc=%T/move-template-class/template_class_test.cpp -old_header=../move-template-class/template_class_test.h %T/move-template-class/template_class_test.cpp --
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.cpp -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.h -check-prefix=CHECK-OLD-TEST-EMPTY -allow-empty %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE1 %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s
+//
+// RUN: cp %S/Inputs/template_class_test*  %T/move-template-class
+// RUN: clang-move -names="A" -new_cc=%T/move-template-class/new_template_class_test.cpp -new_header=%T/move-template-class/new_template_class_test.h -old_cc=%T/move-template-class/template_class_test.cpp -old_header=../move-template-class/template_class_test.h %T/move-template-class/template_class_test.cpp --
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.h -check-prefix=CHECK-OLD-TEST-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-template-class/template_class_test.cpp -check-prefix=CHECK-OLD-TEST-CPP-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s
+// RUN: FileCheck -input-file=%T/move-template-class/new_template_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE2 %s
+//
+//
+// CHECK-OLD-TEST-EMPTY: {{^}}{{$}}
+//
+// CHECK-NEW-TEST-H-CASE1: #ifndef TEMPLATE_CLASS_TEST_H // comment 1
+// CHECK-NEW-TEST-H-CASE1: #define TEMPLATE_CLASS_TEST_H
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: class A {
+// CHECK-NEW-TEST-H-CASE1:  public:
+// CHECK-NEW-TEST-H-CASE1:   void f();
+// CHECK-NEW-TEST-H-CASE1:   void g();
+// CHECK-NEW-TEST-H-CASE1:   template <typename U> void h();
+// CHECK-NEW-TEST-H-CASE1:   template <typename U> void k();
+// CHECK-NEW-TEST-H-CASE1:   static int b;
+// CHECK-NEW-TEST-H-CASE1:   static int c;
+// CHECK-NEW-TEST-H-CASE1: };
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: void A<T>::f() {}
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: template <typename U>
+// CHECK-NEW-TEST-H-CASE1: void A<T>::h() {}
+// CHECK-NEW-TEST-H-CASE1: template <typename T>
+// CHECK-NEW-TEST-H-CASE1: int A<T>::b = 2;
+// CHECK-NEW-TEST-H-CASE1: class B {
+// CHECK-NEW-TEST-H-CASE1:  public:
+// CHECK-NEW-TEST-H-CASE1:   void f();
+// CHECK-NEW-TEST-H-CASE1: };
+// CHECK-NEW-TEST-H-CASE1: #endif // TEMPLATE_CLASS_TEST_H
+//
+// CHECK-NEW-TEST-CPP-CASE1: #include "{{.*}}new_template_class_test.h"
+// CHECK-NEW-TEST-CPP-CASE1: template <typename T>
+// CHECK-NEW-TEST-CPP-CASE1: void A<T>::g() {}
+// CHECK-NEW-TEST-CPP-CASE1: template <typename T>
+// CHECK-NEW-TEST-CPP-CASE1: template <typename U>
+// CHECK-NEW-TEST-CPP-CASE1: void A<T>::k() {}
+// CHECK-NEW-TEST-CPP-CASE1: template <typename T>
+// CHECK-NEW-TEST-CPP-CASE1: int A<T>::c = 2;
+// CHECK-NEW-TEST-CPP-CASE1: void B::f() {}
+//
+// CHECK-OLD-TEST-H-CASE2: #ifndef TEMPLATE_CLASS_TEST_H // comment 1
+// CHECK-OLD-TEST-H-CASE2: #define TEMPLATE_CLASS_TEST_H
+// CHECK-OLD-TEST-H-CASE2: class B {
+// CHECK-OLD-TEST-H-CASE2:  public:
+// CHECK-OLD-TEST-H-CASE2:   void f();
+// CHECK-OLD-TEST-H-CASE2: };
+// CHECK-OLD-TEST-H-CASE2: #endif // TEMPLATE_CLASS_TEST_H
+//
+// CHECK-OLD-TEST-CPP-CASE2: #include "template_class_test.h"
+// CHECK-OLD-TEST-CPP-CASE2:  void B::f() {}
+//
+// CHECK-NEW-TEST-H-CASE2: #ifndef {{.*}}NEW_TEMPLATE_CLASS_TEST_H
+// CHECK-NEW-TEST-H-CASE2: #define {{.*}}NEW_TEMPLATE_CLASS_TEST_H
+// CHECK-NEW-TEST-H-CASE2: template <typename T>
+// CHECK-NEW-TEST-H-CASE2: class A {
+// CHECK-NEW-TEST-H-CASE2:  public:
+// CHECK-NEW-TEST-H-CASE2:   void f();
+// CHECK-NEW-TEST-H-CASE2:   void g();
+// CHECK-NEW-TEST-H-CASE2:   template <typename U> void h();
+// CHECK-NEW-TEST-H-CASE2:   template <typename U> void k();
+// CHECK-NEW-TEST-H-CASE2:   static int b;
+// CHECK-NEW-TEST-H-CASE2:   static int c;
+// CHECK-NEW-TEST-H-CASE2: };
+// CHECK-NEW-TEST-H-CASE2: template <typename T> void A<T>::f() {}
+// CHECK-NEW-TEST-H-CASE2: template <typename T> template <typename U> void A<T>::h() {}
+// CHECK-NEW-TEST-H-CASE2: template <typename T> int A<T>::b = 2;
+// CHECK-NEW-TEST-H-CASE2: #endif // {{.*}}NEW_TEMPLATE_CLASS_TEST_H
+//
+// CHECK-NEW-TEST-CPP-CASE2: #include "{{.*}}new_template_class_test.h"
+// CHECK-NEW-TEST-CPP-CASE2: template <typename T> void A<T>::g() {}
+// CHECK-NEW-TEST-CPP-CASE2: template <typename T> template <typename U> void A<T>::k() {}
+// CHECK-NEW-TEST-CPP-CASE2: template <typename T> int A<T>::c = 2;
Index: test/clang-move/Inputs/template_class_test.h
===================================================================
--- /dev/null
+++ test/clang-move/Inputs/template_class_test.h
@@ -0,0 +1,30 @@
+#ifndef TEMPLATE_CLASS_TEST_H // comment 1
+#define TEMPLATE_CLASS_TEST_H
+
+template <typename T>
+class A {
+ public:
+  void f();
+  void g();
+  template <typename U> void h();
+  template <typename U> void k();
+  static int b;
+  static int c;
+};
+
+template <typename T>
+void A<T>::f() {}
+
+template <typename T>
+template <typename U>
+void A<T>::h() {}
+
+template <typename T>
+int A<T>::b = 2;
+
+class B {
+ public:
+  void f();
+};
+
+#endif // TEMPLATE_CLASS_TEST_H
Index: test/clang-move/Inputs/template_class_test.cpp
===================================================================
--- /dev/null
+++ test/clang-move/Inputs/template_class_test.cpp
@@ -0,0 +1,13 @@
+#include "template_class_test.h"
+
+template <typename T>
+void A<T>::g() {}
+
+template <typename T>
+template <typename U>
+void A<T>::k() {}
+
+template <typename T>
+int A<T>::c = 2;
+
+void B::f() {}
Index: clang-move/ClangMove.cpp
===================================================================
--- clang-move/ClangMove.cpp
+++ clang-move/ClangMove.cpp
@@ -364,16 +364,15 @@
                     isDefinition())
           .bind("class_method"),
       this);
-
-  //============================================================================
-  // Matchers for old cc
-  //============================================================================
   // Match static member variable definition of the moved class.
   Finder->addMatcher(
-      varDecl(InMovedClass, InOldCC, isDefinition(), isStaticDataMember())
+      varDecl(InMovedClass, InOldFiles, isDefinition(), isStaticDataMember())
           .bind("class_static_var_decl"),
       this);
 
+  //============================================================================
+  // Matchers for old cc
+  //============================================================================
   auto InOldCCNamedNamespace =
       allOf(hasParent(namespaceDecl(unless(isAnonymous()))), InOldCC);
   // Matching using decls/type alias decls which are in named namespace. Those
@@ -412,16 +411,26 @@
     if (!CMD->isInlined()) {
       MovedDecls.emplace_back(CMD, &Result.Context->getSourceManager());
       RemovedDecls.push_back(MovedDecls.back());
+      if (const auto *FTD = CMD->getDescribedFunctionTemplate()) {
+        UnremovedDeclsInOldHeader.erase(FTD);
+      } else {
+        UnremovedDeclsInOldHeader.erase(CMD);
+      }
     }
   } else if (const auto *VD = Result.Nodes.getNodeAs<clang::VarDecl>(
                  "class_static_var_decl")) {
     MovedDecls.emplace_back(VD, &Result.Context->getSourceManager());
     RemovedDecls.push_back(MovedDecls.back());
-  } else if (const auto *class_decl =
+    UnremovedDeclsInOldHeader.erase(MovedDecls.back().Decl);
+  } else if (const auto *CD =
                  Result.Nodes.getNodeAs<clang::CXXRecordDecl>("moved_class")) {
-    MovedDecls.emplace_back(class_decl, &Result.Context->getSourceManager());
+    if (const auto * TC = CD->getDescribedClassTemplate()) {
+      MovedDecls.emplace_back(TC, &Result.Context->getSourceManager());
+    } else {
+      MovedDecls.emplace_back(CD, &Result.Context->getSourceManager());
+    }
     RemovedDecls.push_back(MovedDecls.back());
-    UnremovedDeclsInOldHeader.erase(class_decl);
+    UnremovedDeclsInOldHeader.erase(MovedDecls.back().Decl);
   } else if (const auto *FWD =
                  Result.Nodes.getNodeAs<clang::CXXRecordDecl>("fwd_decl")) {
     // Skip all forwad declarations which appear after moved class declaration.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to