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 "clang/AST/ASTConsumer.h"
     34 #include "clang/Frontend/PCHContainerOperations.h"
     35 #include "clang/Basic/Diagnostic.h"
     36 #include "clang/Basic/FileManager.h"
     37 #include "clang/Basic/LLVM.h"
     38 #include "clang/Driver/Util.h"
     39 #include "clang/Frontend/FrontendAction.h"
     40 #include "clang/Lex/ModuleLoader.h"
     41 #include "clang/Tooling/ArgumentsAdjusters.h"
     42 #include "clang/Tooling/CompilationDatabase.h"
     43 #include "llvm/ADT/StringMap.h"
     44 #include "llvm/ADT/Twine.h"
     45 #include "llvm/Option/Option.h"
     46 #include <memory>
     47 #include <string>
     48 #include <vector>
     49 
     50 namespace clang {
     51 
     52 namespace driver {
     53 class Compilation;
     54 } // end namespace driver
     55 
     56 class CompilerInvocation;
     57 class SourceManager;
     58 class FrontendAction;
     59 
     60 namespace tooling {
     61 
     62 /// \brief Interface to process a clang::CompilerInvocation.
     63 ///
     64 /// If your tool is based on FrontendAction, you should be deriving from
     65 /// FrontendActionFactory instead.
     66 class ToolAction {
     67 public:
     68   virtual ~ToolAction();
     69 
     70   /// \brief Perform an action for an invocation.
     71   virtual bool
     72   runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
     73                 FileManager *Files,
     74                 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     75                 DiagnosticConsumer *DiagConsumer) = 0;
     76 };
     77 
     78 /// \brief Interface to generate clang::FrontendActions.
     79 ///
     80 /// Having a factory interface allows, for example, a new FrontendAction to be
     81 /// created for each translation unit processed by ClangTool.  This class is
     82 /// also a ToolAction which uses the FrontendActions created by create() to
     83 /// process each translation unit.
     84 class FrontendActionFactory : public ToolAction {
     85 public:
     86   ~FrontendActionFactory() override;
     87 
     88   /// \brief Invokes the compiler with a FrontendAction created by create().
     89   bool runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
     90                      FileManager *Files,
     91                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     92                      DiagnosticConsumer *DiagConsumer) override;
     93 
     94   /// \brief Returns a new clang::FrontendAction.
     95   ///
     96   /// The caller takes ownership of the returned action.
     97   virtual clang::FrontendAction *create() = 0;
     98 };
     99 
    100 /// \brief Returns a new FrontendActionFactory for a given type.
    101 ///
    102 /// T must derive from clang::FrontendAction.
    103 ///
    104 /// Example:
    105 /// FrontendActionFactory *Factory =
    106 ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
    107 template <typename T>
    108 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
    109 
    110 /// \brief Callbacks called before and after each source file processed by a
    111 /// FrontendAction created by the FrontedActionFactory returned by \c
    112 /// newFrontendActionFactory.
    113 class SourceFileCallbacks {
    114 public:
    115   virtual ~SourceFileCallbacks() {}
    116 
    117   /// \brief Called before a source file is processed by a FrontEndAction.
    118   /// \see clang::FrontendAction::BeginSourceFileAction
    119   virtual bool handleBeginSource(CompilerInstance &CI) {
    120     return true;
    121   }
    122 
    123   /// \brief Called after a source file is processed by a FrontendAction.
    124   /// \see clang::FrontendAction::EndSourceFileAction
    125   virtual void handleEndSource() {}
    126 };
    127 
    128 /// \brief Returns a new FrontendActionFactory for any type that provides an
    129 /// implementation of newASTConsumer().
    130 ///
    131 /// FactoryT must implement: ASTConsumer *newASTConsumer().
    132 ///
    133 /// Example:
    134 /// struct ProvidesASTConsumers {
    135 ///   clang::ASTConsumer *newASTConsumer();
    136 /// } Factory;
    137 /// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
    138 ///   newFrontendActionFactory(&Factory));
    139 template <typename FactoryT>
    140 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
    141     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
    142 
    143 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
    144 ///
    145 /// \param ToolAction The action to run over the code.
    146 /// \param Code C++ code.
    147 /// \param FileName The file name which 'Code' will be mapped as.
    148 /// \param PCHContainerOps  The PCHContainerOperations for loading and creating
    149 ///                         clang modules.
    150 ///
    151 /// \return - True if 'ToolAction' was successfully executed.
    152 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
    153                    const Twine &FileName = "input.cc",
    154                    std::shared_ptr<PCHContainerOperations> PCHContainerOps =
    155                        std::make_shared<PCHContainerOperations>());
    156 
    157 /// The first part of the pair is the filename, the second part the
    158 /// file-content.
    159 typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
    160 
    161 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
    162 ///        with additional other flags.
    163 ///
    164 /// \param ToolAction The action to run over the code.
    165 /// \param Code C++ code.
    166 /// \param Args Additional flags to pass on.
    167 /// \param FileName The file name which 'Code' will be mapped as.
    168 /// \param ToolName The name of the binary running the tool. Standard library
    169 ///                 header paths will be resolved relative to this.
    170 /// \param PCHContainerOps   The PCHContainerOperations for loading and creating
    171 ///                          clang modules.
    172 ///
    173 /// \return - True if 'ToolAction' was successfully executed.
    174 bool runToolOnCodeWithArgs(
    175     clang::FrontendAction *ToolAction, const Twine &Code,
    176     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
    177     const Twine &ToolName = "clang-tool",
    178     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
    179         std::make_shared<PCHContainerOperations>(),
    180     const FileContentMappings &VirtualMappedFiles = FileContentMappings());
    181 
    182 /// \brief Builds an AST for 'Code'.
    183 ///
    184 /// \param Code C++ code.
    185 /// \param FileName The file name which 'Code' will be mapped as.
    186 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
    187 /// clang modules.
    188 ///
    189 /// \return The resulting AST or null if an error occurred.
    190 std::unique_ptr<ASTUnit>
    191 buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
    192                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
    193                      std::make_shared<PCHContainerOperations>());
    194 
    195 /// \brief Builds an AST for 'Code' with additional flags.
    196 ///
    197 /// \param Code C++ code.
    198 /// \param Args Additional flags to pass on.
    199 /// \param FileName The file name which 'Code' will be mapped as.
    200 /// \param ToolName The name of the binary running the tool. Standard library
    201 ///                 header paths will be resolved relative to this.
    202 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
    203 /// clang modules.
    204 ///
    205 /// \param Adjuster A function to filter the command line arguments as specified.
    206 ///
    207 /// \return The resulting AST or null if an error occurred.
    208 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
    209     const Twine &Code, const std::vector<std::string> &Args,
    210     const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool",
    211     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
    212       std::make_shared<PCHContainerOperations>(),
    213     ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
    214 
    215 /// \brief Utility to run a FrontendAction in a single clang invocation.
    216 class ToolInvocation {
    217 public:
    218   /// \brief Create a tool invocation.
    219   ///
    220   /// \param CommandLine The command line arguments to clang. Note that clang
    221   /// uses its binary name (CommandLine[0]) to locate its builtin headers.
    222   /// Callers have to ensure that they are installed in a compatible location
    223   /// (see clang driver implementation) or mapped in via mapVirtualFile.
    224   /// \param FAction The action to be executed. Class takes ownership.
    225   /// \param Files The FileManager used for the execution. Class does not take
    226   /// ownership.
    227   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
    228   /// clang modules.
    229   ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
    230                  FileManager *Files,
    231                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
    232                      std::make_shared<PCHContainerOperations>());
    233 
    234   /// \brief Create a tool invocation.
    235   ///
    236   /// \param CommandLine The command line arguments to clang.
    237   /// \param Action The action to be executed.
    238   /// \param Files The FileManager used for the execution.
    239   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
    240   /// clang modules.
    241   ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
    242                  FileManager *Files,
    243                  std::shared_ptr<PCHContainerOperations> PCHContainerOps);
    244 
    245   ~ToolInvocation();
    246 
    247   /// \brief Set a \c DiagnosticConsumer to use during parsing.
    248   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
    249     this->DiagConsumer = DiagConsumer;
    250   }
    251 
    252   /// \brief Map a virtual file to be used while running the tool.
    253   ///
    254   /// \param FilePath The path at which the content will be mapped.
    255   /// \param Content A null terminated buffer of the file's content.
    256   // FIXME: remove this when all users have migrated!
    257   void mapVirtualFile(StringRef FilePath, StringRef Content);
    258 
    259   /// \brief Run the clang invocation.
    260   ///
    261   /// \returns True if there were no errors during execution.
    262   bool run();
    263 
    264  private:
    265   void addFileMappingsTo(SourceManager &SourceManager);
    266 
    267   bool runInvocation(const char *BinaryName,
    268                      clang::driver::Compilation *Compilation,
    269                      std::shared_ptr<clang::CompilerInvocation> Invocation,
    270                      std::shared_ptr<PCHContainerOperations> PCHContainerOps);
    271 
    272   std::vector<std::string> CommandLine;
    273   ToolAction *Action;
    274   bool OwnsAction;
    275   FileManager *Files;
    276   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
    277   // Maps <file name> -> <file content>.
    278   llvm::StringMap<StringRef> MappedFileContents;
    279   DiagnosticConsumer *DiagConsumer;
    280 };
    281 
    282 /// \brief Utility to run a FrontendAction over a set of files.
    283 ///
    284 /// This class is written to be usable for command line utilities.
    285 /// By default the class uses ClangSyntaxOnlyAdjuster to modify
    286 /// command line arguments before the arguments are used to run
    287 /// a frontend action. One could install an additional command line
    288 /// arguments adjuster by calling the appendArgumentsAdjuster() method.
    289 class ClangTool {
    290  public:
    291   /// \brief Constructs a clang tool to run over a list of files.
    292   ///
    293   /// \param Compilations The CompilationDatabase which contains the compile
    294   ///        command lines for the given source paths.
    295   /// \param SourcePaths The source files to run over. If a source files is
    296   ///        not found in Compilations, it is skipped.
    297   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
    298   /// clang modules.
    299   ClangTool(const CompilationDatabase &Compilations,
    300             ArrayRef<std::string> SourcePaths,
    301             std::shared_ptr<PCHContainerOperations> PCHContainerOps =
    302                 std::make_shared<PCHContainerOperations>());
    303 
    304   ~ClangTool();
    305 
    306   /// \brief Set a \c DiagnosticConsumer to use during parsing.
    307   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
    308     this->DiagConsumer = DiagConsumer;
    309   }
    310 
    311   /// \brief Map a virtual file to be used while running the tool.
    312   ///
    313   /// \param FilePath The path at which the content will be mapped.
    314   /// \param Content A null terminated buffer of the file's content.
    315   void mapVirtualFile(StringRef FilePath, StringRef Content);
    316 
    317   /// \brief Append a command line arguments adjuster to the adjuster chain.
    318   ///
    319   /// \param Adjuster An argument adjuster, which will be run on the output of
    320   ///        previous argument adjusters.
    321   void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
    322 
    323   /// \brief Clear the command line arguments adjuster chain.
    324   void clearArgumentsAdjusters();
    325 
    326   /// Runs an action over all files specified in the command line.
    327   ///
    328   /// \param Action Tool action.
    329   int run(ToolAction *Action);
    330 
    331   /// \brief Create an AST for each file specified in the command line and
    332   /// append them to ASTs.
    333   int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
    334 
    335   /// \brief Returns the file manager used in the tool.
    336   ///
    337   /// The file manager is shared between all translation units.
    338   FileManager &getFiles() { return *Files; }
    339 
    340  private:
    341   const CompilationDatabase &Compilations;
    342   std::vector<std::string> SourcePaths;
    343   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
    344 
    345   llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem;
    346   llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
    347   llvm::IntrusiveRefCntPtr<FileManager> Files;
    348   // Contains a list of pairs (<file name>, <file content>).
    349   std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
    350   llvm::StringSet<> SeenWorkingDirectories;
    351 
    352   ArgumentsAdjuster ArgsAdjuster;
    353 
    354   DiagnosticConsumer *DiagConsumer;
    355 };
    356 
    357 template <typename T>
    358 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
    359   class SimpleFrontendActionFactory : public FrontendActionFactory {
    360   public:
    361     clang::FrontendAction *create() override { return new T; }
    362   };
    363 
    364   return std::unique_ptr<FrontendActionFactory>(
    365       new SimpleFrontendActionFactory);
    366 }
    367 
    368 template <typename FactoryT>
    369 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
    370     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
    371   class FrontendActionFactoryAdapter : public FrontendActionFactory {
    372   public:
    373     explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
    374                                           SourceFileCallbacks *Callbacks)
    375       : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
    376 
    377     clang::FrontendAction *create() override {
    378       return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
    379     }
    380 
    381   private:
    382     class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
    383     public:
    384       ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
    385                              SourceFileCallbacks *Callbacks)
    386         : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
    387 
    388       std::unique_ptr<clang::ASTConsumer>
    389       CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
    390         return ConsumerFactory->newASTConsumer();
    391       }
    392 
    393     protected:
    394       bool BeginSourceFileAction(CompilerInstance &CI) override {
    395         if (!clang::ASTFrontendAction::BeginSourceFileAction(CI))
    396           return false;
    397         if (Callbacks)
    398           return Callbacks->handleBeginSource(CI);
    399         return true;
    400       }
    401       void EndSourceFileAction() override {
    402         if (Callbacks)
    403           Callbacks->handleEndSource();
    404         clang::ASTFrontendAction::EndSourceFileAction();
    405       }
    406 
    407     private:
    408       FactoryT *ConsumerFactory;
    409       SourceFileCallbacks *Callbacks;
    410     };
    411     FactoryT *ConsumerFactory;
    412     SourceFileCallbacks *Callbacks;
    413   };
    414 
    415   return std::unique_ptr<FrontendActionFactory>(
    416       new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
    417 }
    418 
    419 /// \brief Returns the absolute path of \c File, by prepending it with
    420 /// the current directory if \c File is not absolute.
    421 ///
    422 /// Otherwise returns \c File.
    423 /// If 'File' starts with "./", the returned path will not contain the "./".
    424 /// Otherwise, the returned path will contain the literal path-concatenation of
    425 /// the current directory and \c File.
    426 ///
    427 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
    428 /// does by removing "./" and computing native paths.
    429 ///
    430 /// \param File Either an absolute or relative path.
    431 std::string getAbsolutePath(StringRef File);
    432 
    433 /// \brief Changes CommandLine to contain implicit flags that would have been
    434 /// defined had the compiler driver been invoked through the path InvokedAs.
    435 ///
    436 /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
    437 /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
    438 /// be inserted after the first argument in \c CommandLine.
    439 ///
    440 /// This function will not add new `-target` or `--driver-mode` flags if they
    441 /// are already present in `CommandLine` (even if they have different settings
    442 /// than would have been inserted).
    443 ///
    444 /// \pre `llvm::InitializeAllTargets()` has been called.
    445 ///
    446 /// \param CommandLine the command line used to invoke the compiler driver or
    447 /// Clang tool, including the path to the executable as \c CommandLine[0].
    448 /// \param InvokedAs the path to the driver used to infer implicit flags.
    449 ///
    450 /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
    451 /// infrastructure expects that CommandLine[0] is a tool path relative to which
    452 /// the builtin headers can be found.
    453 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
    454                                     StringRef InvokedAs);
    455 
    456 /// \brief Creates a \c CompilerInvocation.
    457 clang::CompilerInvocation *newInvocation(
    458     clang::DiagnosticsEngine *Diagnostics,
    459     const llvm::opt::ArgStringList &CC1Args);
    460 
    461 } // end namespace tooling
    462 } // end namespace clang
    463 
    464 #endif // LLVM_CLANG_TOOLING_TOOLING_H
    465