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