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