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 runToolOnCode, 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 "clang/Basic/FileManager.h" 34 #include "clang/Basic/LLVM.h" 35 #include "clang/Driver/Util.h" 36 #include "clang/Frontend/FrontendAction.h" 37 #include "clang/Tooling/ArgumentsAdjusters.h" 38 #include "clang/Tooling/CompilationDatabase.h" 39 #include "llvm/ADT/StringMap.h" 40 #include "llvm/ADT/Twine.h" 41 #include <string> 42 #include <vector> 43 44 namespace clang { 45 46 namespace driver { 47 class Compilation; 48 } // end namespace driver 49 50 class CompilerInvocation; 51 class SourceManager; 52 class FrontendAction; 53 54 namespace tooling { 55 56 /// \brief Interface to generate clang::FrontendActions. 57 class FrontendActionFactory { 58 public: 59 virtual ~FrontendActionFactory(); 60 61 /// \brief Returns a new clang::FrontendAction. 62 /// 63 /// The caller takes ownership of the returned action. 64 virtual clang::FrontendAction *create() = 0; 65 }; 66 67 /// \brief Returns a new FrontendActionFactory for a given type. 68 /// 69 /// T must extend clang::FrontendAction. 70 /// 71 /// Example: 72 /// FrontendActionFactory *Factory = 73 /// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 74 template <typename T> 75 FrontendActionFactory *newFrontendActionFactory(); 76 77 /// \brief Called at the end of each source file when used with 78 /// \c newFrontendActionFactory. 79 class EndOfSourceFileCallback { 80 public: 81 virtual ~EndOfSourceFileCallback() {} 82 virtual void run() = 0; 83 }; 84 85 /// \brief Returns a new FrontendActionFactory for any type that provides an 86 /// implementation of newASTConsumer(). 87 /// 88 /// FactoryT must implement: ASTConsumer *newASTConsumer(). 89 /// 90 /// Example: 91 /// struct ProvidesASTConsumers { 92 /// clang::ASTConsumer *newASTConsumer(); 93 /// } Factory; 94 /// FrontendActionFactory *FactoryAdapter = 95 /// newFrontendActionFactory(&Factory); 96 template <typename FactoryT> 97 inline FrontendActionFactory *newFrontendActionFactory( 98 FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback = NULL); 99 100 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 101 /// 102 /// \param ToolAction The action to run over the code. 103 /// \param Code C++ code. 104 /// \param FileName The file name which 'Code' will be mapped as. 105 /// 106 /// \return - True if 'ToolAction' was successfully executed. 107 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 108 const Twine &FileName = "input.cc"); 109 110 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and 111 /// with additional other flags. 112 /// 113 /// \param ToolAction The action to run over the code. 114 /// \param Code C++ code. 115 /// \param Args Additional flags to pass on. 116 /// \param FileName The file name which 'Code' will be mapped as. 117 /// 118 /// \return - True if 'ToolAction' was successfully executed. 119 bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, 120 const std::vector<std::string> &Args, 121 const Twine &FileName = "input.cc"); 122 123 /// \brief Utility to run a FrontendAction in a single clang invocation. 124 class ToolInvocation { 125 public: 126 /// \brief Create a tool invocation. 127 /// 128 /// \param CommandLine The command line arguments to clang. Note that clang 129 /// uses its binary name (CommandLine[0]) to locate its builtin headers. 130 /// Callers have to ensure that they are installed in a compatible location 131 /// (see clang driver implementation) or mapped in via mapVirtualFile. 132 /// \param ToolAction The action to be executed. Class takes ownership. 133 /// \param Files The FileManager used for the execution. Class does not take 134 /// ownership. 135 ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction, 136 FileManager *Files); 137 138 /// \brief Map a virtual file to be used while running the tool. 139 /// 140 /// \param FilePath The path at which the content will be mapped. 141 /// \param Content A null terminated buffer of the file's content. 142 void mapVirtualFile(StringRef FilePath, StringRef Content); 143 144 /// \brief Run the clang invocation. 145 /// 146 /// \returns True if there were no errors during execution. 147 bool run(); 148 149 private: 150 void addFileMappingsTo(SourceManager &SourceManager); 151 152 bool runInvocation(const char *BinaryName, 153 clang::driver::Compilation *Compilation, 154 clang::CompilerInvocation *Invocation); 155 156 std::vector<std::string> CommandLine; 157 OwningPtr<FrontendAction> ToolAction; 158 FileManager *Files; 159 // Maps <file name> -> <file content>. 160 llvm::StringMap<StringRef> MappedFileContents; 161 }; 162 163 /// \brief Utility to run a FrontendAction over a set of files. 164 /// 165 /// This class is written to be usable for command line utilities. 166 /// By default the class uses ClangSyntaxOnlyAdjuster to modify 167 /// command line arguments before the arguments are used to run 168 /// a frontend action. One could install another command line 169 /// arguments adjuster by call setArgumentsAdjuster() method. 170 class ClangTool { 171 public: 172 /// \brief Constructs a clang tool to run over a list of files. 173 /// 174 /// \param Compilations The CompilationDatabase which contains the compile 175 /// command lines for the given source paths. 176 /// \param SourcePaths The source files to run over. If a source files is 177 /// not found in Compilations, it is skipped. 178 ClangTool(const CompilationDatabase &Compilations, 179 ArrayRef<std::string> SourcePaths); 180 181 virtual ~ClangTool() {} 182 183 /// \brief Map a virtual file to be used while running the tool. 184 /// 185 /// \param FilePath The path at which the content will be mapped. 186 /// \param Content A null terminated buffer of the file's content. 187 void mapVirtualFile(StringRef FilePath, StringRef Content); 188 189 /// \brief Install command line arguments adjuster. 190 /// 191 /// \param Adjuster Command line arguments adjuster. 192 void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 193 194 /// Runs a frontend action over all files specified in the command line. 195 /// 196 /// \param ActionFactory Factory generating the frontend actions. The function 197 /// takes ownership of this parameter. A new action is generated for every 198 /// processed translation unit. 199 virtual int run(FrontendActionFactory *ActionFactory); 200 201 /// \brief Returns the file manager used in the tool. 202 /// 203 /// The file manager is shared between all translation units. 204 FileManager &getFiles() { return Files; } 205 206 private: 207 // We store compile commands as pair (file name, compile command). 208 std::vector< std::pair<std::string, CompileCommand> > CompileCommands; 209 210 FileManager Files; 211 // Contains a list of pairs (<file name>, <file content>). 212 std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 213 214 OwningPtr<ArgumentsAdjuster> ArgsAdjuster; 215 }; 216 217 template <typename T> 218 FrontendActionFactory *newFrontendActionFactory() { 219 class SimpleFrontendActionFactory : public FrontendActionFactory { 220 public: 221 virtual clang::FrontendAction *create() { return new T; } 222 }; 223 224 return new SimpleFrontendActionFactory; 225 } 226 227 template <typename FactoryT> 228 inline FrontendActionFactory *newFrontendActionFactory( 229 FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback) { 230 class FrontendActionFactoryAdapter : public FrontendActionFactory { 231 public: 232 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, 233 EndOfSourceFileCallback *EndCallback) 234 : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} 235 236 virtual clang::FrontendAction *create() { 237 return new ConsumerFactoryAdaptor(ConsumerFactory, EndCallback); 238 } 239 240 private: 241 class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { 242 public: 243 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, 244 EndOfSourceFileCallback *EndCallback) 245 : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} 246 247 clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, 248 StringRef) { 249 return ConsumerFactory->newASTConsumer(); 250 } 251 252 protected: 253 virtual void EndSourceFileAction() { 254 if (EndCallback != NULL) 255 EndCallback->run(); 256 clang::ASTFrontendAction::EndSourceFileAction(); 257 } 258 259 private: 260 FactoryT *ConsumerFactory; 261 EndOfSourceFileCallback *EndCallback; 262 }; 263 FactoryT *ConsumerFactory; 264 EndOfSourceFileCallback *EndCallback; 265 }; 266 267 return new FrontendActionFactoryAdapter(ConsumerFactory, EndCallback); 268 } 269 270 /// \brief Returns the absolute path of \c File, by prepending it with 271 /// the current directory if \c File is not absolute. 272 /// 273 /// Otherwise returns \c File. 274 /// If 'File' starts with "./", the returned path will not contain the "./". 275 /// Otherwise, the returned path will contain the literal path-concatenation of 276 /// the current directory and \c File. 277 /// 278 /// The difference to llvm::sys::fs::make_absolute is that we prefer 279 /// ::getenv("PWD") if available. 280 /// FIXME: Make this functionality available from llvm::sys::fs and delete 281 /// this function. 282 /// 283 /// \param File Either an absolute or relative path. 284 std::string getAbsolutePath(StringRef File); 285 286 } // end namespace tooling 287 } // end namespace clang 288 289 #endif // LLVM_CLANG_TOOLING_TOOLING_H 290