Index: clang-tools-extra/trunk/clang-move/ClangMove.cpp =================================================================== --- clang-tools-extra/trunk/clang-move/ClangMove.cpp +++ clang-tools-extra/trunk/clang-move/ClangMove.cpp @@ -166,6 +166,27 @@ ClangMoveTool *MoveTool; }; +class TypeAliasMatch : public MatchFinder::MatchCallback { +public: + explicit TypeAliasMatch(ClangMoveTool *MoveTool) + : MoveTool(MoveTool) {} + + void run(const MatchFinder::MatchResult &Result) override { + if (const auto *TD = Result.Nodes.getNodeAs("typedef")) + MoveDeclFromOldFileToNewFile(MoveTool, TD); + else if (const auto *TAD = + Result.Nodes.getNodeAs("type_alias")) { + const NamedDecl * D = TAD; + if (const auto * TD = TAD->getDescribedAliasTemplate()) + D = TD; + MoveDeclFromOldFileToNewFile(MoveTool, D); + } + } + +private: + ClangMoveTool *MoveTool; +}; + class EnumDeclarationMatch : public MatchFinder::MatchCallback { public: explicit EnumDeclarationMatch(ClangMoveTool *MoveTool) @@ -587,13 +608,22 @@ .bind("function"), MatchCallbacks.back().get()); - // Match enum definition in old.h. Enum helpers (which are definied in old.cc) + // Match enum definition in old.h. Enum helpers (which are defined in old.cc) // will not be moved for now no matter whether they are used or not. MatchCallbacks.push_back(llvm::make_unique(this)); Finder->addMatcher( enumDecl(InOldHeader, *HasAnySymbolNames, isDefinition(), TopLevelDecl) .bind("enum"), MatchCallbacks.back().get()); + + // Match type alias in old.h, this includes "typedef" and "using" type alias + // declarations. Type alias helpers (which are defined in old.cc) will not be + // moved for now no matter whether they are used or not. + MatchCallbacks.push_back(llvm::make_unique(this)); + Finder->addMatcher(namedDecl(anyOf(typedefDecl().bind("typedef"), + typeAliasDecl().bind("type_alias")), + InOldHeader, *HasAnySymbolNames, TopLevelDecl), + MatchCallbacks.back().get()); } void ClangMoveTool::run(const ast_matchers::MatchFinder::MatchResult &Result) { @@ -828,6 +858,9 @@ case Decl::Kind::ClassTemplate: case Decl::Kind::CXXRecord: case Decl::Kind::Enum: + case Decl::Kind::Typedef: + case Decl::Kind::TypeAlias: + case Decl::Kind::TypeAliasTemplate: return true; default: return false; Index: clang-tools-extra/trunk/test/clang-move/Inputs/type_alias.h =================================================================== --- clang-tools-extra/trunk/test/clang-move/Inputs/type_alias.h +++ clang-tools-extra/trunk/test/clang-move/Inputs/type_alias.h @@ -0,0 +1,11 @@ +typedef int Int1; +using Int2 = int; + +template +struct A {}; + +template using B = A; + +class C { + typedef int Int3; +}; Index: clang-tools-extra/trunk/test/clang-move/move-type-alias.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-move/move-type-alias.cpp +++ clang-tools-extra/trunk/test/clang-move/move-type-alias.cpp @@ -0,0 +1,52 @@ +// RUN: mkdir -p %T/move-type-alias +// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h +// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp +// RUN: cd %T/move-type-alias +// +// ----------------------------------------------------------------------------- +// Test moving typedef declarations. +// ----------------------------------------------------------------------------- +// RUN: clang-move -names="Int1" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11 +// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s +// RUN: FileCheck -input-file=%T/move-type-alias/type_alias.h -check-prefix=CHECK-OLD-TEST-H-CASE1 %s + +// CHECK-NEW-TEST-H-CASE1: typedef int Int1; + +// CHECK-OLD-TEST-H-CASE1-NOT: typedef int Int1; + + +// ----------------------------------------------------------------------------- +// Test moving type alias declarations. +// ----------------------------------------------------------------------------- +// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h +// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp +// RUN: clang-move -names="Int2" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11 +// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s +// RUN: FileCheck -input-file=%T/move-type-alias/type_alias.h -check-prefix=CHECK-OLD-TEST-H-CASE2 %s + +// CHECK-NEW-TEST-H-CASE2: using Int2 = int; + +// CHECK-OLD-TEST-H-CASE2-NOT: using Int2 = int; + + +// ----------------------------------------------------------------------------- +// Test moving template type alias declarations. +// ----------------------------------------------------------------------------- +// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h +// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp +// RUN: clang-move -names="B" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11 +// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -check-prefix=CHECK-OLD-TEST-H-CASE3 %s + +// CHECK-NEW-TEST-H-CASE3: template using B = A; +// CHECK-OLD-TEST-H-CASE3-NOT: template using B = A; + + +// ----------------------------------------------------------------------------- +// Test not moving class-insided typedef declarations. +// ----------------------------------------------------------------------------- +// RUN: cp %S/Inputs/type_alias.h %T/move-type-alias/type_alias.h +// RUN: echo '#include "type_alias.h"' > %T/move-type-alias/type_alias.cpp +// RUN: clang-move -names="C::Int3" -new_cc=%T/move-type-alias/new_test.cpp -new_header=%T/move-type-alias/new_test.h -old_cc=%T/move-type-alias/type_alias.cpp -old_header=%T/move-type-alias/type_alias.h %T/move-type-alias/type_alias.cpp -- -std=c++11 +// RUN: FileCheck -input-file=%T/move-type-alias/new_test.h -allow-empty -check-prefix=CHECK-EMPTY %s + +// CHECK-EMPTY: {{^}}{{$}} Index: clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp +++ clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp @@ -365,25 +365,6 @@ } } -TEST(ClangMove, IgnoreUnsupportedKindsAndMoveAll) { - const char Code[] = "#include \"foo.h\"\nint A::f() { return 0; }"; - std::vector TestHeaders = { - "typedef int Int;\nclass A {\npublic:\n int f();\n};\n", - "using Int = int;\nclass A {\npublic:\n int f();\n};\n", - }; - move::MoveDefinitionSpec Spec; - Spec.Names.push_back("A"); - Spec.OldHeader = "foo.h"; - Spec.OldCC = "foo.cc"; - Spec.NewHeader = "new_foo.h"; - Spec.NewCC = "new_foo.cc"; - for (const auto &Header : TestHeaders) { - auto Results = runClangMoveOnCode(Spec, Header.c_str(), Code); - EXPECT_EQ(Header, Results[Spec.NewHeader]); - EXPECT_EQ("", Results[Spec.OldHeader]); - } -} - TEST(ClangMove, MacroInFunction) { const char TestHeader[] = "#define INT int\n" "class A {\npublic:\n int f();\n};\n"