Thanks to visit codestin.com
Credit goes to clang.llvm.org

clang 22.0.0git
DependencyScannerImpl.cpp
Go to the documentation of this file.
1//===- DependencyScanner.cpp - Performs module dependency scanning --------===//
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
14
15using namespace clang;
16using namespace tooling;
17using namespace dependencies;
18
19namespace {
20/// Forwards the gatherered dependencies to the consumer.
21class DependencyConsumerForwarder : public DependencyFileGenerator {
22public:
23 DependencyConsumerForwarder(std::unique_ptr<DependencyOutputOptions> Opts,
24 StringRef WorkingDirectory, DependencyConsumer &C)
25 : DependencyFileGenerator(*Opts), WorkingDirectory(WorkingDirectory),
26 Opts(std::move(Opts)), C(C) {}
27
28 void finishedMainFile(DiagnosticsEngine &Diags) override {
29 C.handleDependencyOutputOpts(*Opts);
30 llvm::SmallString<256> CanonPath;
31 for (const auto &File : getDependencies()) {
32 CanonPath = File;
33 llvm::sys::path::remove_dots(CanonPath, /*remove_dot_dot=*/true);
34 llvm::sys::fs::make_absolute(WorkingDirectory, CanonPath);
35 C.handleFileDependency(CanonPath);
36 }
37 }
38
39private:
40 StringRef WorkingDirectory;
41 std::unique_ptr<DependencyOutputOptions> Opts;
42 DependencyConsumer &C;
43};
44
45static bool checkHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
46 const HeaderSearchOptions &ExistingHSOpts,
47 DiagnosticsEngine *Diags,
48 const LangOptions &LangOpts) {
49 if (LangOpts.Modules) {
50 if (HSOpts.VFSOverlayFiles != ExistingHSOpts.VFSOverlayFiles) {
51 if (Diags) {
52 Diags->Report(diag::warn_pch_vfsoverlay_mismatch);
53 auto VFSNote = [&](int Type, ArrayRef<std::string> VFSOverlays) {
54 if (VFSOverlays.empty()) {
55 Diags->Report(diag::note_pch_vfsoverlay_empty) << Type;
56 } else {
57 std::string Files = llvm::join(VFSOverlays, "\n");
58 Diags->Report(diag::note_pch_vfsoverlay_files) << Type << Files;
59 }
60 };
61 VFSNote(0, HSOpts.VFSOverlayFiles);
62 VFSNote(1, ExistingHSOpts.VFSOverlayFiles);
63 }
64 }
65 }
66 return false;
67}
68
69using PrebuiltModuleFilesT = decltype(HeaderSearchOptions::PrebuiltModuleFiles);
70
71/// A listener that collects the imported modules and the input
72/// files. While visiting, collect vfsoverlays and file inputs that determine
73/// whether prebuilt modules fully resolve in stable directories.
74class PrebuiltModuleListener : public ASTReaderListener {
75public:
76 PrebuiltModuleListener(PrebuiltModuleFilesT &PrebuiltModuleFiles,
77 llvm::SmallVector<std::string> &NewModuleFiles,
78 PrebuiltModulesAttrsMap &PrebuiltModulesASTMap,
79 const HeaderSearchOptions &HSOpts,
80 const LangOptions &LangOpts, DiagnosticsEngine &Diags,
81 const ArrayRef<StringRef> StableDirs)
82 : PrebuiltModuleFiles(PrebuiltModuleFiles),
83 NewModuleFiles(NewModuleFiles),
84 PrebuiltModulesASTMap(PrebuiltModulesASTMap), ExistingHSOpts(HSOpts),
85 ExistingLangOpts(LangOpts), Diags(Diags), StableDirs(StableDirs) {}
86
87 bool needsImportVisitation() const override { return true; }
88 bool needsInputFileVisitation() override { return true; }
89 bool needsSystemInputFileVisitation() override { return true; }
90
91 /// Accumulate the modules are transitively depended on by the initial
92 /// prebuilt module.
93 void visitImport(StringRef ModuleName, StringRef Filename) override {
94 if (PrebuiltModuleFiles.insert({ModuleName.str(), Filename.str()}).second)
95 NewModuleFiles.push_back(Filename.str());
96
97 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(Filename);
98 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;
99 if (PrebuiltMapEntry.second)
100 PrebuiltModule.setInStableDir(!StableDirs.empty());
101
102 if (auto It = PrebuiltModulesASTMap.find(CurrentFile);
103 It != PrebuiltModulesASTMap.end() && CurrentFile != Filename)
104 PrebuiltModule.addDependent(It->getKey());
105 }
106
107 /// For each input file discovered, check whether it's external path is in a
108 /// stable directory. Traversal is stopped if the current module is not
109 /// considered stable.
110 bool visitInputFileAsRequested(StringRef FilenameAsRequested,
111 StringRef Filename, bool isSystem,
112 bool isOverridden,
113 bool isExplicitModule) override {
114 if (StableDirs.empty())
115 return false;
116 auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);
117 if ((PrebuiltEntryIt == PrebuiltModulesASTMap.end()) ||
118 (!PrebuiltEntryIt->second.isInStableDir()))
119 return false;
120
121 PrebuiltEntryIt->second.setInStableDir(
122 isPathInStableDir(StableDirs, Filename));
123 return PrebuiltEntryIt->second.isInStableDir();
124 }
125
126 /// Update which module that is being actively traversed.
127 void visitModuleFile(StringRef Filename,
128 serialization::ModuleKind Kind) override {
129 // If the CurrentFile is not
130 // considered stable, update any of it's transitive dependents.
131 auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);
132 if ((PrebuiltEntryIt != PrebuiltModulesASTMap.end()) &&
133 !PrebuiltEntryIt->second.isInStableDir())
134 PrebuiltEntryIt->second.updateDependentsNotInStableDirs(
135 PrebuiltModulesASTMap);
136 CurrentFile = Filename;
137 }
138
139 /// Check the header search options for a given module when considering
140 /// if the module comes from stable directories.
141 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
142 StringRef ModuleFilename,
143 StringRef SpecificModuleCachePath,
144 bool Complain) override {
145
146 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(CurrentFile);
147 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;
148 if (PrebuiltMapEntry.second)
149 PrebuiltModule.setInStableDir(!StableDirs.empty());
150
151 if (PrebuiltModule.isInStableDir())
152 PrebuiltModule.setInStableDir(areOptionsInStableDir(StableDirs, HSOpts));
153
154 return false;
155 }
156
157 /// Accumulate vfsoverlays used to build these prebuilt modules.
158 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
159 bool Complain) override {
160
161 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(CurrentFile);
162 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;
163 if (PrebuiltMapEntry.second)
164 PrebuiltModule.setInStableDir(!StableDirs.empty());
165
166 PrebuiltModule.setVFS(
167 llvm::StringSet<>(llvm::from_range, HSOpts.VFSOverlayFiles));
168
169 return checkHeaderSearchPaths(
170 HSOpts, ExistingHSOpts, Complain ? &Diags : nullptr, ExistingLangOpts);
171 }
172
173private:
174 PrebuiltModuleFilesT &PrebuiltModuleFiles;
175 llvm::SmallVector<std::string> &NewModuleFiles;
176 PrebuiltModulesAttrsMap &PrebuiltModulesASTMap;
177 const HeaderSearchOptions &ExistingHSOpts;
178 const LangOptions &ExistingLangOpts;
179 DiagnosticsEngine &Diags;
180 std::string CurrentFile;
181 const ArrayRef<StringRef> StableDirs;
182};
183
184/// Visit the given prebuilt module and collect all of the modules it
185/// transitively imports and contributing input files.
186static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename,
188 PrebuiltModuleFilesT &ModuleFiles,
189 PrebuiltModulesAttrsMap &PrebuiltModulesASTMap,
190 DiagnosticsEngine &Diags,
191 const ArrayRef<StringRef> StableDirs) {
192 // List of module files to be processed.
194
195 PrebuiltModuleListener Listener(ModuleFiles, Worklist, PrebuiltModulesASTMap,
197 Diags, StableDirs);
198
199 Listener.visitModuleFile(PrebuiltModuleFilename,
202 PrebuiltModuleFilename, CI.getFileManager(), CI.getModuleCache(),
204 /*FindModuleFileExtensions=*/false, Listener,
205 /*ValidateDiagnosticOptions=*/false, ASTReader::ARR_OutOfDate))
206 return true;
207
208 while (!Worklist.empty()) {
209 Listener.visitModuleFile(Worklist.back(), serialization::MK_ExplicitModule);
211 Worklist.pop_back_val(), CI.getFileManager(), CI.getModuleCache(),
213 /*FindModuleFileExtensions=*/false, Listener,
214 /*ValidateDiagnosticOptions=*/false))
215 return true;
216 }
217 return false;
218}
219
220/// Transform arbitrary file name into an object-like file name.
221static std::string makeObjFileName(StringRef FileName) {
222 SmallString<128> ObjFileName(FileName);
223 llvm::sys::path::replace_extension(ObjFileName, "o");
224 return std::string(ObjFileName);
225}
226
227/// Deduce the dependency target based on the output file and input files.
228static std::string
229deduceDepTarget(const std::string &OutputFile,
230 const SmallVectorImpl<FrontendInputFile> &InputFiles) {
231 if (OutputFile != "-")
232 return OutputFile;
233
234 if (InputFiles.empty() || !InputFiles.front().isFile())
235 return "clang-scan-deps\\ dependency";
236
237 return makeObjFileName(InputFiles.front().getFile());
238}
239
240// Clang implements -D and -U by splatting text into a predefines buffer. This
241// allows constructs such as `-DFඞ=3 "-D F\u{0D9E} 4 3 2”` to be accepted and
242// define the same macro, or adding C++ style comments before the macro name.
243//
244// This function checks that the first non-space characters in the macro
245// obviously form an identifier that can be uniqued on without lexing. Failing
246// to do this could lead to changing the final definition of a macro.
247//
248// We could set up a preprocessor and actually lex the name, but that's very
249// heavyweight for a situation that will almost never happen in practice.
250static std::optional<StringRef> getSimpleMacroName(StringRef Macro) {
251 StringRef Name = Macro.split("=").first.ltrim(" \t");
252 std::size_t I = 0;
253
254 auto FinishName = [&]() -> std::optional<StringRef> {
255 StringRef SimpleName = Name.slice(0, I);
256 if (SimpleName.empty())
257 return std::nullopt;
258 return SimpleName;
259 };
260
261 for (; I != Name.size(); ++I) {
262 switch (Name[I]) {
263 case '(': // Start of macro parameter list
264 case ' ': // End of macro name
265 case '\t':
266 return FinishName();
267 case '_':
268 continue;
269 default:
270 if (llvm::isAlnum(Name[I]))
271 continue;
272 return std::nullopt;
273 }
274 }
275 return FinishName();
276}
277
278static void canonicalizeDefines(PreprocessorOptions &PPOpts) {
279 using MacroOpt = std::pair<StringRef, std::size_t>;
280 std::vector<MacroOpt> SimpleNames;
281 SimpleNames.reserve(PPOpts.Macros.size());
282 std::size_t Index = 0;
283 for (const auto &M : PPOpts.Macros) {
284 auto SName = getSimpleMacroName(M.first);
285 // Skip optimizing if we can't guarantee we can preserve relative order.
286 if (!SName)
287 return;
288 SimpleNames.emplace_back(*SName, Index);
289 ++Index;
290 }
291
292 llvm::stable_sort(SimpleNames, llvm::less_first());
293 // Keep the last instance of each macro name by going in reverse
294 auto NewEnd = std::unique(
295 SimpleNames.rbegin(), SimpleNames.rend(),
296 [](const MacroOpt &A, const MacroOpt &B) { return A.first == B.first; });
297 SimpleNames.erase(SimpleNames.begin(), NewEnd.base());
298
299 // Apply permutation.
300 decltype(PPOpts.Macros) NewMacros;
301 NewMacros.reserve(SimpleNames.size());
302 for (std::size_t I = 0, E = SimpleNames.size(); I != E; ++I) {
303 std::size_t OriginalIndex = SimpleNames[I].second;
304 // We still emit undefines here as they may be undefining a predefined macro
305 NewMacros.push_back(std::move(PPOpts.Macros[OriginalIndex]));
306 }
307 std::swap(PPOpts.Macros, NewMacros);
308}
309
310class ScanningDependencyDirectivesGetter : public DependencyDirectivesGetter {
311 DependencyScanningWorkerFilesystem *DepFS;
312
313public:
314 ScanningDependencyDirectivesGetter(FileManager &FileMgr) : DepFS(nullptr) {
315 FileMgr.getVirtualFileSystem().visit([&](llvm::vfs::FileSystem &FS) {
316 auto *DFS = llvm::dyn_cast<DependencyScanningWorkerFilesystem>(&FS);
317 if (DFS) {
318 assert(!DepFS && "Found multiple scanning VFSs");
319 DepFS = DFS;
320 }
321 });
322 assert(DepFS && "Did not find scanning VFS");
323 }
324
325 std::unique_ptr<DependencyDirectivesGetter>
326 cloneFor(FileManager &FileMgr) override {
327 return std::make_unique<ScanningDependencyDirectivesGetter>(FileMgr);
328 }
329
330 std::optional<ArrayRef<dependency_directives_scan::Directive>>
331 operator()(FileEntryRef File) override {
332 return DepFS->getDirectiveTokens(File.getName());
333 }
334};
335} // namespace
336
337/// Sanitize diagnostic options for dependency scan.
339 DiagnosticOptions &DiagOpts) {
340 // Don't print 'X warnings and Y errors generated'.
341 DiagOpts.ShowCarets = false;
342 // Don't write out diagnostic file.
343 DiagOpts.DiagnosticSerializationFile.clear();
344 // Don't emit warnings except for scanning specific warnings.
345 // TODO: It would be useful to add a more principled way to ignore all
346 // warnings that come from source code. The issue is that we need to
347 // ignore warnings that could be surpressed by
348 // `#pragma clang diagnostic`, while still allowing some scanning
349 // warnings for things we're not ready to turn into errors yet.
350 // See `test/ClangScanDeps/diagnostic-pragmas.c` for an example.
351 llvm::erase_if(DiagOpts.Warnings, [](StringRef Warning) {
352 return llvm::StringSwitch<bool>(Warning)
353 .Cases("pch-vfs-diff", "error=pch-vfs-diff", false)
354 .StartsWith("no-error=", false)
355 .Default(true);
356 });
357}
358
360 std::shared_ptr<CompilerInvocation> Invocation,
362 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
363 DiagnosticConsumer *DiagConsumer) {
364 // Making sure that we canonicalize the defines before we create the deep
365 // copy to avoid unnecessary variants in the scanner and in the resulting
366 // explicit command lines.
367 if (any(Service.getOptimizeArgs() & ScanningOptimizations::Macros))
368 canonicalizeDefines(Invocation->getPreprocessorOpts());
369
370 // Make a deep copy of the original Clang invocation.
371 CompilerInvocation OriginalInvocation(*Invocation);
372
373 if (Scanned) {
374 // Scanning runs once for the first -cc1 invocation in a chain of driver
375 // jobs. For any dependent jobs, reuse the scanning result and just
376 // update the LastCC1Arguments to correspond to the new invocation.
377 // FIXME: to support multi-arch builds, each arch requires a separate scan
378 setLastCC1Arguments(std::move(OriginalInvocation));
379 return true;
380 }
381
382 Scanned = true;
383
384 // Create a compiler instance to handle the actual work.
385 auto ModCache = makeInProcessModuleCache(Service.getModuleCacheEntries());
386 ScanInstanceStorage.emplace(std::move(Invocation), std::move(PCHContainerOps),
387 ModCache.get());
388 CompilerInstance &ScanInstance = *ScanInstanceStorage;
389 ScanInstance.setBuildingModule(false);
390
391 ScanInstance.createVirtualFileSystem(FS, DiagConsumer);
392
393 // Create the compiler's actual diagnostics engine.
394 sanitizeDiagOpts(ScanInstance.getDiagnosticOpts());
395 assert(!DiagConsumerFinished && "attempt to reuse finished consumer");
396 ScanInstance.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
397 if (!ScanInstance.hasDiagnostics())
398 return false;
399
401 true;
402
405 Service.getBuildSessionTimestamp();
406
407 ScanInstance.getFrontendOpts().DisableFree = false;
408 ScanInstance.getFrontendOpts().GenerateGlobalModuleIndex = false;
409 ScanInstance.getFrontendOpts().UseGlobalModuleIndex = false;
410 // This will prevent us compiling individual modules asynchronously since
411 // FileManager is not thread-safe, but it does improve performance for now.
412 ScanInstance.getFrontendOpts().ModulesShareFileManager = true;
413 ScanInstance.getHeaderSearchOpts().ModuleFormat = "raw";
415 any(Service.getOptimizeArgs() & ScanningOptimizations::VFS);
416
417 // Create a new FileManager to match the invocation's FileSystemOptions.
418 auto *FileMgr = ScanInstance.createFileManager();
419
420 // Use the dependency scanning optimized file system if requested to do so.
421 if (DepFS) {
422 DepFS->resetBypassedPathPrefix();
423 if (!ScanInstance.getHeaderSearchOpts().ModuleCachePath.empty()) {
424 SmallString<256> ModulesCachePath;
427 ModulesCachePath);
428 DepFS->setBypassedPathPrefix(ModulesCachePath);
429 }
430
432 std::make_unique<ScanningDependencyDirectivesGetter>(*FileMgr));
433 }
434
435 ScanInstance.createSourceManager(*FileMgr);
436
437 // Create a collection of stable directories derived from the ScanInstance
438 // for determining whether module dependencies would fully resolve from
439 // those directories.
441 const StringRef Sysroot = ScanInstance.getHeaderSearchOpts().Sysroot;
442 if (!Sysroot.empty() && (llvm::sys::path::root_directory(Sysroot) != Sysroot))
443 StableDirs = {Sysroot, ScanInstance.getHeaderSearchOpts().ResourceDir};
444
445 // Store a mapping of prebuilt module files and their properties like header
446 // search options. This will prevent the implicit build to create duplicate
447 // modules and will force reuse of the existing prebuilt module files
448 // instead.
449 PrebuiltModulesAttrsMap PrebuiltModulesASTMap;
450
451 if (!ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
452 if (visitPrebuiltModule(
453 ScanInstance.getPreprocessorOpts().ImplicitPCHInclude, ScanInstance,
455 PrebuiltModulesASTMap, ScanInstance.getDiagnostics(), StableDirs))
456 return false;
457
458 // Create the dependency collector that will collect the produced
459 // dependencies.
460 //
461 // This also moves the existing dependency output options from the
462 // invocation to the collector. The options in the invocation are reset,
463 // which ensures that the compiler won't create new dependency collectors,
464 // and thus won't write out the extra '.d' files to disk.
465 auto Opts = std::make_unique<DependencyOutputOptions>();
466 std::swap(*Opts, ScanInstance.getInvocation().getDependencyOutputOpts());
467 // We need at least one -MT equivalent for the generator of make dependency
468 // files to work.
469 if (Opts->Targets.empty())
470 Opts->Targets = {deduceDepTarget(ScanInstance.getFrontendOpts().OutputFile,
471 ScanInstance.getFrontendOpts().Inputs)};
472 Opts->IncludeSystemHeaders = true;
473
474 switch (Service.getFormat()) {
476 ScanInstance.addDependencyCollector(
477 std::make_shared<DependencyConsumerForwarder>(
478 std::move(Opts), WorkingDirectory, Consumer));
479 break;
482 MDC = std::make_shared<ModuleDepCollector>(
483 Service, std::move(Opts), ScanInstance, Consumer, Controller,
484 OriginalInvocation, std::move(PrebuiltModulesASTMap), StableDirs);
485 ScanInstance.addDependencyCollector(MDC);
486 break;
487 }
488
489 // Consider different header search and diagnostic options to create
490 // different modules. This avoids the unsound aliasing of module PCMs.
491 //
492 // TODO: Implement diagnostic bucketing to reduce the impact of strict
493 // context hashing.
494 ScanInstance.getHeaderSearchOpts().ModulesStrictContextHash = true;
500
501 // Avoid some checks and module map parsing when loading PCM files.
502 ScanInstance.getPreprocessorOpts().ModulesCheckRelocated = false;
503
504 std::unique_ptr<FrontendAction> Action;
505
506 if (Service.getFormat() == ScanningOutputFormat::P1689)
507 Action = std::make_unique<PreprocessOnlyAction>();
508 else if (ModuleName)
509 Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName);
510 else
511 Action = std::make_unique<ReadPCHAndPreprocessAction>();
512
513 if (ScanInstance.getDiagnostics().hasErrorOccurred())
514 return false;
515
516 const bool Result = ScanInstance.ExecuteAction(*Action);
517
518 // ExecuteAction is responsible for calling finish.
519 DiagConsumerFinished = true;
520
521 if (Result)
522 setLastCC1Arguments(std::move(OriginalInvocation));
523
524 return Result;
525}
Abstract interface for callback invocations by the ASTReader.
Definition ASTReader.h:117
@ ARR_OutOfDate
The client can handle an AST file that cannot load because it is out-of-date relative to its input fi...
Definition ASTReader.h:1837
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities=ARR_ConfigurationMismatch|ARR_OutOfDate)
Read the control block for the named AST file.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
FileManager & getFileManager() const
Return the current file manager to the caller.
ModuleCache & getModuleCache() const
void addDependencyCollector(std::shared_ptr< DependencyCollector > Listener)
void createVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS=llvm::vfs::getRealFileSystem(), DiagnosticConsumer *DC=nullptr)
Create a virtual file system instance based on the invocation.
FrontendOptions & getFrontendOpts()
HeaderSearchOptions & getHeaderSearchOpts()
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
FileManager * createFileManager()
Create the file manager and replace any existing one with it.
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object.
DiagnosticOptions & getDiagnosticOpts()
void setDependencyDirectivesGetter(std::unique_ptr< DependencyDirectivesGetter > Getter)
Helper class for holding the data necessary to invoke the compiler.
DependencyOutputOptions & getDependencyOutputOpts()
Functor that returns the dependency directives for a given file.
Builds a dependency file when attached to a Preprocessor (for includes) and ASTReader (for module imp...
Definition Utils.h:104
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Options for controlling the compiler diagnostics engine.
std::vector< std::string > Warnings
The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:231
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
Definition Diagnostic.h:871
llvm::vfs::FileSystem & getVirtualFileSystem() const
unsigned ModulesShareFileManager
Whether to share the FileManager when building modules.
std::string OutputFile
The output file, if any.
unsigned GenerateGlobalModuleIndex
Whether we can generate the global module index if needed.
unsigned DisableFree
Disable memory freeing on exit.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
unsigned UseGlobalModuleIndex
Whether we can use the global module index if available.
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
unsigned ModulesStrictContextHash
Whether we should include all things that could impact the module in the hash.
unsigned ModulesForceValidateUserHeaders
Whether to force the validation of user input files when a module is loaded (even despite the build s...
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
uint64_t BuildSessionTimestamp
The time in seconds when the build session started.
unsigned ModulesSkipHeaderSearchPaths
Whether to entirely skip writing header search paths.
std::string ModuleFormat
The module/pch container format.
std::string Sysroot
If non-empty, the directory to use as a "virtual system root" for include paths.
unsigned ModulesSkipDiagnosticOptions
Whether to entirely skip writing diagnostic options.
std::string ModuleCachePath
The directory used for the module cache.
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
unsigned ModulesSerializeOnlyPreprocessor
Whether AST files should only contain the preprocessor information.
unsigned ModulesSkipPragmaDiagnosticMappings
Whether to entirely skip writing pragma diagnostic mappings.
unsigned ModulesIncludeVFSUsage
Whether to include ivfsoverlay usage information in written AST files.
std::string ResourceDir
The directory which holds the compiler resource files (builtin includes, etc.).
unsigned ModulesValidateOncePerBuildSession
If true, skip verifying input files used by modules if the module was already verified during this bu...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void setBuildingModule(bool BuildingModuleFlag)
Flag indicating whether this instance is building a module.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
bool ModulesCheckRelocated
Perform extra checks when loading PCM files for mutable file systems.
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
bool AllowPCHWithDifferentModulesCachePath
When true, a PCH with modules cache path different to the current compilation will not be rejected.
std::vector< std::pair< std::string, bool > > Macros
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool runInvocation(std::shared_ptr< CompilerInvocation > Invocation, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, DiagnosticConsumer *DiagConsumer)
void setVFS(llvm::StringSet<> &&VFS)
Update the VFSMap to the one discovered from serializing the AST file.
void addDependent(StringRef ModuleFile)
Add a direct dependent module file, so it can be updated if the current module is from stable directo...
void setInStableDir(bool V=false)
Update whether the prebuilt module resolves entirely in a stable directories.
bool isInStableDir() const
Read-only access to whether the module is made up of dependencies in stable directories.
ModuleKind
Specifies the kind of module that has been loaded.
Definition ModuleFile.h:43
@ MK_ExplicitModule
File is an explicitly-loaded module.
Definition ModuleFile.h:48
@ Make
This is the Makefile compatible dep format.
@ Full
This outputs the full clang module dependency graph suitable for use for explicitly building modules.
@ P1689
This outputs the dependency graph for standard c++ modules in P1689R5 format.
bool areOptionsInStableDir(const ArrayRef< StringRef > Directories, const HeaderSearchOptions &HSOpts)
Determine if options collected from a module's compilation can safely be considered as stable.
IntrusiveRefCntPtr< ModuleCache > makeInProcessModuleCache(ModuleCacheEntries &Entries)
bool isPathInStableDir(const ArrayRef< StringRef > Directories, const StringRef Input)
Determine if Input can be resolved within a stable directory.
llvm::StringMap< PrebuiltModuleASTAttrs > PrebuiltModulesAttrsMap
Attributes loaded from AST files of prebuilt modules collected prior to ModuleDepCollector creation.
void sanitizeDiagOpts(DiagnosticOptions &DiagOpts)
Sanitize diagnostic options for dependency scan.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
Definition TypeBase.h:905
void normalizeModuleCachePath(FileManager &FileMgr, StringRef Path, SmallVectorImpl< char > &NormalizedPath)
int __ovld __cnfn any(char)
Returns 1 if the most significant bit in any component of x is set; otherwise returns 0.