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