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