1234287Sdim//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===// 2234287Sdim// 3234287Sdim// The LLVM Compiler Infrastructure 4234287Sdim// 5234287Sdim// This file is distributed under the University of Illinois Open Source 6234287Sdim// License. See LICENSE.TXT for details. 7234287Sdim// 8234287Sdim//===----------------------------------------------------------------------===// 9234287Sdim// 10234287Sdim// This file implements functions to run clang tools standalone instead 11234287Sdim// of running them as a plugin. 12234287Sdim// 13234287Sdim// A ClangTool is initialized with a CompilationDatabase and a set of files 14234287Sdim// to run over. The tool will then run a user-specified FrontendAction over 15234287Sdim// all TUs in which the given files are compiled. 16234287Sdim// 17234287Sdim// It is also possible to run a FrontendAction over a snippet of code by 18239462Sdim// calling runToolOnCode, which is useful for unit testing. 19234287Sdim// 20234287Sdim// Applications that need more fine grained control over how to run 21234287Sdim// multiple FrontendActions over code can use ToolInvocation. 22234287Sdim// 23234287Sdim// Example tools: 24234287Sdim// - running clang -fsyntax-only over source code from an editor to get 25234287Sdim// fast syntax checks 26234287Sdim// - running match/replace tools over C++ code 27234287Sdim// 28234287Sdim//===----------------------------------------------------------------------===// 29234287Sdim 30234287Sdim#ifndef LLVM_CLANG_TOOLING_TOOLING_H 31234287Sdim#define LLVM_CLANG_TOOLING_TOOLING_H 32234287Sdim 33263508Sdim#include "clang/Basic/Diagnostic.h" 34234287Sdim#include "clang/Basic/FileManager.h" 35234287Sdim#include "clang/Basic/LLVM.h" 36234287Sdim#include "clang/Driver/Util.h" 37239462Sdim#include "clang/Frontend/FrontendAction.h" 38239462Sdim#include "clang/Tooling/ArgumentsAdjusters.h" 39239462Sdim#include "clang/Tooling/CompilationDatabase.h" 40249423Sdim#include "llvm/ADT/StringMap.h" 41249423Sdim#include "llvm/ADT/Twine.h" 42234287Sdim#include <string> 43234287Sdim#include <vector> 44234287Sdim 45234287Sdimnamespace clang { 46234287Sdim 47234287Sdimnamespace driver { 48234287Sdimclass Compilation; 49234287Sdim} // end namespace driver 50234287Sdim 51234287Sdimclass CompilerInvocation; 52234287Sdimclass SourceManager; 53234287Sdimclass FrontendAction; 54234287Sdim 55234287Sdimnamespace tooling { 56234287Sdim 57263508Sdim/// \brief Interface to process a clang::CompilerInvocation. 58263508Sdim/// 59263508Sdim/// If your tool is based on FrontendAction, you should be deriving from 60263508Sdim/// FrontendActionFactory instead. 61263508Sdimclass ToolAction { 62263508Sdimpublic: 63263508Sdim virtual ~ToolAction(); 64263508Sdim 65263508Sdim /// \brief Perform an action for an invocation. 66263508Sdim virtual bool runInvocation(clang::CompilerInvocation *Invocation, 67263508Sdim FileManager *Files, 68263508Sdim DiagnosticConsumer *DiagConsumer) = 0; 69263508Sdim}; 70263508Sdim 71234287Sdim/// \brief Interface to generate clang::FrontendActions. 72263508Sdim/// 73263508Sdim/// Having a factory interface allows, for example, a new FrontendAction to be 74263508Sdim/// created for each translation unit processed by ClangTool. This class is 75263508Sdim/// also a ToolAction which uses the FrontendActions created by create() to 76263508Sdim/// process each translation unit. 77263508Sdimclass FrontendActionFactory : public ToolAction { 78234287Sdimpublic: 79234287Sdim virtual ~FrontendActionFactory(); 80234287Sdim 81263508Sdim /// \brief Invokes the compiler with a FrontendAction created by create(). 82263508Sdim bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files, 83263508Sdim DiagnosticConsumer *DiagConsumer); 84263508Sdim 85234287Sdim /// \brief Returns a new clang::FrontendAction. 86234287Sdim /// 87234287Sdim /// The caller takes ownership of the returned action. 88234287Sdim virtual clang::FrontendAction *create() = 0; 89234287Sdim}; 90234287Sdim 91234287Sdim/// \brief Returns a new FrontendActionFactory for a given type. 92234287Sdim/// 93263508Sdim/// T must derive from clang::FrontendAction. 94234287Sdim/// 95234287Sdim/// Example: 96234287Sdim/// FrontendActionFactory *Factory = 97234287Sdim/// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 98234287Sdimtemplate <typename T> 99234287SdimFrontendActionFactory *newFrontendActionFactory(); 100234287Sdim 101263508Sdim/// \brief Callbacks called before and after each source file processed by a 102263508Sdim/// FrontendAction created by the FrontedActionFactory returned by \c 103263508Sdim/// newFrontendActionFactory. 104263508Sdimclass SourceFileCallbacks { 105243830Sdimpublic: 106263508Sdim virtual ~SourceFileCallbacks() {} 107263508Sdim 108263508Sdim /// \brief Called before a source file is processed by a FrontEndAction. 109263508Sdim /// \see clang::FrontendAction::BeginSourceFileAction 110263508Sdim virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) { 111263508Sdim return true; 112263508Sdim } 113263508Sdim 114263508Sdim /// \brief Called after a source file is processed by a FrontendAction. 115263508Sdim /// \see clang::FrontendAction::EndSourceFileAction 116263508Sdim virtual void handleEndSource() {} 117243830Sdim}; 118243830Sdim 119234287Sdim/// \brief Returns a new FrontendActionFactory for any type that provides an 120239462Sdim/// implementation of newASTConsumer(). 121234287Sdim/// 122239462Sdim/// FactoryT must implement: ASTConsumer *newASTConsumer(). 123234287Sdim/// 124234287Sdim/// Example: 125239462Sdim/// struct ProvidesASTConsumers { 126239462Sdim/// clang::ASTConsumer *newASTConsumer(); 127234287Sdim/// } Factory; 128234287Sdim/// FrontendActionFactory *FactoryAdapter = 129234287Sdim/// newFrontendActionFactory(&Factory); 130234287Sdimtemplate <typename FactoryT> 131239462Sdiminline FrontendActionFactory *newFrontendActionFactory( 132263508Sdim FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = NULL); 133234287Sdim 134234287Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 135234287Sdim/// 136234287Sdim/// \param ToolAction The action to run over the code. 137234287Sdim/// \param Code C++ code. 138234287Sdim/// \param FileName The file name which 'Code' will be mapped as. 139234287Sdim/// 140234287Sdim/// \return - True if 'ToolAction' was successfully executed. 141234287Sdimbool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 142234287Sdim const Twine &FileName = "input.cc"); 143234287Sdim 144243830Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and 145243830Sdim/// with additional other flags. 146243830Sdim/// 147243830Sdim/// \param ToolAction The action to run over the code. 148243830Sdim/// \param Code C++ code. 149243830Sdim/// \param Args Additional flags to pass on. 150243830Sdim/// \param FileName The file name which 'Code' will be mapped as. 151243830Sdim/// 152243830Sdim/// \return - True if 'ToolAction' was successfully executed. 153243830Sdimbool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, 154243830Sdim const std::vector<std::string> &Args, 155243830Sdim const Twine &FileName = "input.cc"); 156243830Sdim 157263508Sdim/// \brief Builds an AST for 'Code'. 158263508Sdim/// 159263508Sdim/// \param Code C++ code. 160263508Sdim/// \param FileName The file name which 'Code' will be mapped as. 161263508Sdim/// 162263508Sdim/// \return The resulting AST or null if an error occurred. 163263508SdimASTUnit *buildASTFromCode(const Twine &Code, 164263508Sdim const Twine &FileName = "input.cc"); 165263508Sdim 166263508Sdim/// \brief Builds an AST for 'Code' with additional flags. 167263508Sdim/// 168263508Sdim/// \param Code C++ code. 169263508Sdim/// \param Args Additional flags to pass on. 170263508Sdim/// \param FileName The file name which 'Code' will be mapped as. 171263508Sdim/// 172263508Sdim/// \return The resulting AST or null if an error occurred. 173263508SdimASTUnit *buildASTFromCodeWithArgs(const Twine &Code, 174263508Sdim const std::vector<std::string> &Args, 175263508Sdim const Twine &FileName = "input.cc"); 176263508Sdim 177234287Sdim/// \brief Utility to run a FrontendAction in a single clang invocation. 178234287Sdimclass ToolInvocation { 179234287Sdim public: 180234287Sdim /// \brief Create a tool invocation. 181234287Sdim /// 182239462Sdim /// \param CommandLine The command line arguments to clang. Note that clang 183239462Sdim /// uses its binary name (CommandLine[0]) to locate its builtin headers. 184239462Sdim /// Callers have to ensure that they are installed in a compatible location 185239462Sdim /// (see clang driver implementation) or mapped in via mapVirtualFile. 186263508Sdim /// \param FAction The action to be executed. Class takes ownership. 187234287Sdim /// \param Files The FileManager used for the execution. Class does not take 188234287Sdim /// ownership. 189263508Sdim ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction, 190234287Sdim FileManager *Files); 191234287Sdim 192263508Sdim /// \brief Create a tool invocation. 193263508Sdim /// 194263508Sdim /// \param CommandLine The command line arguments to clang. 195263508Sdim /// \param Action The action to be executed. 196263508Sdim /// \param Files The FileManager used for the execution. 197263508Sdim ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action, 198263508Sdim FileManager *Files); 199263508Sdim 200263508Sdim ~ToolInvocation(); 201263508Sdim 202263508Sdim /// \brief Set a \c DiagnosticConsumer to use during parsing. 203263508Sdim void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer); 204263508Sdim 205234287Sdim /// \brief Map a virtual file to be used while running the tool. 206234287Sdim /// 207234287Sdim /// \param FilePath The path at which the content will be mapped. 208234287Sdim /// \param Content A null terminated buffer of the file's content. 209234287Sdim void mapVirtualFile(StringRef FilePath, StringRef Content); 210234287Sdim 211234287Sdim /// \brief Run the clang invocation. 212234287Sdim /// 213234287Sdim /// \returns True if there were no errors during execution. 214234287Sdim bool run(); 215234287Sdim 216234287Sdim private: 217234287Sdim void addFileMappingsTo(SourceManager &SourceManager); 218234287Sdim 219234287Sdim bool runInvocation(const char *BinaryName, 220234287Sdim clang::driver::Compilation *Compilation, 221249423Sdim clang::CompilerInvocation *Invocation); 222234287Sdim 223234287Sdim std::vector<std::string> CommandLine; 224263508Sdim ToolAction *Action; 225263508Sdim bool OwnsAction; 226234287Sdim FileManager *Files; 227234287Sdim // Maps <file name> -> <file content>. 228234287Sdim llvm::StringMap<StringRef> MappedFileContents; 229263508Sdim DiagnosticConsumer *DiagConsumer; 230234287Sdim}; 231234287Sdim 232234287Sdim/// \brief Utility to run a FrontendAction over a set of files. 233234287Sdim/// 234234287Sdim/// This class is written to be usable for command line utilities. 235239462Sdim/// By default the class uses ClangSyntaxOnlyAdjuster to modify 236239462Sdim/// command line arguments before the arguments are used to run 237263508Sdim/// a frontend action. One could install an additional command line 238263508Sdim/// arguments adjuster by calling the appendArgumentsAdjuster() method. 239234287Sdimclass ClangTool { 240234287Sdim public: 241234287Sdim /// \brief Constructs a clang tool to run over a list of files. 242234287Sdim /// 243234287Sdim /// \param Compilations The CompilationDatabase which contains the compile 244234287Sdim /// command lines for the given source paths. 245234287Sdim /// \param SourcePaths The source files to run over. If a source files is 246234287Sdim /// not found in Compilations, it is skipped. 247234287Sdim ClangTool(const CompilationDatabase &Compilations, 248234287Sdim ArrayRef<std::string> SourcePaths); 249234287Sdim 250263508Sdim virtual ~ClangTool() { clearArgumentsAdjusters(); } 251249423Sdim 252263508Sdim /// \brief Set a \c DiagnosticConsumer to use during parsing. 253263508Sdim void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer); 254263508Sdim 255234287Sdim /// \brief Map a virtual file to be used while running the tool. 256234287Sdim /// 257234287Sdim /// \param FilePath The path at which the content will be mapped. 258234287Sdim /// \param Content A null terminated buffer of the file's content. 259234287Sdim void mapVirtualFile(StringRef FilePath, StringRef Content); 260234287Sdim 261239462Sdim /// \brief Install command line arguments adjuster. 262239462Sdim /// 263239462Sdim /// \param Adjuster Command line arguments adjuster. 264263508Sdim // 265263508Sdim /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead. 266263508Sdim /// Remove it once all callers are gone. 267239462Sdim void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 268239462Sdim 269263508Sdim /// \brief Append a command line arguments adjuster to the adjuster chain. 270234287Sdim /// 271263508Sdim /// \param Adjuster An argument adjuster, which will be run on the output of 272263508Sdim /// previous argument adjusters. 273263508Sdim void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 274234287Sdim 275263508Sdim /// \brief Clear the command line arguments adjuster chain. 276263508Sdim void clearArgumentsAdjusters(); 277263508Sdim 278263508Sdim /// Runs an action over all files specified in the command line. 279263508Sdim /// 280263508Sdim /// \param Action Tool action. 281263508Sdim int run(ToolAction *Action); 282263508Sdim 283263508Sdim /// \brief Create an AST for each file specified in the command line and 284263508Sdim /// append them to ASTs. 285263508Sdim int buildASTs(std::vector<ASTUnit *> &ASTs); 286263508Sdim 287234287Sdim /// \brief Returns the file manager used in the tool. 288234287Sdim /// 289234287Sdim /// The file manager is shared between all translation units. 290263508Sdim FileManager &getFiles() { return *Files; } 291234287Sdim 292234287Sdim private: 293239462Sdim // We store compile commands as pair (file name, compile command). 294239462Sdim std::vector< std::pair<std::string, CompileCommand> > CompileCommands; 295234287Sdim 296263508Sdim llvm::IntrusiveRefCntPtr<FileManager> Files; 297234287Sdim // Contains a list of pairs (<file name>, <file content>). 298234287Sdim std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 299239462Sdim 300263508Sdim SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters; 301263508Sdim 302263508Sdim DiagnosticConsumer *DiagConsumer; 303234287Sdim}; 304234287Sdim 305234287Sdimtemplate <typename T> 306234287SdimFrontendActionFactory *newFrontendActionFactory() { 307234287Sdim class SimpleFrontendActionFactory : public FrontendActionFactory { 308234287Sdim public: 309234287Sdim virtual clang::FrontendAction *create() { return new T; } 310234287Sdim }; 311234287Sdim 312234287Sdim return new SimpleFrontendActionFactory; 313234287Sdim} 314234287Sdim 315234287Sdimtemplate <typename FactoryT> 316239462Sdiminline FrontendActionFactory *newFrontendActionFactory( 317263508Sdim FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) { 318234287Sdim class FrontendActionFactoryAdapter : public FrontendActionFactory { 319234287Sdim public: 320243830Sdim explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, 321263508Sdim SourceFileCallbacks *Callbacks) 322263508Sdim : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 323234287Sdim 324234287Sdim virtual clang::FrontendAction *create() { 325263508Sdim return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks); 326234287Sdim } 327234287Sdim 328234287Sdim private: 329239462Sdim class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { 330239462Sdim public: 331243830Sdim ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, 332263508Sdim SourceFileCallbacks *Callbacks) 333263508Sdim : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {} 334239462Sdim 335239462Sdim clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, 336249423Sdim StringRef) { 337239462Sdim return ConsumerFactory->newASTConsumer(); 338239462Sdim } 339239462Sdim 340243830Sdim protected: 341263508Sdim virtual bool BeginSourceFileAction(CompilerInstance &CI, 342263508Sdim StringRef Filename) LLVM_OVERRIDE { 343263508Sdim if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename)) 344263508Sdim return false; 345263508Sdim if (Callbacks != NULL) 346263508Sdim return Callbacks->handleBeginSource(CI, Filename); 347263508Sdim return true; 348263508Sdim } 349263508Sdim virtual void EndSourceFileAction() LLVM_OVERRIDE { 350263508Sdim if (Callbacks != NULL) 351263508Sdim Callbacks->handleEndSource(); 352243830Sdim clang::ASTFrontendAction::EndSourceFileAction(); 353243830Sdim } 354243830Sdim 355239462Sdim private: 356239462Sdim FactoryT *ConsumerFactory; 357263508Sdim SourceFileCallbacks *Callbacks; 358239462Sdim }; 359239462Sdim FactoryT *ConsumerFactory; 360263508Sdim SourceFileCallbacks *Callbacks; 361234287Sdim }; 362234287Sdim 363263508Sdim return new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks); 364234287Sdim} 365234287Sdim 366239462Sdim/// \brief Returns the absolute path of \c File, by prepending it with 367239462Sdim/// the current directory if \c File is not absolute. 368239462Sdim/// 369239462Sdim/// Otherwise returns \c File. 370239462Sdim/// If 'File' starts with "./", the returned path will not contain the "./". 371239462Sdim/// Otherwise, the returned path will contain the literal path-concatenation of 372239462Sdim/// the current directory and \c File. 373239462Sdim/// 374263508Sdim/// The difference to llvm::sys::fs::make_absolute is the canonicalization this 375263508Sdim/// does by removing "./" and computing native paths. 376239462Sdim/// 377239462Sdim/// \param File Either an absolute or relative path. 378239462Sdimstd::string getAbsolutePath(StringRef File); 379239462Sdim 380234287Sdim} // end namespace tooling 381234287Sdim} // end namespace clang 382234287Sdim 383234287Sdim#endif // LLVM_CLANG_TOOLING_TOOLING_H 384