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/AST/ASTConsumer.h" 34 #include "clang/Frontend/PCHContainerOperations.h" 35 #include "clang/Basic/Diagnostic.h" 36 #include "clang/Basic/FileManager.h" 37 #include "clang/Basic/LLVM.h" 38 #include "clang/Driver/Util.h" 39 #include "clang/Frontend/FrontendAction.h" 40 #include "clang/Lex/ModuleLoader.h" 41 #include "clang/Tooling/ArgumentsAdjusters.h" 42 #include "clang/Tooling/CompilationDatabase.h" 43 #include "llvm/ADT/StringMap.h" 44 #include "llvm/ADT/Twine.h" 45 #include "llvm/Option/Option.h" 46 #include <memory> 47 #include <string> 48 #include <vector> 49 50 namespace clang { 51 52 namespace driver { 53 class Compilation; 54 } // end namespace driver 55 56 class CompilerInvocation; 57 class SourceManager; 58 class FrontendAction; 59 60 namespace tooling { 61 62 /// \brief Interface to process a clang::CompilerInvocation. 63 /// 64 /// If your tool is based on FrontendAction, you should be deriving from 65 /// FrontendActionFactory instead. 66 class ToolAction { 67 public: 68 virtual ~ToolAction(); 69 70 /// \brief Perform an action for an invocation. 71 virtual bool 72 runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation, 73 FileManager *Files, 74 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 75 DiagnosticConsumer *DiagConsumer) = 0; 76 }; 77 78 /// \brief Interface to generate clang::FrontendActions. 79 /// 80 /// Having a factory interface allows, for example, a new FrontendAction to be 81 /// created for each translation unit processed by ClangTool. This class is 82 /// also a ToolAction which uses the FrontendActions created by create() to 83 /// process each translation unit. 84 class FrontendActionFactory : public ToolAction { 85 public: 86 ~FrontendActionFactory() override; 87 88 /// \brief Invokes the compiler with a FrontendAction created by create(). 89 bool runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation, 90 FileManager *Files, 91 std::shared_ptr<PCHContainerOperations> PCHContainerOps, 92 DiagnosticConsumer *DiagConsumer) override; 93 94 /// \brief Returns a new clang::FrontendAction. 95 /// 96 /// The caller takes ownership of the returned action. 97 virtual clang::FrontendAction *create() = 0; 98 }; 99 100 /// \brief Returns a new FrontendActionFactory for a given type. 101 /// 102 /// T must derive from clang::FrontendAction. 103 /// 104 /// Example: 105 /// FrontendActionFactory *Factory = 106 /// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 107 template <typename T> 108 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(); 109 110 /// \brief Callbacks called before and after each source file processed by a 111 /// FrontendAction created by the FrontedActionFactory returned by \c 112 /// newFrontendActionFactory. 113 class SourceFileCallbacks { 114 public: 115 virtual ~SourceFileCallbacks() {} 116 117 /// \brief Called before a source file is processed by a FrontEndAction. 118 /// \see clang::FrontendAction::BeginSourceFileAction 119 virtual bool handleBeginSource(CompilerInstance &CI) { 120 return true; 121 } 122 123 /// \brief Called after a source file is processed by a FrontendAction. 124 /// \see clang::FrontendAction::EndSourceFileAction 125 virtual void handleEndSource() {} 126 }; 127 128 /// \brief Returns a new FrontendActionFactory for any type that provides an 129 /// implementation of newASTConsumer(). 130 /// 131 /// FactoryT must implement: ASTConsumer *newASTConsumer(). 132 /// 133 /// Example: 134 /// struct ProvidesASTConsumers { 135 /// clang::ASTConsumer *newASTConsumer(); 136 /// } Factory; 137 /// std::unique_ptr<FrontendActionFactory> FactoryAdapter( 138 /// newFrontendActionFactory(&Factory)); 139 template <typename FactoryT> 140 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory( 141 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr); 142 143 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 144 /// 145 /// \param ToolAction The action to run over the code. 146 /// \param Code C++ code. 147 /// \param FileName The file name which 'Code' will be mapped as. 148 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 149 /// clang modules. 150 /// 151 /// \return - True if 'ToolAction' was successfully executed. 152 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 153 const Twine &FileName = "input.cc", 154 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 155 std::make_shared<PCHContainerOperations>()); 156 157 /// The first part of the pair is the filename, the second part the 158 /// file-content. 159 typedef std::vector<std::pair<std::string, std::string>> FileContentMappings; 160 161 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and 162 /// with additional other flags. 163 /// 164 /// \param ToolAction The action to run over the code. 165 /// \param Code C++ code. 166 /// \param Args Additional flags to pass on. 167 /// \param FileName The file name which 'Code' will be mapped as. 168 /// \param ToolName The name of the binary running the tool. Standard library 169 /// header paths will be resolved relative to this. 170 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 171 /// clang modules. 172 /// 173 /// \return - True if 'ToolAction' was successfully executed. 174 bool runToolOnCodeWithArgs( 175 clang::FrontendAction *ToolAction, const Twine &Code, 176 const std::vector<std::string> &Args, const Twine &FileName = "input.cc", 177 const Twine &ToolName = "clang-tool", 178 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 179 std::make_shared<PCHContainerOperations>(), 180 const FileContentMappings &VirtualMappedFiles = FileContentMappings()); 181 182 /// \brief Builds an AST for 'Code'. 183 /// 184 /// \param Code C++ code. 185 /// \param FileName The file name which 'Code' will be mapped as. 186 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 187 /// clang modules. 188 /// 189 /// \return The resulting AST or null if an error occurred. 190 std::unique_ptr<ASTUnit> 191 buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc", 192 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 193 std::make_shared<PCHContainerOperations>()); 194 195 /// \brief Builds an AST for 'Code' with additional flags. 196 /// 197 /// \param Code C++ code. 198 /// \param Args Additional flags to pass on. 199 /// \param FileName The file name which 'Code' will be mapped as. 200 /// \param ToolName The name of the binary running the tool. Standard library 201 /// header paths will be resolved relative to this. 202 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 203 /// clang modules. 204 /// 205 /// \param Adjuster A function to filter the command line arguments as specified. 206 /// 207 /// \return The resulting AST or null if an error occurred. 208 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs( 209 const Twine &Code, const std::vector<std::string> &Args, 210 const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool", 211 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 212 std::make_shared<PCHContainerOperations>(), 213 ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster()); 214 215 /// \brief Utility to run a FrontendAction in a single clang invocation. 216 class ToolInvocation { 217 public: 218 /// \brief Create a tool invocation. 219 /// 220 /// \param CommandLine The command line arguments to clang. Note that clang 221 /// uses its binary name (CommandLine[0]) to locate its builtin headers. 222 /// Callers have to ensure that they are installed in a compatible location 223 /// (see clang driver implementation) or mapped in via mapVirtualFile. 224 /// \param FAction The action to be executed. Class takes ownership. 225 /// \param Files The FileManager used for the execution. Class does not take 226 /// ownership. 227 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 228 /// clang modules. 229 ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction, 230 FileManager *Files, 231 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 232 std::make_shared<PCHContainerOperations>()); 233 234 /// \brief Create a tool invocation. 235 /// 236 /// \param CommandLine The command line arguments to clang. 237 /// \param Action The action to be executed. 238 /// \param Files The FileManager used for the execution. 239 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 240 /// clang modules. 241 ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action, 242 FileManager *Files, 243 std::shared_ptr<PCHContainerOperations> PCHContainerOps); 244 245 ~ToolInvocation(); 246 247 /// \brief Set a \c DiagnosticConsumer to use during parsing. 248 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) { 249 this->DiagConsumer = DiagConsumer; 250 } 251 252 /// \brief Map a virtual file to be used while running the tool. 253 /// 254 /// \param FilePath The path at which the content will be mapped. 255 /// \param Content A null terminated buffer of the file's content. 256 // FIXME: remove this when all users have migrated! 257 void mapVirtualFile(StringRef FilePath, StringRef Content); 258 259 /// \brief Run the clang invocation. 260 /// 261 /// \returns True if there were no errors during execution. 262 bool run(); 263 264 private: 265 void addFileMappingsTo(SourceManager &SourceManager); 266 267 bool runInvocation(const char *BinaryName, 268 clang::driver::Compilation *Compilation, 269 std::shared_ptr<clang::CompilerInvocation> Invocation, 270 std::shared_ptr<PCHContainerOperations> PCHContainerOps); 271 272 std::vector<std::string> CommandLine; 273 ToolAction *Action; 274 bool OwnsAction; 275 FileManager *Files; 276 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 277 // Maps <file name> -> <file content>. 278 llvm::StringMap<StringRef> MappedFileContents; 279 DiagnosticConsumer *DiagConsumer; 280 }; 281 282 /// \brief Utility to run a FrontendAction over a set of files. 283 /// 284 /// This class is written to be usable for command line utilities. 285 /// By default the class uses ClangSyntaxOnlyAdjuster to modify 286 /// command line arguments before the arguments are used to run 287 /// a frontend action. One could install an additional command line 288 /// arguments adjuster by calling the appendArgumentsAdjuster() method. 289 class ClangTool { 290 public: 291 /// \brief Constructs a clang tool to run over a list of files. 292 /// 293 /// \param Compilations The CompilationDatabase which contains the compile 294 /// command lines for the given source paths. 295 /// \param SourcePaths The source files to run over. If a source files is 296 /// not found in Compilations, it is skipped. 297 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 298 /// clang modules. 299 ClangTool(const CompilationDatabase &Compilations, 300 ArrayRef<std::string> SourcePaths, 301 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 302 std::make_shared<PCHContainerOperations>()); 303 304 ~ClangTool(); 305 306 /// \brief Set a \c DiagnosticConsumer to use during parsing. 307 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) { 308 this->DiagConsumer = DiagConsumer; 309 } 310 311 /// \brief Map a virtual file to be used while running the tool. 312 /// 313 /// \param FilePath The path at which the content will be mapped. 314 /// \param Content A null terminated buffer of the file's content. 315 void mapVirtualFile(StringRef FilePath, StringRef Content); 316 317 /// \brief Append a command line arguments adjuster to the adjuster chain. 318 /// 319 /// \param Adjuster An argument adjuster, which will be run on the output of 320 /// previous argument adjusters. 321 void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster); 322 323 /// \brief Clear the command line arguments adjuster chain. 324 void clearArgumentsAdjusters(); 325 326 /// Runs an action over all files specified in the command line. 327 /// 328 /// \param Action Tool action. 329 int run(ToolAction *Action); 330 331 /// \brief Create an AST for each file specified in the command line and 332 /// append them to ASTs. 333 int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs); 334 335 /// \brief Returns the file manager used in the tool. 336 /// 337 /// The file manager is shared between all translation units. 338 FileManager &getFiles() { return *Files; } 339 340 private: 341 const CompilationDatabase &Compilations; 342 std::vector<std::string> SourcePaths; 343 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 344 345 llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem; 346 llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem; 347 llvm::IntrusiveRefCntPtr<FileManager> Files; 348 // Contains a list of pairs (<file name>, <file content>). 349 std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 350 llvm::StringSet<> SeenWorkingDirectories; 351 352 ArgumentsAdjuster ArgsAdjuster; 353 354 DiagnosticConsumer *DiagConsumer; 355 }; 356 357 template <typename T> 358 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() { 359 class SimpleFrontendActionFactory : public FrontendActionFactory { 360 public: 361 clang::FrontendAction *create() override { return new T; } 362 }; 363 364 return std::unique_ptr<FrontendActionFactory>( 365 new SimpleFrontendActionFactory); 366 } 367 368 template <typename FactoryT> 369 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory( 370 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) { 371 class FrontendActionFactoryAdapter : public FrontendActionFactory { 372 public: 373 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, 374 SourceFileCallbacks *Callbacks) 375 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 376 377 clang::FrontendAction *create() override { 378 return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks); 379 } 380 381 private: 382 class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { 383 public: 384 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, 385 SourceFileCallbacks *Callbacks) 386 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 387 388 std::unique_ptr<clang::ASTConsumer> 389 CreateASTConsumer(clang::CompilerInstance &, StringRef) override { 390 return ConsumerFactory->newASTConsumer(); 391 } 392 393 protected: 394 bool BeginSourceFileAction(CompilerInstance &CI) override { 395 if (!clang::ASTFrontendAction::BeginSourceFileAction(CI)) 396 return false; 397 if (Callbacks) 398 return Callbacks->handleBeginSource(CI); 399 return true; 400 } 401 void EndSourceFileAction() override { 402 if (Callbacks) 403 Callbacks->handleEndSource(); 404 clang::ASTFrontendAction::EndSourceFileAction(); 405 } 406 407 private: 408 FactoryT *ConsumerFactory; 409 SourceFileCallbacks *Callbacks; 410 }; 411 FactoryT *ConsumerFactory; 412 SourceFileCallbacks *Callbacks; 413 }; 414 415 return std::unique_ptr<FrontendActionFactory>( 416 new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks)); 417 } 418 419 /// \brief Returns the absolute path of \c File, by prepending it with 420 /// the current directory if \c File is not absolute. 421 /// 422 /// Otherwise returns \c File. 423 /// If 'File' starts with "./", the returned path will not contain the "./". 424 /// Otherwise, the returned path will contain the literal path-concatenation of 425 /// the current directory and \c File. 426 /// 427 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this 428 /// does by removing "./" and computing native paths. 429 /// 430 /// \param File Either an absolute or relative path. 431 std::string getAbsolutePath(StringRef File); 432 433 /// \brief Changes CommandLine to contain implicit flags that would have been 434 /// defined had the compiler driver been invoked through the path InvokedAs. 435 /// 436 /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`, 437 /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will 438 /// be inserted after the first argument in \c CommandLine. 439 /// 440 /// This function will not add new `-target` or `--driver-mode` flags if they 441 /// are already present in `CommandLine` (even if they have different settings 442 /// than would have been inserted). 443 /// 444 /// \pre `llvm::InitializeAllTargets()` has been called. 445 /// 446 /// \param CommandLine the command line used to invoke the compiler driver or 447 /// Clang tool, including the path to the executable as \c CommandLine[0]. 448 /// \param InvokedAs the path to the driver used to infer implicit flags. 449 /// 450 /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling 451 /// infrastructure expects that CommandLine[0] is a tool path relative to which 452 /// the builtin headers can be found. 453 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine, 454 StringRef InvokedAs); 455 456 /// \brief Creates a \c CompilerInvocation. 457 clang::CompilerInvocation *newInvocation( 458 clang::DiagnosticsEngine *Diagnostics, 459 const llvm::opt::ArgStringList &CC1Args); 460 461 } // end namespace tooling 462 } // end namespace clang 463 464 #endif // LLVM_CLANG_TOOLING_TOOLING_H 465