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