Home | History | Annotate | Download | only in Tooling
      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 runSyntaxOnlyToolOnCode, 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 <string>
     39 #include <vector>
     40 
     41 namespace clang {
     42 
     43 namespace driver {
     44 class Compilation;
     45 } // end namespace driver
     46 
     47 class CompilerInvocation;
     48 class SourceManager;
     49 class FrontendAction;
     50 
     51 namespace tooling {
     52 
     53 class CompilationDatabase;
     54 
     55 /// \brief Interface to generate clang::FrontendActions.
     56 class FrontendActionFactory {
     57 public:
     58   virtual ~FrontendActionFactory();
     59 
     60   /// \brief Returns a new clang::FrontendAction.
     61   ///
     62   /// The caller takes ownership of the returned action.
     63   virtual clang::FrontendAction *create() = 0;
     64 };
     65 
     66 /// \brief Returns a new FrontendActionFactory for a given type.
     67 ///
     68 /// T must extend clang::FrontendAction.
     69 ///
     70 /// Example:
     71 /// FrontendActionFactory *Factory =
     72 ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
     73 template <typename T>
     74 FrontendActionFactory *newFrontendActionFactory();
     75 
     76 /// \brief Returns a new FrontendActionFactory for any type that provides an
     77 /// implementation of newFrontendAction().
     78 ///
     79 /// FactoryT must implement: FrontendAction *newFrontendAction().
     80 ///
     81 /// Example:
     82 /// struct ProvidesFrontendActions {
     83 ///   FrontendAction *newFrontendAction();
     84 /// } Factory;
     85 /// FrontendActionFactory *FactoryAdapter =
     86 ///   newFrontendActionFactory(&Factory);
     87 template <typename FactoryT>
     88 FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory);
     89 
     90 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
     91 ///
     92 /// \param ToolAction The action to run over the code.
     93 /// \param Code C++ code.
     94 /// \param FileName The file name which 'Code' will be mapped as.
     95 ///
     96 /// \return - True if 'ToolAction' was successfully executed.
     97 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
     98                    const Twine &FileName = "input.cc");
     99 
    100 /// \brief Utility to run a FrontendAction in a single clang invocation.
    101 class ToolInvocation {
    102  public:
    103   /// \brief Create a tool invocation.
    104   ///
    105   /// \param CommandLine The command line arguments to clang.
    106   /// \param ToolAction The action to be executed. Class takes ownership.
    107   /// \param Files The FileManager used for the execution. Class does not take
    108   /// ownership.
    109   ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,
    110                  FileManager *Files);
    111 
    112   /// \brief Map a virtual file to be used while running the tool.
    113   ///
    114   /// \param FilePath The path at which the content will be mapped.
    115   /// \param Content A null terminated buffer of the file's content.
    116   void mapVirtualFile(StringRef FilePath, StringRef Content);
    117 
    118   /// \brief Run the clang invocation.
    119   ///
    120   /// \returns True if there were no errors during execution.
    121   bool run();
    122 
    123  private:
    124   void addFileMappingsTo(SourceManager &SourceManager);
    125 
    126   bool runInvocation(const char *BinaryName,
    127                      clang::driver::Compilation *Compilation,
    128                      clang::CompilerInvocation *Invocation,
    129                      const clang::driver::ArgStringList &CC1Args,
    130                      clang::FrontendAction *ToolAction);
    131 
    132   std::vector<std::string> CommandLine;
    133   llvm::OwningPtr<FrontendAction> ToolAction;
    134   FileManager *Files;
    135   // Maps <file name> -> <file content>.
    136   llvm::StringMap<StringRef> MappedFileContents;
    137 };
    138 
    139 /// \brief Utility to run a FrontendAction over a set of files.
    140 ///
    141 /// This class is written to be usable for command line utilities.
    142 class ClangTool {
    143  public:
    144   /// \brief Constructs a clang tool to run over a list of files.
    145   ///
    146   /// \param Compilations The CompilationDatabase which contains the compile
    147   ///        command lines for the given source paths.
    148   /// \param SourcePaths The source files to run over. If a source files is
    149   ///        not found in Compilations, it is skipped.
    150   ClangTool(const CompilationDatabase &Compilations,
    151             ArrayRef<std::string> SourcePaths);
    152 
    153   /// \brief Map a virtual file to be used while running the tool.
    154   ///
    155   /// \param FilePath The path at which the content will be mapped.
    156   /// \param Content A null terminated buffer of the file's content.
    157   void mapVirtualFile(StringRef FilePath, StringRef Content);
    158 
    159   /// Runs a frontend action over all files specified in the command line.
    160   ///
    161   /// \param ActionFactory Factory generating the frontend actions. The function
    162   /// takes ownership of this parameter. A new action is generated for every
    163   /// processed translation unit.
    164   int run(FrontendActionFactory *ActionFactory);
    165 
    166   /// \brief Returns the file manager used in the tool.
    167   ///
    168   /// The file manager is shared between all translation units.
    169   FileManager &getFiles() { return Files; }
    170 
    171  private:
    172   // We store command lines as pair (file name, command line).
    173   typedef std::pair< std::string, std::vector<std::string> > CommandLine;
    174   std::vector<CommandLine> CommandLines;
    175 
    176   FileManager Files;
    177   // Contains a list of pairs (<file name>, <file content>).
    178   std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
    179 };
    180 
    181 template <typename T>
    182 FrontendActionFactory *newFrontendActionFactory() {
    183   class SimpleFrontendActionFactory : public FrontendActionFactory {
    184   public:
    185     virtual clang::FrontendAction *create() { return new T; }
    186   };
    187 
    188   return new SimpleFrontendActionFactory;
    189 }
    190 
    191 template <typename FactoryT>
    192 FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory) {
    193   class FrontendActionFactoryAdapter : public FrontendActionFactory {
    194   public:
    195     explicit FrontendActionFactoryAdapter(FactoryT *ActionFactory)
    196       : ActionFactory(ActionFactory) {}
    197 
    198     virtual clang::FrontendAction *create() {
    199       return ActionFactory->newFrontendAction();
    200     }
    201 
    202   private:
    203     FactoryT *ActionFactory;
    204   };
    205 
    206   return new FrontendActionFactoryAdapter(ActionFactory);
    207 }
    208 
    209 } // end namespace tooling
    210 } // end namespace clang
    211 
    212 #endif // LLVM_CLANG_TOOLING_TOOLING_H
    213 
    214