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
33234287Sdim#include "clang/Basic/FileManager.h"
34234287Sdim#include "clang/Basic/LLVM.h"
35234287Sdim#include "clang/Driver/Util.h"
36239462Sdim#include "clang/Frontend/FrontendAction.h"
37239462Sdim#include "clang/Tooling/ArgumentsAdjusters.h"
38239462Sdim#include "clang/Tooling/CompilationDatabase.h"
39249423Sdim#include "llvm/ADT/StringMap.h"
40249423Sdim#include "llvm/ADT/Twine.h"
41234287Sdim#include <string>
42234287Sdim#include <vector>
43234287Sdim
44234287Sdimnamespace clang {
45234287Sdim
46234287Sdimnamespace driver {
47234287Sdimclass Compilation;
48234287Sdim} // end namespace driver
49234287Sdim
50234287Sdimclass CompilerInvocation;
51234287Sdimclass SourceManager;
52234287Sdimclass FrontendAction;
53234287Sdim
54234287Sdimnamespace tooling {
55234287Sdim
56234287Sdim/// \brief Interface to generate clang::FrontendActions.
57234287Sdimclass FrontendActionFactory {
58234287Sdimpublic:
59234287Sdim  virtual ~FrontendActionFactory();
60234287Sdim
61234287Sdim  /// \brief Returns a new clang::FrontendAction.
62234287Sdim  ///
63234287Sdim  /// The caller takes ownership of the returned action.
64234287Sdim  virtual clang::FrontendAction *create() = 0;
65234287Sdim};
66234287Sdim
67234287Sdim/// \brief Returns a new FrontendActionFactory for a given type.
68234287Sdim///
69234287Sdim/// T must extend clang::FrontendAction.
70234287Sdim///
71234287Sdim/// Example:
72234287Sdim/// FrontendActionFactory *Factory =
73234287Sdim///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
74234287Sdimtemplate <typename T>
75234287SdimFrontendActionFactory *newFrontendActionFactory();
76234287Sdim
77243830Sdim/// \brief Called at the end of each source file when used with
78243830Sdim/// \c newFrontendActionFactory.
79243830Sdimclass EndOfSourceFileCallback {
80243830Sdimpublic:
81243830Sdim  virtual ~EndOfSourceFileCallback() {}
82243830Sdim  virtual void run() = 0;
83243830Sdim};
84243830Sdim
85234287Sdim/// \brief Returns a new FrontendActionFactory for any type that provides an
86239462Sdim/// implementation of newASTConsumer().
87234287Sdim///
88239462Sdim/// FactoryT must implement: ASTConsumer *newASTConsumer().
89234287Sdim///
90234287Sdim/// Example:
91239462Sdim/// struct ProvidesASTConsumers {
92239462Sdim///   clang::ASTConsumer *newASTConsumer();
93234287Sdim/// } Factory;
94234287Sdim/// FrontendActionFactory *FactoryAdapter =
95234287Sdim///   newFrontendActionFactory(&Factory);
96234287Sdimtemplate <typename FactoryT>
97239462Sdiminline FrontendActionFactory *newFrontendActionFactory(
98243830Sdim    FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback = NULL);
99234287Sdim
100234287Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
101234287Sdim///
102234287Sdim/// \param ToolAction The action to run over the code.
103234287Sdim/// \param Code C++ code.
104234287Sdim/// \param FileName The file name which 'Code' will be mapped as.
105234287Sdim///
106234287Sdim/// \return - True if 'ToolAction' was successfully executed.
107234287Sdimbool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
108234287Sdim                   const Twine &FileName = "input.cc");
109234287Sdim
110243830Sdim/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
111243830Sdim///        with additional other flags.
112243830Sdim///
113243830Sdim/// \param ToolAction The action to run over the code.
114243830Sdim/// \param Code C++ code.
115243830Sdim/// \param Args Additional flags to pass on.
116243830Sdim/// \param FileName The file name which 'Code' will be mapped as.
117243830Sdim///
118243830Sdim/// \return - True if 'ToolAction' was successfully executed.
119243830Sdimbool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
120243830Sdim                           const std::vector<std::string> &Args,
121243830Sdim                           const Twine &FileName = "input.cc");
122243830Sdim
123234287Sdim/// \brief Utility to run a FrontendAction in a single clang invocation.
124234287Sdimclass ToolInvocation {
125234287Sdim public:
126234287Sdim  /// \brief Create a tool invocation.
127234287Sdim  ///
128239462Sdim  /// \param CommandLine The command line arguments to clang. Note that clang
129239462Sdim  /// uses its binary name (CommandLine[0]) to locate its builtin headers.
130239462Sdim  /// Callers have to ensure that they are installed in a compatible location
131239462Sdim  /// (see clang driver implementation) or mapped in via mapVirtualFile.
132234287Sdim  /// \param ToolAction The action to be executed. Class takes ownership.
133234287Sdim  /// \param Files The FileManager used for the execution. Class does not take
134234287Sdim  /// ownership.
135234287Sdim  ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,
136234287Sdim                 FileManager *Files);
137234287Sdim
138234287Sdim  /// \brief Map a virtual file to be used while running the tool.
139234287Sdim  ///
140234287Sdim  /// \param FilePath The path at which the content will be mapped.
141234287Sdim  /// \param Content A null terminated buffer of the file's content.
142234287Sdim  void mapVirtualFile(StringRef FilePath, StringRef Content);
143234287Sdim
144234287Sdim  /// \brief Run the clang invocation.
145234287Sdim  ///
146234287Sdim  /// \returns True if there were no errors during execution.
147234287Sdim  bool run();
148234287Sdim
149234287Sdim private:
150234287Sdim  void addFileMappingsTo(SourceManager &SourceManager);
151234287Sdim
152234287Sdim  bool runInvocation(const char *BinaryName,
153234287Sdim                     clang::driver::Compilation *Compilation,
154249423Sdim                     clang::CompilerInvocation *Invocation);
155234287Sdim
156234287Sdim  std::vector<std::string> CommandLine;
157249423Sdim  OwningPtr<FrontendAction> ToolAction;
158234287Sdim  FileManager *Files;
159234287Sdim  // Maps <file name> -> <file content>.
160234287Sdim  llvm::StringMap<StringRef> MappedFileContents;
161234287Sdim};
162234287Sdim
163234287Sdim/// \brief Utility to run a FrontendAction over a set of files.
164234287Sdim///
165234287Sdim/// This class is written to be usable for command line utilities.
166239462Sdim/// By default the class uses ClangSyntaxOnlyAdjuster to modify
167239462Sdim/// command line arguments before the arguments are used to run
168239462Sdim/// a frontend action. One could install another command line
169239462Sdim/// arguments adjuster by call setArgumentsAdjuster() method.
170234287Sdimclass ClangTool {
171234287Sdim public:
172234287Sdim  /// \brief Constructs a clang tool to run over a list of files.
173234287Sdim  ///
174234287Sdim  /// \param Compilations The CompilationDatabase which contains the compile
175234287Sdim  ///        command lines for the given source paths.
176234287Sdim  /// \param SourcePaths The source files to run over. If a source files is
177234287Sdim  ///        not found in Compilations, it is skipped.
178234287Sdim  ClangTool(const CompilationDatabase &Compilations,
179234287Sdim            ArrayRef<std::string> SourcePaths);
180234287Sdim
181249423Sdim  virtual ~ClangTool() {}
182249423Sdim
183234287Sdim  /// \brief Map a virtual file to be used while running the tool.
184234287Sdim  ///
185234287Sdim  /// \param FilePath The path at which the content will be mapped.
186234287Sdim  /// \param Content A null terminated buffer of the file's content.
187234287Sdim  void mapVirtualFile(StringRef FilePath, StringRef Content);
188234287Sdim
189239462Sdim  /// \brief Install command line arguments adjuster.
190239462Sdim  ///
191239462Sdim  /// \param Adjuster Command line arguments adjuster.
192239462Sdim  void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
193239462Sdim
194234287Sdim  /// Runs a frontend action over all files specified in the command line.
195234287Sdim  ///
196234287Sdim  /// \param ActionFactory Factory generating the frontend actions. The function
197234287Sdim  /// takes ownership of this parameter. A new action is generated for every
198234287Sdim  /// processed translation unit.
199249423Sdim  virtual int run(FrontendActionFactory *ActionFactory);
200234287Sdim
201234287Sdim  /// \brief Returns the file manager used in the tool.
202234287Sdim  ///
203234287Sdim  /// The file manager is shared between all translation units.
204234287Sdim  FileManager &getFiles() { return Files; }
205234287Sdim
206234287Sdim private:
207239462Sdim  // We store compile commands as pair (file name, compile command).
208239462Sdim  std::vector< std::pair<std::string, CompileCommand> > CompileCommands;
209234287Sdim
210234287Sdim  FileManager Files;
211234287Sdim  // Contains a list of pairs (<file name>, <file content>).
212234287Sdim  std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
213239462Sdim
214249423Sdim  OwningPtr<ArgumentsAdjuster> ArgsAdjuster;
215234287Sdim};
216234287Sdim
217234287Sdimtemplate <typename T>
218234287SdimFrontendActionFactory *newFrontendActionFactory() {
219234287Sdim  class SimpleFrontendActionFactory : public FrontendActionFactory {
220234287Sdim  public:
221234287Sdim    virtual clang::FrontendAction *create() { return new T; }
222234287Sdim  };
223234287Sdim
224234287Sdim  return new SimpleFrontendActionFactory;
225234287Sdim}
226234287Sdim
227234287Sdimtemplate <typename FactoryT>
228239462Sdiminline FrontendActionFactory *newFrontendActionFactory(
229243830Sdim    FactoryT *ConsumerFactory, EndOfSourceFileCallback *EndCallback) {
230234287Sdim  class FrontendActionFactoryAdapter : public FrontendActionFactory {
231234287Sdim  public:
232243830Sdim    explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
233243830Sdim                                          EndOfSourceFileCallback *EndCallback)
234243830Sdim      : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {}
235234287Sdim
236234287Sdim    virtual clang::FrontendAction *create() {
237243830Sdim      return new ConsumerFactoryAdaptor(ConsumerFactory, EndCallback);
238234287Sdim    }
239234287Sdim
240234287Sdim  private:
241239462Sdim    class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
242239462Sdim    public:
243243830Sdim      ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
244243830Sdim                             EndOfSourceFileCallback *EndCallback)
245243830Sdim        : ConsumerFactory(ConsumerFactory), EndCallback(EndCallback) {}
246239462Sdim
247239462Sdim      clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
248249423Sdim                                            StringRef) {
249239462Sdim        return ConsumerFactory->newASTConsumer();
250239462Sdim      }
251239462Sdim
252243830Sdim    protected:
253243830Sdim      virtual void EndSourceFileAction() {
254243830Sdim        if (EndCallback != NULL)
255243830Sdim          EndCallback->run();
256243830Sdim        clang::ASTFrontendAction::EndSourceFileAction();
257243830Sdim      }
258243830Sdim
259239462Sdim    private:
260239462Sdim      FactoryT *ConsumerFactory;
261243830Sdim      EndOfSourceFileCallback *EndCallback;
262239462Sdim    };
263239462Sdim    FactoryT *ConsumerFactory;
264243830Sdim    EndOfSourceFileCallback *EndCallback;
265234287Sdim  };
266234287Sdim
267243830Sdim  return new FrontendActionFactoryAdapter(ConsumerFactory, EndCallback);
268234287Sdim}
269234287Sdim
270239462Sdim/// \brief Returns the absolute path of \c File, by prepending it with
271239462Sdim/// the current directory if \c File is not absolute.
272239462Sdim///
273239462Sdim/// Otherwise returns \c File.
274239462Sdim/// If 'File' starts with "./", the returned path will not contain the "./".
275239462Sdim/// Otherwise, the returned path will contain the literal path-concatenation of
276239462Sdim/// the current directory and \c File.
277239462Sdim///
278239462Sdim/// The difference to llvm::sys::fs::make_absolute is that we prefer
279239462Sdim/// ::getenv("PWD") if available.
280239462Sdim/// FIXME: Make this functionality available from llvm::sys::fs and delete
281239462Sdim///        this function.
282239462Sdim///
283239462Sdim/// \param File Either an absolute or relative path.
284239462Sdimstd::string getAbsolutePath(StringRef File);
285239462Sdim
286234287Sdim} // end namespace tooling
287234287Sdim} // end namespace clang
288234287Sdim
289234287Sdim#endif // LLVM_CLANG_TOOLING_TOOLING_H
290