clang API Documentation

Tooling.h
Go to the documentation of this file.
00001 //===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements functions to run clang tools standalone instead
00011 //  of running them as a plugin.
00012 //
00013 //  A ClangTool is initialized with a CompilationDatabase and a set of files
00014 //  to run over. The tool will then run a user-specified FrontendAction over
00015 //  all TUs in which the given files are compiled.
00016 //
00017 //  It is also possible to run a FrontendAction over a snippet of code by
00018 //  calling runToolOnCode, which is useful for unit testing.
00019 //
00020 //  Applications that need more fine grained control over how to run
00021 //  multiple FrontendActions over code can use ToolInvocation.
00022 //
00023 //  Example tools:
00024 //  - running clang -fsyntax-only over source code from an editor to get
00025 //    fast syntax checks
00026 //  - running match/replace tools over C++ code
00027 //
00028 //===----------------------------------------------------------------------===//
00029 
00030 #ifndef LLVM_CLANG_TOOLING_TOOLING_H
00031 #define LLVM_CLANG_TOOLING_TOOLING_H
00032 
00033 #include "clang/AST/ASTConsumer.h"
00034 #include "clang/Basic/Diagnostic.h"
00035 #include "clang/Basic/FileManager.h"
00036 #include "clang/Basic/LLVM.h"
00037 #include "clang/Driver/Util.h"
00038 #include "clang/Frontend/FrontendAction.h"
00039 #include "clang/Tooling/ArgumentsAdjusters.h"
00040 #include "clang/Tooling/CompilationDatabase.h"
00041 #include "llvm/ADT/StringMap.h"
00042 #include "llvm/ADT/Twine.h"
00043 #include <memory>
00044 #include <string>
00045 #include <vector>
00046 
00047 namespace clang {
00048 
00049 namespace driver {
00050 class Compilation;
00051 } // end namespace driver
00052 
00053 class CompilerInvocation;
00054 class SourceManager;
00055 class FrontendAction;
00056 
00057 namespace tooling {
00058 
00059 /// \brief Interface to process a clang::CompilerInvocation.
00060 ///
00061 /// If your tool is based on FrontendAction, you should be deriving from
00062 /// FrontendActionFactory instead.
00063 class ToolAction {
00064 public:
00065   virtual ~ToolAction();
00066 
00067   /// \brief Perform an action for an invocation.
00068   virtual bool runInvocation(clang::CompilerInvocation *Invocation,
00069                              FileManager *Files,
00070                              DiagnosticConsumer *DiagConsumer) = 0;
00071 };
00072 
00073 /// \brief Interface to generate clang::FrontendActions.
00074 ///
00075 /// Having a factory interface allows, for example, a new FrontendAction to be
00076 /// created for each translation unit processed by ClangTool.  This class is
00077 /// also a ToolAction which uses the FrontendActions created by create() to
00078 /// process each translation unit.
00079 class FrontendActionFactory : public ToolAction {
00080 public:
00081   virtual ~FrontendActionFactory();
00082 
00083   /// \brief Invokes the compiler with a FrontendAction created by create().
00084   bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
00085                      DiagnosticConsumer *DiagConsumer) override;
00086 
00087   /// \brief Returns a new clang::FrontendAction.
00088   ///
00089   /// The caller takes ownership of the returned action.
00090   virtual clang::FrontendAction *create() = 0;
00091 };
00092 
00093 /// \brief Returns a new FrontendActionFactory for a given type.
00094 ///
00095 /// T must derive from clang::FrontendAction.
00096 ///
00097 /// Example:
00098 /// FrontendActionFactory *Factory =
00099 ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
00100 template <typename T>
00101 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
00102 
00103 /// \brief Callbacks called before and after each source file processed by a
00104 /// FrontendAction created by the FrontedActionFactory returned by \c
00105 /// newFrontendActionFactory.
00106 class SourceFileCallbacks {
00107 public:
00108   virtual ~SourceFileCallbacks() {}
00109 
00110   /// \brief Called before a source file is processed by a FrontEndAction.
00111   /// \see clang::FrontendAction::BeginSourceFileAction
00112   virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) {
00113     return true;
00114   }
00115 
00116   /// \brief Called after a source file is processed by a FrontendAction.
00117   /// \see clang::FrontendAction::EndSourceFileAction
00118   virtual void handleEndSource() {}
00119 };
00120 
00121 /// \brief Returns a new FrontendActionFactory for any type that provides an
00122 /// implementation of newASTConsumer().
00123 ///
00124 /// FactoryT must implement: ASTConsumer *newASTConsumer().
00125 ///
00126 /// Example:
00127 /// struct ProvidesASTConsumers {
00128 ///   clang::ASTConsumer *newASTConsumer();
00129 /// } Factory;
00130 /// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
00131 ///   newFrontendActionFactory(&Factory));
00132 template <typename FactoryT>
00133 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
00134     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
00135 
00136 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
00137 ///
00138 /// \param ToolAction The action to run over the code.
00139 /// \param Code C++ code.
00140 /// \param FileName The file name which 'Code' will be mapped as.
00141 ///
00142 /// \return - True if 'ToolAction' was successfully executed.
00143 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
00144                    const Twine &FileName = "input.cc");
00145 
00146 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
00147 ///        with additional other flags.
00148 ///
00149 /// \param ToolAction The action to run over the code.
00150 /// \param Code C++ code.
00151 /// \param Args Additional flags to pass on.
00152 /// \param FileName The file name which 'Code' will be mapped as.
00153 ///
00154 /// \return - True if 'ToolAction' was successfully executed.
00155 bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
00156                            const std::vector<std::string> &Args,
00157                            const Twine &FileName = "input.cc");
00158 
00159 /// \brief Builds an AST for 'Code'.
00160 ///
00161 /// \param Code C++ code.
00162 /// \param FileName The file name which 'Code' will be mapped as.
00163 ///
00164 /// \return The resulting AST or null if an error occurred.
00165 std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
00166                                           const Twine &FileName = "input.cc");
00167 
00168 /// \brief Builds an AST for 'Code' with additional flags.
00169 ///
00170 /// \param Code C++ code.
00171 /// \param Args Additional flags to pass on.
00172 /// \param FileName The file name which 'Code' will be mapped as.
00173 ///
00174 /// \return The resulting AST or null if an error occurred.
00175 std::unique_ptr<ASTUnit>
00176 buildASTFromCodeWithArgs(const Twine &Code,
00177                          const std::vector<std::string> &Args,
00178                          const Twine &FileName = "input.cc");
00179 
00180 /// \brief Utility to run a FrontendAction in a single clang invocation.
00181 class ToolInvocation {
00182  public:
00183   /// \brief Create a tool invocation.
00184   ///
00185   /// \param CommandLine The command line arguments to clang. Note that clang
00186   /// uses its binary name (CommandLine[0]) to locate its builtin headers.
00187   /// Callers have to ensure that they are installed in a compatible location
00188   /// (see clang driver implementation) or mapped in via mapVirtualFile.
00189   /// \param FAction The action to be executed. Class takes ownership.
00190   /// \param Files The FileManager used for the execution. Class does not take
00191   /// ownership.
00192   ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
00193                  FileManager *Files);
00194 
00195   /// \brief Create a tool invocation.
00196   ///
00197   /// \param CommandLine The command line arguments to clang.
00198   /// \param Action The action to be executed.
00199   /// \param Files The FileManager used for the execution.
00200   ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
00201                  FileManager *Files);
00202 
00203   ~ToolInvocation();
00204 
00205   /// \brief Set a \c DiagnosticConsumer to use during parsing.
00206   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
00207     this->DiagConsumer = DiagConsumer;
00208   }
00209 
00210   /// \brief Map a virtual file to be used while running the tool.
00211   ///
00212   /// \param FilePath The path at which the content will be mapped.
00213   /// \param Content A null terminated buffer of the file's content.
00214   void mapVirtualFile(StringRef FilePath, StringRef Content);
00215 
00216   /// \brief Run the clang invocation.
00217   ///
00218   /// \returns True if there were no errors during execution.
00219   bool run();
00220 
00221  private:
00222   void addFileMappingsTo(SourceManager &SourceManager);
00223 
00224   bool runInvocation(const char *BinaryName,
00225                      clang::driver::Compilation *Compilation,
00226                      clang::CompilerInvocation *Invocation);
00227 
00228   std::vector<std::string> CommandLine;
00229   ToolAction *Action;
00230   bool OwnsAction;
00231   FileManager *Files;
00232   // Maps <file name> -> <file content>.
00233   llvm::StringMap<StringRef> MappedFileContents;
00234   DiagnosticConsumer *DiagConsumer;
00235 };
00236 
00237 /// \brief Utility to run a FrontendAction over a set of files.
00238 ///
00239 /// This class is written to be usable for command line utilities.
00240 /// By default the class uses ClangSyntaxOnlyAdjuster to modify
00241 /// command line arguments before the arguments are used to run
00242 /// a frontend action. One could install an additional command line
00243 /// arguments adjuster by calling the appendArgumentsAdjuster() method.
00244 class ClangTool {
00245  public:
00246   /// \brief Constructs a clang tool to run over a list of files.
00247   ///
00248   /// \param Compilations The CompilationDatabase which contains the compile
00249   ///        command lines for the given source paths.
00250   /// \param SourcePaths The source files to run over. If a source files is
00251   ///        not found in Compilations, it is skipped.
00252   ClangTool(const CompilationDatabase &Compilations,
00253             ArrayRef<std::string> SourcePaths);
00254 
00255   ~ClangTool();
00256 
00257   /// \brief Set a \c DiagnosticConsumer to use during parsing.
00258   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
00259     this->DiagConsumer = DiagConsumer;
00260   }
00261 
00262   /// \brief Map a virtual file to be used while running the tool.
00263   ///
00264   /// \param FilePath The path at which the content will be mapped.
00265   /// \param Content A null terminated buffer of the file's content.
00266   void mapVirtualFile(StringRef FilePath, StringRef Content);
00267 
00268   /// \brief Append a command line arguments adjuster to the adjuster chain.
00269   ///
00270   /// \param Adjuster An argument adjuster, which will be run on the output of
00271   ///        previous argument adjusters.
00272   void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
00273 
00274   /// \brief Clear the command line arguments adjuster chain.
00275   void clearArgumentsAdjusters();
00276 
00277   /// Runs an action over all files specified in the command line.
00278   ///
00279   /// \param Action Tool action.
00280   int run(ToolAction *Action);
00281 
00282   /// \brief Create an AST for each file specified in the command line and
00283   /// append them to ASTs.
00284   int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
00285 
00286   /// \brief Returns the file manager used in the tool.
00287   ///
00288   /// The file manager is shared between all translation units.
00289   FileManager &getFiles() { return *Files; }
00290 
00291  private:
00292   const CompilationDatabase &Compilations;
00293   std::vector<std::string> SourcePaths;
00294 
00295   llvm::IntrusiveRefCntPtr<FileManager> Files;
00296   // Contains a list of pairs (<file name>, <file content>).
00297   std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
00298 
00299   SmallVector<std::unique_ptr<ArgumentsAdjuster>, 2> ArgsAdjusters;
00300 
00301   DiagnosticConsumer *DiagConsumer;
00302 };
00303 
00304 template <typename T>
00305 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
00306   class SimpleFrontendActionFactory : public FrontendActionFactory {
00307   public:
00308     clang::FrontendAction *create() override { return new T; }
00309   };
00310 
00311   return std::unique_ptr<FrontendActionFactory>(
00312       new SimpleFrontendActionFactory);
00313 }
00314 
00315 template <typename FactoryT>
00316 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
00317     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
00318   class FrontendActionFactoryAdapter : public FrontendActionFactory {
00319   public:
00320     explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
00321                                           SourceFileCallbacks *Callbacks)
00322       : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
00323 
00324     clang::FrontendAction *create() override {
00325       return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
00326     }
00327 
00328   private:
00329     class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
00330     public:
00331       ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
00332                              SourceFileCallbacks *Callbacks)
00333         : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
00334 
00335       std::unique_ptr<clang::ASTConsumer>
00336       CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
00337         return ConsumerFactory->newASTConsumer();
00338       }
00339 
00340     protected:
00341       bool BeginSourceFileAction(CompilerInstance &CI,
00342                                  StringRef Filename) override {
00343         if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
00344           return false;
00345         if (Callbacks)
00346           return Callbacks->handleBeginSource(CI, Filename);
00347         return true;
00348       }
00349       void EndSourceFileAction() override {
00350         if (Callbacks)
00351           Callbacks->handleEndSource();
00352         clang::ASTFrontendAction::EndSourceFileAction();
00353       }
00354 
00355     private:
00356       FactoryT *ConsumerFactory;
00357       SourceFileCallbacks *Callbacks;
00358     };
00359     FactoryT *ConsumerFactory;
00360     SourceFileCallbacks *Callbacks;
00361   };
00362 
00363   return std::unique_ptr<FrontendActionFactory>(
00364       new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
00365 }
00366 
00367 /// \brief Returns the absolute path of \c File, by prepending it with
00368 /// the current directory if \c File is not absolute.
00369 ///
00370 /// Otherwise returns \c File.
00371 /// If 'File' starts with "./", the returned path will not contain the "./".
00372 /// Otherwise, the returned path will contain the literal path-concatenation of
00373 /// the current directory and \c File.
00374 ///
00375 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
00376 /// does by removing "./" and computing native paths.
00377 ///
00378 /// \param File Either an absolute or relative path.
00379 std::string getAbsolutePath(StringRef File);
00380 
00381 } // end namespace tooling
00382 } // end namespace clang
00383 
00384 #endif // LLVM_CLANG_TOOLING_TOOLING_H