Tooling.h revision 360784
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 51namespace clang { 52 53class CompilerInstance; 54class CompilerInvocation; 55class DiagnosticConsumer; 56class DiagnosticsEngine; 57class SourceManager; 58 59namespace driver { 60 61class Compilation; 62 63} // namespace driver 64 65namespace tooling { 66 67class 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. 73class ToolAction { 74public: 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. 91class FrontendActionFactory : public ToolAction { 92public: 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>(); 112template <typename T> 113std::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. 118class SourceFileCallbacks { 119public: 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)); 144template <typename FactoryT> 145inline 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. 157bool 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. 164using 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. 179bool 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. 188bool 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. 204std::unique_ptr<ASTUnit> 205buildASTFromCode(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. 222std::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 230/// Utility to run a FrontendAction in a single clang invocation. 231class ToolInvocation { 232public: 233 /// Create a tool invocation. 234 /// 235 /// \param CommandLine The command line arguments to clang. Note that clang 236 /// uses its binary name (CommandLine[0]) to locate its builtin headers. 237 /// Callers have to ensure that they are installed in a compatible location 238 /// (see clang driver implementation) or mapped in via mapVirtualFile. 239 /// \param FAction The action to be executed. 240 /// \param Files The FileManager used for the execution. Class does not take 241 /// ownership. 242 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 243 /// clang modules. 244 ToolInvocation(std::vector<std::string> CommandLine, 245 std::unique_ptr<FrontendAction> FAction, FileManager *Files, 246 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 247 std::make_shared<PCHContainerOperations>()); 248 249 /// Create a tool invocation. 250 /// 251 /// \param CommandLine The command line arguments to clang. 252 /// \param Action The action to be executed. 253 /// \param Files The FileManager used for the execution. 254 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 255 /// clang modules. 256 ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action, 257 FileManager *Files, 258 std::shared_ptr<PCHContainerOperations> PCHContainerOps); 259 260 ~ToolInvocation(); 261 262 /// Set a \c DiagnosticConsumer to use during parsing. 263 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) { 264 this->DiagConsumer = DiagConsumer; 265 } 266 267 /// Map a virtual file to be used while running the tool. 268 /// 269 /// \param FilePath The path at which the content will be mapped. 270 /// \param Content A null terminated buffer of the file's content. 271 // FIXME: remove this when all users have migrated! 272 void mapVirtualFile(StringRef FilePath, StringRef Content); 273 274 /// Run the clang invocation. 275 /// 276 /// \returns True if there were no errors during execution. 277 bool run(); 278 279 private: 280 void addFileMappingsTo(SourceManager &SourceManager); 281 282 bool runInvocation(const char *BinaryName, 283 driver::Compilation *Compilation, 284 std::shared_ptr<CompilerInvocation> Invocation, 285 std::shared_ptr<PCHContainerOperations> PCHContainerOps); 286 287 std::vector<std::string> CommandLine; 288 ToolAction *Action; 289 bool OwnsAction; 290 FileManager *Files; 291 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 292 // Maps <file name> -> <file content>. 293 llvm::StringMap<StringRef> MappedFileContents; 294 DiagnosticConsumer *DiagConsumer = nullptr; 295}; 296 297/// Utility to run a FrontendAction over a set of files. 298/// 299/// This class is written to be usable for command line utilities. 300/// By default the class uses ClangSyntaxOnlyAdjuster to modify 301/// command line arguments before the arguments are used to run 302/// a frontend action. One could install an additional command line 303/// arguments adjuster by calling the appendArgumentsAdjuster() method. 304class ClangTool { 305public: 306 /// Constructs a clang tool to run over a list of files. 307 /// 308 /// \param Compilations The CompilationDatabase which contains the compile 309 /// command lines for the given source paths. 310 /// \param SourcePaths The source files to run over. If a source files is 311 /// not found in Compilations, it is skipped. 312 /// \param PCHContainerOps The PCHContainerOperations for loading and creating 313 /// clang modules. 314 /// \param BaseFS VFS used for all underlying file accesses when running the 315 /// tool. 316 /// \param Files The file manager to use for underlying file operations when 317 /// running the tool. 318 ClangTool(const CompilationDatabase &Compilations, 319 ArrayRef<std::string> SourcePaths, 320 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 321 std::make_shared<PCHContainerOperations>(), 322 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS = 323 llvm::vfs::getRealFileSystem(), 324 IntrusiveRefCntPtr<FileManager> Files = nullptr); 325 326 ~ClangTool(); 327 328 /// Set a \c DiagnosticConsumer to use during parsing. 329 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) { 330 this->DiagConsumer = DiagConsumer; 331 } 332 333 /// Map a virtual file to be used while running the tool. 334 /// 335 /// \param FilePath The path at which the content will be mapped. 336 /// \param Content A null terminated buffer of the file's content. 337 void mapVirtualFile(StringRef FilePath, StringRef Content); 338 339 /// Append a command line arguments adjuster to the adjuster chain. 340 /// 341 /// \param Adjuster An argument adjuster, which will be run on the output of 342 /// previous argument adjusters. 343 void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster); 344 345 /// Clear the command line arguments adjuster chain. 346 void clearArgumentsAdjusters(); 347 348 /// Runs an action over all files specified in the command line. 349 /// 350 /// \param Action Tool action. 351 /// 352 /// \returns 0 on success; 1 if any error occurred; 2 if there is no error but 353 /// some files are skipped due to missing compile commands. 354 int run(ToolAction *Action); 355 356 /// Create an AST for each file specified in the command line and 357 /// append them to ASTs. 358 int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs); 359 360 /// Sets whether working directory should be restored after calling run(). By 361 /// default, working directory is restored. However, it could be useful to 362 /// turn this off when running on multiple threads to avoid the raciness. 363 void setRestoreWorkingDir(bool RestoreCWD); 364 365 /// Sets whether an error message should be printed out if an action fails. By 366 /// default, if an action fails, a message is printed out to stderr. 367 void setPrintErrorMessage(bool PrintErrorMessage); 368 369 /// Returns the file manager used in the tool. 370 /// 371 /// The file manager is shared between all translation units. 372 FileManager &getFiles() { return *Files; } 373 374 llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; } 375 376private: 377 const CompilationDatabase &Compilations; 378 std::vector<std::string> SourcePaths; 379 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 380 381 llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem; 382 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem; 383 llvm::IntrusiveRefCntPtr<FileManager> Files; 384 385 // Contains a list of pairs (<file name>, <file content>). 386 std::vector<std::pair<StringRef, StringRef>> MappedFileContents; 387 388 llvm::StringSet<> SeenWorkingDirectories; 389 390 ArgumentsAdjuster ArgsAdjuster; 391 392 DiagnosticConsumer *DiagConsumer = nullptr; 393 394 bool RestoreCWD = true; 395 bool PrintErrorMessage = true; 396}; 397 398template <typename T> 399std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() { 400 class SimpleFrontendActionFactory : public FrontendActionFactory { 401 public: 402 std::unique_ptr<FrontendAction> create() override { 403 return std::make_unique<T>(); 404 } 405 }; 406 407 return std::unique_ptr<FrontendActionFactory>( 408 new SimpleFrontendActionFactory); 409} 410 411template <typename FactoryT> 412inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory( 413 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) { 414 class FrontendActionFactoryAdapter : public FrontendActionFactory { 415 public: 416 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, 417 SourceFileCallbacks *Callbacks) 418 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 419 420 std::unique_ptr<FrontendAction> create() override { 421 return std::make_unique<ConsumerFactoryAdaptor>(ConsumerFactory, 422 Callbacks); 423 } 424 425 private: 426 class ConsumerFactoryAdaptor : public ASTFrontendAction { 427 public: 428 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, 429 SourceFileCallbacks *Callbacks) 430 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 431 432 std::unique_ptr<ASTConsumer> 433 CreateASTConsumer(CompilerInstance &, StringRef) override { 434 return ConsumerFactory->newASTConsumer(); 435 } 436 437 protected: 438 bool BeginSourceFileAction(CompilerInstance &CI) override { 439 if (!ASTFrontendAction::BeginSourceFileAction(CI)) 440 return false; 441 if (Callbacks) 442 return Callbacks->handleBeginSource(CI); 443 return true; 444 } 445 446 void EndSourceFileAction() override { 447 if (Callbacks) 448 Callbacks->handleEndSource(); 449 ASTFrontendAction::EndSourceFileAction(); 450 } 451 452 private: 453 FactoryT *ConsumerFactory; 454 SourceFileCallbacks *Callbacks; 455 }; 456 FactoryT *ConsumerFactory; 457 SourceFileCallbacks *Callbacks; 458 }; 459 460 return std::unique_ptr<FrontendActionFactory>( 461 new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks)); 462} 463 464/// Returns the absolute path of \c File, by prepending it with 465/// the current directory if \c File is not absolute. 466/// 467/// Otherwise returns \c File. 468/// If 'File' starts with "./", the returned path will not contain the "./". 469/// Otherwise, the returned path will contain the literal path-concatenation of 470/// the current directory and \c File. 471/// 472/// The difference to llvm::sys::fs::make_absolute is the canonicalization this 473/// does by removing "./" and computing native paths. 474/// 475/// \param File Either an absolute or relative path. 476std::string getAbsolutePath(StringRef File); 477 478/// An overload of getAbsolutePath that works over the provided \p FS. 479llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS, 480 StringRef File); 481 482/// Changes CommandLine to contain implicit flags that would have been 483/// defined had the compiler driver been invoked through the path InvokedAs. 484/// 485/// For example, when called with \c InvokedAs set to `i686-linux-android-g++`, 486/// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will 487/// be inserted after the first argument in \c CommandLine. 488/// 489/// This function will not add new `-target` or `--driver-mode` flags if they 490/// are already present in `CommandLine` (even if they have different settings 491/// than would have been inserted). 492/// 493/// \pre `llvm::InitializeAllTargets()` has been called. 494/// 495/// \param CommandLine the command line used to invoke the compiler driver or 496/// Clang tool, including the path to the executable as \c CommandLine[0]. 497/// \param InvokedAs the path to the driver used to infer implicit flags. 498/// 499/// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling 500/// infrastructure expects that CommandLine[0] is a tool path relative to which 501/// the builtin headers can be found. 502void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine, 503 StringRef InvokedAs); 504 505/// Creates a \c CompilerInvocation. 506CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics, 507 const llvm::opt::ArgStringList &CC1Args); 508 509} // namespace tooling 510 511} // namespace clang 512 513#endif // LLVM_CLANG_TOOLING_TOOLING_H 514