83fe43ac59e020afec0cf899ad2281809a931c9b
[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   ///
103   /// The caller takes ownership of the returned action.
104   virtual FrontendAction *create() = 0;
105 };
106
107 /// Returns a new FrontendActionFactory for a given type.
108 ///
109 /// T must derive from clang::FrontendAction.
110 ///
111 /// Example:
112 /// FrontendActionFactory *Factory =
113 ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
114 template <typename T>
115 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
116
117 /// Callbacks called before and after each source file processed by a
118 /// FrontendAction created by the FrontedActionFactory returned by \c
119 /// newFrontendActionFactory.
120 class SourceFileCallbacks {
121 public:
122   virtual ~SourceFileCallbacks() = default;
123
124   /// Called before a source file is processed by a FrontEndAction.
125   /// \see clang::FrontendAction::BeginSourceFileAction
126   virtual bool handleBeginSource(CompilerInstance &CI) {
127     return true;
128   }
129
130   /// Called after a source file is processed by a FrontendAction.
131   /// \see clang::FrontendAction::EndSourceFileAction
132   virtual void handleEndSource() {}
133 };
134
135 /// Returns a new FrontendActionFactory for any type that provides an
136 /// implementation of newASTConsumer().
137 ///
138 /// FactoryT must implement: ASTConsumer *newASTConsumer().
139 ///
140 /// Example:
141 /// struct ProvidesASTConsumers {
142 ///   clang::ASTConsumer *newASTConsumer();
143 /// } Factory;
144 /// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
145 ///   newFrontendActionFactory(&Factory));
146 template <typename FactoryT>
147 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
148     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
149
150 /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
151 ///
152 /// \param ToolAction The action to run over the code.
153 /// \param Code C++ code.
154 /// \param FileName The file name which 'Code' will be mapped as.
155 /// \param PCHContainerOps  The PCHContainerOperations for loading and creating
156 ///                         clang modules.
157 ///
158 /// \return - True if 'ToolAction' was successfully executed.
159 bool runToolOnCode(FrontendAction *ToolAction, const Twine &Code,
160                    const Twine &FileName = "input.cc",
161                    std::shared_ptr<PCHContainerOperations> PCHContainerOps =
162                        std::make_shared<PCHContainerOperations>());
163
164 /// The first part of the pair is the filename, the second part the
165 /// file-content.
166 using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
167
168 /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
169 ///        with additional other flags.
170 ///
171 /// \param ToolAction The action to run over the code.
172 /// \param Code C++ code.
173 /// \param Args Additional flags to pass on.
174 /// \param FileName The file name which 'Code' will be mapped as.
175 /// \param ToolName The name of the binary running the tool. Standard library
176 ///                 header paths will be resolved relative to this.
177 /// \param PCHContainerOps   The PCHContainerOperations for loading and creating
178 ///                          clang modules.
179 ///
180 /// \return - True if 'ToolAction' was successfully executed.
181 bool runToolOnCodeWithArgs(
182     FrontendAction *ToolAction, const Twine &Code,
183     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
184     const Twine &ToolName = "clang-tool",
185     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
186         std::make_shared<PCHContainerOperations>(),
187     const FileContentMappings &VirtualMappedFiles = FileContentMappings());
188
189 // Similar to the overload except this takes a VFS.
190 bool runToolOnCodeWithArgs(
191     FrontendAction *ToolAction, const Twine &Code,
192     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
193     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
194     const Twine &ToolName = "clang-tool",
195     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
196         std::make_shared<PCHContainerOperations>());
197
198 /// Builds an AST for 'Code'.
199 ///
200 /// \param Code C++ code.
201 /// \param FileName The file name which 'Code' will be mapped as.
202 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
203 /// clang modules.
204 ///
205 /// \return The resulting AST or null if an error occurred.
206 std::unique_ptr<ASTUnit>
207 buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
208                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
209                      std::make_shared<PCHContainerOperations>());
210
211 /// Builds an AST for 'Code' with additional flags.
212 ///
213 /// \param Code C++ code.
214 /// \param Args Additional flags to pass on.
215 /// \param FileName The file name which 'Code' will be mapped as.
216 /// \param ToolName The name of the binary running the tool. Standard library
217 ///                 header paths will be resolved relative to this.
218 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
219 /// clang modules.
220 ///
221 /// \param Adjuster A function to filter the command line arguments as specified.
222 ///
223 /// \return The resulting AST or null if an error occurred.
224 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
225     StringRef Code, const std::vector<std::string> &Args,
226     StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
227     std::shared_ptr<PCHContainerOperations> PCHContainerOps =
228         std::make_shared<PCHContainerOperations>(),
229     ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
230
231 /// Utility to run a FrontendAction in a single clang invocation.
232 class ToolInvocation {
233 public:
234   /// Create a tool invocation.
235   ///
236   /// \param CommandLine The command line arguments to clang. Note that clang
237   /// uses its binary name (CommandLine[0]) to locate its builtin headers.
238   /// Callers have to ensure that they are installed in a compatible location
239   /// (see clang driver implementation) or mapped in via mapVirtualFile.
240   /// \param FAction The action to be executed. Class takes ownership.
241   /// \param Files The FileManager used for the execution. Class does not take
242   /// ownership.
243   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
244   /// clang modules.
245   ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
246                  FileManager *Files,
247                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
248                      std::make_shared<PCHContainerOperations>());
249
250   /// Create a tool invocation.
251   ///
252   /// \param CommandLine The command line arguments to clang.
253   /// \param Action The action to be executed.
254   /// \param Files The FileManager used for the execution.
255   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
256   /// clang modules.
257   ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
258                  FileManager *Files,
259                  std::shared_ptr<PCHContainerOperations> PCHContainerOps);
260
261   ~ToolInvocation();
262
263   /// Set a \c DiagnosticConsumer to use during parsing.
264   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
265     this->DiagConsumer = DiagConsumer;
266   }
267
268   /// Map a virtual file to be used while running the tool.
269   ///
270   /// \param FilePath The path at which the content will be mapped.
271   /// \param Content A null terminated buffer of the file's content.
272   // FIXME: remove this when all users have migrated!
273   void mapVirtualFile(StringRef FilePath, StringRef Content);
274
275   /// Run the clang invocation.
276   ///
277   /// \returns True if there were no errors during execution.
278   bool run();
279
280  private:
281   void addFileMappingsTo(SourceManager &SourceManager);
282
283   bool runInvocation(const char *BinaryName,
284                      driver::Compilation *Compilation,
285                      std::shared_ptr<CompilerInvocation> Invocation,
286                      std::shared_ptr<PCHContainerOperations> PCHContainerOps);
287
288   std::vector<std::string> CommandLine;
289   ToolAction *Action;
290   bool OwnsAction;
291   FileManager *Files;
292   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
293   // Maps <file name> -> <file content>.
294   llvm::StringMap<StringRef> MappedFileContents;
295   DiagnosticConsumer *DiagConsumer = nullptr;
296 };
297
298 /// Utility to run a FrontendAction over a set of files.
299 ///
300 /// This class is written to be usable for command line utilities.
301 /// By default the class uses ClangSyntaxOnlyAdjuster to modify
302 /// command line arguments before the arguments are used to run
303 /// a frontend action. One could install an additional command line
304 /// arguments adjuster by calling the appendArgumentsAdjuster() method.
305 class ClangTool {
306 public:
307   /// Constructs a clang tool to run over a list of files.
308   ///
309   /// \param Compilations The CompilationDatabase which contains the compile
310   ///        command lines for the given source paths.
311   /// \param SourcePaths The source files to run over. If a source files is
312   ///        not found in Compilations, it is skipped.
313   /// \param PCHContainerOps The PCHContainerOperations for loading and creating
314   /// clang modules.
315   /// \param BaseFS VFS used for all underlying file accesses when running the
316   /// tool.
317   ClangTool(const CompilationDatabase &Compilations,
318             ArrayRef<std::string> SourcePaths,
319             std::shared_ptr<PCHContainerOperations> PCHContainerOps =
320                 std::make_shared<PCHContainerOperations>(),
321             IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
322                 llvm::vfs::getRealFileSystem());
323
324   ~ClangTool();
325
326   /// Set a \c DiagnosticConsumer to use during parsing.
327   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
328     this->DiagConsumer = DiagConsumer;
329   }
330
331   /// Map a virtual file to be used while running the tool.
332   ///
333   /// \param FilePath The path at which the content will be mapped.
334   /// \param Content A null terminated buffer of the file's content.
335   void mapVirtualFile(StringRef FilePath, StringRef Content);
336
337   /// Append a command line arguments adjuster to the adjuster chain.
338   ///
339   /// \param Adjuster An argument adjuster, which will be run on the output of
340   ///        previous argument adjusters.
341   void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
342
343   /// Clear the command line arguments adjuster chain.
344   void clearArgumentsAdjusters();
345
346   /// Runs an action over all files specified in the command line.
347   ///
348   /// \param Action Tool action.
349   ///
350   /// \returns 0 on success; 1 if any error occurred; 2 if there is no error but
351   /// some files are skipped due to missing compile commands.
352   int run(ToolAction *Action);
353
354   /// Create an AST for each file specified in the command line and
355   /// append them to ASTs.
356   int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
357
358   /// Sets whether working directory should be restored after calling run(). By
359   /// default, working directory is restored. However, it could be useful to
360   /// turn this off when running on multiple threads to avoid the raciness.
361   void setRestoreWorkingDir(bool RestoreCWD);
362
363   /// Sets whether an error message should be printed out if an action fails. By
364   /// default, if an action fails, a message is printed out to stderr.
365   void setPrintErrorMessage(bool PrintErrorMessage);
366
367   /// Returns the file manager used in the tool.
368   ///
369   /// The file manager is shared between all translation units.
370   FileManager &getFiles() { return *Files; }
371
372   llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }
373
374 private:
375   const CompilationDatabase &Compilations;
376   std::vector<std::string> SourcePaths;
377   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
378
379   llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
380   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
381   llvm::IntrusiveRefCntPtr<FileManager> Files;
382
383   // Contains a list of pairs (<file name>, <file content>).
384   std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
385
386   llvm::StringSet<> SeenWorkingDirectories;
387
388   ArgumentsAdjuster ArgsAdjuster;
389
390   DiagnosticConsumer *DiagConsumer = nullptr;
391
392   bool RestoreCWD = true;
393   bool PrintErrorMessage = true;
394 };
395
396 template <typename T>
397 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
398   class SimpleFrontendActionFactory : public FrontendActionFactory {
399   public:
400     FrontendAction *create() override { return new T; }
401   };
402
403   return std::unique_ptr<FrontendActionFactory>(
404       new SimpleFrontendActionFactory);
405 }
406
407 template <typename FactoryT>
408 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
409     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
410   class FrontendActionFactoryAdapter : public FrontendActionFactory {
411   public:
412     explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
413                                           SourceFileCallbacks *Callbacks)
414         : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
415
416     FrontendAction *create() override {
417       return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
418     }
419
420   private:
421     class ConsumerFactoryAdaptor : public ASTFrontendAction {
422     public:
423       ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
424                              SourceFileCallbacks *Callbacks)
425           : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
426
427       std::unique_ptr<ASTConsumer>
428       CreateASTConsumer(CompilerInstance &, StringRef) override {
429         return ConsumerFactory->newASTConsumer();
430       }
431
432     protected:
433       bool BeginSourceFileAction(CompilerInstance &CI) override {
434         if (!ASTFrontendAction::BeginSourceFileAction(CI))
435           return false;
436         if (Callbacks)
437           return Callbacks->handleBeginSource(CI);
438         return true;
439       }
440
441       void EndSourceFileAction() override {
442         if (Callbacks)
443           Callbacks->handleEndSource();
444         ASTFrontendAction::EndSourceFileAction();
445       }
446
447     private:
448       FactoryT *ConsumerFactory;
449       SourceFileCallbacks *Callbacks;
450     };
451     FactoryT *ConsumerFactory;
452     SourceFileCallbacks *Callbacks;
453   };
454
455   return std::unique_ptr<FrontendActionFactory>(
456       new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
457 }
458
459 /// Returns the absolute path of \c File, by prepending it with
460 /// the current directory if \c File is not absolute.
461 ///
462 /// Otherwise returns \c File.
463 /// If 'File' starts with "./", the returned path will not contain the "./".
464 /// Otherwise, the returned path will contain the literal path-concatenation of
465 /// the current directory and \c File.
466 ///
467 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
468 /// does by removing "./" and computing native paths.
469 ///
470 /// \param File Either an absolute or relative path.
471 std::string getAbsolutePath(StringRef File);
472
473 /// An overload of getAbsolutePath that works over the provided \p FS.
474 llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
475                                             StringRef File);
476
477 /// Changes CommandLine to contain implicit flags that would have been
478 /// defined had the compiler driver been invoked through the path InvokedAs.
479 ///
480 /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
481 /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
482 /// be inserted after the first argument in \c CommandLine.
483 ///
484 /// This function will not add new `-target` or `--driver-mode` flags if they
485 /// are already present in `CommandLine` (even if they have different settings
486 /// than would have been inserted).
487 ///
488 /// \pre `llvm::InitializeAllTargets()` has been called.
489 ///
490 /// \param CommandLine the command line used to invoke the compiler driver or
491 /// Clang tool, including the path to the executable as \c CommandLine[0].
492 /// \param InvokedAs the path to the driver used to infer implicit flags.
493 ///
494 /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
495 /// infrastructure expects that CommandLine[0] is a tool path relative to which
496 /// the builtin headers can be found.
497 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
498                                     StringRef InvokedAs);
499
500 /// Creates a \c CompilerInvocation.
501 CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
502                                   const llvm::opt::ArgStringList &CC1Args);
503
504 } // namespace tooling
505
506 } // namespace clang
507
508 #endif // LLVM_CLANG_TOOLING_TOOLING_H