Author: hokein Date: Wed Nov 9 23:33:26 2016 New Revision: 286427 URL: http://llvm.org/viewvc/llvm-project?rev=286427&view=rev Log: [clang-move] Support template class.
Reviewers: ioeric Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D26423 Added: clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.cpp clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.h clang-tools-extra/trunk/test/clang-move/move-template-class.cpp Modified: clang-tools-extra/trunk/clang-move/ClangMove.cpp Modified: clang-tools-extra/trunk/clang-move/ClangMove.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-move/ClangMove.cpp?rev=286427&r1=286426&r2=286427&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-move/ClangMove.cpp (original) +++ clang-tools-extra/trunk/clang-move/ClangMove.cpp Wed Nov 9 23:33:26 2016 @@ -364,16 +364,15 @@ void ClangMoveTool::registerMatchers(ast 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,25 +411,36 @@ void ClangMoveTool::run(const ast_matche if (!CMD->isInlined()) { MovedDecls.emplace_back(CMD, &Result.Context->getSourceManager()); RemovedDecls.push_back(MovedDecls.back()); + // Get template class method from its method declaration as + // UnremovedDecls stores template class method. + 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()); + // Get class template from its class declaration as UnremovedDecls stores + // class template. + 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. if (RemovedDecls.empty()) { - if (const auto *DCT = FWD->getDescribedClassTemplate()) { + if (const auto *DCT = FWD->getDescribedClassTemplate()) MovedDecls.emplace_back(DCT, &Result.Context->getSourceManager()); - } else { + else MovedDecls.emplace_back(FWD, &Result.Context->getSourceManager()); - } } } else if (const auto *ANS = Result.Nodes.getNodeAs<clang::NamespaceDecl>("anonymous_ns")) { Added: clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.cpp?rev=286427&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.cpp (added) +++ clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.cpp Wed Nov 9 23:33:26 2016 @@ -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() {} Added: clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.h?rev=286427&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.h (added) +++ clang-tools-extra/trunk/test/clang-move/Inputs/template_class_test.h Wed Nov 9 23:33:26 2016 @@ -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 Added: clang-tools-extra/trunk/test/clang-move/move-template-class.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-move/move-template-class.cpp?rev=286427&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-move/move-template-class.cpp (added) +++ clang-tools-extra/trunk/test/clang-move/move-template-class.cpp Wed Nov 9 23:33:26 2016 @@ -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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits