diff --git a/clang-tools-extra/clang-move/ClangMove.cpp b/clang-tools-extra/clang-move/ClangMove.cpp index a4088a34575d..050b53a1308c 100644 --- a/clang-tools-extra/clang-move/ClangMove.cpp +++ b/clang-tools-extra/clang-move/ClangMove.cpp @@ -713,7 +713,24 @@ void ClangMoveTool::onEndOfTranslationUnit() { if (RemovedDecls.empty()) return; - if (UnremovedDeclsInOldHeader.empty() && !Context->Spec.OldHeader.empty()) { + // Ignore symbols that are not supported (e.g. typedef and enum) when + // checking if there is unremoved symbol in old header. This makes sure that + // we always move old files to new files when all symbols produced from + // dump_decls are moved. + auto IsSupportedKind = [](const clang::NamedDecl *Decl) { + switch (Decl->getKind()) { + case Decl::Kind::Function: + case Decl::Kind::FunctionTemplate: + case Decl::Kind::ClassTemplate: + case Decl::Kind::CXXRecord: + return true; + default: + return false; + } + }; + if (std::none_of(UnremovedDeclsInOldHeader.begin(), + UnremovedDeclsInOldHeader.end(), IsSupportedKind) && + !Context->Spec.OldHeader.empty()) { auto &SM = RemovedDecls[0]->getASTContext().getSourceManager(); moveAll(SM, Context->Spec.OldHeader, Context->Spec.NewHeader); moveAll(SM, Context->Spec.OldCC, Context->Spec.NewCC); diff --git a/clang-tools-extra/clang-move/ClangMove.h b/clang-tools-extra/clang-move/ClangMove.h index e4e145cfc43b..dcc23077307a 100644 --- a/clang-tools-extra/clang-move/ClangMove.h +++ b/clang-tools-extra/clang-move/ClangMove.h @@ -95,7 +95,9 @@ struct ClangMoveContext { // The goal of this tool is to make the new files as compliable as possible. // // Note: When all declarations in old header are being moved, all code in -// old.h/cc will be moved, which means old.h/cc are empty. +// old.h/cc will be moved, which means old.h/cc are empty. This ignores symbols +// that are not supported (e.g. typedef and enum) so that we always move old +// files to new files when all symbols produced from dump_decls are moved. class ClangMoveTool : public ast_matchers::MatchFinder::MatchCallback { public: ClangMoveTool(ClangMoveContext *const Context, diff --git a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp index bc88bc309f46..3c4a9b591dcf 100644 --- a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp +++ b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp @@ -330,11 +330,8 @@ TEST(ClangMove, DontMoveAll) { "#endif // NEW_FOO_H\n"; 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", "class B {};\nclass A {\npublic:\n int f();\n};\n", "void f() {};\nclass A {\npublic:\n int f();\n};\n", - "enum Color { RED };\nclass A {\npublic:\n int f();\n};\n", }; move::MoveDefinitionSpec Spec; Spec.Names.push_back("A"); @@ -351,6 +348,26 @@ TEST(ClangMove, DontMoveAll) { } } +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", + "enum Color { RED };\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"