clang  14.0.0git
DependencyScanningWorker.cpp
Go to the documentation of this file.
1 //===- DependencyScanningWorker.cpp - clang-scan-deps worker --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
15 #include "clang/Frontend/Utils.h"
19 #include "clang/Tooling/Tooling.h"
20 
21 using namespace clang;
22 using namespace tooling;
23 using namespace dependencies;
24 
25 namespace {
26 
27 /// Forwards the gatherered dependencies to the consumer.
28 class DependencyConsumerForwarder : public DependencyFileGenerator {
29 public:
30  DependencyConsumerForwarder(std::unique_ptr<DependencyOutputOptions> Opts,
31  DependencyConsumer &C)
32  : DependencyFileGenerator(*Opts), Opts(std::move(Opts)), C(C) {}
33 
34  void finishedMainFile(DiagnosticsEngine &Diags) override {
35  C.handleDependencyOutputOpts(*Opts);
36  llvm::SmallString<256> CanonPath;
37  for (const auto &File : getDependencies()) {
38  CanonPath = File;
39  llvm::sys::path::remove_dots(CanonPath, /*remove_dot_dot=*/true);
40  C.handleFileDependency(CanonPath);
41  }
42  }
43 
44 private:
45  std::unique_ptr<DependencyOutputOptions> Opts;
46  DependencyConsumer &C;
47 };
48 
49 /// A listener that collects the imported modules and optionally the input
50 /// files.
51 class PrebuiltModuleListener : public ASTReaderListener {
52 public:
53  PrebuiltModuleListener(llvm::StringMap<std::string> &PrebuiltModuleFiles,
54  llvm::StringSet<> &InputFiles, bool VisitInputFiles)
55  : PrebuiltModuleFiles(PrebuiltModuleFiles), InputFiles(InputFiles),
56  VisitInputFiles(VisitInputFiles) {}
57 
58  bool needsImportVisitation() const override { return true; }
59  bool needsInputFileVisitation() override { return VisitInputFiles; }
60  bool needsSystemInputFileVisitation() override { return VisitInputFiles; }
61 
62  void visitImport(StringRef ModuleName, StringRef Filename) override {
63  PrebuiltModuleFiles.insert({ModuleName, Filename.str()});
64  }
65 
66  bool visitInputFile(StringRef Filename, bool isSystem, bool isOverridden,
67  bool isExplicitModule) override {
68  InputFiles.insert(Filename);
69  return true;
70  }
71 
72 private:
73  llvm::StringMap<std::string> &PrebuiltModuleFiles;
74  llvm::StringSet<> &InputFiles;
75  bool VisitInputFiles;
76 };
77 
78 using PrebuiltModuleFilesT = decltype(HeaderSearchOptions::PrebuiltModuleFiles);
79 
80 /// Visit the given prebuilt module and collect all of the modules it
81 /// transitively imports and contributing input files.
82 static void visitPrebuiltModule(StringRef PrebuiltModuleFilename,
83  CompilerInstance &CI,
84  PrebuiltModuleFilesT &ModuleFiles,
85  llvm::StringSet<> &InputFiles,
86  bool VisitInputFiles) {
87  // Maps the names of modules that weren't yet visited to their PCM path.
88  llvm::StringMap<std::string> ModuleFilesWorklist;
89  // Contains PCM paths of all visited modules.
90  llvm::StringSet<> VisitedModuleFiles;
91 
92  PrebuiltModuleListener Listener(ModuleFilesWorklist, InputFiles,
93  VisitInputFiles);
94 
95  auto GatherModuleFileInfo = [&](StringRef ASTFile) {
97  ASTFile, CI.getFileManager(), CI.getPCHContainerReader(),
98  /*FindModuleFileExtensions=*/false, Listener,
99  /*ValidateDiagnosticOptions=*/false);
100  };
101 
102  GatherModuleFileInfo(PrebuiltModuleFilename);
103  while (!ModuleFilesWorklist.empty()) {
104  auto WorklistItemIt = ModuleFilesWorklist.begin();
105 
106  if (!VisitedModuleFiles.contains(WorklistItemIt->getValue())) {
107  VisitedModuleFiles.insert(WorklistItemIt->getValue());
108  GatherModuleFileInfo(WorklistItemIt->getValue());
109  ModuleFiles[WorklistItemIt->getKey().str()] = WorklistItemIt->getValue();
110  }
111 
112  ModuleFilesWorklist.erase(WorklistItemIt);
113  }
114 }
115 
116 /// Transform arbitrary file name into an object-like file name.
117 static std::string makeObjFileName(StringRef FileName) {
118  SmallString<128> ObjFileName(FileName);
119  llvm::sys::path::replace_extension(ObjFileName, "o");
120  return std::string(ObjFileName.str());
121 }
122 
123 /// Deduce the dependency target based on the output file and input files.
124 static std::string
125 deduceDepTarget(const std::string &OutputFile,
126  const SmallVectorImpl<FrontendInputFile> &InputFiles) {
127  if (OutputFile != "-")
128  return OutputFile;
129 
130  if (InputFiles.empty() || !InputFiles.front().isFile())
131  return "clang-scan-deps\\ dependency";
132 
133  return makeObjFileName(InputFiles.front().getFile());
134 }
135 
136 /// Sanitize diagnostic options for dependency scan.
137 static void sanitizeDiagOpts(DiagnosticOptions &DiagOpts) {
138  // Don't print 'X warnings and Y errors generated'.
139  DiagOpts.ShowCarets = false;
140  // Don't write out diagnostic file.
141  DiagOpts.DiagnosticSerializationFile.clear();
142  // Don't treat warnings as errors.
143  DiagOpts.Warnings.push_back("no-error");
144 }
145 
146 /// A clang tool that runs the preprocessor in a mode that's optimized for
147 /// dependency scanning for the given compiler invocation.
148 class DependencyScanningAction : public tooling::ToolAction {
149 public:
150  DependencyScanningAction(
151  StringRef WorkingDirectory, DependencyConsumer &Consumer,
154  ScanningOutputFormat Format, bool OptimizeArgs,
155  llvm::Optional<StringRef> ModuleName = None)
156  : WorkingDirectory(WorkingDirectory), Consumer(Consumer),
157  DepFS(std::move(DepFS)), PPSkipMappings(PPSkipMappings), Format(Format),
158  OptimizeArgs(OptimizeArgs), ModuleName(ModuleName) {}
159 
160  bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
161  FileManager *FileMgr,
162  std::shared_ptr<PCHContainerOperations> PCHContainerOps,
163  DiagnosticConsumer *DiagConsumer) override {
164  // Make a deep copy of the original Clang invocation.
165  CompilerInvocation OriginalInvocation(*Invocation);
166 
167  // Create a compiler instance to handle the actual work.
168  CompilerInstance Compiler(std::move(PCHContainerOps));
169  Compiler.setInvocation(std::move(Invocation));
170 
171  // Create the compiler's actual diagnostics engine.
172  sanitizeDiagOpts(Compiler.getDiagnosticOpts());
173  Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
174  if (!Compiler.hasDiagnostics())
175  return false;
176 
177  Compiler.getPreprocessorOpts().AllowPCHWithDifferentModulesCachePath = true;
178 
179  FileMgr->getFileSystemOpts().WorkingDir = std::string(WorkingDirectory);
180  Compiler.setFileManager(FileMgr);
181  Compiler.createSourceManager(*FileMgr);
182 
183  llvm::StringSet<> PrebuiltModulesInputFiles;
184  // Store the list of prebuilt module files into header search options. This
185  // will prevent the implicit build to create duplicate modules and will
186  // force reuse of the existing prebuilt module files instead.
187  if (!Compiler.getPreprocessorOpts().ImplicitPCHInclude.empty())
188  visitPrebuiltModule(
189  Compiler.getPreprocessorOpts().ImplicitPCHInclude, Compiler,
190  Compiler.getHeaderSearchOpts().PrebuiltModuleFiles,
191  PrebuiltModulesInputFiles, /*VisitInputFiles=*/DepFS != nullptr);
192 
193  // Use the dependency scanning optimized file system if requested to do so.
194  if (DepFS) {
195  const CompilerInvocation &CI = Compiler.getInvocation();
196  DepFS->clearIgnoredFiles();
197  // Ignore any files that contributed to prebuilt modules. The implicit
198  // build validates the modules by comparing the reported sizes of their
199  // inputs to the current state of the filesystem. Minimization would throw
200  // this mechanism off.
201  for (const auto &File : PrebuiltModulesInputFiles)
202  DepFS->ignoreFile(File.getKey());
203  // Add any filenames that were explicity passed in the build settings and
204  // that might be opened, as we want to ensure we don't run source
205  // minimization on them.
206  for (const auto &Entry : CI.getHeaderSearchOpts().UserEntries)
207  DepFS->ignoreFile(Entry.Path);
208  for (const auto &Entry : CI.getHeaderSearchOpts().VFSOverlayFiles)
209  DepFS->ignoreFile(Entry);
210 
211  // Support for virtual file system overlays on top of the caching
212  // filesystem.
214  CI, Compiler.getDiagnostics(), DepFS));
215 
216  // Pass the skip mappings which should speed up excluded conditional block
217  // skipping in the preprocessor.
218  if (PPSkipMappings)
219  Compiler.getPreprocessorOpts()
220  .ExcludedConditionalDirectiveSkipMappings = PPSkipMappings;
221  }
222 
223  // Create the dependency collector that will collect the produced
224  // dependencies.
225  //
226  // This also moves the existing dependency output options from the
227  // invocation to the collector. The options in the invocation are reset,
228  // which ensures that the compiler won't create new dependency collectors,
229  // and thus won't write out the extra '.d' files to disk.
230  auto Opts = std::make_unique<DependencyOutputOptions>();
231  std::swap(*Opts, Compiler.getInvocation().getDependencyOutputOpts());
232  // We need at least one -MT equivalent for the generator of make dependency
233  // files to work.
234  if (Opts->Targets.empty())
235  Opts->Targets = {deduceDepTarget(Compiler.getFrontendOpts().OutputFile,
236  Compiler.getFrontendOpts().Inputs)};
237  Opts->IncludeSystemHeaders = true;
238 
239  switch (Format) {
241  Compiler.addDependencyCollector(
242  std::make_shared<DependencyConsumerForwarder>(std::move(Opts),
243  Consumer));
244  break;
246  Compiler.addDependencyCollector(std::make_shared<ModuleDepCollector>(
247  std::move(Opts), Compiler, Consumer, std::move(OriginalInvocation),
248  OptimizeArgs));
249  break;
250  }
251 
252  // Consider different header search and diagnostic options to create
253  // different modules. This avoids the unsound aliasing of module PCMs.
254  //
255  // TODO: Implement diagnostic bucketing to reduce the impact of strict
256  // context hashing.
257  Compiler.getHeaderSearchOpts().ModulesStrictContextHash = true;
258 
259  std::unique_ptr<FrontendAction> Action;
260 
261  if (ModuleName.hasValue())
262  Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName);
263  else
264  Action = std::make_unique<ReadPCHAndPreprocessAction>();
265 
266  const bool Result = Compiler.ExecuteAction(*Action);
267  if (!DepFS)
268  FileMgr->clearStatCache();
269  return Result;
270  }
271 
272 private:
273  StringRef WorkingDirectory;
274  DependencyConsumer &Consumer;
277  ScanningOutputFormat Format;
278  bool OptimizeArgs;
279  llvm::Optional<StringRef> ModuleName;
280 };
281 
282 } // end anonymous namespace
283 
285  DependencyScanningService &Service)
286  : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()) {
287  PCHContainerOps = std::make_shared<PCHContainerOperations>();
288  PCHContainerOps->registerReader(
289  std::make_unique<ObjectFilePCHContainerReader>());
290  // We don't need to write object files, but the current PCH implementation
291  // requires the writer to be registered as well.
292  PCHContainerOps->registerWriter(
293  std::make_unique<ObjectFilePCHContainerWriter>());
294 
295  auto OverlayFS = llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(
296  llvm::vfs::createPhysicalFileSystem());
297  InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
298  OverlayFS->pushOverlay(InMemoryFS);
299  RealFS = OverlayFS;
300 
301  if (Service.canSkipExcludedPPRanges())
302  PPSkipMappings =
303  std::make_unique<ExcludedPreprocessorDirectiveSkipMapping>();
306  Service.getSharedCache(), RealFS, PPSkipMappings.get());
307  if (Service.canReuseFileManager())
308  Files = new FileManager(FileSystemOptions(), RealFS);
309 }
310 
311 static llvm::Error
313  llvm::function_ref<bool(DiagnosticConsumer &, DiagnosticOptions &)>
314  BodyShouldSucceed) {
315  sanitizeDiagOpts(*DiagOpts);
316 
317  // Capture the emitted diagnostics and report them to the client
318  // in the case of a failure.
319  std::string DiagnosticOutput;
320  llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
321  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts);
322 
323  if (BodyShouldSucceed(DiagPrinter, *DiagOpts))
324  return llvm::Error::success();
325  return llvm::make_error<llvm::StringError>(DiagnosticsOS.str(),
326  llvm::inconvertibleErrorCode());
327 }
328 
330  StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
331  DependencyConsumer &Consumer, llvm::Optional<StringRef> ModuleName) {
332  // Reset what might have been modified in the previous worker invocation.
333  RealFS->setCurrentWorkingDirectory(WorkingDirectory);
334  if (Files)
335  Files->setVirtualFileSystem(RealFS);
336 
338  Files ? Files : new FileManager(FileSystemOptions(), RealFS);
339 
340  Optional<std::vector<std::string>> ModifiedCommandLine;
341  if (ModuleName.hasValue()) {
342  ModifiedCommandLine = CommandLine;
343  InMemoryFS->addFile(*ModuleName, 0, llvm::MemoryBuffer::getMemBuffer(""));
344  ModifiedCommandLine->emplace_back(*ModuleName);
345  }
346 
347  const std::vector<std::string> &FinalCommandLine =
348  ModifiedCommandLine ? *ModifiedCommandLine : CommandLine;
349 
350  std::vector<const char *> FinalCCommandLine(CommandLine.size(), nullptr);
351  llvm::transform(CommandLine, FinalCCommandLine.begin(),
352  [](const std::string &Str) { return Str.c_str(); });
353 
354  return runWithDiags(CreateAndPopulateDiagOpts(FinalCCommandLine).release(),
355  [&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) {
356  DependencyScanningAction Action(
357  WorkingDirectory, Consumer, DepFS,
358  PPSkipMappings.get(), Format, OptimizeArgs,
359  ModuleName);
360  // Create an invocation that uses the underlying file
361  // system to ensure that any file system requests that
362  // are made by the driver do not go through the
363  // dependency scanning filesystem.
364  ToolInvocation Invocation(FinalCommandLine, &Action,
365  CurrentFiles.get(),
366  PCHContainerOps);
367  Invocation.setDiagnosticConsumer(&DC);
368  Invocation.setDiagnosticOptions(&DiagOpts);
369  return Invocation.run();
370  });
371 }
DependencyScanningService.h
clang::tooling::ToolInvocation
Utility to run a FrontendAction in a single clang invocation.
Definition: Tooling.h:240
clang::DiagnosticOptions::DiagnosticSerializationFile
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Definition: DiagnosticOptions.h:107
clang::DeclaratorContext::File
@ File
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::tooling::dependencies::DependencyConsumer
Definition: DependencyScanningWorker.h:32
clang::FileManager::clearStatCache
void clearStatCache()
Removes the FileSystemStatCache object from the manager.
Definition: FileManager.cpp:68
clang::DiagnosticConsumer
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Definition: Diagnostic.h:1722
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:54
Filename
StringRef Filename
Definition: Format.cpp:2333
clang::DiagnosticsEngine
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:191
clang::tooling::ToolInvocation::setDiagnosticConsumer
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer)
Set a DiagnosticConsumer to use during driver command-line parsing and the action invocation itself.
Definition: Tooling.h:273
llvm::Optional
Definition: LLVM.h:40
clang::CompilerInvocationRefBase::getHeaderSearchOpts
HeaderSearchOptions & getHeaderSearchOpts()
Definition: CompilerInvocation.h:112
clang::tooling::dependencies::DependencyScanningService::canReuseFileManager
bool canReuseFileManager() const
Definition: DependencyScanningService.h:58
clang::ExcludedPreprocessorDirectiveSkipMapping
llvm::DenseMap< const char *, const PreprocessorSkippedRangeMapping * > ExcludedPreprocessorDirectiveSkipMapping
The datastructure that holds the mapping between the active memory buffers and the individual skip ma...
Definition: PreprocessorExcludedConditionalDirectiveSkipMapping.h:26
clang::FileSystemOptions::WorkingDir
std::string WorkingDir
If set, paths are resolved as if the working directory was set to the value of WorkingDir.
Definition: FileSystemOptions.h:26
clang::CompilerInstance::getPCHContainerReader
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
Definition: CompilerInstance.h:544
CompilerInvocation.h
clang::FileSystemOptions
Keeps track of options that affect how file operations are performed.
Definition: FileSystemOptions.h:22
clang::tooling::ToolAction
Interface to process a clang::CompilerInvocation.
Definition: Tooling.h:81
clang::CompilerInstance::getFileManager
FileManager & getFileManager() const
Return the current file manager to the caller.
Definition: CompilerInstance.h:404
clang::tooling::dependencies::ScanningOutputFormat
ScanningOutputFormat
The format that is output by the dependency scanner.
Definition: DependencyScanningService.h:34
clang::FileManager::setVirtualFileSystem
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Definition: FileManager.h:245
Utils.h
llvm::SmallString
Definition: LLVM.h:37
clang::ASTReader::readASTFileControlBlock
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions)
Read the control block for the named AST file.
Definition: ASTReader.cpp:5149
DependencyScanningWorker.h
clang::tooling::ToolInvocation::setDiagnosticOptions
void setDiagnosticOptions(DiagnosticOptions *DiagOpts)
Set a DiagnosticOptions to use during driver command-line parsing.
Definition: Tooling.h:278
clang::tooling::dependencies::DependencyScanningWorker::computeDependencies
llvm::Error computeDependencies(StringRef WorkingDirectory, const std::vector< std::string > &CommandLine, DependencyConsumer &Consumer, llvm::Optional< StringRef > ModuleName=None)
Run the dependency scanning tool for a given clang driver command-line, and report the discovered dep...
Definition: DependencyScanningWorker.cpp:329
clang::CompilerInstance
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Definition: CompilerInstance.h:74
clang::HeaderSearchOptions::PrebuiltModuleFiles
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
Definition: HeaderSearchOptions.h:119
clang::FileManager::getFileSystemOpts
FileSystemOptions & getFileSystemOpts()
Returns the current file system options.
Definition: FileManager.h:240
clang::DependencyFileGenerator
Builds a dependency file when attached to a Preprocessor (for includes) and ASTReader (for module imp...
Definition: Utils.h:118
clang::tooling::dependencies::DependencyScanningWorker::DependencyScanningWorker
DependencyScanningWorker(DependencyScanningService &Service)
Definition: DependencyScanningWorker.cpp:284
runWithDiags
static llvm::Error runWithDiags(DiagnosticOptions *DiagOpts, llvm::function_ref< bool(DiagnosticConsumer &, DiagnosticOptions &)> BodyShouldSucceed)
Definition: DependencyScanningWorker.cpp:312
clang::tooling::dependencies::DependencyScanningService::getMode
ScanningMode getMode() const
Definition: DependencyScanningService.h:54
ModuleDepCollector.h
Tooling.h
clang::tooling::dependencies::ScanningMode::MinimizedSourcePreprocessing
@ MinimizedSourcePreprocessing
This mode is used to compute the dependencies by running the preprocessor over the source files that ...
clang::tooling::dependencies::DependencyScanningService::getSharedCache
DependencyScanningFilesystemSharedCache & getSharedCache()
Definition: DependencyScanningService.h:64
clang::DiagnosticOptions::Warnings
std::vector< std::string > Warnings
The list of -W...
Definition: DiagnosticOptions.h:111
TextDiagnosticPrinter.h
clang::tooling::ToolInvocation::run
bool run()
Run the clang invocation.
Definition: Tooling.cpp:341
clang::CompilerInstance::getInvocation
CompilerInvocation & getInvocation()
Definition: CompilerInstance.h:231
FrontendActions.h
clang::HeaderSearchOptions::UserEntries
std::vector< Entry > UserEntries
User specified include entries.
Definition: HeaderSearchOptions.h:103
clang::tooling::dependencies::DependencyScanningService
The dependency scanning service contains the shared state that is used by the invidual dependency sca...
Definition: DependencyScanningService.h:47
clang::createVFSFromCompilerInvocation
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
Definition: CompilerInvocation.cpp:4657
clang::tooling::dependencies::DependencyScanningWorkerFilesystem
A virtual file system optimized for the dependency discovery.
Definition: DependencyScanningFilesystem.h:185
std
Definition: Format.h:4034
clang::tooling::dependencies::ScanningOutputFormat::Make
@ Make
This is the Makefile compatible dep format.
clang::HeaderSearchOptions::VFSOverlayFiles
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
Definition: HeaderSearchOptions.h:179
clang
Definition: CalledOnceCheck.h:17
clang::FileManager
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
clang::ASTReaderListener
Abstract interface for callback invocations by the ASTReader.
Definition: ASTReader.h:114
clang::CompilerInvocation
Helper class for holding the data necessary to invoke the compiler.
Definition: CompilerInvocation.h:193
clang::SrcMgr::isSystem
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:87
clang::TextDiagnosticPrinter
Definition: TextDiagnosticPrinter.h:27
clang::CreateAndPopulateDiagOpts
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
Definition: CompilerInvocation.cpp:2283
CompilerInstance.h
llvm::SmallVectorImpl
Definition: LLVM.h:39
PreprocessorOptions.h
clang::tooling::dependencies::ScanningOutputFormat::Full
@ Full
This outputs the full module dependency graph suitable for use for explicitly building modules.
ObjectFilePCHContainerOperations.h
llvm::IntrusiveRefCntPtr
Definition: LLVM.h:47
clang::DiagnosticOptions
Options for controlling the compiler diagnostics engine.
Definition: DiagnosticOptions.h:70
clang::tooling::dependencies::DependencyScanningService::canSkipExcludedPPRanges
bool canSkipExcludedPPRanges() const
Definition: DependencyScanningService.h:60