LCOV - code coverage report
Current view: top level - clang/Tooling - Tooling.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 19 24 79.2 %
Date: 2016-01-31 12:01:00 Functions: 13 13 100.0 %

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

Generated by: LCOV version 1.11