forked from OSchip/llvm-project
[clang-move] Support moving function.
Reviewers: ioeric Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D26665 llvm-svn: 287101
This commit is contained in:
parent
f9889f22a9
commit
4543feceb3
|
@ -136,6 +136,27 @@ private:
|
|||
ClangMoveTool *const MoveTool;
|
||||
};
|
||||
|
||||
class FunctionDeclarationMatch : public MatchFinder::MatchCallback {
|
||||
public:
|
||||
explicit FunctionDeclarationMatch(ClangMoveTool *MoveTool)
|
||||
: MoveTool(MoveTool) {}
|
||||
|
||||
void run(const MatchFinder::MatchResult &Result) override {
|
||||
const auto *FD = Result.Nodes.getNodeAs<clang::FunctionDecl>("function");
|
||||
assert(FD);
|
||||
const clang::NamedDecl *D = FD;
|
||||
if (const auto *FTD = FD->getDescribedFunctionTemplate())
|
||||
D = FTD;
|
||||
MoveTool->getMovedDecls().emplace_back(D,
|
||||
&Result.Context->getSourceManager());
|
||||
MoveTool->getUnremovedDeclsInOldHeader().erase(D);
|
||||
MoveTool->getRemovedDecls().push_back(MoveTool->getMovedDecls().back());
|
||||
}
|
||||
|
||||
private:
|
||||
ClangMoveTool *MoveTool;
|
||||
};
|
||||
|
||||
class ClassDeclarationMatch : public MatchFinder::MatchCallback {
|
||||
public:
|
||||
explicit ClassDeclarationMatch(ClangMoveTool *MoveTool)
|
||||
|
@ -389,15 +410,15 @@ ClangMoveTool::ClangMoveTool(
|
|||
}
|
||||
|
||||
void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||
Optional<ast_matchers::internal::Matcher<NamedDecl>> InMovedClassNames;
|
||||
for (StringRef ClassName : Spec.Names) {
|
||||
llvm::StringRef GlobalClassName = ClassName.trim().ltrim(':');
|
||||
const auto HasName = hasName(("::" + GlobalClassName).str());
|
||||
InMovedClassNames =
|
||||
InMovedClassNames ? anyOf(*InMovedClassNames, HasName) : HasName;
|
||||
Optional<ast_matchers::internal::Matcher<NamedDecl>> HasAnySymbolNames;
|
||||
for (StringRef SymbolName: Spec.Names) {
|
||||
llvm::StringRef GlobalSymbolName = SymbolName.trim().ltrim(':');
|
||||
const auto HasName = hasName(("::" + GlobalSymbolName).str());
|
||||
HasAnySymbolNames =
|
||||
HasAnySymbolNames ? anyOf(*HasAnySymbolNames, HasName) : HasName;
|
||||
}
|
||||
if (!InMovedClassNames) {
|
||||
llvm::errs() << "No classes being moved.\n";
|
||||
if (!HasAnySymbolNames) {
|
||||
llvm::errs() << "No symbols being moved.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -405,7 +426,7 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
|||
auto InOldCC = isExpansionInFile(makeAbsolutePath(Spec.OldCC));
|
||||
auto InOldFiles = anyOf(InOldHeader, InOldCC);
|
||||
auto InMovedClass =
|
||||
hasOutermostEnclosingClass(cxxRecordDecl(*InMovedClassNames));
|
||||
hasOutermostEnclosingClass(cxxRecordDecl(*HasAnySymbolNames));
|
||||
|
||||
auto ForwardDecls =
|
||||
cxxRecordDecl(unless(anyOf(isImplicit(), isDefinition())));
|
||||
|
@ -466,14 +487,14 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
|||
// Match moved class declarations.
|
||||
auto MovedClass =
|
||||
cxxRecordDecl(
|
||||
InOldFiles, *InMovedClassNames, isDefinition(),
|
||||
InOldFiles, *HasAnySymbolNames, isDefinition(),
|
||||
hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())))
|
||||
.bind("moved_class");
|
||||
Finder->addMatcher(MovedClass, MatchCallbacks.back().get());
|
||||
// Match moved class methods (static methods included) which are defined
|
||||
// outside moved class declaration.
|
||||
Finder->addMatcher(
|
||||
cxxMethodDecl(InOldFiles, ofOutermostEnclosingClass(*InMovedClassNames),
|
||||
cxxMethodDecl(InOldFiles, ofOutermostEnclosingClass(*HasAnySymbolNames),
|
||||
isDefinition())
|
||||
.bind("class_method"),
|
||||
MatchCallbacks.back().get());
|
||||
|
@ -483,6 +504,12 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
|||
.bind("class_static_var_decl"),
|
||||
MatchCallbacks.back().get());
|
||||
|
||||
MatchCallbacks.push_back(llvm::make_unique<FunctionDeclarationMatch>(this));
|
||||
Finder->addMatcher(functionDecl(InOldFiles, *HasAnySymbolNames,
|
||||
anyOf(hasDeclContext(namespaceDecl()),
|
||||
hasDeclContext(translationUnitDecl())))
|
||||
.bind("function"),
|
||||
MatchCallbacks.back().get());
|
||||
}
|
||||
|
||||
void ClangMoveTool::run(const ast_matchers::MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#include "function_test.h"
|
||||
|
||||
void f() {}
|
||||
|
||||
void A::f() {}
|
|
@ -0,0 +1,14 @@
|
|||
void f();
|
||||
|
||||
inline int g() { return 0; }
|
||||
|
||||
template<typename T>
|
||||
void h(T t) {}
|
||||
|
||||
template<>
|
||||
void h(int t) {}
|
||||
|
||||
class A {
|
||||
public:
|
||||
void f();
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
// RUN: mkdir -p %T/move-function
|
||||
// RUN: cp %S/Inputs/function_test* %T/move-function
|
||||
// RUN: cd %T/move-function
|
||||
// RUN: clang-move -names="g" -new_header=%T/move-function/new_function_test.h -old_header=../move-function/function_test.h %T/move-function/function_test.cpp --
|
||||
// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE1 %s
|
||||
//
|
||||
// CHECK-NEW-TEST-H-CASE1: #ifndef {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE1: #define {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE1: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE1: inline int g() { return 0; }
|
||||
// CHECK-NEW-TEST-H-CASE1: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE1: #endif // {{.*}}NEW_FUNCTION_TEST_H
|
||||
//
|
||||
// RUN: cp %S/Inputs/function_test* %T/move-function
|
||||
// RUN: clang-move -names="h" -new_header=%T/move-function/new_function_test.h -old_header=../move-function/function_test.h %T/move-function/function_test.cpp --
|
||||
// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE2 %s
|
||||
//
|
||||
// CHECK-NEW-TEST-H-CASE2: #ifndef {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE2: #define {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE2: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE2: template <typename T> void h(T t) {}
|
||||
// CHECK-NEW-TEST-H-CASE2: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE2: template <> void h(int t) {}
|
||||
// CHECK-NEW-TEST-H-CASE2: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE2: #endif // {{.*}}NEW_FUNCTION_TEST_H
|
||||
//
|
||||
// RUN: cp %S/Inputs/function_test* %T/move-function
|
||||
// RUN: clang-move -names="f" -new_header=%T/move-function/new_function_test.h -new_cc=%T/move-function/new_function_test.cpp -old_header=../move-function/function_test.h -old_cc=../move-function/function_test.cpp %T/move-function/function_test.cpp --
|
||||
// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE3 %s
|
||||
// RUN: FileCheck -input-file=%T/move-function/new_function_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE3 %s
|
||||
//
|
||||
// CHECK-NEW-TEST-H-CASE3: #ifndef {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE3: #define {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE3: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE3: void f();
|
||||
// CHECK-NEW-TEST-H-CASE3: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE3: #endif // {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-CPP-CASE3: #include "{{.*}}new_function_test.h"
|
||||
// CHECK-NEW-TEST-CPP-CASE3: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-CPP-CASE3: void f() {}
|
||||
//
|
||||
// RUN: cp %S/Inputs/function_test* %T/move-function
|
||||
// RUN: clang-move -names="A::f" -new_header=%T/move-function/new_function_test.h -new_cc=%T/move-function/new_function_test.cpp -old_header=../move-function/function_test.h -old_cc=../move-function/function_test.cpp %T/move-function/function_test.cpp -dump_result -- | FileCheck %s -check-prefix=CHECK-EMPTY
|
||||
//
|
||||
// CHECK-EMPTY: [{{[[:space:]]*}}]
|
||||
//
|
||||
// RUN: cp %S/Inputs/function_test* %T/move-function
|
||||
// RUN: clang-move -names="f,A" -new_header=%T/move-function/new_function_test.h -new_cc=%T/move-function/new_function_test.cpp -old_header=../move-function/function_test.h -old_cc=../move-function/function_test.cpp %T/move-function/function_test.cpp --
|
||||
// RUN: FileCheck -input-file=%T/move-function/new_function_test.h -check-prefix=CHECK-NEW-TEST-H-CASE4 %s
|
||||
// RUN: FileCheck -input-file=%T/move-function/new_function_test.cpp -check-prefix=CHECK-NEW-TEST-CPP-CASE4 %s
|
||||
|
||||
// CHECK-NEW-TEST-H-CASE4: #ifndef {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE4: #define {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-H-CASE4: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE4: void f();
|
||||
// CHECK-NEW-TEST-H-CASE4: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE4: class A {
|
||||
// CHECK-NEW-TEST-H-CASE4: public:
|
||||
// CHECK-NEW-TEST-H-CASE4: void f();
|
||||
// CHECK-NEW-TEST-H-CASE4: };
|
||||
// CHECK-NEW-TEST-H-CASE4: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-H-CASE4: #endif // {{.*}}NEW_FUNCTION_TEST_H
|
||||
// CHECK-NEW-TEST-CPP-CASE4: #include "{{.*}}new_function_test.h"
|
||||
// CHECK-NEW-TEST-CPP-CASE4: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-CPP-CASE4: void f() {}
|
||||
// CHECK-NEW-TEST-CPP-CASE4: {{[[:space:]]+}}
|
||||
// CHECK-NEW-TEST-CPP-CASE4: void A::f() {}
|
Loading…
Reference in New Issue