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