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 "llvm/ADT/StringMap.h"
34#include "llvm/ADT/Twine.h"
35#include "clang/Basic/FileManager.h"
36#include "clang/Basic/LLVM.h"
37#include "clang/Driver/Util.h"
38#include "clang/Frontend/FrontendAction.h"
39#include "clang/Tooling/ArgumentsAdjusters.h"
40#include "clang/Tooling/CompilationDatabase.h"
41#include <string>
42#include <vector>
43
44namespace clang {
45
46namespace driver {
47class Compilation;
48} // end namespace driver
49
50class CompilerInvocation;
51class SourceManager;
52class FrontendAction;
53
54namespace tooling {
55
56/// \brief Interface to generate clang::FrontendActions.
57class FrontendActionFactory {
58public:
59  virtual ~FrontendActionFactory();
60
61  /// \brief Returns a new clang::FrontendAction.
62  ///
63  /// The caller takes ownership of the returned action.
64  virtual clang::FrontendAction *create() = 0;
65};
66
67/// \brief Returns a new FrontendActionFactory for a given type.
68///
69/// T must extend clang::FrontendAction.
70///
71/// Example:
72/// FrontendActionFactory *Factory =
73///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
74template <typename T>
75FrontendActionFactory *newFrontendActionFactory();
76
77/// \brief Returns a new FrontendActionFactory for any type that provides an
78/// implementation of newASTConsumer().
79///
80/// FactoryT must implement: ASTConsumer *newASTConsumer().
81///
82/// Example:
83/// struct ProvidesASTConsumers {
84///   clang::ASTConsumer *newASTConsumer();
85/// } Factory;
86/// FrontendActionFactory *FactoryAdapter =
87///   newFrontendActionFactory(&Factory);
88template <typename FactoryT>
89inline FrontendActionFactory *newFrontendActionFactory(
90    FactoryT *ConsumerFactory);
91
92/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
93///
94/// \param ToolAction The action to run over the code.
95/// \param Code C++ code.
96/// \param FileName The file name which 'Code' will be mapped as.
97///
98/// \return - True if 'ToolAction' was successfully executed.
99bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
100                   const Twine &FileName = "input.cc");
101
102/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
103///        with additional other flags.
104///
105/// \param ToolAction The action to run over the code.
106/// \param Code C++ code.
107/// \param Args Additional flags to pass on.
108/// \param FileName The file name which 'Code' will be mapped as.
109///
110/// \return - True if 'ToolAction' was successfully executed.
111bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
112                           const std::vector<std::string> &Args,
113                           const Twine &FileName = "input.cc");
114
115/// \brief Utility to run a FrontendAction in a single clang invocation.
116class ToolInvocation {
117 public:
118  /// \brief Create a tool invocation.
119  ///
120  /// \param CommandLine The command line arguments to clang. Note that clang
121  /// uses its binary name (CommandLine[0]) to locate its builtin headers.
122  /// Callers have to ensure that they are installed in a compatible location
123  /// (see clang driver implementation) or mapped in via mapVirtualFile.
124  /// \param ToolAction The action to be executed. Class takes ownership.
125  /// \param Files The FileManager used for the execution. Class does not take
126  /// ownership.
127  ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,
128                 FileManager *Files);
129
130  /// \brief Map a virtual file to be used while running the tool.
131  ///
132  /// \param FilePath The path at which the content will be mapped.
133  /// \param Content A null terminated buffer of the file's content.
134  void mapVirtualFile(StringRef FilePath, StringRef Content);
135
136  /// \brief Run the clang invocation.
137  ///
138  /// \returns True if there were no errors during execution.
139  bool run();
140
141 private:
142  void addFileMappingsTo(SourceManager &SourceManager);
143
144  bool runInvocation(const char *BinaryName,
145                     clang::driver::Compilation *Compilation,
146                     clang::CompilerInvocation *Invocation,
147                     const clang::driver::ArgStringList &CC1Args);
148
149  std::vector<std::string> CommandLine;
150  llvm::OwningPtr<FrontendAction> ToolAction;
151  FileManager *Files;
152  // Maps <file name> -> <file content>.
153  llvm::StringMap<StringRef> MappedFileContents;
154};
155
156/// \brief Utility to run a FrontendAction over a set of files.
157///
158/// This class is written to be usable for command line utilities.
159/// By default the class uses ClangSyntaxOnlyAdjuster to modify
160/// command line arguments before the arguments are used to run
161/// a frontend action. One could install another command line
162/// arguments adjuster by call setArgumentsAdjuster() method.
163class ClangTool {
164 public:
165  /// \brief Constructs a clang tool to run over a list of files.
166  ///
167  /// \param Compilations The CompilationDatabase which contains the compile
168  ///        command lines for the given source paths.
169  /// \param SourcePaths The source files to run over. If a source files is
170  ///        not found in Compilations, it is skipped.
171  ClangTool(const CompilationDatabase &Compilations,
172            ArrayRef<std::string> SourcePaths);
173
174  /// \brief Map a virtual file to be used while running the tool.
175  ///
176  /// \param FilePath The path at which the content will be mapped.
177  /// \param Content A null terminated buffer of the file's content.
178  void mapVirtualFile(StringRef FilePath, StringRef Content);
179
180  /// \brief Install command line arguments adjuster.
181  ///
182  /// \param Adjuster Command line arguments adjuster.
183  void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
184
185  /// Runs a frontend action over all files specified in the command line.
186  ///
187  /// \param ActionFactory Factory generating the frontend actions. The function
188  /// takes ownership of this parameter. A new action is generated for every
189  /// processed translation unit.
190  int run(FrontendActionFactory *ActionFactory);
191
192  /// \brief Returns the file manager used in the tool.
193  ///
194  /// The file manager is shared between all translation units.
195  FileManager &getFiles() { return Files; }
196
197 private:
198  // We store compile commands as pair (file name, compile command).
199  std::vector< std::pair<std::string, CompileCommand> > CompileCommands;
200
201  FileManager Files;
202  // Contains a list of pairs (<file name>, <file content>).
203  std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
204
205  llvm::OwningPtr<ArgumentsAdjuster> ArgsAdjuster;
206};
207
208template <typename T>
209FrontendActionFactory *newFrontendActionFactory() {
210  class SimpleFrontendActionFactory : public FrontendActionFactory {
211  public:
212    virtual clang::FrontendAction *create() { return new T; }
213  };
214
215  return new SimpleFrontendActionFactory;
216}
217
218template <typename FactoryT>
219inline FrontendActionFactory *newFrontendActionFactory(
220    FactoryT *ConsumerFactory) {
221  class FrontendActionFactoryAdapter : public FrontendActionFactory {
222  public:
223    explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory)
224      : ConsumerFactory(ConsumerFactory) {}
225
226    virtual clang::FrontendAction *create() {
227      return new ConsumerFactoryAdaptor(ConsumerFactory);
228    }
229
230  private:
231    class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
232    public:
233      ConsumerFactoryAdaptor(FactoryT *ConsumerFactory)
234        : ConsumerFactory(ConsumerFactory) {}
235
236      clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
237                                            llvm::StringRef) {
238        return ConsumerFactory->newASTConsumer();
239      }
240
241    private:
242      FactoryT *ConsumerFactory;
243    };
244    FactoryT *ConsumerFactory;
245  };
246
247  return new FrontendActionFactoryAdapter(ConsumerFactory);
248}
249
250/// \brief Returns the absolute path of \c File, by prepending it with
251/// the current directory if \c File is not absolute.
252///
253/// Otherwise returns \c File.
254/// If 'File' starts with "./", the returned path will not contain the "./".
255/// Otherwise, the returned path will contain the literal path-concatenation of
256/// the current directory and \c File.
257///
258/// The difference to llvm::sys::fs::make_absolute is that we prefer
259/// ::getenv("PWD") if available.
260/// FIXME: Make this functionality available from llvm::sys::fs and delete
261///        this function.
262///
263/// \param File Either an absolute or relative path.
264std::string getAbsolutePath(StringRef File);
265
266} // end namespace tooling
267} // end namespace clang
268
269#endif // LLVM_CLANG_TOOLING_TOOLING_H
270