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 runSyntaxOnlyToolOnCode, 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 <string>
39#include <vector>
40
41namespace clang {
42
43namespace driver {
44class Compilation;
45} // end namespace driver
46
47class CompilerInvocation;
48class SourceManager;
49class FrontendAction;
50
51namespace tooling {
52
53class CompilationDatabase;
54
55/// \brief Interface to generate clang::FrontendActions.
56class FrontendActionFactory {
57public:
58  virtual ~FrontendActionFactory();
59
60  /// \brief Returns a new clang::FrontendAction.
61  ///
62  /// The caller takes ownership of the returned action.
63  virtual clang::FrontendAction *create() = 0;
64};
65
66/// \brief Returns a new FrontendActionFactory for a given type.
67///
68/// T must extend clang::FrontendAction.
69///
70/// Example:
71/// FrontendActionFactory *Factory =
72///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
73template <typename T>
74FrontendActionFactory *newFrontendActionFactory();
75
76/// \brief Returns a new FrontendActionFactory for any type that provides an
77/// implementation of newFrontendAction().
78///
79/// FactoryT must implement: FrontendAction *newFrontendAction().
80///
81/// Example:
82/// struct ProvidesFrontendActions {
83///   FrontendAction *newFrontendAction();
84/// } Factory;
85/// FrontendActionFactory *FactoryAdapter =
86///   newFrontendActionFactory(&Factory);
87template <typename FactoryT>
88FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory);
89
90/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
91///
92/// \param ToolAction The action to run over the code.
93/// \param Code C++ code.
94/// \param FileName The file name which 'Code' will be mapped as.
95///
96/// \return - True if 'ToolAction' was successfully executed.
97bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
98                   const Twine &FileName = "input.cc");
99
100/// \brief Utility to run a FrontendAction in a single clang invocation.
101class ToolInvocation {
102 public:
103  /// \brief Create a tool invocation.
104  ///
105  /// \param CommandLine The command line arguments to clang.
106  /// \param ToolAction The action to be executed. Class takes ownership.
107  /// \param Files The FileManager used for the execution. Class does not take
108  /// ownership.
109  ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,
110                 FileManager *Files);
111
112  /// \brief Map a virtual file to be used while running the tool.
113  ///
114  /// \param FilePath The path at which the content will be mapped.
115  /// \param Content A null terminated buffer of the file's content.
116  void mapVirtualFile(StringRef FilePath, StringRef Content);
117
118  /// \brief Run the clang invocation.
119  ///
120  /// \returns True if there were no errors during execution.
121  bool run();
122
123 private:
124  void addFileMappingsTo(SourceManager &SourceManager);
125
126  bool runInvocation(const char *BinaryName,
127                     clang::driver::Compilation *Compilation,
128                     clang::CompilerInvocation *Invocation,
129                     const clang::driver::ArgStringList &CC1Args,
130                     clang::FrontendAction *ToolAction);
131
132  std::vector<std::string> CommandLine;
133  llvm::OwningPtr<FrontendAction> ToolAction;
134  FileManager *Files;
135  // Maps <file name> -> <file content>.
136  llvm::StringMap<StringRef> MappedFileContents;
137};
138
139/// \brief Utility to run a FrontendAction over a set of files.
140///
141/// This class is written to be usable for command line utilities.
142class ClangTool {
143 public:
144  /// \brief Constructs a clang tool to run over a list of files.
145  ///
146  /// \param Compilations The CompilationDatabase which contains the compile
147  ///        command lines for the given source paths.
148  /// \param SourcePaths The source files to run over. If a source files is
149  ///        not found in Compilations, it is skipped.
150  ClangTool(const CompilationDatabase &Compilations,
151            ArrayRef<std::string> SourcePaths);
152
153  /// \brief Map a virtual file to be used while running the tool.
154  ///
155  /// \param FilePath The path at which the content will be mapped.
156  /// \param Content A null terminated buffer of the file's content.
157  void mapVirtualFile(StringRef FilePath, StringRef Content);
158
159  /// Runs a frontend action over all files specified in the command line.
160  ///
161  /// \param ActionFactory Factory generating the frontend actions. The function
162  /// takes ownership of this parameter. A new action is generated for every
163  /// processed translation unit.
164  int run(FrontendActionFactory *ActionFactory);
165
166  /// \brief Returns the file manager used in the tool.
167  ///
168  /// The file manager is shared between all translation units.
169  FileManager &getFiles() { return Files; }
170
171 private:
172  // We store command lines as pair (file name, command line).
173  typedef std::pair< std::string, std::vector<std::string> > CommandLine;
174  std::vector<CommandLine> CommandLines;
175
176  FileManager Files;
177  // Contains a list of pairs (<file name>, <file content>).
178  std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
179};
180
181template <typename T>
182FrontendActionFactory *newFrontendActionFactory() {
183  class SimpleFrontendActionFactory : public FrontendActionFactory {
184  public:
185    virtual clang::FrontendAction *create() { return new T; }
186  };
187
188  return new SimpleFrontendActionFactory;
189}
190
191template <typename FactoryT>
192FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory) {
193  class FrontendActionFactoryAdapter : public FrontendActionFactory {
194  public:
195    explicit FrontendActionFactoryAdapter(FactoryT *ActionFactory)
196      : ActionFactory(ActionFactory) {}
197
198    virtual clang::FrontendAction *create() {
199      return ActionFactory->newFrontendAction();
200    }
201
202  private:
203    FactoryT *ActionFactory;
204  };
205
206  return new FrontendActionFactoryAdapter(ActionFactory);
207}
208
209} // end namespace tooling
210} // end namespace clang
211
212#endif // LLVM_CLANG_TOOLING_TOOLING_H
213
214