1234287Sdim//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
2234287Sdim//
3234287Sdim//                     The LLVM Compiler Infrastructure
4234287Sdim//
5234287Sdim// This file is distributed under the University of Illinois Open Source
6234287Sdim// License. See LICENSE.TXT for details.
7234287Sdim//
8234287Sdim//===----------------------------------------------------------------------===//
9234287Sdim//
10234287Sdim//  This file implements functions to run clang tools standalone instead
11234287Sdim//  of running them as a plugin.
12234287Sdim//
13234287Sdim//  A ClangTool is initialized with a CompilationDatabase and a set of files
14234287Sdim//  to run over. The tool will then run a user-specified FrontendAction over
15234287Sdim//  all TUs in which the given files are compiled.
16234287Sdim//
17234287Sdim//  It is also possible to run a FrontendAction over a snippet of code by
18239462Sdim//  calling runToolOnCode, which is useful for unit testing.
19234287Sdim//
20234287Sdim//  Applications that need more fine grained control over how to run
21234287Sdim//  multiple FrontendActions over code can use ToolInvocation.
22234287Sdim//
23234287Sdim//  Example tools:
24234287Sdim//  - running clang -fsyntax-only over source code from an editor to get
25234287Sdim//    fast syntax checks
26234287Sdim//  - running match/replace tools over C++ code
27234287Sdim//
28234287Sdim//===----------------------------------------------------------------------===//
29234287Sdim
30234287Sdim#ifndef LLVM_CLANG_TOOLING_TOOLING_H
31234287Sdim#define LLVM_CLANG_TOOLING_TOOLING_H
32234287Sdim
33263508Sdim#include "clang/Basic/Diagnostic.h"
34234287Sdim#include "clang/Basic/FileManager.h"
35234287Sdim#include "clang/Basic/LLVM.h"
36234287Sdim#include "clang/Driver/Util.h"
37239462Sdim#include "clang/Frontend/FrontendAction.h"
38239462Sdim#include "clang/Tooling/ArgumentsAdjusters.h"
39239462Sdim#include "clang/Tooling/CompilationDatabase.h"
40249423Sdim#include "llvm/ADT/StringMap.h"
41249423Sdim#include "llvm/ADT/Twine.h"
42234287Sdim#include <string>
43234287Sdim#include <vector>
44234287Sdim
45234287Sdimnamespace clang {
46234287Sdim
47234287Sdimnamespace driver {
48234287Sdimclass Compilation;
49234287Sdim} // end namespace driver
50234287Sdim
51234287Sdimclass CompilerInvocation;
52234287Sdimclass SourceManager;
53234287Sdimclass FrontendAction;
54234287Sdim
55234287Sdimnamespace tooling {
56234287Sdim
57263508Sdim/// \brief Interface to process a clang::CompilerInvocation.
58263508Sdim///
59263508Sdim/// If your tool is based on FrontendAction, you should be deriving from
60263508Sdim/// FrontendActionFactory instead.
61263508Sdimclass ToolAction {
62263508Sdimpublic:
63263508Sdim  virtual ~ToolAction();
64263508Sdim
65263508Sdim  /// \brief Perform an action for an invocation.
66263508Sdim  virtual bool runInvocation(clang::CompilerInvocation *Invocation,
67263508Sdim                             FileManager *Files,
68263508Sdim                             DiagnosticConsumer *DiagConsumer) = 0;
69263508Sdim};
70263508Sdim
71234287Sdim/// \brief Interface to generate clang::FrontendActions.
72263508Sdim///
73263508Sdim/// Having a factory interface allows, for example, a new FrontendAction to be
74263508Sdim/// created for each translation unit processed by ClangTool.  This class is
75263508Sdim/// also a ToolAction which uses the FrontendActions created by create() to
76263508Sdim/// process each translation unit.
77263508Sdimclass FrontendActionFactory : public ToolAction {
78234287Sdimpublic:
79234287Sdim  virtual ~FrontendActionFactory();
80234287Sdim
81263508Sdim  /// \brief Invokes the compiler with a FrontendAction created by create().
82263508Sdim  bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
83263508Sdim                     DiagnosticConsumer *DiagConsumer);
84263508Sdim
85234287Sdim  /// \brief Returns a new clang::FrontendAction.
86234287Sdim  ///
87234287Sdim  /// The caller takes ownership of the returned action.
88234287Sdim  virtual clang::FrontendAction *create() = 0;
89234287Sdim};
90234287Sdim
91234287Sdim/// \brief Returns a new FrontendActionFactory for a given type.
92234287Sdim///
93263508Sdim/// T must derive from clang::FrontendAction.
94234287Sdim///
95234287Sdim/// Example:
96234287Sdim/// FrontendActionFactory *Factory =
97234287Sdim///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
98234287Sdimtemplate <typename T>
99234287SdimFrontendActionFactory *newFrontendActionFactory();
100234287Sdim
101263508Sdim/// \brief Callbacks called before and after each source file processed by a
102263508Sdim/// FrontendAction created by the FrontedActionFactory returned by \c
103263508Sdim/// newFrontendActionFactory.
104263508Sdimclass SourceFileCallbacks {
105243830Sdimpublic:
106263508Sdim  virtual ~SourceFileCallbacks() {}
107263508Sdim
108263508Sdim  /// \brief Called before a source file is processed by a FrontEndAction.
109263508Sdim  /// \see clang::FrontendAction::BeginSourceFileAction
110263508Sdim  virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) {
111263508Sdim    return true;
112263508Sdim  }
113263508Sdim
114263508Sdim  /// \brief Called after a source file is processed by a FrontendAction.
115263508Sdim  /// \see clang::FrontendAction::EndSourceFileAction
116263508Sdim  virtual void handleEndSource() {}
117243830Sdim};
118243830Sdim
119234287Sdim/// \brief Returns a new FrontendActionFactory for any type that provides an
120239462Sdim/// implementation of newASTConsumer().
121234287Sdim///
122239462Sdim/// FactoryT must implement: ASTConsumer *newASTConsumer().
123234287Sdim///
124234287Sdim/// Example:
125239462Sdim/// struct ProvidesASTConsumers {
126239462Sdim///   clang::ASTConsumer *newASTConsumer();
127234287Sdim/// } Factory;
128234287Sdim/// FrontendActionFactory *FactoryAdapter =
129234287Sdim///   newFrontendActionFactory(&Factory);
130234287Sdimtemplate <typename FactoryT>
131239462Sdiminline FrontendActionFactory *newFrontendActionFactory(
132263508Sdim    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = NULL);
133234287Sdim
134234287Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
135234287Sdim///
136234287Sdim/// \param ToolAction The action to run over the code.
137234287Sdim/// \param Code C++ code.
138234287Sdim/// \param FileName The file name which 'Code' will be mapped as.
139234287Sdim///
140234287Sdim/// \return - True if 'ToolAction' was successfully executed.
141234287Sdimbool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
142234287Sdim                   const Twine &FileName = "input.cc");
143234287Sdim
144243830Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
145243830Sdim///        with additional other flags.
146243830Sdim///
147243830Sdim/// \param ToolAction The action to run over the code.
148243830Sdim/// \param Code C++ code.
149243830Sdim/// \param Args Additional flags to pass on.
150243830Sdim/// \param FileName The file name which 'Code' will be mapped as.
151243830Sdim///
152243830Sdim/// \return - True if 'ToolAction' was successfully executed.
153243830Sdimbool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
154243830Sdim                           const std::vector<std::string> &Args,
155243830Sdim                           const Twine &FileName = "input.cc");
156243830Sdim
157263508Sdim/// \brief Builds an AST for 'Code'.
158263508Sdim///
159263508Sdim/// \param Code C++ code.
160263508Sdim/// \param FileName The file name which 'Code' will be mapped as.
161263508Sdim///
162263508Sdim/// \return The resulting AST or null if an error occurred.
163263508SdimASTUnit *buildASTFromCode(const Twine &Code,
164263508Sdim                          const Twine &FileName = "input.cc");
165263508Sdim
166263508Sdim/// \brief Builds an AST for 'Code' with additional flags.
167263508Sdim///
168263508Sdim/// \param Code C++ code.
169263508Sdim/// \param Args Additional flags to pass on.
170263508Sdim/// \param FileName The file name which 'Code' will be mapped as.
171263508Sdim///
172263508Sdim/// \return The resulting AST or null if an error occurred.
173263508SdimASTUnit *buildASTFromCodeWithArgs(const Twine &Code,
174263508Sdim                                  const std::vector<std::string> &Args,
175263508Sdim                                  const Twine &FileName = "input.cc");
176263508Sdim
177234287Sdim/// \brief Utility to run a FrontendAction in a single clang invocation.
178234287Sdimclass ToolInvocation {
179234287Sdim public:
180234287Sdim  /// \brief Create a tool invocation.
181234287Sdim  ///
182239462Sdim  /// \param CommandLine The command line arguments to clang. Note that clang
183239462Sdim  /// uses its binary name (CommandLine[0]) to locate its builtin headers.
184239462Sdim  /// Callers have to ensure that they are installed in a compatible location
185239462Sdim  /// (see clang driver implementation) or mapped in via mapVirtualFile.
186263508Sdim  /// \param FAction The action to be executed. Class takes ownership.
187234287Sdim  /// \param Files The FileManager used for the execution. Class does not take
188234287Sdim  /// ownership.
189263508Sdim  ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction,
190234287Sdim                 FileManager *Files);
191234287Sdim
192263508Sdim  /// \brief Create a tool invocation.
193263508Sdim  ///
194263508Sdim  /// \param CommandLine The command line arguments to clang.
195263508Sdim  /// \param Action The action to be executed.
196263508Sdim  /// \param Files The FileManager used for the execution.
197263508Sdim  ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action,
198263508Sdim                 FileManager *Files);
199263508Sdim
200263508Sdim  ~ToolInvocation();
201263508Sdim
202263508Sdim  /// \brief Set a \c DiagnosticConsumer to use during parsing.
203263508Sdim  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
204263508Sdim
205234287Sdim  /// \brief Map a virtual file to be used while running the tool.
206234287Sdim  ///
207234287Sdim  /// \param FilePath The path at which the content will be mapped.
208234287Sdim  /// \param Content A null terminated buffer of the file's content.
209234287Sdim  void mapVirtualFile(StringRef FilePath, StringRef Content);
210234287Sdim
211234287Sdim  /// \brief Run the clang invocation.
212234287Sdim  ///
213234287Sdim  /// \returns True if there were no errors during execution.
214234287Sdim  bool run();
215234287Sdim
216234287Sdim private:
217234287Sdim  void addFileMappingsTo(SourceManager &SourceManager);
218234287Sdim
219234287Sdim  bool runInvocation(const char *BinaryName,
220234287Sdim                     clang::driver::Compilation *Compilation,
221249423Sdim                     clang::CompilerInvocation *Invocation);
222234287Sdim
223234287Sdim  std::vector<std::string> CommandLine;
224263508Sdim  ToolAction *Action;
225263508Sdim  bool OwnsAction;
226234287Sdim  FileManager *Files;
227234287Sdim  // Maps <file name> -> <file content>.
228234287Sdim  llvm::StringMap<StringRef> MappedFileContents;
229263508Sdim  DiagnosticConsumer *DiagConsumer;
230234287Sdim};
231234287Sdim
232234287Sdim/// \brief Utility to run a FrontendAction over a set of files.
233234287Sdim///
234234287Sdim/// This class is written to be usable for command line utilities.
235239462Sdim/// By default the class uses ClangSyntaxOnlyAdjuster to modify
236239462Sdim/// command line arguments before the arguments are used to run
237263508Sdim/// a frontend action. One could install an additional command line
238263508Sdim/// arguments adjuster by calling the appendArgumentsAdjuster() method.
239234287Sdimclass ClangTool {
240234287Sdim public:
241234287Sdim  /// \brief Constructs a clang tool to run over a list of files.
242234287Sdim  ///
243234287Sdim  /// \param Compilations The CompilationDatabase which contains the compile
244234287Sdim  ///        command lines for the given source paths.
245234287Sdim  /// \param SourcePaths The source files to run over. If a source files is
246234287Sdim  ///        not found in Compilations, it is skipped.
247234287Sdim  ClangTool(const CompilationDatabase &Compilations,
248234287Sdim            ArrayRef<std::string> SourcePaths);
249234287Sdim
250263508Sdim  virtual ~ClangTool() { clearArgumentsAdjusters(); }
251249423Sdim
252263508Sdim  /// \brief Set a \c DiagnosticConsumer to use during parsing.
253263508Sdim  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
254263508Sdim
255234287Sdim  /// \brief Map a virtual file to be used while running the tool.
256234287Sdim  ///
257234287Sdim  /// \param FilePath The path at which the content will be mapped.
258234287Sdim  /// \param Content A null terminated buffer of the file's content.
259234287Sdim  void mapVirtualFile(StringRef FilePath, StringRef Content);
260234287Sdim
261239462Sdim  /// \brief Install command line arguments adjuster.
262239462Sdim  ///
263239462Sdim  /// \param Adjuster Command line arguments adjuster.
264263508Sdim  //
265263508Sdim  /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead.
266263508Sdim  /// Remove it once all callers are gone.
267239462Sdim  void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
268239462Sdim
269263508Sdim  /// \brief Append a command line arguments adjuster to the adjuster chain.
270234287Sdim  ///
271263508Sdim  /// \param Adjuster An argument adjuster, which will be run on the output of
272263508Sdim  ///        previous argument adjusters.
273263508Sdim  void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
274234287Sdim
275263508Sdim  /// \brief Clear the command line arguments adjuster chain.
276263508Sdim  void clearArgumentsAdjusters();
277263508Sdim
278263508Sdim  /// Runs an action over all files specified in the command line.
279263508Sdim  ///
280263508Sdim  /// \param Action Tool action.
281263508Sdim  int run(ToolAction *Action);
282263508Sdim
283263508Sdim  /// \brief Create an AST for each file specified in the command line and
284263508Sdim  /// append them to ASTs.
285263508Sdim  int buildASTs(std::vector<ASTUnit *> &ASTs);
286263508Sdim
287234287Sdim  /// \brief Returns the file manager used in the tool.
288234287Sdim  ///
289234287Sdim  /// The file manager is shared between all translation units.
290263508Sdim  FileManager &getFiles() { return *Files; }
291234287Sdim
292234287Sdim private:
293239462Sdim  // We store compile commands as pair (file name, compile command).
294239462Sdim  std::vector< std::pair<std::string, CompileCommand> > CompileCommands;
295234287Sdim
296263508Sdim  llvm::IntrusiveRefCntPtr<FileManager> Files;
297234287Sdim  // Contains a list of pairs (<file name>, <file content>).
298234287Sdim  std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
299239462Sdim
300263508Sdim  SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters;
301263508Sdim
302263508Sdim  DiagnosticConsumer *DiagConsumer;
303234287Sdim};
304234287Sdim
305234287Sdimtemplate <typename T>
306234287SdimFrontendActionFactory *newFrontendActionFactory() {
307234287Sdim  class SimpleFrontendActionFactory : public FrontendActionFactory {
308234287Sdim  public:
309234287Sdim    virtual clang::FrontendAction *create() { return new T; }
310234287Sdim  };
311234287Sdim
312234287Sdim  return new SimpleFrontendActionFactory;
313234287Sdim}
314234287Sdim
315234287Sdimtemplate <typename FactoryT>
316239462Sdiminline FrontendActionFactory *newFrontendActionFactory(
317263508Sdim    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
318234287Sdim  class FrontendActionFactoryAdapter : public FrontendActionFactory {
319234287Sdim  public:
320243830Sdim    explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
321263508Sdim                                          SourceFileCallbacks *Callbacks)
322263508Sdim      : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
323234287Sdim
324234287Sdim    virtual clang::FrontendAction *create() {
325263508Sdim      return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
326234287Sdim    }
327234287Sdim
328234287Sdim  private:
329239462Sdim    class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
330239462Sdim    public:
331243830Sdim      ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
332263508Sdim                             SourceFileCallbacks *Callbacks)
333263508Sdim        : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
334239462Sdim
335239462Sdim      clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
336249423Sdim                                            StringRef) {
337239462Sdim        return ConsumerFactory->newASTConsumer();
338239462Sdim      }
339239462Sdim
340243830Sdim    protected:
341263508Sdim      virtual bool BeginSourceFileAction(CompilerInstance &CI,
342263508Sdim                                         StringRef Filename) LLVM_OVERRIDE {
343263508Sdim        if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
344263508Sdim          return false;
345263508Sdim        if (Callbacks != NULL)
346263508Sdim          return Callbacks->handleBeginSource(CI, Filename);
347263508Sdim        return true;
348263508Sdim      }
349263508Sdim      virtual void EndSourceFileAction() LLVM_OVERRIDE {
350263508Sdim        if (Callbacks != NULL)
351263508Sdim          Callbacks->handleEndSource();
352243830Sdim        clang::ASTFrontendAction::EndSourceFileAction();
353243830Sdim      }
354243830Sdim
355239462Sdim    private:
356239462Sdim      FactoryT *ConsumerFactory;
357263508Sdim      SourceFileCallbacks *Callbacks;
358239462Sdim    };
359239462Sdim    FactoryT *ConsumerFactory;
360263508Sdim    SourceFileCallbacks *Callbacks;
361234287Sdim  };
362234287Sdim
363263508Sdim  return new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks);
364234287Sdim}
365234287Sdim
366239462Sdim/// \brief Returns the absolute path of \c File, by prepending it with
367239462Sdim/// the current directory if \c File is not absolute.
368239462Sdim///
369239462Sdim/// Otherwise returns \c File.
370239462Sdim/// If 'File' starts with "./", the returned path will not contain the "./".
371239462Sdim/// Otherwise, the returned path will contain the literal path-concatenation of
372239462Sdim/// the current directory and \c File.
373239462Sdim///
374263508Sdim/// The difference to llvm::sys::fs::make_absolute is the canonicalization this
375263508Sdim/// does by removing "./" and computing native paths.
376239462Sdim///
377239462Sdim/// \param File Either an absolute or relative path.
378239462Sdimstd::string getAbsolutePath(StringRef File);
379239462Sdim
380234287Sdim} // end namespace tooling
381234287Sdim} // end namespace clang
382234287Sdim
383234287Sdim#endif // LLVM_CLANG_TOOLING_TOOLING_H
384