Changed FrontendActionFactory::create to return a std::unique_ptr
[lldb.git] / clang / include / clang / Tooling / Tooling.h
1 //===- Tooling.h - Framework for standalone Clang tools ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file implements functions to run clang tools standalone instead
10 //  of running them as a plugin.
11 //
12 //  A ClangTool is initialized with a CompilationDatabase and a set of files
13 //  to run over. The tool will then run a user-specified FrontendAction over
14 //  all TUs in which the given files are compiled.
15 //
16 //  It is also possible to run a FrontendAction over a snippet of code by
17 //  calling runToolOnCode, which is useful for unit testing.
18 //
19 //  Applications that need more fine grained control over how to run
20 //  multiple FrontendActions over code can use ToolInvocation.
21 //
22 //  Example tools:
23 //  - running clang -fsyntax-only over source code from an editor to get
24 //    fast syntax checks
25 //  - running match/replace tools over C++ code
26 //
27 //===----------------------------------------------------------------------===//
28
29 #ifndef LLVM_CLANG_TOOLING_TOOLING_H
30 #define LLVM_CLANG_TOOLING_TOOLING_H
31
32 #include "clang/AST/ASTConsumer.h"
33 #include "clang/Basic/FileManager.h"
34 #include "clang/Basic/LLVM.h"
35 #include "clang/Frontend/FrontendAction.h"
36 #include "clang/Frontend/PCHContainerOperations.h"
37 #include "clang/Tooling/ArgumentsAdjusters.h"
38 #include "llvm/ADT/ArrayRef.h"
39 #include "llvm/ADT/IntrusiveRefCntPtr.h"
40 #include "llvm/ADT/StringMap.h"
41 #include "llvm/ADT/StringRef.h"
42 #include "llvm/ADT/StringSet.h"
43 #include "llvm/ADT/Twine.h"
44 #include "llvm/Option/Option.h"
45 #include "llvm/Support/VirtualFileSystem.h"
46 #include <memory>
47 #include <string>
48 #include <utility>
49 #include <vector>
50
51 namespace clang {
52
53 class CompilerInstance;
54 class CompilerInvocation;
55 class DiagnosticConsumer;
56 class DiagnosticsEngine;
57 class SourceManager;
58
59 namespace driver {
60
61 class Compilation;
62
63 } // namespace driver
64
65 namespace tooling {
66
67 class CompilationDatabase;
68
69 /// Interface to process a clang::CompilerInvocation.
70 ///
71 /// If your tool is based on FrontendAction, you should be deriving from
72 /// FrontendActionFactory instead.
73 class ToolAction {
74 public:
75   virtual ~ToolAction();
76
77   /// Perform an action for an invocation.
78   virtual bool
79   runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
80                 FileManager *Files,
81                 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
82                 DiagnosticConsumer *DiagConsumer) = 0;
83 };
84
85 /// Interface to generate clang::FrontendActions.
86 ///
87 /// Having a factory interface allows, for example, a new FrontendAction to be
88 /// created for each translation unit processed by ClangTool.  This class is
89 /// also a ToolAction which uses the FrontendActions created by create() to
90 /// process each translation unit.
91 class FrontendActionFactory : public ToolAction {
92 public:
93   ~FrontendActionFactory() override;
94
95   /// Invokes the compiler with a FrontendAction created by create().
96   bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
97                      FileManager *Files,
98                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
99                      DiagnosticConsumer *DiagConsumer) override;
100
101   /// Returns a new clang::FrontendAction.
102   virtual std::unique_ptr<FrontendAction> create() = 0;
103 };
104
105 /// Returns a new FrontendActionFactory for a given type.
106 ///
107 /// T must derive from clang::FrontendAction.
108 ///
109 /// Example:
110 /// FrontendActionFactory *Factory =
111 ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
112 template <typename T>
113 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
114
115 /// Callbacks called before and after each source file processed by a
116 /// FrontendAction created by the FrontedActionFactory returned by \c
117 /// newFrontendActionFactory.
118 class SourceFileCallbacks {
119 public:
120   virtual ~SourceFileCallbacks() = default;
121
122   /// Called before a source file is processed by a FrontEndAction.
123   /// \see clang::FrontendAction::BeginSourceFileAction
124   virtual bool handleBeginSource(CompilerInstance &CI) {
125     return true;
126   }
127
128   /// Called after a source file is processed by a FrontendAction.
129   /// \see clang::FrontendAction::EndSourceFileAction
130   virtual void handleEndSource() {}
131 };
132
133 /// Returns a new FrontendActionFactory for any type that provides an
134 /// implementation of newASTConsumer().
135 ///
136 /// FactoryT must implement: ASTConsumer *newASTConsumer().
137 ///
138 /// Example:
139 /// struct ProvidesASTConsumers {
140 ///   clang::ASTConsumer *newASTConsumer();
141 /// } Factory;
142 /// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
143 ///   newFrontendActionFactory(&Factory));
144 template <typename FactoryT>
145 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
146     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
147
148 /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
149 ///
150 /// \param ToolAction The action to run over the code.
151 /// \param Code C++ code.
152 /// \param FileName The file name which 'Code' will be mapped as.
153 /// \param PCHContainerOps  The PCHContainerOperations for loading and creating
154 ///                         clang modules.
155 ///
156 /// \return - True if 'ToolAction' was successfully executed.
157 bool runToolOnCode(FrontendAction *ToolAction, const Twine &Code,
158                    const Twine &FileName = "input.cc",
159                    std::shared_ptr<PCHContainerOperations> PCHContainerOps =
160                        std::make_shared<PCHContainerOperations>());
161
162 inline bool
163 runToolOnCode(std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
164               const Twine &FileName = "input.cc",
165               std::shared_ptr<PCHContainerOperations> PCHContainerOps =
166                   std::make_shared<PCHContainerOperations>()) {
167   return runToolOnCode(ToolAction.release(), Code, FileName, PCHContainerOps);
168 }
169
170 /// The first part of the pair is the filename, the second part the
171 /// file-content.
172 using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
173
174 /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
175 ///        with additional other flags.
176 ///
177 /// \param ToolAction The action to run over the code.
178 /// \param Code C++ code.
179 /// \param Args Additional flags to pass on.
180 /// \param FileName The file name which 'Code' will be mapped as.
181 /// \param ToolName The name of the binary running the tool. Standard library
182 ///                 header paths will be resolved relative to this.
183 /// \param PCHContainerOps   The PCHContainerOperations for loading and creating
184 ///                          clang modules.
185 ///
186 /// \return - True if 'ToolAction' was successfully executed.
187 bool runToolOnCodeWithArgs(
188     FrontendAction *ToolAction, const Twine &Code,
189     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
190     const Twine &ToolName = "clang-tool",
191     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
192         std::make_shared<PCHContainerOperations>(),
193     const FileContentMappings &VirtualMappedFiles = FileContentMappings());
194
195 inline bool runToolOnCodeWithArgs(
196     std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
197     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
198     const Twine &ToolName = "clang-tool",
199     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
200         std::make_shared<PCHContainerOperations>(),
201     const FileContentMappings &VirtualMappedFiles = FileContentMappings()) {
202   return runToolOnCodeWithArgs(ToolAction.release(), Code, Args, FileName,
203                                ToolName, PCHContainerOps, VirtualMappedFiles);
204 }
205
206 // Similar to the overload except this takes a VFS.
207 bool runToolOnCodeWithArgs(
208     FrontendAction *ToolAction, const Twine &Code,
209     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
210     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
211     const Twine &ToolName = "clang-tool",
212     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
213         std::make_shared<PCHContainerOperations>());
214
215 inline bool runToolOnCodeWithArgs(
216     std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
217     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
218     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
219     const Twine &ToolName = "clang-tool",
220     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
221         std::make_shared<PCHContainerOperations>()) {
222   return runToolOnCodeWithArgs(ToolAction.release(), Code, VFS, Args, FileName,
223                                ToolName, PCHContainerOps);
224 }
225
226 /// Builds an AST for 'Code'.
227 ///
228 /// \param Code C++ code.
229 /// \param FileName The file name which 'Code' will be mapped as.
230 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
231 /// clang modules.
232 ///
233 /// \return The resulting AST or null if an error occurred.
234 std::unique_ptr<ASTUnit>
235 buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
236                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
237                      std::make_shared<PCHContainerOperations>());
238
239 /// Builds an AST for 'Code' with additional flags.
240 ///
241 /// \param Code C++ code.
242 /// \param Args Additional flags to pass on.
243 /// \param FileName The file name which 'Code' will be mapped as.
244 /// \param ToolName The name of the binary running the tool. Standard library
245 ///                 header paths will be resolved relative to this.
246 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
247 /// clang modules.
248 ///
249 /// \param Adjuster A function to filter the command line arguments as specified.
250 ///
251 /// \return The resulting AST or null if an error occurred.
252 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
253     StringRef Code, const std::vector<std::string> &Args,
254     StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
255     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
256         std::make_shared<PCHContainerOperations>(),
257     ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
258
259 /// Utility to run a FrontendAction in a single clang invocation.
260 class ToolInvocation {
261 public:
262   /// Create a tool invocation.
263   ///
264   /// \param CommandLine The command line arguments to clang. Note that clang
265   /// uses its binary name (CommandLine[0]) to locate its builtin headers.
266   /// Callers have to ensure that they are installed in a compatible location
267   /// (see clang driver implementation) or mapped in via mapVirtualFile.
268   /// \param FAction The action to be executed. Class takes ownership.
269   /// \param Files The FileManager used for the execution. Class does not take
270   /// ownership.
271   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
272   /// clang modules.
273   ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
274                  FileManager *Files,
275                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
276                      std::make_shared<PCHContainerOperations>());
277
278   ToolInvocation(std::vector<std::string> CommandLine,
279                  std::unique_ptr<FrontendAction> FAction, FileManager *Files,
280                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
281                      std::make_shared<PCHContainerOperations>())
282       : ToolInvocation(std::move(CommandLine), FAction.release(), Files,
283                        PCHContainerOps) {}
284
285   /// Create a tool invocation.
286   ///
287   /// \param CommandLine The command line arguments to clang.
288   /// \param Action The action to be executed.
289   /// \param Files The FileManager used for the execution.
290   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
291   /// clang modules.
292   ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
293                  FileManager *Files,
294                  std::shared_ptr<PCHContainerOperations> PCHContainerOps);
295
296   ~ToolInvocation();
297
298   /// Set a \c DiagnosticConsumer to use during parsing.
299   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
300     this->DiagConsumer = DiagConsumer;
301   }
302
303   /// Map a virtual file to be used while running the tool.
304   ///
305   /// \param FilePath The path at which the content will be mapped.
306   /// \param Content A null terminated buffer of the file's content.
307   // FIXME: remove this when all users have migrated!
308   void mapVirtualFile(StringRef FilePath, StringRef Content);
309
310   /// Run the clang invocation.
311   ///
312   /// \returns True if there were no errors during execution.
313   bool run();
314
315  private:
316   void addFileMappingsTo(SourceManager &SourceManager);
317
318   bool runInvocation(const char *BinaryName,
319                      driver::Compilation *Compilation,
320                      std::shared_ptr<CompilerInvocation> Invocation,
321                      std::shared_ptr<PCHContainerOperations> PCHContainerOps);
322
323   std::vector<std::string> CommandLine;
324   ToolAction *Action;
325   bool OwnsAction;
326   FileManager *Files;
327   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
328   // Maps <file name> -> <file content>.
329   llvm::StringMap<StringRef> MappedFileContents;
330   DiagnosticConsumer *DiagConsumer = nullptr;
331 };
332
333 /// Utility to run a FrontendAction over a set of files.
334 ///
335 /// This class is written to be usable for command line utilities.
336 /// By default the class uses ClangSyntaxOnlyAdjuster to modify
337 /// command line arguments before the arguments are used to run
338 /// a frontend action. One could install an additional command line
339 /// arguments adjuster by calling the appendArgumentsAdjuster() method.
340 class ClangTool {
341 public:
342   /// Constructs a clang tool to run over a list of files.
343   ///
344   /// \param Compilations The CompilationDatabase which contains the compile
345   ///        command lines for the given source paths.
346   /// \param SourcePaths The source files to run over. If a source files is
347   ///        not found in Compilations, it is skipped.
348   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
349   /// clang modules.
350   /// \param BaseFS VFS used for all underlying file accesses when running the
351   /// tool.
352   ClangTool(const CompilationDatabase &Compilations,
353             ArrayRef<std::string> SourcePaths,
354             std::shared_ptr<PCHContainerOperations> PCHContainerOps =
355                 std::make_shared<PCHContainerOperations>(),
356             IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
357                 llvm::vfs::getRealFileSystem());
358
359   ~ClangTool();
360
361   /// Set a \c DiagnosticConsumer to use during parsing.
362   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
363     this->DiagConsumer = DiagConsumer;
364   }
365
366   /// Map a virtual file to be used while running the tool.
367   ///
368   /// \param FilePath The path at which the content will be mapped.
369   /// \param Content A null terminated buffer of the file's content.
370   void mapVirtualFile(StringRef FilePath, StringRef Content);
371
372   /// Append a command line arguments adjuster to the adjuster chain.
373   ///
374   /// \param Adjuster An argument adjuster, which will be run on the output of
375   ///        previous argument adjusters.
376   void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
377
378   /// Clear the command line arguments adjuster chain.
379   void clearArgumentsAdjusters();
380
381   /// Runs an action over all files specified in the command line.
382   ///
383   /// \param Action Tool action.
384   ///
385   /// \returns 0 on success; 1 if any error occurred; 2 if there is no error but
386   /// some files are skipped due to missing compile commands.
387   int run(ToolAction *Action);
388
389   /// Create an AST for each file specified in the command line and
390   /// append them to ASTs.
391   int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
392
393   /// Sets whether working directory should be restored after calling run(). By
394   /// default, working directory is restored. However, it could be useful to
395   /// turn this off when running on multiple threads to avoid the raciness.
396   void setRestoreWorkingDir(bool RestoreCWD);
397
398   /// Sets whether an error message should be printed out if an action fails. By
399   /// default, if an action fails, a message is printed out to stderr.
400   void setPrintErrorMessage(bool PrintErrorMessage);
401
402   /// Returns the file manager used in the tool.
403   ///
404   /// The file manager is shared between all translation units.
405   FileManager &getFiles() { return *Files; }
406
407   llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }
408
409 private:
410   const CompilationDatabase &Compilations;
411   std::vector<std::string> SourcePaths;
412   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
413
414   llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
415   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
416   llvm::IntrusiveRefCntPtr<FileManager> Files;
417
418   // Contains a list of pairs (<file name>, <file content>).
419   std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
420
421   llvm::StringSet<> SeenWorkingDirectories;
422
423   ArgumentsAdjuster ArgsAdjuster;
424
425   DiagnosticConsumer *DiagConsumer = nullptr;
426
427   bool RestoreCWD = true;
428   bool PrintErrorMessage = true;
429 };
430
431 template <typename T>
432 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
433   class SimpleFrontendActionFactory : public FrontendActionFactory {
434   public:
435     std::unique_ptr<FrontendAction> create() override {
436       return std::make_unique<T>();
437     }
438   };
439
440   return std::unique_ptr<FrontendActionFactory>(
441       new SimpleFrontendActionFactory);
442 }
443
444 template <typename FactoryT>
445 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
446     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
447   class FrontendActionFactoryAdapter : public FrontendActionFactory {
448   public:
449     explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
450                                           SourceFileCallbacks *Callbacks)
451         : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
452
453     std::unique_ptr<FrontendAction> create() override {
454       return std::make_unique<ConsumerFactoryAdaptor>(ConsumerFactory,
455                                                       Callbacks);
456     }
457
458   private:
459     class ConsumerFactoryAdaptor : public ASTFrontendAction {
460     public:
461       ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
462                              SourceFileCallbacks *Callbacks)
463           : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
464
465       std::unique_ptr<ASTConsumer>
466       CreateASTConsumer(CompilerInstance &, StringRef) override {
467         return ConsumerFactory->newASTConsumer();
468       }
469
470     protected:
471       bool BeginSourceFileAction(CompilerInstance &CI) override {
472         if (!ASTFrontendAction::BeginSourceFileAction(CI))
473           return false;
474         if (Callbacks)
475           return Callbacks->handleBeginSource(CI);
476         return true;
477       }
478
479       void EndSourceFileAction() override {
480         if (Callbacks)
481           Callbacks->handleEndSource();
482         ASTFrontendAction::EndSourceFileAction();
483       }
484
485     private:
486       FactoryT *ConsumerFactory;
487       SourceFileCallbacks *Callbacks;
488     };
489     FactoryT *ConsumerFactory;
490     SourceFileCallbacks *Callbacks;
491   };
492
493   return std::unique_ptr<FrontendActionFactory>(
494       new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
495 }
496
497 /// Returns the absolute path of \c File, by prepending it with
498 /// the current directory if \c File is not absolute.
499 ///
500 /// Otherwise returns \c File.
501 /// If 'File' starts with "./", the returned path will not contain the "./".
502 /// Otherwise, the returned path will contain the literal path-concatenation of
503 /// the current directory and \c File.
504 ///
505 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
506 /// does by removing "./" and computing native paths.
507 ///
508 /// \param File Either an absolute or relative path.
509 std::string getAbsolutePath(StringRef File);
510
511 /// An overload of getAbsolutePath that works over the provided \p FS.
512 llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
513                                             StringRef File);
514
515 /// Changes CommandLine to contain implicit flags that would have been
516 /// defined had the compiler driver been invoked through the path InvokedAs.
517 ///
518 /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
519 /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
520 /// be inserted after the first argument in \c CommandLine.
521 ///
522 /// This function will not add new `-target` or `--driver-mode` flags if they
523 /// are already present in `CommandLine` (even if they have different settings
524 /// than would have been inserted).
525 ///
526 /// \pre `llvm::InitializeAllTargets()` has been called.
527 ///
528 /// \param CommandLine the command line used to invoke the compiler driver or
529 /// Clang tool, including the path to the executable as \c CommandLine[0].
530 /// \param InvokedAs the path to the driver used to infer implicit flags.
531 ///
532 /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
533 /// infrastructure expects that CommandLine[0] is a tool path relative to which
534 /// the builtin headers can be found.
535 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
536                                     StringRef InvokedAs);
537
538 /// Creates a \c CompilerInvocation.
539 CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
540                                   const llvm::opt::ArgStringList &CC1Args);
541
542 } // namespace tooling
543
544 } // namespace clang
545
546 #endif // LLVM_CLANG_TOOLING_TOOLING_H