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 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 
     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 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);
     88 template <typename FactoryT>
     89 inline 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.
     99 bool 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.
    111 bool 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.
    116 class 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.
    163 class 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 
    208 template <typename T>
    209 FrontendActionFactory *newFrontendActionFactory() {
    210   class SimpleFrontendActionFactory : public FrontendActionFactory {
    211   public:
    212     virtual clang::FrontendAction *create() { return new T; }
    213   };
    214 
    215   return new SimpleFrontendActionFactory;
    216 }
    217 
    218 template <typename FactoryT>
    219 inline 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.
    264 std::string getAbsolutePath(StringRef File);
    265 
    266 } // end namespace tooling
    267 } // end namespace clang
    268 
    269 #endif // LLVM_CLANG_TOOLING_TOOLING_H
    270