1 //===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements functions to run clang tools standalone instead 11 // of running them as a plugin. 12 // 13 // A ClangTool is initialized with a CompilationDatabase and a set of files 14 // to run over. The tool will then run a user-specified FrontendAction over 15 // all TUs in which the given files are compiled. 16 // 17 // It is also possible to run a FrontendAction over a snippet of code by 18 // calling runSyntaxOnlyToolOnCode, which is useful for unit testing. 19 // 20 // Applications that need more fine grained control over how to run 21 // multiple FrontendActions over code can use ToolInvocation. 22 // 23 // Example tools: 24 // - running clang -fsyntax-only over source code from an editor to get 25 // fast syntax checks 26 // - running match/replace tools over C++ code 27 // 28 //===----------------------------------------------------------------------===// 29 30 #ifndef LLVM_CLANG_TOOLING_TOOLING_H 31 #define LLVM_CLANG_TOOLING_TOOLING_H 32 33 #include "llvm/ADT/StringMap.h" 34 #include "llvm/ADT/Twine.h" 35 #include "clang/Basic/FileManager.h" 36 #include "clang/Basic/LLVM.h" 37 #include "clang/Driver/Util.h" 38 #include <string> 39 #include <vector> 40 41 namespace clang { 42 43 namespace driver { 44 class Compilation; 45 } // end namespace driver 46 47 class CompilerInvocation; 48 class SourceManager; 49 class FrontendAction; 50 51 namespace tooling { 52 53 class CompilationDatabase; 54 55 /// \brief Interface to generate clang::FrontendActions. 56 class FrontendActionFactory { 57 public: 58 virtual ~FrontendActionFactory(); 59 60 /// \brief Returns a new clang::FrontendAction. 61 /// 62 /// The caller takes ownership of the returned action. 63 virtual clang::FrontendAction *create() = 0; 64 }; 65 66 /// \brief Returns a new FrontendActionFactory for a given type. 67 /// 68 /// T must extend clang::FrontendAction. 69 /// 70 /// Example: 71 /// FrontendActionFactory *Factory = 72 /// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 73 template <typename T> 74 FrontendActionFactory *newFrontendActionFactory(); 75 76 /// \brief Returns a new FrontendActionFactory for any type that provides an 77 /// implementation of newFrontendAction(). 78 /// 79 /// FactoryT must implement: FrontendAction *newFrontendAction(). 80 /// 81 /// Example: 82 /// struct ProvidesFrontendActions { 83 /// FrontendAction *newFrontendAction(); 84 /// } Factory; 85 /// FrontendActionFactory *FactoryAdapter = 86 /// newFrontendActionFactory(&Factory); 87 template <typename FactoryT> 88 FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory); 89 90 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 91 /// 92 /// \param ToolAction The action to run over the code. 93 /// \param Code C++ code. 94 /// \param FileName The file name which 'Code' will be mapped as. 95 /// 96 /// \return - True if 'ToolAction' was successfully executed. 97 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 98 const Twine &FileName = "input.cc"); 99 100 /// \brief Utility to run a FrontendAction in a single clang invocation. 101 class ToolInvocation { 102 public: 103 /// \brief Create a tool invocation. 104 /// 105 /// \param CommandLine The command line arguments to clang. 106 /// \param ToolAction The action to be executed. Class takes ownership. 107 /// \param Files The FileManager used for the execution. Class does not take 108 /// ownership. 109 ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction, 110 FileManager *Files); 111 112 /// \brief Map a virtual file to be used while running the tool. 113 /// 114 /// \param FilePath The path at which the content will be mapped. 115 /// \param Content A null terminated buffer of the file's content. 116 void mapVirtualFile(StringRef FilePath, StringRef Content); 117 118 /// \brief Run the clang invocation. 119 /// 120 /// \returns True if there were no errors during execution. 121 bool run(); 122 123 private: 124 void addFileMappingsTo(SourceManager &SourceManager); 125 126 bool runInvocation(const char *BinaryName, 127 clang::driver::Compilation *Compilation, 128 clang::CompilerInvocation *Invocation, 129 const clang::driver::ArgStringList &CC1Args, 130 clang::FrontendAction *ToolAction); 131 132 std::vector<std::string> CommandLine; 133 llvm::OwningPtr<FrontendAction> ToolAction; 134 FileManager *Files; 135 // Maps <file name> -> <file content>. 136 llvm::StringMap<StringRef> MappedFileContents; 137 }; 138 139 /// \brief Utility to run a FrontendAction over a set of files. 140 /// 141 /// This class is written to be usable for command line utilities. 142 class ClangTool { 143 public: 144 /// \brief Constructs a clang tool to run over a list of files. 145 /// 146 /// \param Compilations The CompilationDatabase which contains the compile 147 /// command lines for the given source paths. 148 /// \param SourcePaths The source files to run over. If a source files is 149 /// not found in Compilations, it is skipped. 150 ClangTool(const CompilationDatabase &Compilations, 151 ArrayRef<std::string> SourcePaths); 152 153 /// \brief Map a virtual file to be used while running the tool. 154 /// 155 /// \param FilePath The path at which the content will be mapped. 156 /// \param Content A null terminated buffer of the file's content. 157 void mapVirtualFile(StringRef FilePath, StringRef Content); 158 159 /// Runs a frontend action over all files specified in the command line. 160 /// 161 /// \param ActionFactory Factory generating the frontend actions. The function 162 /// takes ownership of this parameter. A new action is generated for every 163 /// processed translation unit. 164 int run(FrontendActionFactory *ActionFactory); 165 166 /// \brief Returns the file manager used in the tool. 167 /// 168 /// The file manager is shared between all translation units. 169 FileManager &getFiles() { return Files; } 170 171 private: 172 // We store command lines as pair (file name, command line). 173 typedef std::pair< std::string, std::vector<std::string> > CommandLine; 174 std::vector<CommandLine> CommandLines; 175 176 FileManager Files; 177 // Contains a list of pairs (<file name>, <file content>). 178 std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 179 }; 180 181 template <typename T> 182 FrontendActionFactory *newFrontendActionFactory() { 183 class SimpleFrontendActionFactory : public FrontendActionFactory { 184 public: 185 virtual clang::FrontendAction *create() { return new T; } 186 }; 187 188 return new SimpleFrontendActionFactory; 189 } 190 191 template <typename FactoryT> 192 FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory) { 193 class FrontendActionFactoryAdapter : public FrontendActionFactory { 194 public: 195 explicit FrontendActionFactoryAdapter(FactoryT *ActionFactory) 196 : ActionFactory(ActionFactory) {} 197 198 virtual clang::FrontendAction *create() { 199 return ActionFactory->newFrontendAction(); 200 } 201 202 private: 203 FactoryT *ActionFactory; 204 }; 205 206 return new FrontendActionFactoryAdapter(ActionFactory); 207 } 208 209 } // end namespace tooling 210 } // end namespace clang 211 212 #endif // LLVM_CLANG_TOOLING_TOOLING_H 213 214