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