1 //===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements functions to run clang tools standalone instead
11 // of running them as a plugin.
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.
17 // It is also possible to run a FrontendAction over a snippet of code by
18 // calling runToolOnCode, which is useful for unit testing.
20 // Applications that need more fine grained control over how to run
21 // multiple FrontendActions over code can use ToolInvocation.
24 // - running clang -fsyntax-only over source code from an editor to get
26 // - running match/replace tools over C++ code
28 //===----------------------------------------------------------------------===//
30 #ifndef LLVM_CLANG_TOOLING_TOOLING_H
31 #define LLVM_CLANG_TOOLING_TOOLING_H
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"
54 } // end namespace driver
56 class CompilerInvocation;
62 /// \brief Interface to process a clang::CompilerInvocation.
64 /// If your tool is based on FrontendAction, you should be deriving from
65 /// FrontendActionFactory instead.
68 virtual ~ToolAction();
70 /// \brief Perform an action for an invocation.
72 runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
73 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
74 DiagnosticConsumer *DiagConsumer) = 0;
77 /// \brief Interface to generate clang::FrontendActions.
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 {
85 ~FrontendActionFactory() override;
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;
92 /// \brief Returns a new clang::FrontendAction.
94 /// The caller takes ownership of the returned action.
95 virtual clang::FrontendAction *create() = 0;
98 /// \brief Returns a new FrontendActionFactory for a given type.
100 /// T must derive from clang::FrontendAction.
103 /// FrontendActionFactory *Factory =
104 /// newFrontendActionFactory<clang::SyntaxOnlyAction>();
105 template <typename T>
106 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
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 {
113 virtual ~SourceFileCallbacks() {}
115 /// \brief Called before a source file is processed by a FrontEndAction.
116 /// \see clang::FrontendAction::BeginSourceFileAction
117 virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) {
121 /// \brief Called after a source file is processed by a FrontendAction.
122 /// \see clang::FrontendAction::EndSourceFileAction
123 virtual void handleEndSource() {}
126 /// \brief Returns a new FrontendActionFactory for any type that provides an
127 /// implementation of newASTConsumer().
129 /// FactoryT must implement: ASTConsumer *newASTConsumer().
132 /// struct ProvidesASTConsumers {
133 /// clang::ASTConsumer *newASTConsumer();
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);
141 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
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
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>());
155 /// The first part of the pair is the filename, the second part the
157 typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
159 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
160 /// with additional other flags.
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
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());
177 /// \brief Builds an AST for 'Code'.
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
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>());
190 /// \brief Builds an AST for 'Code' with additional flags.
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
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>());
205 /// \brief Utility to run a FrontendAction in a single clang invocation.
206 class ToolInvocation {
208 /// \brief Create a tool invocation.
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
217 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
219 ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
221 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
222 std::make_shared<PCHContainerOperations>());
224 /// \brief Create a tool invocation.
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
231 ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
233 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
237 /// \brief Set a \c DiagnosticConsumer to use during parsing.
238 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
239 this->DiagConsumer = DiagConsumer;
242 /// \brief Map a virtual file to be used while running the tool.
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 void mapVirtualFile(StringRef FilePath, StringRef Content);
248 /// \brief Run the clang invocation.
250 /// \returns True if there were no errors during execution.
254 void addFileMappingsTo(SourceManager &SourceManager);
256 bool runInvocation(const char *BinaryName,
257 clang::driver::Compilation *Compilation,
258 clang::CompilerInvocation *Invocation,
259 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
261 std::vector<std::string> CommandLine;
265 std::shared_ptr<PCHContainerOperations> PCHContainerOps;
266 // Maps <file name> -> <file content>.
267 llvm::StringMap<StringRef> MappedFileContents;
268 DiagnosticConsumer *DiagConsumer;
271 /// \brief Utility to run a FrontendAction over a set of files.
273 /// This class is written to be usable for command line utilities.
274 /// By default the class uses ClangSyntaxOnlyAdjuster to modify
275 /// command line arguments before the arguments are used to run
276 /// a frontend action. One could install an additional command line
277 /// arguments adjuster by calling the appendArgumentsAdjuster() method.
280 /// \brief Constructs a clang tool to run over a list of files.
282 /// \param Compilations The CompilationDatabase which contains the compile
283 /// command lines for the given source paths.
284 /// \param SourcePaths The source files to run over. If a source files is
285 /// not found in Compilations, it is skipped.
286 /// \param PCHContainerOps The PCHContainerOperations for loading and creating
288 ClangTool(const CompilationDatabase &Compilations,
289 ArrayRef<std::string> SourcePaths,
290 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
291 std::make_shared<PCHContainerOperations>());
295 /// \brief Set a \c DiagnosticConsumer to use during parsing.
296 void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
297 this->DiagConsumer = DiagConsumer;
300 /// \brief Map a virtual file to be used while running the tool.
302 /// \param FilePath The path at which the content will be mapped.
303 /// \param Content A null terminated buffer of the file's content.
304 void mapVirtualFile(StringRef FilePath, StringRef Content);
306 /// \brief Append a command line arguments adjuster to the adjuster chain.
308 /// \param Adjuster An argument adjuster, which will be run on the output of
309 /// previous argument adjusters.
310 void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
312 /// \brief Clear the command line arguments adjuster chain.
313 void clearArgumentsAdjusters();
315 /// Runs an action over all files specified in the command line.
317 /// \param Action Tool action.
318 int run(ToolAction *Action);
320 /// \brief Create an AST for each file specified in the command line and
321 /// append them to ASTs.
322 int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
324 /// \brief Returns the file manager used in the tool.
326 /// The file manager is shared between all translation units.
327 FileManager &getFiles() { return *Files; }
330 const CompilationDatabase &Compilations;
331 std::vector<std::string> SourcePaths;
332 std::shared_ptr<PCHContainerOperations> PCHContainerOps;
334 llvm::IntrusiveRefCntPtr<FileManager> Files;
335 // Contains a list of pairs (<file name>, <file content>).
336 std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
338 ArgumentsAdjuster ArgsAdjuster;
340 DiagnosticConsumer *DiagConsumer;
343 template <typename T>
344 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
345 class SimpleFrontendActionFactory : public FrontendActionFactory {
347 clang::FrontendAction *create() override { return new T; }
350 return std::unique_ptr<FrontendActionFactory>(
351 new SimpleFrontendActionFactory);
354 template <typename FactoryT>
355 inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
356 FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
357 class FrontendActionFactoryAdapter : public FrontendActionFactory {
359 explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
360 SourceFileCallbacks *Callbacks)
361 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
363 clang::FrontendAction *create() override {
364 return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
368 class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
370 ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
371 SourceFileCallbacks *Callbacks)
372 : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
374 std::unique_ptr<clang::ASTConsumer>
375 CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
376 return ConsumerFactory->newASTConsumer();
380 bool BeginSourceFileAction(CompilerInstance &CI,
381 StringRef Filename) override {
382 if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
385 return Callbacks->handleBeginSource(CI, Filename);
388 void EndSourceFileAction() override {
390 Callbacks->handleEndSource();
391 clang::ASTFrontendAction::EndSourceFileAction();
395 FactoryT *ConsumerFactory;
396 SourceFileCallbacks *Callbacks;
398 FactoryT *ConsumerFactory;
399 SourceFileCallbacks *Callbacks;
402 return std::unique_ptr<FrontendActionFactory>(
403 new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
406 /// \brief Returns the absolute path of \c File, by prepending it with
407 /// the current directory if \c File is not absolute.
409 /// Otherwise returns \c File.
410 /// If 'File' starts with "./", the returned path will not contain the "./".
411 /// Otherwise, the returned path will contain the literal path-concatenation of
412 /// the current directory and \c File.
414 /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
415 /// does by removing "./" and computing native paths.
417 /// \param File Either an absolute or relative path.
418 std::string getAbsolutePath(StringRef File);
420 /// \brief Creates a \c CompilerInvocation.
421 clang::CompilerInvocation *newInvocation(
422 clang::DiagnosticsEngine *Diagnostics,
423 const llvm::opt::ArgStringList &CC1Args);
425 } // end namespace tooling
426 } // end namespace clang
428 #endif // LLVM_CLANG_TOOLING_TOOLING_H