Index: clang-move/ClangMove.h =================================================================== --- clang-move/ClangMove.h +++ clang-move/ClangMove.h @@ -16,6 +16,7 @@ #include "clang/Tooling/Tooling.h" #include "llvm/ADT/SmallPtrSet.h" #include +#include #include #include @@ -80,6 +81,14 @@ clang::CharSourceRange IncludeFilenameRange, const SourceManager &SM); + std::vector &getMovedDecls() { return MovedDecls; } + + std::vector &getRemovedDecls() { return RemovedDecls; } + + llvm::SmallPtrSet &getUnremovedDeclsInOldHeader() { + return UnremovedDeclsInOldHeader; + } + private: // Make the Path absolute using the OrignalRunningDirectory if the Path is not // an absolute path. An empty Path will result in an empty string. @@ -90,6 +99,9 @@ void moveAll(SourceManager& SM, StringRef OldFile, StringRef NewFile); MoveDefinitionSpec Spec; + // Stores all MatchCallbacks created by this tool. + std::vector> + MatchCallbacks; // The Key is file path, value is the replacements being applied to the file. std::map &FileToReplacements; // All declarations (the class decl being moved, forward decls) that need to Index: clang-move/ClangMove.cpp =================================================================== --- clang-move/ClangMove.cpp +++ clang-move/ClangMove.cpp @@ -136,6 +136,73 @@ ClangMoveTool *const MoveTool; }; +class ClassDeclarationMatch : public MatchFinder::MatchCallback { +public: + explicit ClassDeclarationMatch(ClangMoveTool *MoveTool) + : MoveTool(MoveTool) {} + void run(const MatchFinder::MatchResult &Result) override { + if (MatchClassMethod(Result)) return; + if (MatchClassStaticVariable(Result)) return; + if (MatchClassDeclaration(Result)) return; + } + +private: + bool MatchClassMethod(const MatchFinder::MatchResult &Result) { + if (const auto *CMD = + Result.Nodes.getNodeAs("class_method")) { + // Skip inline class methods. isInline() ast matcher doesn't ignore this + // case. + if (!CMD->isInlined()) { + MoveTool->getMovedDecls().emplace_back( + CMD, &Result.Context->getSourceManager()); + MoveTool->getRemovedDecls().push_back(MoveTool->getMovedDecls().back()); + // Get template class method from its method declaration as + // UnremovedDecls stores template class method. + if (const auto *FTD = CMD->getDescribedFunctionTemplate()) { + MoveTool->getUnremovedDeclsInOldHeader().erase(FTD); + } else { + MoveTool->getUnremovedDeclsInOldHeader().erase(CMD); + } + } + return true; + } + return false; + } + + bool MatchClassStaticVariable(const MatchFinder::MatchResult &Result) { + if (const auto *VD = Result.Nodes.getNodeAs( + "class_static_var_decl")) { + MoveTool->getMovedDecls().emplace_back( + VD, &Result.Context->getSourceManager()); + MoveTool->getRemovedDecls().push_back(MoveTool->getMovedDecls().back()); + MoveTool->getUnremovedDeclsInOldHeader().erase(VD); + return true; + } + return false; + } + + bool MatchClassDeclaration(const MatchFinder::MatchResult &Result) { + if (const auto *CD = Result.Nodes.getNodeAs( + "moved_class")) { + // Get class template from its class declaration as UnremovedDecls stores + // class template. + if (const auto *TC = CD->getDescribedClassTemplate()) { + MoveTool->getMovedDecls().emplace_back( + TC, &Result.Context->getSourceManager()); + } else { + MoveTool->getMovedDecls().emplace_back( + CD, &Result.Context->getSourceManager()); + } + MoveTool->getRemovedDecls().push_back(MoveTool->getMovedDecls().back()); + MoveTool->getUnremovedDeclsInOldHeader().erase( + MoveTool->getMovedDecls().back().Decl); + return true; + } + return false; + } + ClangMoveTool *MoveTool; +}; + // Expand to get the end location of the line where the EndLoc of the given // Decl. SourceLocation @@ -352,23 +419,27 @@ //============================================================================ // Matchers for old files, including old.h/old.cc //============================================================================ + // Create a MatchCallback for class declarations. + MatchCallbacks.push_back(llvm::make_unique(this)); // Match moved class declarations. - auto MovedClass = cxxRecordDecl( - InOldFiles, *InMovedClassNames, isDefinition(), - hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl()))); - Finder->addMatcher(MovedClass.bind("moved_class"), this); + auto MovedClass = + cxxRecordDecl( + InOldFiles, *InMovedClassNames, 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), isDefinition()) .bind("class_method"), - this); + MatchCallbacks.back().get()); // Match static member variable definition of the moved class. Finder->addMatcher( varDecl(InMovedClass, InOldFiles, isDefinition(), isStaticDataMember()) .bind("class_static_var_decl"), - this); + MatchCallbacks.back().get()); //============================================================================ // Matchers for old cc @@ -404,35 +475,6 @@ if (const auto *D = Result.Nodes.getNodeAs("decls_in_header")) { UnremovedDeclsInOldHeader.insert(D); - } else if (const auto *CMD = - Result.Nodes.getNodeAs("class_method")) { - // Skip inline class methods. isInline() ast matcher doesn't ignore this - // case. - if (!CMD->isInlined()) { - MovedDecls.emplace_back(CMD, &Result.Context->getSourceManager()); - RemovedDecls.push_back(MovedDecls.back()); - // Get template class method from its method declaration as - // UnremovedDecls stores template class method. - if (const auto *FTD = CMD->getDescribedFunctionTemplate()) - UnremovedDeclsInOldHeader.erase(FTD); - else - UnremovedDeclsInOldHeader.erase(CMD); - } - } else if (const auto *VD = Result.Nodes.getNodeAs( - "class_static_var_decl")) { - MovedDecls.emplace_back(VD, &Result.Context->getSourceManager()); - RemovedDecls.push_back(MovedDecls.back()); - UnremovedDeclsInOldHeader.erase(MovedDecls.back().Decl); - } else if (const auto *CD = - Result.Nodes.getNodeAs("moved_class")) { - // Get class template from its class declaration as UnremovedDecls stores - // class template. - if (const auto * TC = CD->getDescribedClassTemplate()) - MovedDecls.emplace_back(TC, &Result.Context->getSourceManager()); - else - MovedDecls.emplace_back(CD, &Result.Context->getSourceManager()); - RemovedDecls.push_back(MovedDecls.back()); - UnremovedDeclsInOldHeader.erase(MovedDecls.back().Decl); } else if (const auto *FWD = Result.Nodes.getNodeAs("fwd_decl")) { // Skip all forwad declarations which appear after moved class declaration.