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