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/Diagnostic.h" 34 #include "clang/Basic/FileManager.h" 35 #include "clang/Basic/LLVM.h" 36 #include "clang/Driver/Util.h" 37 #include "clang/Frontend/FrontendAction.h" 38 #include "clang/Tooling/ArgumentsAdjusters.h" 39 #include "clang/Tooling/CompilationDatabase.h" 40 #include "llvm/ADT/StringMap.h" 41 #include "llvm/ADT/Twine.h" 42 #include <string> 43 #include <vector> 44 45 namespace clang { 46 47 namespace driver { 48 class Compilation; 49 } // end namespace driver 50 51 class CompilerInvocation; 52 class SourceManager; 53 class FrontendAction; 54 55 namespace tooling { 56 57 /// \brief Interface to process a clang::CompilerInvocation. 58 /// 59 /// If your tool is based on FrontendAction, you should be deriving from 60 /// FrontendActionFactory instead. 61 class ToolAction { 62 public: 63 virtual ~ToolAction(); 64 65 /// \brief Perform an action for an invocation. 66 virtual bool runInvocation(clang::CompilerInvocation *Invocation, 67 FileManager *Files, 68 DiagnosticConsumer *DiagConsumer) = 0; 69 }; 70 71 /// \brief Interface to generate clang::FrontendActions. 72 /// 73 /// Having a factory interface allows, for example, a new FrontendAction to be 74 /// created for each translation unit processed by ClangTool. This class is 75 /// also a ToolAction which uses the FrontendActions created by create() to 76 /// process each translation unit. 77 class FrontendActionFactory : public ToolAction { 78 public: 79 virtual ~FrontendActionFactory(); 80 81 /// \brief Invokes the compiler with a FrontendAction created by create(). 82 bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files, 83 DiagnosticConsumer *DiagConsumer); 84 85 /// \brief Returns a new clang::FrontendAction. 86 /// 87 /// The caller takes ownership of the returned action. 88 virtual clang::FrontendAction *create() = 0; 89 }; 90 91 /// \brief Returns a new FrontendActionFactory for a given type. 92 /// 93 /// T must derive from clang::FrontendAction. 94 /// 95 /// Example: 96 /// FrontendActionFactory *Factory = 97 /// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 98 template <typename T> 99 FrontendActionFactory *newFrontendActionFactory(); 100 101 /// \brief Callbacks called before and after each source file processed by a 102 /// FrontendAction created by the FrontedActionFactory returned by \c 103 /// newFrontendActionFactory. 104 class SourceFileCallbacks { 105 public: 106 virtual ~SourceFileCallbacks() {} 107 108 /// \brief Called before a source file is processed by a FrontEndAction. 109 /// \see clang::FrontendAction::BeginSourceFileAction 110 virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) { 111 return true; 112 } 113 114 /// \brief Called after a source file is processed by a FrontendAction. 115 /// \see clang::FrontendAction::EndSourceFileAction 116 virtual void handleEndSource() {} 117 }; 118 119 /// \brief Returns a new FrontendActionFactory for any type that provides an 120 /// implementation of newASTConsumer(). 121 /// 122 /// FactoryT must implement: ASTConsumer *newASTConsumer(). 123 /// 124 /// Example: 125 /// struct ProvidesASTConsumers { 126 /// clang::ASTConsumer *newASTConsumer(); 127 /// } Factory; 128 /// FrontendActionFactory *FactoryAdapter = 129 /// newFrontendActionFactory(&Factory); 130 template <typename FactoryT> 131 inline FrontendActionFactory *newFrontendActionFactory( 132 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = NULL); 133 134 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 135 /// 136 /// \param ToolAction The action to run over the code. 137 /// \param Code C++ code. 138 /// \param FileName The file name which 'Code' will be mapped as. 139 /// 140 /// \return - True if 'ToolAction' was successfully executed. 141 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 142 const Twine &FileName = "input.cc"); 143 144 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and 145 /// with additional other flags. 146 /// 147 /// \param ToolAction The action to run over the code. 148 /// \param Code C++ code. 149 /// \param Args Additional flags to pass on. 150 /// \param FileName The file name which 'Code' will be mapped as. 151 /// 152 /// \return - True if 'ToolAction' was successfully executed. 153 bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, 154 const std::vector<std::string> &Args, 155 const Twine &FileName = "input.cc"); 156 157 /// \brief Builds an AST for 'Code'. 158 /// 159 /// \param Code C++ code. 160 /// \param FileName The file name which 'Code' will be mapped as. 161 /// 162 /// \return The resulting AST or null if an error occurred. 163 ASTUnit *buildASTFromCode(const Twine &Code, 164 const Twine &FileName = "input.cc"); 165 166 /// \brief Builds an AST for 'Code' with additional flags. 167 /// 168 /// \param Code C++ code. 169 /// \param Args Additional flags to pass on. 170 /// \param FileName The file name which 'Code' will be mapped as. 171 /// 172 /// \return The resulting AST or null if an error occurred. 173 ASTUnit *buildASTFromCodeWithArgs(const Twine &Code, 174 const std::vector<std::string> &Args, 175 const Twine &FileName = "input.cc"); 176 177 /// \brief Utility to run a FrontendAction in a single clang invocation. 178 class ToolInvocation { 179 public: 180 /// \brief Create a tool invocation. 181 /// 182 /// \param CommandLine The command line arguments to clang. Note that clang 183 /// uses its binary name (CommandLine[0]) to locate its builtin headers. 184 /// Callers have to ensure that they are installed in a compatible location 185 /// (see clang driver implementation) or mapped in via mapVirtualFile. 186 /// \param FAction The action to be executed. Class takes ownership. 187 /// \param Files The FileManager used for the execution. Class does not take 188 /// ownership. 189 ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction, 190 FileManager *Files); 191 192 /// \brief Create a tool invocation. 193 /// 194 /// \param CommandLine The command line arguments to clang. 195 /// \param Action The action to be executed. 196 /// \param Files The FileManager used for the execution. 197 ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action, 198 FileManager *Files); 199 200 ~ToolInvocation(); 201 202 /// \brief Set a \c DiagnosticConsumer to use during parsing. 203 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer); 204 205 /// \brief Map a virtual file to be used while running the tool. 206 /// 207 /// \param FilePath The path at which the content will be mapped. 208 /// \param Content A null terminated buffer of the file's content. 209 void mapVirtualFile(StringRef FilePath, StringRef Content); 210 211 /// \brief Run the clang invocation. 212 /// 213 /// \returns True if there were no errors during execution. 214 bool run(); 215 216 private: 217 void addFileMappingsTo(SourceManager &SourceManager); 218 219 bool runInvocation(const char *BinaryName, 220 clang::driver::Compilation *Compilation, 221 clang::CompilerInvocation *Invocation); 222 223 std::vector<std::string> CommandLine; 224 ToolAction *Action; 225 bool OwnsAction; 226 FileManager *Files; 227 // Maps <file name> -> <file content>. 228 llvm::StringMap<StringRef> MappedFileContents; 229 DiagnosticConsumer *DiagConsumer; 230 }; 231 232 /// \brief Utility to run a FrontendAction over a set of files. 233 /// 234 /// This class is written to be usable for command line utilities. 235 /// By default the class uses ClangSyntaxOnlyAdjuster to modify 236 /// command line arguments before the arguments are used to run 237 /// a frontend action. One could install an additional command line 238 /// arguments adjuster by calling the appendArgumentsAdjuster() method. 239 class ClangTool { 240 public: 241 /// \brief Constructs a clang tool to run over a list of files. 242 /// 243 /// \param Compilations The CompilationDatabase which contains the compile 244 /// command lines for the given source paths. 245 /// \param SourcePaths The source files to run over. If a source files is 246 /// not found in Compilations, it is skipped. 247 ClangTool(const CompilationDatabase &Compilations, 248 ArrayRef<std::string> SourcePaths); 249 250 virtual ~ClangTool() { clearArgumentsAdjusters(); } 251 252 /// \brief Set a \c DiagnosticConsumer to use during parsing. 253 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer); 254 255 /// \brief Map a virtual file to be used while running the tool. 256 /// 257 /// \param FilePath The path at which the content will be mapped. 258 /// \param Content A null terminated buffer of the file's content. 259 void mapVirtualFile(StringRef FilePath, StringRef Content); 260 261 /// \brief Install command line arguments adjuster. 262 /// 263 /// \param Adjuster Command line arguments adjuster. 264 // 265 /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead. 266 /// Remove it once all callers are gone. 267 void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 268 269 /// \brief Append a command line arguments adjuster to the adjuster chain. 270 /// 271 /// \param Adjuster An argument adjuster, which will be run on the output of 272 /// previous argument adjusters. 273 void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 274 275 /// \brief Clear the command line arguments adjuster chain. 276 void clearArgumentsAdjusters(); 277 278 /// Runs an action over all files specified in the command line. 279 /// 280 /// \param Action Tool action. 281 int run(ToolAction *Action); 282 283 /// \brief Create an AST for each file specified in the command line and 284 /// append them to ASTs. 285 int buildASTs(std::vector<ASTUnit *> &ASTs); 286 287 /// \brief Returns the file manager used in the tool. 288 /// 289 /// The file manager is shared between all translation units. 290 FileManager &getFiles() { return *Files; } 291 292 private: 293 // We store compile commands as pair (file name, compile command). 294 std::vector< std::pair<std::string, CompileCommand> > CompileCommands; 295 296 llvm::IntrusiveRefCntPtr<FileManager> Files; 297 // Contains a list of pairs (<file name>, <file content>). 298 std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 299 300 SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters; 301 302 DiagnosticConsumer *DiagConsumer; 303 }; 304 305 template <typename T> 306 FrontendActionFactory *newFrontendActionFactory() { 307 class SimpleFrontendActionFactory : public FrontendActionFactory { 308 public: 309 virtual clang::FrontendAction *create() { return new T; } 310 }; 311 312 return new SimpleFrontendActionFactory; 313 } 314 315 template <typename FactoryT> 316 inline FrontendActionFactory *newFrontendActionFactory( 317 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) { 318 class FrontendActionFactoryAdapter : public FrontendActionFactory { 319 public: 320 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, 321 SourceFileCallbacks *Callbacks) 322 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 323 324 virtual clang::FrontendAction *create() { 325 return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks); 326 } 327 328 private: 329 class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { 330 public: 331 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, 332 SourceFileCallbacks *Callbacks) 333 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 334 335 clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, 336 StringRef) { 337 return ConsumerFactory->newASTConsumer(); 338 } 339 340 protected: 341 virtual bool BeginSourceFileAction(CompilerInstance &CI, 342 StringRef Filename) LLVM_OVERRIDE { 343 if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename)) 344 return false; 345 if (Callbacks != NULL) 346 return Callbacks->handleBeginSource(CI, Filename); 347 return true; 348 } 349 virtual void EndSourceFileAction() LLVM_OVERRIDE { 350 if (Callbacks != NULL) 351 Callbacks->handleEndSource(); 352 clang::ASTFrontendAction::EndSourceFileAction(); 353 } 354 355 private: 356 FactoryT *ConsumerFactory; 357 SourceFileCallbacks *Callbacks; 358 }; 359 FactoryT *ConsumerFactory; 360 SourceFileCallbacks *Callbacks; 361 }; 362 363 return new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks); 364 } 365 366 /// \brief Returns the absolute path of \c File, by prepending it with 367 /// the current directory if \c File is not absolute. 368 /// 369 /// Otherwise returns \c File. 370 /// If 'File' starts with "./", the returned path will not contain the "./". 371 /// Otherwise, the returned path will contain the literal path-concatenation of 372 /// the current directory and \c File. 373 /// 374 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this 375 /// does by removing "./" and computing native paths. 376 /// 377 /// \param File Either an absolute or relative path. 378 std::string getAbsolutePath(StringRef File); 379 380 } // end namespace tooling 381 } // end namespace clang 382 383 #endif // LLVM_CLANG_TOOLING_TOOLING_H 384