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