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 "llvm/ADT/StringMap.h" 34#include "llvm/ADT/Twine.h" 35#include "clang/Basic/FileManager.h" 36#include "clang/Basic/LLVM.h" 37#include "clang/Driver/Util.h" 38#include "clang/Frontend/FrontendAction.h" 39#include "clang/Tooling/ArgumentsAdjusters.h" 40#include "clang/Tooling/CompilationDatabase.h" 41#include <string> 42#include <vector> 43 44namespace clang { 45 46namespace driver { 47class Compilation; 48} // end namespace driver 49 50class CompilerInvocation; 51class SourceManager; 52class FrontendAction; 53 54namespace tooling { 55 56/// \brief Interface to generate clang::FrontendActions. 57class FrontendActionFactory { 58public: 59 virtual ~FrontendActionFactory(); 60 61 /// \brief Returns a new clang::FrontendAction. 62 /// 63 /// The caller takes ownership of the returned action. 64 virtual clang::FrontendAction *create() = 0; 65}; 66 67/// \brief Returns a new FrontendActionFactory for a given type. 68/// 69/// T must extend clang::FrontendAction. 70/// 71/// Example: 72/// FrontendActionFactory *Factory = 73/// newFrontendActionFactory<clang::SyntaxOnlyAction>(); 74template <typename T> 75FrontendActionFactory *newFrontendActionFactory(); 76 77/// \brief Returns a new FrontendActionFactory for any type that provides an 78/// implementation of newASTConsumer(). 79/// 80/// FactoryT must implement: ASTConsumer *newASTConsumer(). 81/// 82/// Example: 83/// struct ProvidesASTConsumers { 84/// clang::ASTConsumer *newASTConsumer(); 85/// } Factory; 86/// FrontendActionFactory *FactoryAdapter = 87/// newFrontendActionFactory(&Factory); 88template <typename FactoryT> 89inline FrontendActionFactory *newFrontendActionFactory( 90 FactoryT *ConsumerFactory); 91 92/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. 93/// 94/// \param ToolAction The action to run over the code. 95/// \param Code C++ code. 96/// \param FileName The file name which 'Code' will be mapped as. 97/// 98/// \return - True if 'ToolAction' was successfully executed. 99bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, 100 const Twine &FileName = "input.cc"); 101 102/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and 103/// with additional other flags. 104/// 105/// \param ToolAction The action to run over the code. 106/// \param Code C++ code. 107/// \param Args Additional flags to pass on. 108/// \param FileName The file name which 'Code' will be mapped as. 109/// 110/// \return - True if 'ToolAction' was successfully executed. 111bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, 112 const std::vector<std::string> &Args, 113 const Twine &FileName = "input.cc"); 114 115/// \brief Utility to run a FrontendAction in a single clang invocation. 116class ToolInvocation { 117 public: 118 /// \brief Create a tool invocation. 119 /// 120 /// \param CommandLine The command line arguments to clang. Note that clang 121 /// uses its binary name (CommandLine[0]) to locate its builtin headers. 122 /// Callers have to ensure that they are installed in a compatible location 123 /// (see clang driver implementation) or mapped in via mapVirtualFile. 124 /// \param ToolAction The action to be executed. Class takes ownership. 125 /// \param Files The FileManager used for the execution. Class does not take 126 /// ownership. 127 ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction, 128 FileManager *Files); 129 130 /// \brief Map a virtual file to be used while running the tool. 131 /// 132 /// \param FilePath The path at which the content will be mapped. 133 /// \param Content A null terminated buffer of the file's content. 134 void mapVirtualFile(StringRef FilePath, StringRef Content); 135 136 /// \brief Run the clang invocation. 137 /// 138 /// \returns True if there were no errors during execution. 139 bool run(); 140 141 private: 142 void addFileMappingsTo(SourceManager &SourceManager); 143 144 bool runInvocation(const char *BinaryName, 145 clang::driver::Compilation *Compilation, 146 clang::CompilerInvocation *Invocation, 147 const clang::driver::ArgStringList &CC1Args); 148 149 std::vector<std::string> CommandLine; 150 llvm::OwningPtr<FrontendAction> ToolAction; 151 FileManager *Files; 152 // Maps <file name> -> <file content>. 153 llvm::StringMap<StringRef> MappedFileContents; 154}; 155 156/// \brief Utility to run a FrontendAction over a set of files. 157/// 158/// This class is written to be usable for command line utilities. 159/// By default the class uses ClangSyntaxOnlyAdjuster to modify 160/// command line arguments before the arguments are used to run 161/// a frontend action. One could install another command line 162/// arguments adjuster by call setArgumentsAdjuster() method. 163class ClangTool { 164 public: 165 /// \brief Constructs a clang tool to run over a list of files. 166 /// 167 /// \param Compilations The CompilationDatabase which contains the compile 168 /// command lines for the given source paths. 169 /// \param SourcePaths The source files to run over. If a source files is 170 /// not found in Compilations, it is skipped. 171 ClangTool(const CompilationDatabase &Compilations, 172 ArrayRef<std::string> SourcePaths); 173 174 /// \brief Map a virtual file to be used while running the tool. 175 /// 176 /// \param FilePath The path at which the content will be mapped. 177 /// \param Content A null terminated buffer of the file's content. 178 void mapVirtualFile(StringRef FilePath, StringRef Content); 179 180 /// \brief Install command line arguments adjuster. 181 /// 182 /// \param Adjuster Command line arguments adjuster. 183 void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); 184 185 /// Runs a frontend action over all files specified in the command line. 186 /// 187 /// \param ActionFactory Factory generating the frontend actions. The function 188 /// takes ownership of this parameter. A new action is generated for every 189 /// processed translation unit. 190 int run(FrontendActionFactory *ActionFactory); 191 192 /// \brief Returns the file manager used in the tool. 193 /// 194 /// The file manager is shared between all translation units. 195 FileManager &getFiles() { return Files; } 196 197 private: 198 // We store compile commands as pair (file name, compile command). 199 std::vector< std::pair<std::string, CompileCommand> > CompileCommands; 200 201 FileManager Files; 202 // Contains a list of pairs (<file name>, <file content>). 203 std::vector< std::pair<StringRef, StringRef> > MappedFileContents; 204 205 llvm::OwningPtr<ArgumentsAdjuster> ArgsAdjuster; 206}; 207 208template <typename T> 209FrontendActionFactory *newFrontendActionFactory() { 210 class SimpleFrontendActionFactory : public FrontendActionFactory { 211 public: 212 virtual clang::FrontendAction *create() { return new T; } 213 }; 214 215 return new SimpleFrontendActionFactory; 216} 217 218template <typename FactoryT> 219inline FrontendActionFactory *newFrontendActionFactory( 220 FactoryT *ConsumerFactory) { 221 class FrontendActionFactoryAdapter : public FrontendActionFactory { 222 public: 223 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory) 224 : ConsumerFactory(ConsumerFactory) {} 225 226 virtual clang::FrontendAction *create() { 227 return new ConsumerFactoryAdaptor(ConsumerFactory); 228 } 229 230 private: 231 class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { 232 public: 233 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory) 234 : ConsumerFactory(ConsumerFactory) {} 235 236 clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &, 237 llvm::StringRef) { 238 return ConsumerFactory->newASTConsumer(); 239 } 240 241 private: 242 FactoryT *ConsumerFactory; 243 }; 244 FactoryT *ConsumerFactory; 245 }; 246 247 return new FrontendActionFactoryAdapter(ConsumerFactory); 248} 249 250/// \brief Returns the absolute path of \c File, by prepending it with 251/// the current directory if \c File is not absolute. 252/// 253/// Otherwise returns \c File. 254/// If 'File' starts with "./", the returned path will not contain the "./". 255/// Otherwise, the returned path will contain the literal path-concatenation of 256/// the current directory and \c File. 257/// 258/// The difference to llvm::sys::fs::make_absolute is that we prefer 259/// ::getenv("PWD") if available. 260/// FIXME: Make this functionality available from llvm::sys::fs and delete 261/// this function. 262/// 263/// \param File Either an absolute or relative path. 264std::string getAbsolutePath(StringRef File); 265 266} // end namespace tooling 267} // end namespace clang 268 269#endif // LLVM_CLANG_TOOLING_TOOLING_H 270