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 33234287Sdim#include "clang/Basic/FileManager.h" 34234287Sdim#include "clang/Basic/LLVM.h" 35234287Sdim#include "clang/Driver/Util.h" 36239462Sdim#include "clang/Frontend/FrontendAction.h" 37239462Sdim#include "clang/Tooling/ArgumentsAdjusters.h" 38239462Sdim#include "clang/Tooling/CompilationDatabase.h" 39249423Sdim#include "llvm/ADT/StringMap.h" 40249423Sdim#include "llvm/ADT/Twine.h" 41234287Sdim#include <string> 42234287Sdim#include <vector> 43234287Sdim 44234287Sdimnamespace clang { 45234287Sdim 46234287Sdimnamespace driver { 47234287Sdimclass Compilation; 48234287Sdim} // end namespace driver 49234287Sdim 50234287Sdimclass CompilerInvocation; 51234287Sdimclass SourceManager; 52234287Sdimclass FrontendAction; 53234287Sdim 54234287Sdimnamespace tooling { 55234287Sdim 56234287Sdim/// \brief Interface to generate clang::FrontendActions. 57234287Sdimclass FrontendActionFactory { 58234287Sdimpublic: 59234287Sdim virtual ~FrontendActionFactory(); 60234287Sdim 61234287Sdim /// \brief Returns a new clang::FrontendAction. 62234287Sdim /// 63234287Sdim /// The caller takes ownership of the returned action. 64234287Sdim virtual clang::FrontendAction *create() = 0; 65234287Sdim}; 66234287Sdim 67234287Sdim/// \brief Returns a new FrontendActionFactory for a given type. 68234287Sdim/// 69234287Sdim/// T must extend clang::FrontendAction. 70234287Sdim/// 71234287Sdim/// Example: 72234287Sdim/// FrontendActionFactory *Factory = 73234287Sdim/// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 74234287Sdimtemplate <typename T> 75234287SdimFrontendActionFactory *newFrontendActionFactory(); 76234287Sdim 77243830Sdim/// \brief Called at the end of each source file when used with 78243830Sdim/// \c newFrontendActionFactory. 79243830Sdimclass EndOfSourceFileCallback { 80243830Sdimpublic: 81243830Sdim virtual ~EndOfSourceFileCallback() {} 82243830Sdim virtual void run() = 0; 83243830Sdim}; 84243830Sdim 85234287Sdim/// \brief Returns a new FrontendActionFactory for any type that provides an 86239462Sdim/// implementation of newASTConsumer(). 87234287Sdim/// 88239462Sdim/// FactoryT must implement: ASTConsumer *newASTConsumer(). 89234287Sdim/// 90234287Sdim/// Example: 91239462Sdim/// struct ProvidesASTConsumers { 92239462Sdim/// clang::ASTConsumer *newASTConsumer(); 93234287Sdim/// } Factory; 94234287Sdim/// FrontendActionFactory *FactoryAdapter = 95234287Sdim/// newFrontendActionFactory(&Factory); 96234287Sdimtemplate <typename FactoryT> 97239462Sdiminline FrontendActionFactory *newFrontendActionFactory( 98243830Sdim FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback = NULL); 99234287Sdim 100234287Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 101234287Sdim/// 102234287Sdim/// \param ToolAction The action to run over the code. 103234287Sdim/// \param Code C++ code. 104234287Sdim/// \param FileName The file name which 'Code' will be mapped as. 105234287Sdim/// 106234287Sdim/// \return - True if 'ToolAction' was successfully executed. 107234287Sdimbool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 108234287Sdim const Twine &FileName = "input.cc"); 109234287Sdim 110243830Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and 111243830Sdim/// with additional other flags. 112243830Sdim/// 113243830Sdim/// \param ToolAction The action to run over the code. 114243830Sdim/// \param Code C++ code. 115243830Sdim/// \param Args Additional flags to pass on. 116243830Sdim/// \param FileName The file name which 'Code' will be mapped as. 117243830Sdim/// 118243830Sdim/// \return - True if 'ToolAction' was successfully executed. 119243830Sdimbool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, 120243830Sdim const std::vector<std::string> &Args, 121243830Sdim const Twine &FileName = "input.cc"); 122243830Sdim 123234287Sdim/// \brief Utility to run a FrontendAction in a single clang invocation. 124234287Sdimclass ToolInvocation { 125234287Sdim public: 126234287Sdim /// \brief Create a tool invocation. 127234287Sdim /// 128239462Sdim /// \param CommandLine The command line arguments to clang. Note that clang 129239462Sdim /// uses its binary name (CommandLine[0]) to locate its builtin headers. 130239462Sdim /// Callers have to ensure that they are installed in a compatible location 131239462Sdim /// (see clang driver implementation) or mapped in via mapVirtualFile. 132234287Sdim /// \param ToolAction The action to be executed. Class takes ownership. 133234287Sdim /// \param Files The FileManager used for the execution. Class does not take 134234287Sdim /// ownership. 135234287Sdim ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction, 136234287Sdim FileManager *Files); 137234287Sdim 138234287Sdim /// \brief Map a virtual file to be used while running the tool. 139234287Sdim /// 140234287Sdim /// \param FilePath The path at which the content will be mapped. 141234287Sdim /// \param Content A null terminated buffer of the file's content. 142234287Sdim void mapVirtualFile(StringRef FilePath, StringRef Content); 143234287Sdim 144234287Sdim /// \brief Run the clang invocation. 145234287Sdim /// 146234287Sdim /// \returns True if there were no errors during execution. 147234287Sdim bool run(); 148234287Sdim 149234287Sdim private: 150234287Sdim void addFileMappingsTo(SourceManager &SourceManager); 151234287Sdim 152234287Sdim bool runInvocation(const char *BinaryName, 153234287Sdim clang::driver::Compilation *Compilation, 154249423Sdim clang::CompilerInvocation *Invocation); 155234287Sdim 156234287Sdim std::vector<std::string> CommandLine; 157249423Sdim OwningPtr<FrontendAction> ToolAction; 158234287Sdim FileManager *Files; 159234287Sdim // Maps <file name> -> <file content>. 160234287Sdim llvm::StringMap<StringRef> MappedFileContents; 161234287Sdim}; 162234287Sdim 163234287Sdim/// \brief Utility to run a FrontendAction over a set of files. 164234287Sdim/// 165234287Sdim/// This class is written to be usable for command line utilities. 166239462Sdim/// By default the class uses ClangSyntaxOnlyAdjuster to modify 167239462Sdim/// command line arguments before the arguments are used to run 168239462Sdim/// a frontend action. One could install another command line 169239462Sdim/// arguments adjuster by call setArgumentsAdjuster() method. 170234287Sdimclass ClangTool { 171234287Sdim public: 172234287Sdim /// \brief Constructs a clang tool to run over a list of files. 173234287Sdim /// 174234287Sdim /// \param Compilations The CompilationDatabase which contains the compile 175234287Sdim /// command lines for the given source paths. 176234287Sdim /// \param SourcePaths The source files to run over. If a source files is 177234287Sdim /// not found in Compilations, it is skipped. 178234287Sdim ClangTool(const CompilationDatabase &Compilations, 179234287Sdim ArrayRef<std::string> SourcePaths); 180234287Sdim 181249423Sdim virtual ~ClangTool() {} 182249423Sdim 183234287Sdim /// \brief Map a virtual file to be used while running the tool. 184234287Sdim /// 185234287Sdim /// \param FilePath The path at which the content will be mapped. 186234287Sdim /// \param Content A null terminated buffer of the file's content. 187234287Sdim void mapVirtualFile(StringRef FilePath, StringRef Content); 188234287Sdim 189239462Sdim /// \brief Install command line arguments adjuster. 190239462Sdim /// 191239462Sdim /// \param Adjuster Command line arguments adjuster. 192239462Sdim void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 193239462Sdim 194234287Sdim /// Runs a frontend action over all files specified in the command line. 195234287Sdim /// 196234287Sdim /// \param ActionFactory Factory generating the frontend actions. The function 197234287Sdim /// takes ownership of this parameter. A new action is generated for every 198234287Sdim /// processed translation unit. 199249423Sdim virtual int run(FrontendActionFactory *ActionFactory); 200234287Sdim 201234287Sdim /// \brief Returns the file manager used in the tool. 202234287Sdim /// 203234287Sdim /// The file manager is shared between all translation units. 204234287Sdim FileManager &getFiles() { return Files; } 205234287Sdim 206234287Sdim private: 207239462Sdim // We store compile commands as pair (file name, compile command). 208239462Sdim std::vector< std::pair<std::string, CompileCommand> > CompileCommands; 209234287Sdim 210234287Sdim FileManager Files; 211234287Sdim // Contains a list of pairs (<file name>, <file content>). 212234287Sdim std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 213239462Sdim 214249423Sdim OwningPtr<ArgumentsAdjuster> ArgsAdjuster; 215234287Sdim}; 216234287Sdim 217234287Sdimtemplate <typename T> 218234287SdimFrontendActionFactory *newFrontendActionFactory() { 219234287Sdim class SimpleFrontendActionFactory : public FrontendActionFactory { 220234287Sdim public: 221234287Sdim virtual clang::FrontendAction *create() { return new T; } 222234287Sdim }; 223234287Sdim 224234287Sdim return new SimpleFrontendActionFactory; 225234287Sdim} 226234287Sdim 227234287Sdimtemplate <typename FactoryT> 228239462Sdiminline FrontendActionFactory *newFrontendActionFactory( 229243830Sdim FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback) { 230234287Sdim class FrontendActionFactoryAdapter : public FrontendActionFactory { 231234287Sdim public: 232243830Sdim explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory, 233243830Sdim EndOfSourceFileCallback *EndCallback) 234243830Sdim : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} 235234287Sdim 236234287Sdim virtual clang::FrontendAction *create() { 237243830Sdim return new ConsumerFactoryAdaptor(ConsumerFactory, EndCallback); 238234287Sdim } 239234287Sdim 240234287Sdim private: 241239462Sdim class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { 242239462Sdim public: 243243830Sdim ConsumerFactoryAdaptor(FactoryT *ConsumerFactory, 244243830Sdim EndOfSourceFileCallback *EndCallback) 245243830Sdim : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {} 246239462Sdim 247239462Sdim clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, 248249423Sdim StringRef) { 249239462Sdim return ConsumerFactory->newASTConsumer(); 250239462Sdim } 251239462Sdim 252243830Sdim protected: 253243830Sdim virtual void EndSourceFileAction() { 254243830Sdim if (EndCallback != NULL) 255243830Sdim EndCallback->run(); 256243830Sdim clang::ASTFrontendAction::EndSourceFileAction(); 257243830Sdim } 258243830Sdim 259239462Sdim private: 260239462Sdim FactoryT *ConsumerFactory; 261243830Sdim EndOfSourceFileCallback *EndCallback; 262239462Sdim }; 263239462Sdim FactoryT *ConsumerFactory; 264243830Sdim EndOfSourceFileCallback *EndCallback; 265234287Sdim }; 266234287Sdim 267243830Sdim return new FrontendActionFactoryAdapter(ConsumerFactory, EndCallback); 268234287Sdim} 269234287Sdim 270239462Sdim/// \brief Returns the absolute path of \c File, by prepending it with 271239462Sdim/// the current directory if \c File is not absolute. 272239462Sdim/// 273239462Sdim/// Otherwise returns \c File. 274239462Sdim/// If 'File' starts with "./", the returned path will not contain the "./". 275239462Sdim/// Otherwise, the returned path will contain the literal path-concatenation of 276239462Sdim/// the current directory and \c File. 277239462Sdim/// 278239462Sdim/// The difference to llvm::sys::fs::make_absolute is that we prefer 279239462Sdim/// ::getenv("PWD") if available. 280239462Sdim/// FIXME: Make this functionality available from llvm::sys::fs and delete 281239462Sdim/// this function. 282239462Sdim/// 283239462Sdim/// \param File Either an absolute or relative path. 284239462Sdimstd::string getAbsolutePath(StringRef File); 285239462Sdim 286234287Sdim} // end namespace tooling 287234287Sdim} // end namespace clang 288234287Sdim 289234287Sdim#endif // LLVM_CLANG_TOOLING_TOOLING_H 290