diff options
author | Nico Weber <nicolasweber@gmx.de> | 2019-03-22 16:34:39 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2019-03-22 16:34:39 +0000 |
commit | 71ebc9eb0b0586c7d995f42e14c1e0180cc299b9 (patch) | |
tree | 96a7dd3e5117fe4a1cf77b8a4b03f939a21b1bb5 /clang-tools-extra/clang-move/Move.h | |
parent | f032e85d6462015ea51d8992bbd44813d1a75c67 (diff) | |
download | llvm-71ebc9eb0b0586c7d995f42e14c1e0180cc299b9.zip llvm-71ebc9eb0b0586c7d995f42e14c1e0180cc299b9.tar.gz llvm-71ebc9eb0b0586c7d995f42e14c1e0180cc299b9.tar.bz2 |
Make clang-move use same file naming convention as other tools
In all the other clang-foo tools, the main library file is called
Foo.cpp and the file in the tool/ folder is called ClangFoo.cpp.
Do this for clang-move too.
No intended behavior change.
Differential Revision: https://reviews.llvm.org/D59700
llvm-svn: 356780
Diffstat (limited to 'clang-tools-extra/clang-move/Move.h')
-rw-r--r-- | clang-tools-extra/clang-move/Move.h | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-move/Move.h b/clang-tools-extra/clang-move/Move.h new file mode 100644 index 0000000..da4bc44 --- /dev/null +++ b/clang-tools-extra/clang-move/Move.h @@ -0,0 +1,240 @@ +//===-- Move.h - Clang move ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H + +#include "HelperDeclRefGraph.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Tooling/Core/Replacement.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include <map> +#include <memory> +#include <string> +#include <vector> + +namespace clang { +namespace move { + +// A reporter which collects and reports declarations in old header. +class DeclarationReporter { +public: + DeclarationReporter() = default; + ~DeclarationReporter() = default; + + void reportDeclaration(llvm::StringRef DeclarationName, llvm::StringRef Type, + bool Templated) { + DeclarationList.emplace_back(DeclarationName, Type, Templated); + }; + + struct Declaration { + Declaration(llvm::StringRef QName, llvm::StringRef Kind, bool Templated) + : QualifiedName(QName), Kind(Kind), Templated(Templated) {} + + friend bool operator==(const Declaration &LHS, const Declaration &RHS) { + return std::tie(LHS.QualifiedName, LHS.Kind, LHS.Templated) == + std::tie(RHS.QualifiedName, RHS.Kind, RHS.Templated); + } + std::string QualifiedName; // E.g. A::B::Foo. + std::string Kind; // E.g. Function, Class + bool Templated = false; // Whether the declaration is templated. + }; + + const std::vector<Declaration> getDeclarationList() const { + return DeclarationList; + } + +private: + std::vector<Declaration> DeclarationList; +}; + +// Specify declarations being moved. It contains all information of the moved +// declarations. +struct MoveDefinitionSpec { + // The list of fully qualified names, e.g. Foo, a::Foo, b::Foo. + SmallVector<std::string, 4> 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. + std::string OldCC; + // The file path of new header, can be relative path and absolute path. + std::string NewHeader; + // The file path of new cc, can be relative path and absolute path. + std::string NewCC; + // Whether old.h depends on new.h. If true, #include "new.h" will be added + // in old.h. + bool OldDependOnNew = false; + // Whether new.h depends on old.h. If true, #include "old.h" will be added + // in new.h. + bool NewDependOnOld = false; +}; + +// A Context which contains extra options which are used in ClangMoveTool. +struct ClangMoveContext { + MoveDefinitionSpec Spec; + // The Key is file path, value is the replacements being applied to the file. + std::map<std::string, tooling::Replacements> &FileToReplacements; + // The original working directory where the local clang-move binary runs. + // + // clang-move will change its current working directory to the build + // directory when analyzing the source file. We save the original working + // directory in order to get the absolute file path for the fields in Spec. + std::string OriginalRunningDirectory; + // The name of a predefined code style. + std::string FallbackStyle; + // Whether dump all declarations in old header. + bool DumpDeclarations; +}; + +// This tool is used to move class/function definitions from the given source +// files (old.h/cc) to new files (new.h/cc). +// The goal of this tool is to make the new/old files as compilable as possible. +// +// When moving a symbol,all used helper declarations (e.g. static +// functions/variables definitions in global/named namespace, +// functions/variables/classes definitions in anonymous namespace) used by the +// moved symbol in old.cc are moved to the new.cc. In addition, all +// using-declarations in old.cc are also moved to new.cc; forward class +// declarations in old.h are also moved to new.h. +// +// The remaining helper declarations which are unused by non-moved symbols in +// old.cc will be removed. +// +// 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. 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, + DeclarationReporter *const Reporter); + + void registerMatchers(ast_matchers::MatchFinder *Finder); + + void run(const ast_matchers::MatchFinder::MatchResult &Result) override; + + void onEndOfTranslationUnit() override; + + /// Add #includes from old.h/cc files. + /// + /// \param IncludeHeader The name of the file being included, as written in + /// the source code. + /// \param IsAngled Whether the file name was enclosed in angle brackets. + /// \param SearchPath The search path which was used to find the IncludeHeader + /// in the file system. It can be a relative path or an absolute path. + /// \param FileName The name of file where the IncludeHeader comes from. + /// \param IncludeFilenameRange The source range for the written file name in + /// #include (i.e. "old.h" for #include "old.h") in old.cc. + /// \param SM The SourceManager. + void addIncludes(llvm::StringRef IncludeHeader, bool IsAngled, + llvm::StringRef SearchPath, llvm::StringRef FileName, + clang::CharSourceRange IncludeFilenameRange, + const SourceManager &SM); + + std::vector<const NamedDecl *> &getMovedDecls() { return MovedDecls; } + + /// Add declarations being removed from old.h/cc. For each declarations, the + /// method also records the mapping relationship between the corresponding + /// FilePath and its FileID. + void addRemovedDecl(const NamedDecl *Decl); + + llvm::SmallPtrSet<const NamedDecl *, 8> &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. + std::string makeAbsolutePath(StringRef Path); + + void removeDeclsInOldFiles(); + void moveDeclsToNewFiles(); + void moveAll(SourceManager& SM, StringRef OldFile, StringRef NewFile); + + // Stores all MatchCallbacks created by this tool. + std::vector<std::unique_ptr<ast_matchers::MatchFinder::MatchCallback>> + MatchCallbacks; + // Store all potential declarations (decls being moved, forward decls) that + // might need to move to new.h/cc. It includes all helper declarations + // (include unused ones) by default. The unused ones will be filtered out in + // the last stage. Saving in an AST-visited order. + std::vector<const NamedDecl *> MovedDecls; + // The declarations that needs to be removed in old.cc/h. + std::vector<const NamedDecl *> RemovedDecls; + // The #includes in old_header.h. + std::vector<std::string> HeaderIncludes; + // The #includes in old_cc.cc. + std::vector<std::string> CCIncludes; + // Records all helper declarations (function/variable/class definitions in + // anonymous namespaces, static function/variable definitions in global/named + // namespaces) in old.cc. saving in an AST-visited order. + std::vector<const NamedDecl *> HelperDeclarations; + // The unmoved named declarations in old header. + llvm::SmallPtrSet<const NamedDecl*, 8> UnremovedDeclsInOldHeader; + /// The source range for the written file name in #include (i.e. "old.h" for + /// #include "old.h") in old.cc, including the enclosing quotes or angle + /// brackets. + clang::CharSourceRange OldHeaderIncludeRangeInCC; + /// The source range for the written file name in #include (i.e. "old.h" for + /// #include "old.h") in old.h, including the enclosing quotes or angle + /// brackets. + clang::CharSourceRange OldHeaderIncludeRangeInHeader; + /// Mapping from FilePath to FileID, which can be used in post processes like + /// cleanup around replacements. + llvm::StringMap<FileID> FilePathToFileID; + /// A context contains all running options. It is not owned. + ClangMoveContext *const Context; + /// A reporter to report all declarations from old header. It is not owned. + DeclarationReporter *const Reporter; + /// Builder for helper declarations reference graph. + HelperDeclRGBuilder RGBuilder; +}; + +class ClangMoveAction : public clang::ASTFrontendAction { +public: + ClangMoveAction(ClangMoveContext *const Context, + DeclarationReporter *const Reporter) + : MoveTool(Context, Reporter) { + MoveTool.registerMatchers(&MatchFinder); + } + + ~ClangMoveAction() override = default; + + std::unique_ptr<clang::ASTConsumer> + CreateASTConsumer(clang::CompilerInstance &Compiler, + llvm::StringRef InFile) override; + +private: + ast_matchers::MatchFinder MatchFinder; + ClangMoveTool MoveTool; +}; + +class ClangMoveActionFactory : public tooling::FrontendActionFactory { +public: + ClangMoveActionFactory(ClangMoveContext *const Context, + DeclarationReporter *const Reporter = nullptr) + : Context(Context), Reporter(Reporter) {} + + clang::FrontendAction *create() override { + return new ClangMoveAction(Context, Reporter); + } + +private: + // Not owned. + ClangMoveContext *const Context; + DeclarationReporter *const Reporter; +}; + +} // namespace move +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H |