Line data Source code
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 12 : 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 12 : 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:
113 : virtual ~SourceFileCallbacks() {}
114 :
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) {
118 : return true;
119 : }
120 :
121 : /// \brief Called after a source file is processed by a FrontendAction.
122 : /// \see clang::FrontendAction::EndSourceFileAction
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.
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 : void mapVirtualFile(StringRef FilePath, StringRef Content);
247 :
248 : /// \brief Run the clang invocation.
249 : ///
250 : /// \returns True if there were no errors during execution.
251 : bool run();
252 :
253 : private:
254 : void addFileMappingsTo(SourceManager &SourceManager);
255 :
256 : bool runInvocation(const char *BinaryName,
257 : clang::driver::Compilation *Compilation,
258 : clang::CompilerInvocation *Invocation,
259 : std::shared_ptr<PCHContainerOperations> PCHContainerOps);
260 :
261 : std::vector<std::string> CommandLine;
262 : ToolAction *Action;
263 : bool OwnsAction;
264 : FileManager *Files;
265 : std::shared_ptr<PCHContainerOperations> PCHContainerOps;
266 : // Maps <file name> -> <file content>.
267 : llvm::StringMap<StringRef> MappedFileContents;
268 : DiagnosticConsumer *DiagConsumer;
269 : };
270 :
271 : /// \brief Utility to run a FrontendAction over a set of files.
272 : ///
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.
278 : class ClangTool {
279 : public:
280 : /// \brief Constructs a clang tool to run over a list of files.
281 : ///
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
287 : /// clang modules.
288 : ClangTool(const CompilationDatabase &Compilations,
289 : ArrayRef<std::string> SourcePaths,
290 : std::shared_ptr<PCHContainerOperations> PCHContainerOps =
291 : std::make_shared<PCHContainerOperations>());
292 :
293 : ~ClangTool();
294 :
295 : /// \brief Set a \c DiagnosticConsumer to use during parsing.
296 : void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
297 : this->DiagConsumer = DiagConsumer;
298 : }
299 :
300 : /// \brief Map a virtual file to be used while running the tool.
301 : ///
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);
305 :
306 : /// \brief Append a command line arguments adjuster to the adjuster chain.
307 : ///
308 : /// \param Adjuster An argument adjuster, which will be run on the output of
309 : /// previous argument adjusters.
310 : void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
311 :
312 : /// \brief Clear the command line arguments adjuster chain.
313 : void clearArgumentsAdjusters();
314 :
315 : /// Runs an action over all files specified in the command line.
316 : ///
317 : /// \param Action Tool action.
318 : int run(ToolAction *Action);
319 :
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);
323 :
324 : /// \brief Returns the file manager used in the tool.
325 : ///
326 : /// The file manager is shared between all translation units.
327 : FileManager &getFiles() { return *Files; }
328 :
329 : private:
330 : const CompilationDatabase &Compilations;
331 : std::vector<std::string> SourcePaths;
332 : std::shared_ptr<PCHContainerOperations> PCHContainerOps;
333 :
334 : llvm::IntrusiveRefCntPtr<FileManager> Files;
335 : // Contains a list of pairs (<file name>, <file content>).
336 : std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
337 :
338 : ArgumentsAdjuster ArgsAdjuster;
339 :
340 : DiagnosticConsumer *DiagConsumer;
341 : };
342 :
343 : template <typename T>
344 : std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
345 : class SimpleFrontendActionFactory : public FrontendActionFactory {
346 : public:
347 : clang::FrontendAction *create() override { return new T; }
348 : };
349 :
350 : return std::unique_ptr<FrontendActionFactory>(
351 : new SimpleFrontendActionFactory);
352 : }
353 :
354 : template <typename FactoryT>
355 : inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
356 : FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
357 24 : class FrontendActionFactoryAdapter : public FrontendActionFactory {
358 : public:
359 12 : explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
360 : SourceFileCallbacks *Callbacks)
361 24 : : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
362 :
363 : clang::FrontendAction *create() override {
364 24 : return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
365 0 : }
366 :
367 : private:
368 24 : class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
369 : public:
370 12 : ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
371 : SourceFileCallbacks *Callbacks)
372 24 : : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
373 :
374 : std::unique_ptr<clang::ASTConsumer>
375 : CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
376 12 : return ConsumerFactory->newASTConsumer();
377 : }
378 :
379 : protected:
380 : bool BeginSourceFileAction(CompilerInstance &CI,
381 : StringRef Filename) override {
382 12 : if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
383 0 : return false;
384 12 : if (Callbacks)
385 0 : return Callbacks->handleBeginSource(CI, Filename);
386 12 : return true;
387 12 : }
388 : void EndSourceFileAction() override {
389 12 : if (Callbacks)
390 0 : Callbacks->handleEndSource();
391 12 : clang::ASTFrontendAction::EndSourceFileAction();
392 12 : }
393 :
394 : private:
395 : FactoryT *ConsumerFactory;
396 : SourceFileCallbacks *Callbacks;
397 : };
398 : FactoryT *ConsumerFactory;
399 : SourceFileCallbacks *Callbacks;
400 : };
401 :
402 12 : return std::unique_ptr<FrontendActionFactory>(
403 24 : new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
404 0 : }
405 :
406 : /// \brief Returns the absolute path of \c File, by prepending it with
407 : /// the current directory if \c File is not absolute.
408 : ///
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.
413 : ///
414 : /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
415 : /// does by removing "./" and computing native paths.
416 : ///
417 : /// \param File Either an absolute or relative path.
418 : std::string getAbsolutePath(StringRef File);
419 :
420 : /// \brief Creates a \c CompilerInvocation.
421 : clang::CompilerInvocation *newInvocation(
422 : clang::DiagnosticsEngine *Diagnostics,
423 : const llvm::opt::ArgStringList &CC1Args);
424 :
425 : } // end namespace tooling
426 : } // end namespace clang
427 :
428 : #endif // LLVM_CLANG_TOOLING_TOOLING_H
|