clang  5.0.0
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.second.empty()) {
194  CommandLine.insert(++CommandLine.begin(), TargetMode.second);
195  }
196  if (!AlreadyHasTarget && !TargetMode.first.empty()) {
197  CommandLine.insert(++CommandLine.begin(), {"-target", TargetMode.first});
198  }
199  }
200 }
201 
202 namespace {
203 
204 class SingleFrontendActionFactory : public FrontendActionFactory {
205  FrontendAction *Action;
206 
207 public:
208  SingleFrontendActionFactory(FrontendAction *Action) : Action(Action) {}
209 
210  FrontendAction *create() override { return Action; }
211 };
212 
213 }
214 
216  std::vector<std::string> CommandLine, ToolAction *Action,
217  FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
218  : CommandLine(std::move(CommandLine)), Action(Action), OwnsAction(false),
219  Files(Files), PCHContainerOps(std::move(PCHContainerOps)),
220  DiagConsumer(nullptr) {}
221 
223  std::vector<std::string> CommandLine, FrontendAction *FAction,
224  FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
225  : CommandLine(std::move(CommandLine)),
226  Action(new SingleFrontendActionFactory(FAction)), OwnsAction(true),
227  Files(Files), PCHContainerOps(std::move(PCHContainerOps)),
228  DiagConsumer(nullptr) {}
229 
231  if (OwnsAction)
232  delete Action;
233 }
234 
235 void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) {
236  SmallString<1024> PathStorage;
237  llvm::sys::path::native(FilePath, PathStorage);
238  MappedFileContents[PathStorage] = Content;
239 }
240 
242  std::vector<const char*> Argv;
243  for (const std::string &Str : CommandLine)
244  Argv.push_back(Str.c_str());
245  const char *const BinaryName = Argv[0];
247  unsigned MissingArgIndex, MissingArgCount;
248  std::unique_ptr<llvm::opt::OptTable> Opts = driver::createDriverOptTable();
249  llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs(
250  ArrayRef<const char *>(Argv).slice(1), MissingArgIndex, MissingArgCount);
251  ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
252  TextDiagnosticPrinter DiagnosticPrinter(
253  llvm::errs(), &*DiagOpts);
254  DiagnosticsEngine Diagnostics(
256  DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
257 
258  const std::unique_ptr<clang::driver::Driver> Driver(
259  newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem()));
260  // Since the input might only be virtual, don't check whether it exists.
261  Driver->setCheckInputsExist(false);
262  const std::unique_ptr<clang::driver::Compilation> Compilation(
263  Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
264  if (!Compilation)
265  return false;
266  const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
267  &Diagnostics, Compilation.get());
268  if (!CC1Args) {
269  return false;
270  }
271  std::unique_ptr<clang::CompilerInvocation> Invocation(
272  newInvocation(&Diagnostics, *CC1Args));
273  // FIXME: remove this when all users have migrated!
274  for (const auto &It : MappedFileContents) {
275  // Inject the code as the given file name into the preprocessor options.
276  std::unique_ptr<llvm::MemoryBuffer> Input =
277  llvm::MemoryBuffer::getMemBuffer(It.getValue());
278  Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(),
279  Input.release());
280  }
281  return runInvocation(BinaryName, Compilation.get(), std::move(Invocation),
282  std::move(PCHContainerOps));
283 }
284 
285 bool ToolInvocation::runInvocation(
286  const char *BinaryName, clang::driver::Compilation *Compilation,
287  std::shared_ptr<clang::CompilerInvocation> Invocation,
288  std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
289  // Show the invocation, with -v.
290  if (Invocation->getHeaderSearchOpts().Verbose) {
291  llvm::errs() << "clang Invocation:\n";
292  Compilation->getJobs().Print(llvm::errs(), "\n", true);
293  llvm::errs() << "\n";
294  }
295 
296  return Action->runInvocation(std::move(Invocation), Files,
297  std::move(PCHContainerOps), DiagConsumer);
298 }
299 
301  std::shared_ptr<CompilerInvocation> Invocation, FileManager *Files,
302  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
303  DiagnosticConsumer *DiagConsumer) {
304  // Create a compiler instance to handle the actual work.
305  clang::CompilerInstance Compiler(std::move(PCHContainerOps));
306  Compiler.setInvocation(std::move(Invocation));
307  Compiler.setFileManager(Files);
308 
309  // The FrontendAction can have lifetime requirements for Compiler or its
310  // members, and we need to ensure it's deleted earlier than Compiler. So we
311  // pass it to an std::unique_ptr declared after the Compiler variable.
312  std::unique_ptr<FrontendAction> ScopedToolAction(create());
313 
314  // Create the compiler's actual diagnostics engine.
315  Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
316  if (!Compiler.hasDiagnostics())
317  return false;
318 
319  Compiler.createSourceManager(*Files);
320 
321  const bool Success = Compiler.ExecuteAction(*ScopedToolAction);
322 
323  Files->clearStatCaches();
324  return Success;
325 }
326 
328  ArrayRef<std::string> SourcePaths,
329  std::shared_ptr<PCHContainerOperations> PCHContainerOps)
330  : Compilations(Compilations), SourcePaths(SourcePaths),
331  PCHContainerOps(std::move(PCHContainerOps)),
332  OverlayFileSystem(new vfs::OverlayFileSystem(vfs::getRealFileSystem())),
333  InMemoryFileSystem(new vfs::InMemoryFileSystem),
334  Files(new FileManager(FileSystemOptions(), OverlayFileSystem)),
335  DiagConsumer(nullptr) {
336  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
340 }
341 
343 
344 void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
345  MappedFileContents.push_back(std::make_pair(FilePath, Content));
346 }
347 
349  if (ArgsAdjuster)
350  ArgsAdjuster =
351  combineAdjusters(std::move(ArgsAdjuster), std::move(Adjuster));
352  else
353  ArgsAdjuster = std::move(Adjuster);
354 }
355 
357  ArgsAdjuster = nullptr;
358 }
359 
360 static void injectResourceDir(CommandLineArguments &Args, const char *Argv0,
361  void *MainAddr) {
362  // Allow users to override the resource dir.
363  for (StringRef Arg : Args)
364  if (Arg.startswith("-resource-dir"))
365  return;
366 
367  // If there's no override in place add our resource dir.
368  Args.push_back("-resource-dir=" +
369  CompilerInvocation::GetResourcesPath(Argv0, MainAddr));
370 }
371 
373  // Exists solely for the purpose of lookup of the resource path.
374  // This just needs to be some symbol in the binary.
375  static int StaticSymbol;
376 
377  llvm::SmallString<128> InitialDirectory;
378  if (std::error_code EC = llvm::sys::fs::current_path(InitialDirectory))
379  llvm::report_fatal_error("Cannot detect current path: " +
380  Twine(EC.message()));
381 
382  // First insert all absolute paths into the in-memory VFS. These are global
383  // for all compile commands.
384  if (SeenWorkingDirectories.insert("/").second)
385  for (const auto &MappedFile : MappedFileContents)
386  if (llvm::sys::path::is_absolute(MappedFile.first))
387  InMemoryFileSystem->addFile(
388  MappedFile.first, 0,
389  llvm::MemoryBuffer::getMemBuffer(MappedFile.second));
390 
391  bool ProcessingFailed = false;
392  for (const auto &SourcePath : SourcePaths) {
393  std::string File(getAbsolutePath(SourcePath));
394 
395  // Currently implementations of CompilationDatabase::getCompileCommands can
396  // change the state of the file system (e.g. prepare generated headers), so
397  // this method needs to run right before we invoke the tool, as the next
398  // file may require a different (incompatible) state of the file system.
399  //
400  // FIXME: Make the compilation database interface more explicit about the
401  // requirements to the order of invocation of its members.
402  std::vector<CompileCommand> CompileCommandsForFile =
403  Compilations.getCompileCommands(File);
404  if (CompileCommandsForFile.empty()) {
405  // FIXME: There are two use cases here: doing a fuzzy
406  // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
407  // about the .cc files that were not found, and the use case where I
408  // specify all files I want to run over explicitly, where this should
409  // be an error. We'll want to add an option for this.
410  llvm::errs() << "Skipping " << File << ". Compile command not found.\n";
411  continue;
412  }
413  for (CompileCommand &CompileCommand : CompileCommandsForFile) {
414  // FIXME: chdir is thread hostile; on the other hand, creating the same
415  // behavior as chdir is complex: chdir resolves the path once, thus
416  // guaranteeing that all subsequent relative path operations work
417  // on the same path the original chdir resulted in. This makes a
418  // difference for example on network filesystems, where symlinks might be
419  // switched during runtime of the tool. Fixing this depends on having a
420  // file system abstraction that allows openat() style interactions.
421  if (OverlayFileSystem->setCurrentWorkingDirectory(
423  llvm::report_fatal_error("Cannot chdir into \"" +
424  Twine(CompileCommand.Directory) + "\n!");
425 
426  // Now fill the in-memory VFS with the relative file mappings so it will
427  // have the correct relative paths. We never remove mappings but that
428  // should be fine.
429  if (SeenWorkingDirectories.insert(CompileCommand.Directory).second)
430  for (const auto &MappedFile : MappedFileContents)
431  if (!llvm::sys::path::is_absolute(MappedFile.first))
432  InMemoryFileSystem->addFile(
433  MappedFile.first, 0,
434  llvm::MemoryBuffer::getMemBuffer(MappedFile.second));
435 
436  std::vector<std::string> CommandLine = CompileCommand.CommandLine;
437  if (ArgsAdjuster)
438  CommandLine = ArgsAdjuster(CommandLine, CompileCommand.Filename);
439  assert(!CommandLine.empty());
440 
441  // Add the resource dir based on the binary of this tool. argv[0] in the
442  // compilation database may refer to a different compiler and we want to
443  // pick up the very same standard library that compiler is using. The
444  // builtin headers in the resource dir need to match the exact clang
445  // version the tool is using.
446  // FIXME: On linux, GetMainExecutable is independent of the value of the
447  // first argument, thus allowing ClangTool and runToolOnCode to just
448  // pass in made-up names here. Make sure this works on other platforms.
449  injectResourceDir(CommandLine, "clang_tool", &StaticSymbol);
450 
451  // FIXME: We need a callback mechanism for the tool writer to output a
452  // customized message for each file.
453  DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; });
454  ToolInvocation Invocation(std::move(CommandLine), Action, Files.get(),
455  PCHContainerOps);
456  Invocation.setDiagnosticConsumer(DiagConsumer);
457 
458  if (!Invocation.run()) {
459  // FIXME: Diagnostics should be used instead.
460  llvm::errs() << "Error while processing " << File << ".\n";
461  ProcessingFailed = true;
462  }
463  // Return to the initial directory to correctly resolve next file by
464  // relative path.
465  if (OverlayFileSystem->setCurrentWorkingDirectory(InitialDirectory.c_str()))
466  llvm::report_fatal_error("Cannot chdir into \"" +
467  Twine(InitialDirectory) + "\n!");
468  }
469  }
470  return ProcessingFailed ? 1 : 0;
471 }
472 
473 namespace {
474 
475 class ASTBuilderAction : public ToolAction {
476  std::vector<std::unique_ptr<ASTUnit>> &ASTs;
477 
478 public:
479  ASTBuilderAction(std::vector<std::unique_ptr<ASTUnit>> &ASTs) : ASTs(ASTs) {}
480 
481  bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
482  FileManager *Files,
483  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
484  DiagnosticConsumer *DiagConsumer) override {
485  std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
486  Invocation, std::move(PCHContainerOps),
487  CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts(),
488  DiagConsumer,
489  /*ShouldOwnClient=*/false),
490  Files);
491  if (!AST)
492  return false;
493 
494  ASTs.push_back(std::move(AST));
495  return true;
496  }
497 };
498 }
499 
500 int ClangTool::buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs) {
501  ASTBuilderAction Action(ASTs);
502  return run(&Action);
503 }
504 
505 std::unique_ptr<ASTUnit>
506 buildASTFromCode(const Twine &Code, const Twine &FileName,
507  std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
508  return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName,
509  "clang-tool", std::move(PCHContainerOps));
510 }
511 
512 std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
513  const Twine &Code, const std::vector<std::string> &Args,
514  const Twine &FileName, const Twine &ToolName,
515  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
516  ArgumentsAdjuster Adjuster) {
517  SmallString<16> FileNameStorage;
518  StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
519 
520  std::vector<std::unique_ptr<ASTUnit>> ASTs;
521  ASTBuilderAction Action(ASTs);
526  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
528  new FileManager(FileSystemOptions(), OverlayFileSystem));
529 
530  ToolInvocation Invocation(
531  getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileNameRef), FileNameRef),
532  &Action, Files.get(), std::move(PCHContainerOps));
533 
534  SmallString<1024> CodeStorage;
535  InMemoryFileSystem->addFile(FileNameRef, 0,
536  llvm::MemoryBuffer::getMemBuffer(
537  Code.toNullTerminatedStringRef(CodeStorage)));
538  if (!Invocation.run())
539  return nullptr;
540 
541  assert(ASTs.size() == 1);
542  return std::move(ASTs[0]);
543 }
544 
545 } // end namespace tooling
546 } // 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 'Code' 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:235
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' 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.
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:222
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
Definition: Job.h:107
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.
const StringRef FilePath
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, ArgumentsAdjuster Second)
Gets an argument adjuster which adjusts the arguments in sequence with the First adjuster and then wi...
void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster)
Append a command line arguments adjuster to the adjuster chain.
Definition: Tooling.cpp:348
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:500
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
void clearArgumentsAdjusters()
Clear the command line arguments adjuster chain.
Definition: Tooling.cpp:356
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
FrontendAction * Action
Definition: Tooling.cpp:205
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:300
A file system that allows overlaying one AbstractFileSystem on top of another.
std::string Directory
The working directory the command was executed from.
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
Definition: FileManager.h:225
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:344
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.
bool run()
Run the clang invocation.
Definition: Tooling.cpp:241
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
FormatToken * Token
JobList - A sequence of jobs to perform.
Definition: Job.h:166
static std::pair< std::string, std::string > getTargetAndModeFromProgramName(StringRef ProgName)
Return any implicit target and/or mode flag for an invocation of the compiler driver as ProgName...
Definition: ToolChain.cpp:180
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 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:360
#define false
Definition: stdbool.h:33
StringRef FileName
Definition: Format.cpp:1465
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
size_type size() const
Definition: Job.h:189
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:327
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 'Code' with additional flags.
Definition: Tooling.cpp:512
void clearStatCaches()
Removes all FileSystemStatCache objects from the manager.
iterator begin()
Definition: Job.h:190
void setTitle(std::string Value)
Definition: Driver.h:291
const llvm::opt::ArgStringList & getArguments() const
Definition: Job.h:126
const char * getName() const
Definition: Tool.h:80
Utility to run a FrontendAction in a single clang invocation.
Definition: Tooling.h:216
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 > CommandLine
std::vector< std::string > CommandLineArguments
A sequence of command line arguments.
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 'Code' 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 'Code'.
Definition: Tooling.cpp:506
ArgumentsAdjuster getClangSyntaxOnlyAdjuster()
Gets an argument adjuster that converts input command line arguments to the "syntax check only" varia...
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
Definition: Job.cpp:423
Keeps track of options that affect how file operations are performed.
void setInvocation(std::shared_ptr< CompilerInvocation > Value)
setInvocation - Replace the current invocation.
std::vector< std::unique_ptr< ASTUnit > > & ASTs
Definition: Tooling.cpp:476
clang::CompilerInvocation * newInvocation(clang::DiagnosticsEngine *Diagnostics, const llvm::opt::ArgStringList &CC1Args)
Creates a CompilerInvocation.
Definition: Tooling.cpp:93
const StringRef Input
static const llvm::opt::ArgStringList * getCC1Arguments(clang::DiagnosticsEngine *Diagnostics, clang::driver::Compilation *Compilation)
Retrieves the clang CC1 specific flags out of the compilation'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:372
virtual clang::FrontendAction * create()=0
Returns a new clang::FrontendAction.
virtual std::vector< CompileCommand > getCompileCommands(StringRef FilePath) const =0
Returns all compile commands in which the specified file was compiled.