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
50namespace clang {
51
52namespace driver {
53class Compilation;
54} // end namespace driver
55
56class CompilerInvocation;
57class SourceManager;
58class FrontendAction;
59
60namespace 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.
66class ToolAction {
67public:
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.
83class FrontendActionFactory : public ToolAction {
84public:
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>();
105template <typename T>
106std::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.
111class SourceFileCallbacks {
112public:
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));
137template <typename FactoryT>
138inline 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.
150bool 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.
157typedef 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.
170bool 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.
185std::unique_ptr<ASTUnit>
186buildASTFromCode(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.
199std::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.
206class ToolInvocation {
207public:
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  // FIXME: remove this when all users have migrated!
247  void mapVirtualFile(StringRef FilePath, StringRef Content);
248
249  /// \brief Run the clang invocation.
250  ///
251  /// \returns True if there were no errors during execution.
252  bool run();
253
254 private:
255  void addFileMappingsTo(SourceManager &SourceManager);
256
257  bool runInvocation(const char *BinaryName,
258                     clang::driver::Compilation *Compilation,
259                     clang::CompilerInvocation *Invocation,
260                     std::shared_ptr<PCHContainerOperations> PCHContainerOps);
261
262  std::vector<std::string> CommandLine;
263  ToolAction *Action;
264  bool OwnsAction;
265  FileManager *Files;
266  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
267  // Maps <file name> -> <file content>.
268  llvm::StringMap<StringRef> MappedFileContents;
269  DiagnosticConsumer *DiagConsumer;
270};
271
272/// \brief Utility to run a FrontendAction over a set of files.
273///
274/// This class is written to be usable for command line utilities.
275/// By default the class uses ClangSyntaxOnlyAdjuster to modify
276/// command line arguments before the arguments are used to run
277/// a frontend action. One could install an additional command line
278/// arguments adjuster by calling the appendArgumentsAdjuster() method.
279class ClangTool {
280 public:
281  /// \brief Constructs a clang tool to run over a list of files.
282  ///
283  /// \param Compilations The CompilationDatabase which contains the compile
284  ///        command lines for the given source paths.
285  /// \param SourcePaths The source files to run over. If a source files is
286  ///        not found in Compilations, it is skipped.
287  /// \param PCHContainerOps The PCHContainerOperations for loading and creating
288  /// clang modules.
289  ClangTool(const CompilationDatabase &Compilations,
290            ArrayRef<std::string> SourcePaths,
291            std::shared_ptr<PCHContainerOperations> PCHContainerOps =
292                std::make_shared<PCHContainerOperations>());
293
294  ~ClangTool();
295
296  /// \brief Set a \c DiagnosticConsumer to use during parsing.
297  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
298    this->DiagConsumer = DiagConsumer;
299  }
300
301  /// \brief Map a virtual file to be used while running the tool.
302  ///
303  /// \param FilePath The path at which the content will be mapped.
304  /// \param Content A null terminated buffer of the file's content.
305  void mapVirtualFile(StringRef FilePath, StringRef Content);
306
307  /// \brief Append a command line arguments adjuster to the adjuster chain.
308  ///
309  /// \param Adjuster An argument adjuster, which will be run on the output of
310  ///        previous argument adjusters.
311  void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
312
313  /// \brief Clear the command line arguments adjuster chain.
314  void clearArgumentsAdjusters();
315
316  /// Runs an action over all files specified in the command line.
317  ///
318  /// \param Action Tool action.
319  int run(ToolAction *Action);
320
321  /// \brief Create an AST for each file specified in the command line and
322  /// append them to ASTs.
323  int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
324
325  /// \brief Returns the file manager used in the tool.
326  ///
327  /// The file manager is shared between all translation units.
328  FileManager &getFiles() { return *Files; }
329
330 private:
331  const CompilationDatabase &Compilations;
332  std::vector<std::string> SourcePaths;
333  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
334
335  llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem;
336  llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
337  llvm::IntrusiveRefCntPtr<FileManager> Files;
338  // Contains a list of pairs (<file name>, <file content>).
339  std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
340  llvm::StringSet<> SeenWorkingDirectories;
341
342  ArgumentsAdjuster ArgsAdjuster;
343
344  DiagnosticConsumer *DiagConsumer;
345};
346
347template <typename T>
348std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
349  class SimpleFrontendActionFactory : public FrontendActionFactory {
350  public:
351    clang::FrontendAction *create() override { return new T; }
352  };
353
354  return std::unique_ptr<FrontendActionFactory>(
355      new SimpleFrontendActionFactory);
356}
357
358template <typename FactoryT>
359inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
360    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
361  class FrontendActionFactoryAdapter : public FrontendActionFactory {
362  public:
363    explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
364                                          SourceFileCallbacks *Callbacks)
365      : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
366
367    clang::FrontendAction *create() override {
368      return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
369    }
370
371  private:
372    class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
373    public:
374      ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
375                             SourceFileCallbacks *Callbacks)
376        : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
377
378      std::unique_ptr<clang::ASTConsumer>
379      CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
380        return ConsumerFactory->newASTConsumer();
381      }
382
383    protected:
384      bool BeginSourceFileAction(CompilerInstance &CI,
385                                 StringRef Filename) override {
386        if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
387          return false;
388        if (Callbacks)
389          return Callbacks->handleBeginSource(CI, Filename);
390        return true;
391      }
392      void EndSourceFileAction() override {
393        if (Callbacks)
394          Callbacks->handleEndSource();
395        clang::ASTFrontendAction::EndSourceFileAction();
396      }
397
398    private:
399      FactoryT *ConsumerFactory;
400      SourceFileCallbacks *Callbacks;
401    };
402    FactoryT *ConsumerFactory;
403    SourceFileCallbacks *Callbacks;
404  };
405
406  return std::unique_ptr<FrontendActionFactory>(
407      new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
408}
409
410/// \brief Returns the absolute path of \c File, by prepending it with
411/// the current directory if \c File is not absolute.
412///
413/// Otherwise returns \c File.
414/// If 'File' starts with "./", the returned path will not contain the "./".
415/// Otherwise, the returned path will contain the literal path-concatenation of
416/// the current directory and \c File.
417///
418/// The difference to llvm::sys::fs::make_absolute is the canonicalization this
419/// does by removing "./" and computing native paths.
420///
421/// \param File Either an absolute or relative path.
422std::string getAbsolutePath(StringRef File);
423
424/// \brief Changes CommandLine to contain implicit flags that would have been
425/// defined had the compiler driver been invoked through the path InvokedAs.
426///
427/// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
428/// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
429/// be inserted after the first argument in \c CommandLine.
430///
431/// This function will not add new `-target` or `--driver-mode` flags if they
432/// are already present in `CommandLine` (even if they have different settings
433/// than would have been inserted).
434///
435/// \pre `llvm::InitializeAllTargets()` has been called.
436///
437/// \param CommandLine the command line used to invoke the compiler driver or
438/// Clang tool, including the path to the executable as \c CommandLine[0].
439/// \param InvokedAs the path to the driver used to infer implicit flags.
440///
441/// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
442/// infrastructure expects that CommandLine[0] is a tool path relative to which
443/// the builtin headers can be found.
444void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
445                                    StringRef InvokedAs);
446
447/// \brief Creates a \c CompilerInvocation.
448clang::CompilerInvocation *newInvocation(
449    clang::DiagnosticsEngine *Diagnostics,
450    const llvm::opt::ArgStringList &CC1Args);
451
452} // end namespace tooling
453} // end namespace clang
454
455#endif // LLVM_CLANG_TOOLING_TOOLING_H
456