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