diff options
| author | Haojian Wu <hokein@google.com> | 2016-10-07 08:29:20 +0000 |
|---|---|---|
| committer | Haojian Wu <hokein@google.com> | 2016-10-07 08:29:20 +0000 |
| commit | a709e384ceb04793838c69e5e5eadb36aa0ab456 (patch) | |
| tree | 51892e098ccf4e67ff05fc02b722c581e14d595b | |
| parent | 9ff8e87ca4b39257ea64ba6b0505261432f92a63 (diff) | |
| download | bcm5719-llvm-a709e384ceb04793838c69e5e5eadb36aa0ab456.tar.gz bcm5719-llvm-a709e384ceb04793838c69e5e5eadb36aa0ab456.zip | |
[clang-move] Support moving multiple classes in one run.
Reviewers: ioeric
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D25309
llvm-svn: 283526
9 files changed, 151 insertions, 16 deletions
diff --git a/clang-tools-extra/clang-move/ClangMove.cpp b/clang-tools-extra/clang-move/ClangMove.cpp index c60b5e583ca..5cb50b601e1 100644 --- a/clang-tools-extra/clang-move/ClangMove.cpp +++ b/clang-tools-extra/clang-move/ClangMove.cpp @@ -287,31 +287,43 @@ ClangMoveTool::ClangMoveTool( : Spec(MoveSpec), FileToReplacements(FileToReplacements), OriginalRunningDirectory(OriginalRunningDirectory), FallbackStyle(FallbackStyle) { - Spec.Name = llvm::StringRef(Spec.Name).ltrim(':'); if (!Spec.NewHeader.empty()) CCIncludes.push_back("#include \"" + Spec.NewHeader + "\"\n"); } void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) { - std::string FullyQualifiedName = "::" + Spec.Name; + SmallVector<StringRef, 4> ClassNames; + llvm::StringRef(Spec.Names).split(ClassNames, ','); + Optional<ast_matchers::internal::Matcher<NamedDecl>> InMovedClassNames; + for (StringRef ClassName : ClassNames) { + llvm::StringRef GlobalClassName = ClassName.trim().ltrim(':'); + const auto HasName = hasName(("::" + GlobalClassName).str()); + InMovedClassNames = + InMovedClassNames ? anyOf(*InMovedClassNames, HasName) : HasName; + } + if (!InMovedClassNames) { + llvm::errs() << "No classes being moved.\n"; + return; + } + auto InOldHeader = isExpansionInFile( MakeAbsolutePath(OriginalRunningDirectory, Spec.OldHeader)); auto InOldCC = isExpansionInFile( MakeAbsolutePath(OriginalRunningDirectory, Spec.OldCC)); auto InOldFiles = anyOf(InOldHeader, InOldCC); auto InMovedClass = - hasDeclContext(cxxRecordDecl(hasName(FullyQualifiedName))); + hasDeclContext(cxxRecordDecl(*InMovedClassNames)); // Match moved class declarations. auto MovedClass = cxxRecordDecl( - InOldFiles, hasName(FullyQualifiedName), isDefinition(), + InOldFiles, *InMovedClassNames, isDefinition(), hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl()))); Finder->addMatcher(MovedClass.bind("moved_class"), this); // Match moved class methods (static methods included) which are defined // outside moved class declaration. Finder->addMatcher(cxxMethodDecl(InOldFiles, - ofClass(hasName(FullyQualifiedName)), + ofClass(*InMovedClassNames), isDefinition()) .bind("class_method"), this); diff --git a/clang-tools-extra/clang-move/ClangMove.h b/clang-tools-extra/clang-move/ClangMove.h index 0cacae8efd3..28885e221be 100644 --- a/clang-tools-extra/clang-move/ClangMove.h +++ b/clang-tools-extra/clang-move/ClangMove.h @@ -37,8 +37,9 @@ public: }; struct MoveDefinitionSpec { - // A fully qualified name, e.g. "X", "a::X". - std::string Name; + // A comma-separated list of fully qualified names, e.g. "Foo", + // "a::Foo, b::Foo". + std::string Names; // The file path of old header, can be relative path and absolute path. std::string OldHeader; // The file path of old cc, can be relative path and absolute path. diff --git a/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp b/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp index 09f5805dcd0..91677d73b2a 100644 --- a/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp +++ b/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp @@ -37,8 +37,10 @@ std::error_code CreateNewFile(const llvm::Twine &path) { cl::OptionCategory ClangMoveCategory("clang-move options"); -cl::opt<std::string> Name("name", cl::desc("The name of class being moved."), - cl::cat(ClangMoveCategory)); +cl::opt<std::string> + Names("names", cl::desc("A comma-separated list of the names of classes " + "being moved, e.g. \"Foo\", \"a::Foo, b::Foo\"."), + cl::cat(ClangMoveCategory)); cl::opt<std::string> OldHeader("old_header", @@ -86,7 +88,7 @@ int main(int argc, const char **argv) { tooling::RefactoringTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); move::ClangMoveTool::MoveDefinitionSpec Spec; - Spec.Name = Name; + Spec.Names = Names; Spec.OldHeader = OldHeader; Spec.NewHeader = NewHeader; Spec.OldCC = OldCC; diff --git a/clang-tools-extra/test/clang-move/Inputs/database_template.json b/clang-tools-extra/test/clang-move/Inputs/database_template.json index 2dc567ba2b0..daff4e54b2e 100644 --- a/clang-tools-extra/test/clang-move/Inputs/database_template.json +++ b/clang-tools-extra/test/clang-move/Inputs/database_template.json @@ -3,5 +3,10 @@ "directory": "$test_dir/build", "command": "clang++ -o test.o $test_dir/test.cpp", "file": "$test_dir/test.cpp" +}, +{ + "directory": "$test_dir/build", + "command": "clang++ -o test.o $test_dir/multiple_class_test.cpp", + "file": "$test_dir/multiple_class_test.cpp" } ] diff --git a/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.cpp b/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.cpp new file mode 100644 index 00000000000..302475baf0f --- /dev/null +++ b/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.cpp @@ -0,0 +1,27 @@ +#include "multiple_class_test.h" + +namespace a { +int Move1::f() { + return 0; +} +} // namespace a + +namespace b { +int Move2::f() { + return 0; +} +} // namespace b + +namespace c { +int Move3::f() { + return 0; +} + +int Move4::f() { + return 0; +} + +int NoMove::f() { + return 0; +} +} // namespace c diff --git a/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.h b/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.h new file mode 100644 index 00000000000..cedb8d58b0c --- /dev/null +++ b/clang-tools-extra/test/clang-move/Inputs/multiple_class_test.h @@ -0,0 +1,30 @@ +namespace a { +class Move1 { +public: + int f(); +}; +} // namespace a + +namespace b { +class Move2 { +public: + int f(); +}; +} // namespace b + +namespace c { +class Move3 { +public: + int f(); +}; + +class Move4 { +public: + int f(); +}; + +class NoMove { +public: + int f(); +}; +} // namespace c diff --git a/clang-tools-extra/test/clang-move/move-class.cpp b/clang-tools-extra/test/clang-move/move-class.cpp index 0c23608a9e9..af49cf5e1e5 100644 --- a/clang-tools-extra/test/clang-move/move-class.cpp +++ b/clang-tools-extra/test/clang-move/move-class.cpp @@ -3,7 +3,7 @@ // RUN: cp %S/Inputs/test* %T/clang-move/ // RUN: touch %T/clang-move/test2.h // RUN: cd %T/clang-move -// RUN: clang-move -name="a::Foo" -new_cc=%T/clang-move/new_test.cpp -new_header=%T/clang-move/new_test.h -old_cc=../clang-move/test.cpp -old_header=../clang-move/test.h %T/clang-move/test.cpp +// RUN: clang-move -names="a::Foo" -new_cc=%T/clang-move/new_test.cpp -new_header=%T/clang-move/new_test.h -old_cc=../clang-move/test.cpp -old_header=../clang-move/test.h %T/clang-move/test.cpp // RUN: FileCheck -input-file=%T/clang-move/new_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s // RUN: FileCheck -input-file=%T/clang-move/new_test.h -check-prefix=CHECK-NEW-TEST-H %s // RUN: FileCheck -input-file=%T/clang-move/test.cpp -check-prefix=CHECK-OLD-TEST-CPP %s @@ -11,7 +11,7 @@ // // RUN: cp %S/Inputs/test* %T/clang-move/ // RUN: cd %T/clang-move -// RUN: clang-move -name="a::Foo" -new_cc=%T/clang-move/new_test.cpp -new_header=%T/clang-move/new_test.h -old_cc=%T/clang-move/test.cpp -old_header=%T/clang-move/test.h %T/clang-move/test.cpp +// RUN: clang-move -names="a::Foo" -new_cc=%T/clang-move/new_test.cpp -new_header=%T/clang-move/new_test.h -old_cc=%T/clang-move/test.cpp -old_header=%T/clang-move/test.h %T/clang-move/test.cpp // RUN: FileCheck -input-file=%T/clang-move/new_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s // RUN: FileCheck -input-file=%T/clang-move/new_test.h -check-prefix=CHECK-NEW-TEST-H %s // RUN: FileCheck -input-file=%T/clang-move/test.cpp -check-prefix=CHECK-OLD-TEST-CPP %s diff --git a/clang-tools-extra/test/clang-move/move-multiple-classes.cpp b/clang-tools-extra/test/clang-move/move-multiple-classes.cpp new file mode 100644 index 00000000000..0633099789e --- /dev/null +++ b/clang-tools-extra/test/clang-move/move-multiple-classes.cpp @@ -0,0 +1,58 @@ +// RUN: mkdir -p %T/clang-move/build +// RUN: sed 's|$test_dir|%/T/clang-move|g' %S/Inputs/database_template.json > %T/clang-move/compile_commands.json +// RUN: cp %S/Inputs/multiple_class_test* %T/clang-move/ +// RUN: cd %T/clang-move +// RUN: clang-move -names="a::Move1, b::Move2,c::Move3,c::Move4" -new_cc=%T/clang-move/new_multiple_class_test.cpp -new_header=%T/clang-move/new_multiple_class_test.h -old_cc=%T/clang-move/multiple_class_test.cpp -old_header=../clang-move/multiple_class_test.h %T/clang-move/multiple_class_test.cpp +// RUN: FileCheck -input-file=%T/clang-move/new_multiple_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s +// RUN: FileCheck -input-file=%T/clang-move/new_multiple_class_test.h -check-prefix=CHECK-NEW-TEST-H %s +// RUN: FileCheck -input-file=%T/clang-move/multiple_class_test.cpp -check-prefix=CHECK-OLD-TEST-CPP %s +// RUN: FileCheck -input-file=%T/clang-move/multiple_class_test.h -check-prefix=CHECK-OLD-TEST-H %s +// +// CHECK-OLD-TEST-H: namespace c { +// CHECK-OLD-TEST-H: class NoMove { +// CHECK-OLD-TEST-H: public: +// CHECK-OLD-TEST-H: int f(); +// CHECK-OLD-TEST-H: }; +// CHECK-OLD-TEST-H: } // namespace c + +// CHECK-OLD-TEST-CPP: #include "{{.*}}multiple_class_test.h" +// CHECK-OLD-TEST-CPP: namespace c { +// CHECK-OLD-TEST-CPP: int NoMove::f() { +// CHECK-OLD-TEST-CPP: return 0; +// CHECK-OLD-TEST-CPP: } +// CHECK-OLD-TEST-CPP: } // namespace c + +// CHECK-NEW-TEST-H: namespace a { +// CHECK-NEW-TEST-H: class Move1 { +// CHECK-NEW-TEST-H: public: +// CHECK-NEW-TEST-H: int f(); +// CHECK-NEW-TEST-H: }; +// CHECK-NEW-TEST-H: } // namespace a +// CHECK-NEW-TEST-H: namespace b { +// CHECK-NEW-TEST-H: class Move2 { +// CHECK-NEW-TEST-H: public: +// CHECK-NEW-TEST-H: int f(); +// CHECK-NEW-TEST-H: }; +// CHECK-NEW-TEST-H: } // namespace b +// CHECK-NEW-TEST-H: namespace c { +// CHECK-NEW-TEST-H: class Move3 { +// CHECK-NEW-TEST-H: public: +// CHECK-NEW-TEST-H: int f(); +// CHECK-NEW-TEST-H: }; +// CHECK-NEW-TEST-H: class Move4 { +// CHECK-NEW-TEST-H: public: +// CHECK-NEW-TEST-H: int f(); +// CHECK-NEW-TEST-H: }; +// CHECK-NEW-TEST-H: } // namespace c + +// CHECK-NEW-TEST-CPP: #include "{{.*}}new_multiple_class_test.h" +// CHECK-NEW-TEST-CPP: namespace a { +// CHECK-NEW-TEST-CPP: int Move1::f() { return 0; } +// CHECK-NEW-TEST-CPP: } // namespace a +// CHECK-NEW-TEST-CPP: namespace b { +// CHECK-NEW-TEST-CPP: int Move2::f() { return 0; } +// CHECK-NEW-TEST-CPP: } // namespace b +// CHECK-NEW-TEST-CPP: namespace c { +// CHECK-NEW-TEST-CPP: int Move3::f() { return 0; } +// CHECK-NEW-TEST-CPP: int Move4::f() { return 0; } +// CHECK-NEW-TEST-CPP: } // namespace c diff --git a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp index 0ac4a652107..f4845cd52c1 100644 --- a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp +++ b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp @@ -210,7 +210,7 @@ runClangMoveOnCode(const move::ClangMoveTool::MoveDefinitionSpec &Spec) { TEST(ClangMove, MoveHeaderAndCC) { move::ClangMoveTool::MoveDefinitionSpec Spec; - Spec.Name = "a::b::Foo"; + Spec.Names = "a::b::Foo"; Spec.OldHeader = "foo.h"; Spec.OldCC = "foo.cc"; Spec.NewHeader = "new_foo.h"; @@ -225,7 +225,7 @@ TEST(ClangMove, MoveHeaderAndCC) { TEST(ClangMove, MoveHeaderOnly) { move::ClangMoveTool::MoveDefinitionSpec Spec; - Spec.Name = "a::b::Foo"; + Spec.Names = "a::b::Foo"; Spec.OldHeader = "foo.h"; Spec.NewHeader = "new_foo.h"; auto Results = runClangMoveOnCode(Spec); @@ -236,7 +236,7 @@ TEST(ClangMove, MoveHeaderOnly) { TEST(ClangMove, MoveCCOnly) { move::ClangMoveTool::MoveDefinitionSpec Spec; - Spec.Name = "a::b::Foo"; + Spec.Names = "a::b::Foo"; Spec.OldCC = "foo.cc"; Spec.NewCC = "new_foo.cc"; std::string ExpectedHeader = "#include \"foo.h\"\n\n"; @@ -248,7 +248,7 @@ TEST(ClangMove, MoveCCOnly) { TEST(ClangMove, MoveNonExistClass) { move::ClangMoveTool::MoveDefinitionSpec Spec; - Spec.Name = "NonExistFoo"; + Spec.Names = "NonExistFoo"; Spec.OldHeader = "foo.h"; Spec.OldCC = "foo.cc"; Spec.NewHeader = "new_foo.h"; |

