clang  6.0.0svn
Tooling.cpp
Go to the documentation of this file.
1 //===--- Tooling.cpp - Running clang standalone tools ---------------------===//
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 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Tooling/Tooling.h"
17 #include "clang/Driver/Driver.h"
18 #include "clang/Driver/Options.h"
19 #include "clang/Driver/Tool.h"
20 #include "clang/Driver/ToolChain.h"
21 #include "clang/Frontend/ASTUnit.h"
28 #include "llvm/ADT/STLExtras.h"
29 #include "llvm/Config/llvm-config.h"
30 #include "llvm/Option/ArgList.h"
31 #include "llvm/Option/Option.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/FileSystem.h"
34 #include "llvm/Support/Host.h"
35 #include "llvm/Support/Path.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include <utility>
38 
39 #define DEBUG_TYPE "clang-tooling"
40 
41 namespace clang {
42 namespace tooling {
43 
45 
47 
48 // FIXME: This file contains structural duplication with other parts of the
49 // code that sets up a compiler to run tools on it, and we should refactor
50 // it to be based on the same framework.
51 
52 /// \brief Builds a clang driver initialized for running clang tools.
54  clang::DiagnosticsEngine *Diagnostics, const char *BinaryName,
56  clang::driver::Driver *CompilerDriver =
57  new clang::driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(),
58  *Diagnostics, std::move(VFS));
59  CompilerDriver->setTitle("clang_based_tool");
60  return CompilerDriver;
61 }
62 
63 /// \brief Retrieves the clang CC1 specific flags out of the compilation's jobs.
64 ///
65 /// Returns NULL on error.
66 static const llvm::opt::ArgStringList *getCC1Arguments(
67  clang::DiagnosticsEngine *Diagnostics,
68  clang::driver::Compilation *Compilation) {
69  // We expect to get back exactly one Command job, if we didn't something
70  // failed. Extract that job from the Compilation.
71  const clang::driver::JobList &Jobs = Compilation->getJobs();
72  if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
73  SmallString<256> error_msg;
74  llvm::raw_svector_ostream error_stream(error_msg);
75  Jobs.Print(error_stream, "; ", true);
76  Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
77  << error_stream.str();
78  return nullptr;
79  }
80 
81  // The one job we find should be to invoke clang again.
82  const clang::driver::Command &Cmd =
83  cast<clang::driver::Command>(*Jobs.begin());
84  if (StringRef(Cmd.getCreator().getName()) != "clang") {
85  Diagnostics->Report(clang::diag::err_fe_expected_clang_command);
86  return nullptr;
87  }
88 
89  return &Cmd.getArguments();
90 }
91 
92 /// \brief Returns a clang build invocation initialized from the CC1 flags.
94  clang::DiagnosticsEngine *Diagnostics,
95  const llvm::opt::ArgStringList &CC1Args) {
96  assert(!CC1Args.empty() && "Must at least contain the program name!");
99  *Invocation, CC1Args.data() + 1, CC1Args.data() + CC1Args.size(),
100  *Diagnostics);
101  Invocation->getFrontendOpts().DisableFree = false;
102  Invocation->getCodeGenOpts().DisableFree = false;
103  return Invocation;
104 }
105 
107  const Twine &FileName,
108  std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
109  return runToolOnCodeWithArgs(ToolAction, Code, std::vector<std::string>(),
110  FileName, "clang-tool",
111  std::move(PCHContainerOps));
112 }
113 
114 static std::vector<std::string>
115 getSyntaxOnlyToolArgs(const Twine &ToolName,
116  const std::vector<std::string> &ExtraArgs,
117  StringRef FileName) {
118  std::vector<std::string> Args;
119  Args.push_back(ToolName.str());
120  Args.push_back("-fsyntax-only");
121  Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end());
122  Args.push_back(FileName.str());
123  return Args;
124 }
125 
127  clang::FrontendAction *ToolAction, const Twine &Code,
128  const std::vector<std::string> &Args, const Twine &FileName,
129  const Twine &ToolName,
130  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
131  const FileContentMappings &VirtualMappedFiles) {
132 
133  SmallString<16> FileNameStorage;
134  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
139  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
141  new FileManager(FileSystemOptions(), OverlayFileSystem));
143  ToolInvocation Invocation(
144  getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileNameRef), FileNameRef),
145  ToolAction, Files.get(),
146  std::move(PCHContainerOps));
147 
148  SmallString<1024> CodeStorage;
149  InMemoryFileSystem->addFile(FileNameRef, 0,
150  llvm::MemoryBuffer::getMemBuffer(
151  Code.toNullTerminatedStringRef(CodeStorage)));
152 
153  for (auto &FilenameWithContent : VirtualMappedFiles) {
154  InMemoryFileSystem->addFile(
155  FilenameWithContent.first, 0,
156  llvm::MemoryBuffer::getMemBuffer(FilenameWithContent.second));
157  }
158 
159  return Invocation.run();
160 }
161 
162 std::string getAbsolutePath(StringRef File) {
163  StringRef RelativePath(File);
164  // FIXME: Should '.\\' be accepted on Win32?
165  if (RelativePath.startswith("./")) {
166  RelativePath = RelativePath.substr(strlen("./"));
167  }
168 
169  SmallString<1024> AbsolutePath = RelativePath;
170  std::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath);
171  assert(!EC);
172  (void)EC;
173  llvm::sys::path::native(AbsolutePath);
174  return AbsolutePath.str();
175 }
176 
177 void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
178  StringRef InvokedAs) {
179  if (!CommandLine.empty() && !InvokedAs.empty()) {
180  bool AlreadyHasTarget = false;
181  bool AlreadyHasMode = false;
182  // Skip CommandLine[0].
183  for (auto Token = ++CommandLine.begin(); Token != CommandLine.end();
184  ++Token) {
185  StringRef TokenRef(*Token);
186  AlreadyHasTarget |=
187  (TokenRef == "-target" || TokenRef.startswith("-target="));
188  AlreadyHasMode |= (TokenRef == "--driver-mode" ||
189  TokenRef.startswith("--driver-mode="));
190  }
191  auto TargetMode =
193  if (!AlreadyHasMode && TargetMode.DriverMode) {
194  CommandLine.insert(++CommandLine.begin(), TargetMode.DriverMode);
195  }
196  if (!AlreadyHasTarget && TargetMode.TargetIsValid) {
197  CommandLine.insert(++CommandLine.begin(), {"-target",
198  TargetMode.TargetPrefix});
199  }
200  }
201 }
202 
203 namespace {
204 
205 class SingleFrontendActionFactory : public FrontendActionFactory {
206  FrontendAction *Action;
207 
208 public:
209  SingleFrontendActionFactory(FrontendAction *Action) : Action(Action) {}
210 
211  FrontendAction *create() override { return Action; }
212 };
213 
214 }
215 
217  std::vector<std::string> CommandLine, ToolAction *Action,
218  FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
219  : CommandLine(std::move(CommandLine)), Action(Action), OwnsAction(false),
220  Files(Files), PCHContainerOps(std::move(PCHContainerOps)),
221  DiagConsumer(nullptr) {}
222 
224  std::vector<std::string> CommandLine, FrontendAction *FAction,
225  FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
226  : CommandLine(std::move(CommandLine)),
227  Action(new SingleFrontendActionFactory(FAction)), OwnsAction(true),
228  Files(Files), PCHContainerOps(std::move(PCHContainerOps)),
229  DiagConsumer(nullptr) {}
230 
232  if (OwnsAction)
233  delete Action;
234 }
235 
236 void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) {
237  SmallString<1024> PathStorage;
238  llvm::sys::path::native(FilePath, PathStorage);
239  MappedFileContents[PathStorage] = Content;
240 }
241 
243  std::vector<const char*> Argv;
244  for (const std::string &Str : CommandLine)
245  Argv.push_back(Str.c_str());
246  const char *const BinaryName = Argv[0];
248  unsigned MissingArgIndex, MissingArgCount;
249  std::unique_ptr<llvm::opt::OptTable> Opts = driver::createDriverOptTable();
250  llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs(
251  ArrayRef<const char *>(Argv).slice(1), MissingArgIndex, MissingArgCount);
252  ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
253  TextDiagnosticPrinter DiagnosticPrinter(
254  llvm::errs(), &*DiagOpts);
255  DiagnosticsEngine Diagnostics(
257  DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
258 
259  const std::unique_ptr<clang::driver::Driver> Driver(
260  newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem()));
261  // Since the input might only be virtual, don't check whether it exists.
262  Driver->setCheckInputsExist(false);
263  const std::unique_ptr<clang::driver::Compilation> Compilation(
264  Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
265  if (!Compilation)
266  return false;
267  const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
268  &Diagnostics, Compilation.get());
269  if (!CC1Args) {
270  return false;
271  }
272  std::unique_ptr<clang::CompilerInvocation> Invocation(
273  newInvocation(&Diagnostics, *CC1Args));
274  // FIXME: remove this when all users have migrated!
275  for (const auto &It : MappedFileContents) {
276  // Inject the code as the given file name into the preprocessor options.
277  std::unique_ptr<llvm::MemoryBuffer> Input =
278  llvm::MemoryBuffer::getMemBuffer(It.getValue());
279  Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(),
280  Input.release());
281  }
282  return runInvocation(BinaryName, Compilation.get(), std::move(Invocation),
283  std::move(PCHContainerOps));
284 }
285 
286 bool ToolInvocation::runInvocation(
287  const char *BinaryName, clang::driver::Compilation *Compilation,
288  std::shared_ptr<clang::CompilerInvocation> Invocation,
289  std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
290  // Show the invocation, with -v.
291  if (Invocation->getHeaderSearchOpts().Verbose) {
292  llvm::errs() << "clang Invocation:\n";
293  Compilation->getJobs().Print(llvm::errs(), "\n", true);
294  llvm::errs() << "\n";
295  }
296 
297  return Action->runInvocation(std::move(Invocation), Files,
298  std::move(PCHContainerOps), DiagConsumer);
299 }
300 
302  std::shared_ptr<CompilerInvocation> Invocation, FileManager *Files,
303  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
304  DiagnosticConsumer *DiagConsumer) {
305  // Create a compiler instance to handle the actual work.
306  clang::CompilerInstance Compiler(std::move(PCHContainerOps));
307  Compiler.setInvocation(std::move(Invocation));
308  Compiler.setFileManager(Files);
309 
310  // The FrontendAction can have lifetime requirements for Compiler or its
311  // members, and we need to ensure it's deleted earlier than Compiler. So we
312  // pass it to an std::unique_ptr declared after the Compiler variable.
313  std::unique_ptr<FrontendAction> ScopedToolAction(create());
314 
315  // Create the compiler's actual diagnostics engine.
316  Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
317  if (!Compiler.hasDiagnostics())
318  return false;
319 
320  Compiler.createSourceManager(*Files);
321 
322  const bool Success = Compiler.ExecuteAction(*ScopedToolAction);
323 
324  Files->clearStatCaches();
325  return Success;
326 }
327 
329  ArrayRef<std::string> SourcePaths,
330  std::shared_ptr<PCHContainerOperations> PCHContainerOps)
331  : Compilations(Compilations), SourcePaths(SourcePaths),
332  PCHContainerOps(std::move(PCHContainerOps)),
333  OverlayFileSystem(new vfs::OverlayFileSystem(vfs::getRealFileSystem())),
334  InMemoryFileSystem(new vfs::InMemoryFileSystem),
335  Files(new FileManager(FileSystemOptions(), OverlayFileSystem)),
336  DiagConsumer(nullptr) {
337  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
341 }
342 
344 
345 void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
346  MappedFileContents.push_back(std::make_pair(FilePath, Content));
347 }
348 
350  if (ArgsAdjuster)
351  ArgsAdjuster =
352  combineAdjusters(std::move(ArgsAdjuster), std::move(Adjuster));
353  else
354  ArgsAdjuster = std::move(Adjuster);
355 }
356 
358  ArgsAdjuster = nullptr;
359 }
360 
361 static void injectResourceDir(CommandLineArguments &Args, const char *Argv0,
362  void *MainAddr) {
363  // Allow users to override the resource dir.
364  for (StringRef Arg : Args)
365  if (Arg.startswith("-resource-dir"))
366  return;
367 
368  // If there's no override in place add our resource dir.
369  Args.push_back("-resource-dir=" +
370  CompilerInvocation::GetResourcesPath(Argv0, MainAddr));
371 }
372 
374  // Exists solely for the purpose of lookup of the resource path.
375  // This just needs to be some symbol in the binary.
376  static int StaticSymbol;
377 
378  llvm::SmallString<128> InitialDirectory;
379  if (std::error_code EC = llvm::sys::fs::current_path(InitialDirectory))
380  llvm::report_fatal_error("Cannot detect current path: " +
381  Twine(EC.message()));
382 
383  // First insert all absolute paths into the in-memory VFS. These are global
384  // for all compile commands.
385  if (SeenWorkingDirectories.insert("/").second)
386  for (const auto &MappedFile : MappedFileContents)
387  if (llvm::sys::path::is_absolute(MappedFile.first))
388  InMemoryFileSystem->addFile(
389  MappedFile.first, 0,
390  llvm::MemoryBuffer::getMemBuffer(MappedFile.second));
391 
392  bool ProcessingFailed = false;
393  for (const auto &SourcePath : SourcePaths) {
394  std::string File(getAbsolutePath(SourcePath));
395 
396  // Currently implementations of CompilationDatabase::getCompileCommands can
397  // change the state of the file system (e.g. prepare generated headers), so
398  // this method needs to run right before we invoke the tool, as the next
399  // file may require a different (incompatible) state of the file system.
400  //
401  // FIXME: Make the compilation database interface more explicit about the
402  // requirements to the order of invocation of its members.
403  std::vector<CompileCommand> CompileCommandsForFile =
404  Compilations.getCompileCommands(File);
405  if (CompileCommandsForFile.empty()) {
406  // FIXME: There are two use cases here: doing a fuzzy
407  // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
408  // about the .cc files that were not found, and the use case where I
409  // specify all files I want to run over explicitly, where this should
410  // be an error. We'll want to add an option for this.
411  llvm::errs() << "Skipping " << File << ". Compile command not found.\n";
412  continue;
413  }
414  for (CompileCommand &CompileCommand : CompileCommandsForFile) {
415  // FIXME: chdir is thread hostile; on the other hand, creating the same
416  // behavior as chdir is complex: chdir resolves the path once, thus
417  // guaranteeing that all subsequent relative path operations work
418  // on the same path the original chdir resulted in. This makes a
419  // difference for example on network filesystems, where symlinks might be
420  // switched during runtime of the tool. Fixing this depends on having a
421  // file system abstraction that allows openat() style interactions.
422  if (OverlayFileSystem->setCurrentWorkingDirectory(
424  llvm::report_fatal_error("Cannot chdir into \"" +
425  Twine(CompileCommand.Directory) + "\n!");
426 
427  // Now fill the in-memory VFS with the relative file mappings so it will
428  // have the correct relative paths. We never remove mappings but that
429  // should be fine.
430  if (SeenWorkingDirectories.insert(CompileCommand.Directory).second)
431  for (const auto &MappedFile : MappedFileContents)
432  if (!llvm::sys::path::is_absolute(MappedFile.first))
433  InMemoryFileSystem->addFile(
434  MappedFile.first, 0,
435  llvm::MemoryBuffer::getMemBuffer(MappedFile.second));
436 
437  std::vector<std::string> CommandLine = CompileCommand.CommandLine;
438  if (ArgsAdjuster)
439  CommandLine = ArgsAdjuster(CommandLine, CompileCommand.Filename);
440  assert(!CommandLine.empty());
441 
442  // Add the resource dir based on the binary of this tool. argv[0] in the
443  // compilation database may refer to a different compiler and we want to
444  // pick up the very same standard library that compiler is using. The
445  // builtin headers in the resource dir need to match the exact clang
446  // version the tool is using.
447  // FIXME: On linux, GetMainExecutable is independent of the value of the
448  // first argument, thus allowing ClangTool and runToolOnCode to just
449  // pass in made-up names here. Make sure this works on other platforms.
450  injectResourceDir(CommandLine, "clang_tool", &StaticSymbol);
451 
452  // FIXME: We need a callback mechanism for the tool writer to output a
453  // customized message for each file.
454  DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; });
455  ToolInvocation Invocation(std::move(CommandLine), Action, Files.get(),
456  PCHContainerOps);
457  Invocation.setDiagnosticConsumer(DiagConsumer);
458 
459  if (!Invocation.run()) {
460  // FIXME: Diagnostics should be used instead.
461  llvm::errs() << "Error while processing " << File << ".\n";
462  ProcessingFailed = true;
463  }
464  // Return to the initial directory to correctly resolve next file by
465  // relative path.
466  if (OverlayFileSystem->setCurrentWorkingDirectory(InitialDirectory.c_str()))
467  llvm::report_fatal_error("Cannot chdir into \"" +
468  Twine(InitialDirectory) + "\n!");
469  }
470  }
471  return ProcessingFailed ? 1 : 0;
472 }
473 
474 namespace {
475 
476 class ASTBuilderAction : public ToolAction {
477  std::vector<std::unique_ptr<ASTUnit>> &ASTs;
478 
479 public:
480  ASTBuilderAction(std::vector<std::unique_ptr<ASTUnit>> &ASTs) : ASTs(ASTs) {}
481 
482  bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
483  FileManager *Files,
484  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
485  DiagnosticConsumer *DiagConsumer) override {
486  std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
487  Invocation, std::move(PCHContainerOps),
488  CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts(),
489  DiagConsumer,
490  /*ShouldOwnClient=*/false),
491  Files);
492  if (!AST)
493  return false;
494 
495  ASTs.push_back(std::move(AST));
496  return true;
497  }
498 };
499 }
500 
501 int ClangTool::buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs) {
502  ASTBuilderAction Action(ASTs);
503  return run(&Action);
504 }
505 
506 std::unique_ptr<ASTUnit>
507 buildASTFromCode(const Twine &Code, const Twine &FileName,
508  std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
509  return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName,
510  "clang-tool", std::move(PCHContainerOps));
511 }
512 
513 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
514  const Twine &Code, const std::vector<std::string> &Args,
515  const Twine &FileName, const Twine &ToolName,
516  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
517  ArgumentsAdjuster Adjuster) {
518  SmallString<16> FileNameStorage;
519  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
520 
521  std::vector<std::unique_ptr<ASTUnit>> ASTs;
522  ASTBuilderAction Action(ASTs);
527  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
529  new FileManager(FileSystemOptions(), OverlayFileSystem));
530 
531  ToolInvocation Invocation(
532  getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileNameRef), FileNameRef),
533  &Action, Files.get(), std::move(PCHContainerOps));
534 
535  SmallString<1024> CodeStorage;
536  InMemoryFileSystem->addFile(FileNameRef, 0,
537  llvm::MemoryBuffer::getMemBuffer(
538  Code.toNullTerminatedStringRef(CodeStorage)));
539  if (!Invocation.run())
540  return nullptr;
541 
542  assert(ASTs.size() == 1);
543  return std::move(ASTs[0]);
544 }
545 
546 } // end namespace tooling
547 } // end namespace clang
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags=nullptr, bool DefaultDiagColor=true, bool DefaultShowOpt=true)
Fill out Opts based on the options given in Args.
static std::vector< std::string > getSyntaxOnlyToolArgs(const Twine &ToolName, const std::vector< std::string > &ExtraArgs, StringRef FileName)
Definition: Tooling.cpp:115
Interface to process a clang::CompilerInvocation.
Definition: Tooling.h:66
bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, const Twine &FileName="input.cc", std::shared_ptr< PCHContainerOperations > PCHContainerOps=std::make_shared< PCHContainerOperations >())
Runs (and deletes) the tool on &#39;Code&#39; with the -fsyntax-only flag.
Definition: Tooling.cpp:106
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:116
void mapVirtualFile(StringRef FilePath, StringRef Content)
Map a virtual file to be used while running the tool.
Definition: Tooling.cpp:236
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation&#39;s diagnostic options and replace any existing one ...
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the &#39;real&#39; file system, as seen by the operating system.
Abstract base class for actions which can be performed by the frontend.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1205
static bool CreateFromArgs(CompilerInvocation &Res, const char *const *ArgBegin, const char *const *ArgEnd, DiagnosticsEngine &Diags)
Create a compiler invocation from a list of input options.
static ParsedClangName getTargetAndModeFromProgramName(StringRef ProgName)
Return any implicit target and/or mode flag for an invocation of the compiler driver as ProgName...
Definition: ToolChain.cpp:179
ToolInvocation(std::vector< std::string > CommandLine, FrontendAction *FAction, FileManager *Files, std::shared_ptr< PCHContainerOperations > PCHContainerOps=std::make_shared< PCHContainerOperations >())
Create a tool invocation.
Definition: Tooling.cpp:223
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Definition: Diagnostic.h:1395
ArgumentsAdjuster getClangStripDependencyFileAdjuster()
Gets an argument adjuster which removes dependency-file related command line arguments.
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, ArgumentsAdjuster Second)
Gets an argument adjuster which adjusts the arguments in sequence with the First adjuster and then wi...
Interface to generate clang::FrontendActions.
Definition: Tooling.h:84
void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster)
Append a command line arguments adjuster to the adjuster chain.
Definition: Tooling.cpp:349
int buildASTs(std::vector< std::unique_ptr< ASTUnit >> &ASTs)
Create an AST for each file specified in the command line and append them to ASTs.
Definition: Tooling.cpp:501
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
Definition: Format.h:1821
void clearArgumentsAdjusters()
Clear the command line arguments adjuster chain.
Definition: Tooling.cpp:357
static clang::driver::Driver * newDriver(clang::DiagnosticsEngine *Diagnostics, const char *BinaryName, IntrusiveRefCntPtr< vfs::FileSystem > VFS)
Builds a clang driver initialized for running clang tools.
Definition: Tooling.cpp:53
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
An in-memory file system.
std::vector< std::pair< std::string, std::string > > FileContentMappings
The first part of the pair is the filename, the second part the file-content.
Definition: Tooling.h:159
bool runInvocation(std::shared_ptr< clang::CompilerInvocation > Invocation, FileManager *Files, std::shared_ptr< PCHContainerOperations > PCHContainerOps, DiagnosticConsumer *DiagConsumer) override
Invokes the compiler with a FrontendAction created by create().
Definition: Tooling.cpp:301
A file system that allows overlaying one AbstractFileSystem on top of another.
std::string Directory
The working directory the command was executed from.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
std::unique_ptr< llvm::opt::OptTable > createDriverOptTable()
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:65
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
void mapVirtualFile(StringRef FilePath, StringRef Content)
Map a virtual file to be used while running the tool.
Definition: Tooling.cpp:345
ArgumentsAdjuster getClangStripOutputAdjuster()
Gets an argument adjuster which removes output-related command line arguments.
std::function< CommandLineArguments(const CommandLineArguments &, StringRef Filename)> ArgumentsAdjuster
A prototype of a command line adjuster.
static std::string GetResourcesPath(const char *Argv0, void *MainAddr)
Get the directory where the compiler headers reside, relative to the compiler binary (found by the pa...
std::string Filename
The source file associated with the command.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
Definition: Job.h:107
bool run()
Run the clang invocation.
Definition: Tooling.cpp:242
std::string getAbsolutePath(StringRef File)
Returns the absolute path of File, by prepending it with the current directory if File is not absolut...
Definition: Tooling.cpp:162
JobList - A sequence of jobs to perform.
Definition: Job.h:166
virtual bool runInvocation(std::shared_ptr< clang::CompilerInvocation > Invocation, FileManager *Files, std::shared_ptr< PCHContainerOperations > PCHContainerOps, DiagnosticConsumer *DiagConsumer)=0
Perform an action for an invocation.
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
Definition: Job.cpp:424
void addTargetAndModeForProgramName(std::vector< std::string > &CommandLine, StringRef InvokedAs)
Changes CommandLine to contain implicit flags that would have been defined had the compiler driver be...
Definition: Tooling.cpp:177
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer)
Set a DiagnosticConsumer to use during parsing.
Definition: Tooling.h:248
Interface for compilation databases.
static void injectResourceDir(CommandLineArguments &Args, const char *Argv0, void *MainAddr)
Definition: Tooling.cpp:361
#define false
Definition: stdbool.h:33
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler&#39;s CompilerInvocation object...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Specifies the working directory and command of a compilation.
Options for controlling the compiler diagnostics engine.
Command - An executable path/name and argument vector to execute.
Definition: Job.h:44
ClangTool(const CompilationDatabase &Compilations, ArrayRef< std::string > SourcePaths, std::shared_ptr< PCHContainerOperations > PCHContainerOps=std::make_shared< PCHContainerOperations >())
Constructs a clang tool to run over a list of files.
Definition: Tooling.cpp:328
std::unique_ptr< ASTUnit > buildASTFromCodeWithArgs(const Twine &Code, const std::vector< std::string > &Args, const Twine &FileName="input.cc", const Twine &ToolName="clang-tool", std::shared_ptr< PCHContainerOperations > PCHContainerOps=std::make_shared< PCHContainerOperations >(), ArgumentsAdjuster Adjuster=getClangStripDependencyFileAdjuster())
Builds an AST for &#39;Code&#39; with additional flags.
Definition: Tooling.cpp:513
void clearStatCaches()
Removes all FileSystemStatCache objects from the manager.
iterator begin()
Definition: Job.h:190
void setTitle(std::string Value)
Definition: Driver.h:293
Utility to run a FrontendAction in a single clang invocation.
Definition: Tooling.h:216
Dataflow Directional Tag Classes.
const llvm::opt::ArgStringList & getArguments() const
Definition: Job.h:126
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Used for handling and querying diagnostic IDs.
Helper class for holding the data necessary to invoke the compiler.
std::vector< std::string > CommandLineArguments
A sequence of command line arguments.
size_type size() const
Definition: Job.h:189
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:34
bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code, const std::vector< std::string > &Args, const Twine &FileName="input.cc", const Twine &ToolName="clang-tool", std::shared_ptr< PCHContainerOperations > PCHContainerOps=std::make_shared< PCHContainerOperations >(), const FileContentMappings &VirtualMappedFiles=FileContentMappings())
Runs (and deletes) the tool on &#39;Code&#39; with the -fsyntax-only flag and with additional other flags...
Definition: Tooling.cpp:126
std::vector< std::string > CommandLine
The command line that was executed.
std::unique_ptr< ASTUnit > buildASTFromCode(const Twine &Code, const Twine &FileName="input.cc", std::shared_ptr< PCHContainerOperations > PCHContainerOps=std::make_shared< PCHContainerOperations >())
Builds an AST for &#39;Code&#39;.
Definition: Tooling.cpp:507
ArgumentsAdjuster getClangSyntaxOnlyAdjuster()
Gets an argument adjuster that converts input command line arguments to the "syntax check only" varia...
Keeps track of options that affect how file operations are performed.
void setInvocation(std::shared_ptr< CompilerInvocation > Value)
setInvocation - Replace the current invocation.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
Definition: FileManager.h:225
const char * getName() const
Definition: Tool.h:80
clang::CompilerInvocation * newInvocation(clang::DiagnosticsEngine *Diagnostics, const llvm::opt::ArgStringList &CC1Args)
Creates a CompilerInvocation.
Definition: Tooling.cpp:93
static const llvm::opt::ArgStringList * getCC1Arguments(clang::DiagnosticsEngine *Diagnostics, clang::driver::Compilation *Compilation)
Retrieves the clang CC1 specific flags out of the compilation&#39;s jobs.
Definition: Tooling.cpp:66
#define true
Definition: stdbool.h:32
int run(ToolAction *Action)
Runs an action over all files specified in the command line.
Definition: Tooling.cpp:373
virtual std::vector< CompileCommand > getCompileCommands(StringRef FilePath) const =0
Returns all compile commands in which the specified file was compiled.