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 ToolName The name of the binary running the tool. Standard library
167 /// header paths will be resolved relative to this.
168 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
169 /// clang modules.
170 ///
171 /// \return - True if 'ToolAction' was successfully executed.
172 bool runToolOnCodeWithArgs(
173 clang::FrontendAction *ToolAction, const Twine &Code,
174 const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
175 const Twine &ToolName = "clang-tool",
176 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
177 std::make_shared<PCHContainerOperations>(),
178 const FileContentMappings &VirtualMappedFiles = FileContentMappings());
179
180 /// \brief Builds an AST for 'Code'.
181 ///
182 /// \param Code C++ code.
183 /// \param FileName The file name which 'Code' will be mapped as.
184 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
185 /// clang modules.
186 ///
187 /// \return The resulting AST or null if an error occurred.
188 std::unique_ptr<ASTUnit>
189 buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
190 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
191 std::make_shared<PCHContainerOperations>());
192
193 /// \brief Builds an AST for 'Code' with additional flags.
194 ///
195 /// \param Code C++ code.
196 /// \param Args Additional flags to pass on.
197 /// \param FileName The file name which 'Code' will be mapped as.
198 /// \param ToolName The name of the binary running the tool. Standard library
199 /// header paths will be resolved relative to this.
200 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
201 /// clang modules.
202 ///
203 /// \return The resulting AST or null if an error occurred.
204 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
205 const Twine &Code, const std::vector<std::string> &Args,
206 const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool",
207 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
208 std::make_shared<PCHContainerOperations>());
209
210 /// \brief Utility to run a FrontendAction in a single clang invocation.
211 class ToolInvocation {
212 public:
213 /// \brief Create a tool invocation.
214 ///
215 /// \param CommandLine The command line arguments to clang. Note that clang
216 /// uses its binary name (CommandLine[0]) to locate its builtin headers.
217 /// Callers have to ensure that they are installed in a compatible location
218 /// (see clang driver implementation) or mapped in via mapVirtualFile.
219 /// \param FAction The action to be executed. Class takes ownership.
220 /// \param Files The FileManager used for the execution. Class does not take
221 /// ownership.
222 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
223 /// clang modules.
224 ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
225 FileManager *Files,
226 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
227 std::make_shared<PCHContainerOperations>());
228
229 /// \brief Create a tool invocation.
230 ///
231 /// \param CommandLine The command line arguments to clang.
232 /// \param Action The action to be executed.
233 /// \param Files The FileManager used for the execution.
234 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
235 /// clang modules.
236 ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
237 FileManager *Files,
238 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
239
240 ~ToolInvocation();
241
242 /// \brief Set a \c DiagnosticConsumer to use during parsing.
setDiagnosticConsumer(DiagnosticConsumer * DiagConsumer)243 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
244 this->DiagConsumer = DiagConsumer;
245 }
246
247 /// \brief Map a virtual file to be used while running the tool.
248 ///
249 /// \param FilePath The path at which the content will be mapped.
250 /// \param Content A null terminated buffer of the file's content.
251 // FIXME: remove this when all users have migrated!
252 void mapVirtualFile(StringRef FilePath, StringRef Content);
253
254 /// \brief Run the clang invocation.
255 ///
256 /// \returns True if there were no errors during execution.
257 bool run();
258
259 private:
260 void addFileMappingsTo(SourceManager &SourceManager);
261
262 bool runInvocation(const char *BinaryName,
263 clang::driver::Compilation *Compilation,
264 clang::CompilerInvocation *Invocation,
265 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
266
267 std::vector<std::string> CommandLine;
268 ToolAction *Action;
269 bool OwnsAction;
270 FileManager *Files;
271 std::shared_ptr<PCHContainerOperations> PCHContainerOps;
272 // Maps <file name> -> <file content>.
273 llvm::StringMap<StringRef> MappedFileContents;
274 DiagnosticConsumer *DiagConsumer;
275 };
276
277 /// \brief Utility to run a FrontendAction over a set of files.
278 ///
279 /// This class is written to be usable for command line utilities.
280 /// By default the class uses ClangSyntaxOnlyAdjuster to modify
281 /// command line arguments before the arguments are used to run
282 /// a frontend action. One could install an additional command line
283 /// arguments adjuster by calling the appendArgumentsAdjuster() method.
284 class ClangTool {
285 public:
286 /// \brief Constructs a clang tool to run over a list of files.
287 ///
288 /// \param Compilations The CompilationDatabase which contains the compile
289 /// command lines for the given source paths.
290 /// \param SourcePaths The source files to run over. If a source files is
291 /// not found in Compilations, it is skipped.
292 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
293 /// clang modules.
294 ClangTool(const CompilationDatabase &Compilations,
295 ArrayRef<std::string> SourcePaths,
296 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
297 std::make_shared<PCHContainerOperations>());
298
299 ~ClangTool();
300
301 /// \brief Set a \c DiagnosticConsumer to use during parsing.
setDiagnosticConsumer(DiagnosticConsumer * DiagConsumer)302 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
303 this->DiagConsumer = DiagConsumer;
304 }
305
306 /// \brief Map a virtual file to be used while running the tool.
307 ///
308 /// \param FilePath The path at which the content will be mapped.
309 /// \param Content A null terminated buffer of the file's content.
310 void mapVirtualFile(StringRef FilePath, StringRef Content);
311
312 /// \brief Append a command line arguments adjuster to the adjuster chain.
313 ///
314 /// \param Adjuster An argument adjuster, which will be run on the output of
315 /// previous argument adjusters.
316 void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
317
318 /// \brief Clear the command line arguments adjuster chain.
319 void clearArgumentsAdjusters();
320
321 /// Runs an action over all files specified in the command line.
322 ///
323 /// \param Action Tool action.
324 int run(ToolAction *Action);
325
326 /// \brief Create an AST for each file specified in the command line and
327 /// append them to ASTs.
328 int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
329
330 /// \brief Returns the file manager used in the tool.
331 ///
332 /// The file manager is shared between all translation units.
getFiles()333 FileManager &getFiles() { return *Files; }
334
335 private:
336 const CompilationDatabase &Compilations;
337 std::vector<std::string> SourcePaths;
338 std::shared_ptr<PCHContainerOperations> PCHContainerOps;
339
340 llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem;
341 llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
342 llvm::IntrusiveRefCntPtr<FileManager> Files;
343 // Contains a list of pairs (<file name>, <file content>).
344 std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
345 llvm::StringSet<> SeenWorkingDirectories;
346
347 ArgumentsAdjuster ArgsAdjuster;
348
349 DiagnosticConsumer *DiagConsumer;
350 };
351
352 template <typename T>
newFrontendActionFactory()353 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
354 class SimpleFrontendActionFactory : public FrontendActionFactory {
355 public:
356 clang::FrontendAction *create() override { return new T; }
357 };
358
359 return std::unique_ptr<FrontendActionFactory>(
360 new SimpleFrontendActionFactory);
361 }
362
363 template <typename FactoryT>
newFrontendActionFactory(FactoryT * ConsumerFactory,SourceFileCallbacks * Callbacks)364 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
365 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
366 class FrontendActionFactoryAdapter : public FrontendActionFactory {
367 public:
368 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
369 SourceFileCallbacks *Callbacks)
370 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
371
372 clang::FrontendAction *create() override {
373 return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
374 }
375
376 private:
377 class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
378 public:
379 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
380 SourceFileCallbacks *Callbacks)
381 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
382
383 std::unique_ptr<clang::ASTConsumer>
384 CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
385 return ConsumerFactory->newASTConsumer();
386 }
387
388 protected:
389 bool BeginSourceFileAction(CompilerInstance &CI,
390 StringRef Filename) override {
391 if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
392 return false;
393 if (Callbacks)
394 return Callbacks->handleBeginSource(CI, Filename);
395 return true;
396 }
397 void EndSourceFileAction() override {
398 if (Callbacks)
399 Callbacks->handleEndSource();
400 clang::ASTFrontendAction::EndSourceFileAction();
401 }
402
403 private:
404 FactoryT *ConsumerFactory;
405 SourceFileCallbacks *Callbacks;
406 };
407 FactoryT *ConsumerFactory;
408 SourceFileCallbacks *Callbacks;
409 };
410
411 return std::unique_ptr<FrontendActionFactory>(
412 new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
413 }
414
415 /// \brief Returns the absolute path of \c File, by prepending it with
416 /// the current directory if \c File is not absolute.
417 ///
418 /// Otherwise returns \c File.
419 /// If 'File' starts with "./", the returned path will not contain the "./".
420 /// Otherwise, the returned path will contain the literal path-concatenation of
421 /// the current directory and \c File.
422 ///
423 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
424 /// does by removing "./" and computing native paths.
425 ///
426 /// \param File Either an absolute or relative path.
427 std::string getAbsolutePath(StringRef File);
428
429 /// \brief Changes CommandLine to contain implicit flags that would have been
430 /// defined had the compiler driver been invoked through the path InvokedAs.
431 ///
432 /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
433 /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
434 /// be inserted after the first argument in \c CommandLine.
435 ///
436 /// This function will not add new `-target` or `--driver-mode` flags if they
437 /// are already present in `CommandLine` (even if they have different settings
438 /// than would have been inserted).
439 ///
440 /// \pre `llvm::InitializeAllTargets()` has been called.
441 ///
442 /// \param CommandLine the command line used to invoke the compiler driver or
443 /// Clang tool, including the path to the executable as \c CommandLine[0].
444 /// \param InvokedAs the path to the driver used to infer implicit flags.
445 ///
446 /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
447 /// infrastructure expects that CommandLine[0] is a tool path relative to which
448 /// the builtin headers can be found.
449 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
450 StringRef InvokedAs);
451
452 /// \brief Creates a \c CompilerInvocation.
453 clang::CompilerInvocation *newInvocation(
454 clang::DiagnosticsEngine *Diagnostics,
455 const llvm::opt::ArgStringList &CC1Args);
456
457 } // end namespace tooling
458 } // end namespace clang
459
460 #endif // LLVM_CLANG_TOOLING_TOOLING_H
461