[clang-move] Better support enclosing class.
Summary: * When moving an outermost enclosing class, all its nested classes should also be moved together. * Add a test for not moving nested class. Reviewers: ioeric Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25369 llvm-svn: 284111
This commit is contained in:
		
							parent
							
								
									2f5ed34279
								
							
						
					
					
						commit
						e77bcc7371
					
				| 
						 | 
				
			
			@ -24,6 +24,32 @@ namespace clang {
 | 
			
		|||
namespace move {
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
AST_MATCHER_P(Decl, hasOutermostEnclosingClass,
 | 
			
		||||
              ast_matchers::internal::Matcher<Decl>, InnerMatcher) {
 | 
			
		||||
  const auto* Context = Node.getDeclContext();
 | 
			
		||||
  if (!Context) return false;
 | 
			
		||||
  while (const auto *NextContext = Context->getParent()) {
 | 
			
		||||
    if (isa<NamespaceDecl>(NextContext) ||
 | 
			
		||||
        isa<TranslationUnitDecl>(NextContext))
 | 
			
		||||
      break;
 | 
			
		||||
    Context = NextContext;
 | 
			
		||||
  }
 | 
			
		||||
  return InnerMatcher.matches(*Decl::castFromDeclContext(Context), Finder,
 | 
			
		||||
                              Builder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AST_MATCHER_P(CXXMethodDecl, ofOutermostEnclosingClass,
 | 
			
		||||
              ast_matchers::internal::Matcher<CXXRecordDecl>, InnerMatcher) {
 | 
			
		||||
  const CXXRecordDecl *Parent = Node.getParent();
 | 
			
		||||
  if (!Parent) return false;
 | 
			
		||||
  while (const auto *NextParent =
 | 
			
		||||
             dyn_cast<CXXRecordDecl>(Parent->getParent())) {
 | 
			
		||||
    Parent = NextParent;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return InnerMatcher.matches(*Parent, Finder, Builder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make the Path absolute using the CurrentDir if the Path is not an absolute
 | 
			
		||||
// path. An empty Path will result in an empty string.
 | 
			
		||||
std::string MakeAbsolutePath(StringRef CurrentDir, StringRef Path) {
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +348,7 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
 | 
			
		|||
      MakeAbsolutePath(OriginalRunningDirectory, Spec.OldCC));
 | 
			
		||||
  auto InOldFiles = anyOf(InOldHeader, InOldCC);
 | 
			
		||||
  auto InMovedClass =
 | 
			
		||||
      hasDeclContext(cxxRecordDecl(*InMovedClassNames));
 | 
			
		||||
      hasOutermostEnclosingClass(cxxRecordDecl(*InMovedClassNames));
 | 
			
		||||
 | 
			
		||||
  // Match moved class declarations.
 | 
			
		||||
  auto MovedClass = cxxRecordDecl(
 | 
			
		||||
| 
						 | 
				
			
			@ -332,11 +358,11 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
 | 
			
		|||
 | 
			
		||||
  // Match moved class methods (static methods included) which are defined
 | 
			
		||||
  // outside moved class declaration.
 | 
			
		||||
  Finder->addMatcher(cxxMethodDecl(InOldFiles,
 | 
			
		||||
                                   ofClass(*InMovedClassNames),
 | 
			
		||||
                                   isDefinition())
 | 
			
		||||
                         .bind("class_method"),
 | 
			
		||||
                     this);
 | 
			
		||||
  Finder->addMatcher(
 | 
			
		||||
      cxxMethodDecl(InOldFiles, ofOutermostEnclosingClass(*InMovedClassNames),
 | 
			
		||||
                    isDefinition())
 | 
			
		||||
          .bind("class_method"),
 | 
			
		||||
      this);
 | 
			
		||||
 | 
			
		||||
  // Match static member variable definition of the moved class.
 | 
			
		||||
  Finder->addMatcher(varDecl(InMovedClass, InOldCC, isDefinition())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,14 @@ int Move4::f() {
 | 
			
		|||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int EnclosingMove5::a = 1;
 | 
			
		||||
 | 
			
		||||
int EnclosingMove5::Nested::f() {
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int EnclosingMove5::Nested::b = 1;
 | 
			
		||||
 | 
			
		||||
int NoMove::f() {
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,15 @@ public:
 | 
			
		|||
  int f();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class EnclosingMove5 {
 | 
			
		||||
public:
 | 
			
		||||
  class Nested {
 | 
			
		||||
    int f();
 | 
			
		||||
    static int b;
 | 
			
		||||
  };
 | 
			
		||||
  static int a;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class NoMove {
 | 
			
		||||
public:
 | 
			
		||||
  int f();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,15 @@
 | 
			
		|||
// RUN: mkdir -p %T/move-multiple-classes
 | 
			
		||||
// RUN: cp %S/Inputs/multiple_class_test*  %T/move-multiple-classes/
 | 
			
		||||
// RUN: cd %T/move-multiple-classes
 | 
			
		||||
// RUN: clang-move -names="a::Move1, b::Move2,c::Move3,c::Move4" -new_cc=%T/move-multiple-classes/new_multiple_class_test.cpp -new_header=%T/move-multiple-classes/new_multiple_class_test.h -old_cc=%T/move-multiple-classes/multiple_class_test.cpp -old_header=../move-multiple-classes/multiple_class_test.h %T/move-multiple-classes/multiple_class_test.cpp --
 | 
			
		||||
// RUN: clang-move -names="c::EnclosingMove5::Nested" -new_cc=%T/move-multiple-classes/new_multiple_class_test.cpp -new_header=%T/move-multiple-classes/new_multiple_class_test.h -old_cc=%T/move-multiple-classes/multiple_class_test.cpp -old_header=../move-multiple-classes/multiple_class_test.h -dump_result %T/move-multiple-classes/multiple_class_test.cpp -- | FileCheck %s -check-prefix=CHECK-EMPTY
 | 
			
		||||
// RUN: clang-move -names="a::Move1, b::Move2,c::Move3,c::Move4,c::EnclosingMove5" -new_cc=%T/move-multiple-classes/new_multiple_class_test.cpp -new_header=%T/move-multiple-classes/new_multiple_class_test.h -old_cc=%T/move-multiple-classes/multiple_class_test.cpp -old_header=../move-multiple-classes/multiple_class_test.h %T/move-multiple-classes/multiple_class_test.cpp --
 | 
			
		||||
// RUN: FileCheck -input-file=%T/move-multiple-classes/new_multiple_class_test.cpp -check-prefix=CHECK-NEW-TEST-CPP %s
 | 
			
		||||
// RUN: FileCheck -input-file=%T/move-multiple-classes/new_multiple_class_test.h -check-prefix=CHECK-NEW-TEST-H %s
 | 
			
		||||
// RUN: FileCheck -input-file=%T/move-multiple-classes/multiple_class_test.cpp -check-prefix=CHECK-OLD-TEST-CPP %s
 | 
			
		||||
// RUN: FileCheck -input-file=%T/move-multiple-classes/multiple_class_test.h -check-prefix=CHECK-OLD-TEST-H %s
 | 
			
		||||
//
 | 
			
		||||
// CHECK-EMPTY: [{{[[:space:]]*}}]
 | 
			
		||||
//
 | 
			
		||||
// CHECK-OLD-TEST-H: namespace c {
 | 
			
		||||
// CHECK-OLD-TEST-H: class NoMove {
 | 
			
		||||
// CHECK-OLD-TEST-H: public:
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +45,14 @@
 | 
			
		|||
// CHECK-NEW-TEST-H: public:
 | 
			
		||||
// CHECK-NEW-TEST-H:   int f();
 | 
			
		||||
// CHECK-NEW-TEST-H: };
 | 
			
		||||
// CHECK-NEW-TEST-H: class EnclosingMove5 {
 | 
			
		||||
// CHECK-NEW-TEST-H: public:
 | 
			
		||||
// CHECK-NEW-TEST-H:   class Nested {
 | 
			
		||||
// CHECK-NEW-TEST-H:     int f();
 | 
			
		||||
// CHECK-NEW-TEST-H:     static int b;
 | 
			
		||||
// CHECK-NEW-TEST-H:   };
 | 
			
		||||
// CHECK-NEW-TEST-H:   static int a;
 | 
			
		||||
// CHECK-NEW-TEST-H: };
 | 
			
		||||
// CHECK-NEW-TEST-H: } // namespace c
 | 
			
		||||
 | 
			
		||||
// CHECK-NEW-TEST-CPP: #include "{{.*}}new_multiple_class_test.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -54,4 +65,7 @@
 | 
			
		|||
// 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: int EnclosingMove5::a = 1;
 | 
			
		||||
// CHECK-NEW-TEST-CPP: int EnclosingMove5::Nested::f() { return 0; }
 | 
			
		||||
// CHECK-NEW-TEST-CPP: int EnclosingMove5::Nested::b = 1;
 | 
			
		||||
// CHECK-NEW-TEST-CPP: } // namespace c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue