clang 23.0.0git
ModuleDepCollector.cpp
Go to the documentation of this file.
1//===- ModuleDepCollector.cpp - Callbacks to collect deps -------*- C++ -*-===//
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
10
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/Support/BLAKE3.h"
17#include <optional>
18
19using namespace clang;
20using namespace dependencies;
21
22void ModuleDeps::forEachFileDep(llvm::function_ref<void(StringRef)> Cb) const {
23 SmallString<0> PathBuf;
24 PathBuf.reserve(256);
25 for (StringRef FileDep : FileDeps) {
26 auto ResolvedFileDep =
27 ASTReader::ResolveImportedPath(PathBuf, FileDep, FileDepsBaseDir);
28 Cb(*ResolvedFileDep);
29 }
30}
31
32const std::vector<std::string> &ModuleDeps::getBuildArguments() const {
33 // FIXME: this operation is not thread safe and is expected to be called
34 // on a single thread. Otherwise it should be protected with a lock.
35 assert(!std::holds_alternative<std::monostate>(BuildInfo) &&
36 "Using uninitialized ModuleDeps");
37 if (const auto *CI = std::get_if<CowCompilerInvocation>(&BuildInfo))
38 BuildInfo = CI->getCC1CommandLine();
39 return std::get<std::vector<std::string>>(BuildInfo);
40}
41
43 PrebuiltModulesAttrsMap &PrebuiltModulesMap) {
45 for (const auto Dep : ModuleFileDependents) {
46 if (!PrebuiltModulesMap[Dep].isInStableDir())
47 return;
48 PrebuiltModulesMap[Dep].updateDependentsNotInStableDirs(PrebuiltModulesMap);
49 }
50}
51
52static void
55 const PrebuiltModulesAttrsMap &PrebuiltModulesASTMap,
56 ScanningOptimizations OptimizeArgs) {
57 if (any(OptimizeArgs & ScanningOptimizations::HeaderSearch)) {
58 // Only preserve search paths that were used during the dependency scan.
59 std::vector<HeaderSearchOptions::Entry> Entries;
60 std::swap(Opts.UserEntries, Entries);
61
62 llvm::BitVector SearchPathUsage(Entries.size());
63 llvm::DenseSet<const serialization::ModuleFile *> Visited;
64 std::function<void(const serialization::ModuleFile *)> VisitMF =
65 [&](const serialization::ModuleFile *MF) {
66 SearchPathUsage |= MF->SearchPathUsage;
67 Visited.insert(MF);
68 for (const serialization::ModuleFile *Import : MF->Imports)
69 if (!Visited.contains(Import))
70 VisitMF(Import);
71 };
72 VisitMF(&MF);
73
74 if (SearchPathUsage.size() != Entries.size())
75 llvm::report_fatal_error(
76 "Inconsistent search path options between modules detected");
77
78 for (auto Idx : SearchPathUsage.set_bits())
79 Opts.UserEntries.push_back(std::move(Entries[Idx]));
80 }
81 if (any(OptimizeArgs & ScanningOptimizations::VFS)) {
82 std::vector<std::string> VFSOverlayFiles;
83 std::swap(Opts.VFSOverlayFiles, VFSOverlayFiles);
84
85 llvm::BitVector VFSUsage(VFSOverlayFiles.size());
86 llvm::DenseSet<const serialization::ModuleFile *> Visited;
87 std::function<void(const serialization::ModuleFile *)> VisitMF =
88 [&](const serialization::ModuleFile *MF) {
89 Visited.insert(MF);
91 VFSUsage |= MF->VFSUsage;
92 // We only need to recurse into implicit modules. Other module types
93 // will have the correct set of VFSs for anything they depend on.
94 for (const serialization::ModuleFile *Import : MF->Imports)
95 if (!Visited.contains(Import))
96 VisitMF(Import);
97 } else {
98 // This is not an implicitly built module, so it may have different
99 // VFS options. Fall back to a string comparison instead.
100 auto PrebuiltModulePropIt =
101 PrebuiltModulesASTMap.find(MF->FileName);
102 if (PrebuiltModulePropIt == PrebuiltModulesASTMap.end())
103 return;
104 for (std::size_t I = 0, E = VFSOverlayFiles.size(); I != E; ++I) {
105 if (PrebuiltModulePropIt->second.getVFS().contains(
106 VFSOverlayFiles[I]))
107 VFSUsage[I] = true;
108 }
109 }
110 };
111 VisitMF(&MF);
112
113 if (VFSUsage.size() != VFSOverlayFiles.size())
114 llvm::report_fatal_error(
115 "Inconsistent -ivfsoverlay options between modules detected");
116
117 for (auto Idx : VFSUsage.set_bits())
118 Opts.VFSOverlayFiles.push_back(std::move(VFSOverlayFiles[Idx]));
119 }
120}
121
123 bool IsSystemModule) {
124 // If this is not a system module or -Wsystem-headers was passed, don't
125 // optimize.
126 if (!IsSystemModule)
127 return;
128 bool Wsystem_headers = false;
129 for (StringRef Opt : Opts.Warnings) {
130 bool isPositive = !Opt.consume_front("no-");
131 if (Opt == "system-headers")
132 Wsystem_headers = isPositive;
133 }
134 if (Wsystem_headers)
135 return;
136
137 // Remove all warning flags. System modules suppress most, but not all,
138 // warnings.
139 Opts.Warnings.clear();
140 Opts.UndefPrefixes.clear();
141 Opts.Remarks.clear();
142}
143
144static void optimizeCWD(CowCompilerInvocation &BuildInvocation, StringRef CWD) {
145 BuildInvocation.getMutFileSystemOpts().WorkingDir.clear();
146 BuildInvocation.getMutCodeGenOpts().DebugCompilationDir.clear();
147 BuildInvocation.getMutCodeGenOpts().CoverageCompilationDir.clear();
148}
149
150static std::vector<std::string> splitString(std::string S, char Separator) {
151 SmallVector<StringRef> Segments;
152 StringRef(S).split(Segments, Separator, /*MaxSplit=*/-1, /*KeepEmpty=*/false);
153 std::vector<std::string> Result;
154 Result.reserve(Segments.size());
155 for (StringRef Segment : Segments)
156 Result.push_back(Segment.str());
157 return Result;
158}
159
160void ModuleDepCollector::addOutputPaths(CowCompilerInvocation &CI,
161 ModuleDeps &Deps) {
163 Controller.lookupModuleOutput(Deps, ModuleOutputKind::ModuleFile);
166 Controller.lookupModuleOutput(
168 if (!CI.getDependencyOutputOpts().OutputFile.empty()) {
170 Controller.lookupModuleOutput(Deps, ModuleOutputKind::DependencyFile);
172 splitString(Controller.lookupModuleOutput(
174 '\0');
175 if (!CI.getDependencyOutputOpts().OutputFile.empty() &&
176 CI.getDependencyOutputOpts().Targets.empty()) {
177 // Fallback to -o as dependency target, as in the driver.
178 SmallString<128> Target;
180 CI.getMutDependencyOutputOpts().Targets.push_back(std::string(Target));
181 }
182 }
183}
184
186 const LangOptions &LangOpts,
187 CodeGenOptions &CGOpts) {
188 // TODO: Figure out better way to set options to their default value.
189 if (ProgramAction == frontend::GenerateModule) {
190 CGOpts.MainFileName.clear();
191 CGOpts.DwarfDebugFlags.clear();
192 }
193 if (ProgramAction == frontend::GeneratePCH ||
194 (ProgramAction == frontend::GenerateModule && !LangOpts.ModulesCodegen)) {
195 CGOpts.DebugCompilationDir.clear();
196 CGOpts.CoverageCompilationDir.clear();
197 CGOpts.CoverageDataFile.clear();
198 CGOpts.CoverageNotesFile.clear();
199 CGOpts.ProfileInstrumentUsePath.clear();
200 CGOpts.SampleProfileFile.clear();
201 CGOpts.ProfileRemappingFile.clear();
202 }
203}
204
206 const StringRef Input) {
207 using namespace llvm::sys;
208
209 if (!path::is_absolute(Input))
210 return false;
211
212 auto PathStartsWith = [](StringRef Prefix, StringRef Path) {
213 auto PrefixIt = path::begin(Prefix), PrefixEnd = path::end(Prefix);
214 for (auto PathIt = path::begin(Path), PathEnd = path::end(Path);
215 PrefixIt != PrefixEnd && PathIt != PathEnd; ++PrefixIt, ++PathIt) {
216 if (*PrefixIt != *PathIt)
217 return false;
218 }
219 return PrefixIt == PrefixEnd;
220 };
221
222 return any_of(Directories, [&](StringRef Dir) {
223 return !Dir.empty() && PathStartsWith(Dir, Input);
224 });
225}
226
228 const HeaderSearchOptions &HSOpts) {
229 assert(isPathInStableDir(Directories, HSOpts.Sysroot) &&
230 "Sysroots differ between module dependencies and current TU");
231
232 assert(isPathInStableDir(Directories, HSOpts.ResourceDir) &&
233 "ResourceDirs differ between module dependencies and current TU");
234
235 for (const auto &Entry : HSOpts.UserEntries) {
236 if (!Entry.IgnoreSysRoot)
237 continue;
238 if (!isPathInStableDir(Directories, Entry.Path))
239 return false;
240 }
241
242 for (const auto &SysPrefix : HSOpts.SystemHeaderPrefixes) {
243 if (!isPathInStableDir(Directories, SysPrefix.Prefix))
244 return false;
245 }
246
247 return true;
248}
249
254
255 // The scanner takes care to avoid passing non-affecting module maps to the
256 // explicit compiles. No need to do extra work just to find out there are no
257 // module map files to prune.
259
260 // Remove options incompatible with explicit module build or are likely to
261 // differ between identical modules discovered from different translation
262 // units.
263 CI.getFrontendOpts().Inputs.clear();
264 CI.getFrontendOpts().OutputFile.clear();
265 CI.getFrontendOpts().GenReducedBMI = false;
269 // LLVM options are not going to affect the AST
270 CI.getFrontendOpts().LLVMArgs.clear();
271
273 CI.getCodeGenOpts());
274
275 // Map output paths that affect behaviour to "-" so their existence is in the
276 // context hash. The final path will be computed in addOutputPaths.
279 if (!CI.getDependencyOutputOpts().OutputFile.empty())
281 CI.getDependencyOutputOpts().Targets.clear();
283
285 CI.getLangOpts().ModuleName.clear();
286
287 // Remove any macro definitions that are explicitly ignored.
288 if (!CI.getHeaderSearchOpts().ModulesIgnoreMacros.empty()) {
289 llvm::erase_if(
291 [&CI](const std::pair<std::string, bool> &Def) {
292 StringRef MacroDef = Def.first;
293 return CI.getHeaderSearchOpts().ModulesIgnoreMacros.contains(
294 llvm::CachedHashString(MacroDef.split('=').first));
295 });
296 // Remove the now unused option.
298 }
299
300 return CI;
301}
302
303CowCompilerInvocation
304ModuleDepCollector::getInvocationAdjustedForModuleBuildWithoutOutputs(
305 const ModuleDeps &Deps,
306 llvm::function_ref<void(CowCompilerInvocation &)> Optimize) const {
307 CowCompilerInvocation CI = CommonInvocation;
308
311
312 // Inputs
313 InputKind ModuleMapInputKind(CI.getFrontendOpts().DashX.getLanguage(),
315 CI.getMutFrontendOpts().Inputs.emplace_back(Deps.ClangModuleMapFile,
316 ModuleMapInputKind);
317
318 auto CurrentModuleMapEntry =
319 ScanInstance.getFileManager().getOptionalFileRef(Deps.ClangModuleMapFile);
320 assert(CurrentModuleMapEntry && "module map file entry not found");
321
322 // Remove directly passed modulemap files. They will get added back if they
323 // were actually used.
325
326 auto DepModuleMapFiles = collectModuleMapFiles(Deps.ClangModuleDeps);
327 for (StringRef ModuleMapFile : Deps.ModuleMapFileDeps) {
328 // TODO: Track these as `FileEntryRef` to simplify the equality check below.
329 auto ModuleMapEntry =
330 ScanInstance.getFileManager().getOptionalFileRef(ModuleMapFile);
331 assert(ModuleMapEntry && "module map file entry not found");
332
333 // Don't report module maps describing eagerly-loaded dependency. This
334 // information will be deserialized from the PCM.
335 // TODO: Verify this works fine when modulemap for module A is eagerly
336 // loaded from A.pcm, and module map passed on the command line contains
337 // definition of a submodule: "explicit module A.Private { ... }".
338 if (Service.getOpts().EagerLoadModules &&
339 DepModuleMapFiles.contains(*ModuleMapEntry))
340 continue;
341
342 // Don't report module map file of the current module unless it also
343 // describes a dependency (for symmetry).
344 if (*ModuleMapEntry == *CurrentModuleMapEntry &&
345 !DepModuleMapFiles.contains(*ModuleMapEntry))
346 continue;
347
348 CI.getMutFrontendOpts().ModuleMapFiles.emplace_back(ModuleMapFile);
349 }
350
351 // Report the prebuilt modules this module uses.
352 for (const auto &PrebuiltModule : Deps.PrebuiltModuleDeps)
353 CI.getMutFrontendOpts().ModuleFiles.push_back(PrebuiltModule.PCMFile);
354
355 // Add module file inputs from dependencies.
356 addModuleFiles(CI, Deps.ClangModuleDeps);
357
359 // Apply -Wsystem-headers-in-module for the current module.
360 if (llvm::is_contained(CI.getDiagnosticOpts().SystemHeaderWarningsModules,
361 Deps.ID.ModuleName))
362 CI.getMutDiagnosticOpts().Warnings.push_back("system-headers");
363 // Remove the now unused option(s).
365 }
366
367 Optimize(CI);
368
369 return CI;
370}
371
372llvm::DenseSet<const FileEntry *> ModuleDepCollector::collectModuleMapFiles(
373 ArrayRef<ModuleID> ClangModuleDeps) const {
374 llvm::DenseSet<const FileEntry *> ModuleMapFiles;
375 for (const ModuleID &MID : ClangModuleDeps) {
376 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
377 assert(MD && "Inconsistent dependency info");
378 // TODO: Track ClangModuleMapFile as `FileEntryRef`.
379 auto FE = ScanInstance.getFileManager().getOptionalFileRef(
381 assert(FE && "Missing module map file that was previously found");
382 ModuleMapFiles.insert(*FE);
383 }
384 return ModuleMapFiles;
385}
386
387void ModuleDepCollector::addModuleMapFiles(
388 CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
389 if (Service.getOpts().EagerLoadModules)
390 return; // Only pcm is needed for eager load.
391
392 for (const ModuleID &MID : ClangModuleDeps) {
393 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
394 assert(MD && "Inconsistent dependency info");
396 }
397}
398
399void ModuleDepCollector::addModuleFiles(
400 CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
401 for (const ModuleID &MID : ClangModuleDeps) {
402 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
403 std::string PCMPath =
404 Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile);
405
406 if (Service.getOpts().EagerLoadModules)
407 CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
408 else
410 {MID.ModuleName, std::move(PCMPath)});
411 }
412}
413
414void ModuleDepCollector::addModuleFiles(
415 CowCompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
416 for (const ModuleID &MID : ClangModuleDeps) {
417 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
418 std::string PCMPath =
419 Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile);
420
421 if (Service.getOpts().EagerLoadModules)
422 CI.getMutFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
423 else
425 {MID.ModuleName, std::move(PCMPath)});
426 }
427}
428
430 switch (FIF.getKind().getLanguage()) {
432 case Language::Asm:
434 return false;
435 default:
436 return true;
437 }
438}
439
443 CI.getLangOpts(), CI.getCodeGenOpts());
445
446 if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
447 Preprocessor &PP = ScanInstance.getPreprocessor();
448 if (Module *CurrentModule = PP.getCurrentModuleImplementation())
449 if (OptionalFileEntryRef CurrentModuleMap =
451 .getModuleMap()
452 .getModuleMapFileForUniquing(CurrentModule))
453 CI.getFrontendOpts().ModuleMapFiles.emplace_back(
454 CurrentModuleMap->getNameAsRequested());
455
456 SmallVector<ModuleID> DirectDeps;
457 for (const auto &KV : ModularDeps)
458 if (DirectModularDeps.contains(KV.first))
459 DirectDeps.push_back(KV.second->ID);
460
461 // TODO: Report module maps the same way it's done for modular dependencies.
462 addModuleMapFiles(CI, DirectDeps);
463
464 addModuleFiles(CI, DirectDeps);
465
466 for (const auto &KV : DirectPrebuiltModularDeps)
467 CI.getFrontendOpts().ModuleFiles.push_back(KV.second.PCMFile);
468 }
469}
470
472 // Check if the command line input uses relative paths.
473 // It is not safe to ignore the current working directory if any of the
474 // command line inputs use relative paths.
475 bool AnyRelative = false;
476 CI.visitPaths([&](StringRef Path) {
477 assert(!AnyRelative && "Continuing path visitation despite returning true");
478 AnyRelative |= !Path.empty() && !llvm::sys::path::is_absolute(Path);
479 return AnyRelative;
480 });
481 return !AnyRelative;
482}
483
484static std::string getModuleContextHash(const ModuleDeps &MD,
485 const CowCompilerInvocation &CI,
486 bool EagerLoadModules,
487 llvm::vfs::FileSystem &VFS) {
488 llvm::HashBuilder<llvm::TruncatedBLAKE3<16>, llvm::endianness::native>
489 HashBuilder;
490
491 // Hash the compiler version and serialization version to ensure the module
492 // will be readable.
493 HashBuilder.add(getClangFullRepositoryVersion());
495 llvm::ErrorOr<std::string> CWD = VFS.getCurrentWorkingDirectory();
496 if (CWD && !MD.IgnoreCWD)
497 HashBuilder.add(*CWD);
498
499 // Hash the BuildInvocation without any input files.
500 SmallString<0> ArgVec;
501 ArgVec.reserve(4096);
502 CI.generateCC1CommandLine([&](const Twine &Arg) {
503 Arg.toVector(ArgVec);
504 ArgVec.push_back('\0');
505 });
506 HashBuilder.add(ArgVec);
507
508 // Hash the module dependencies. These paths may differ even if the invocation
509 // is identical if they depend on the contents of the files in the TU -- for
510 // example, case-insensitive paths to modulemap files. Usually such a case
511 // would indicate a missed optimization to canonicalize, but it may be
512 // difficult to canonicalize all cases when there is a VFS.
513 for (const auto &ID : MD.ClangModuleDeps) {
514 HashBuilder.add(ID.ModuleName);
515 HashBuilder.add(ID.ContextHash);
516 }
517
518 HashBuilder.add(EagerLoadModules);
519
520 llvm::BLAKE3Result<16> Hash = HashBuilder.final();
521 std::array<uint64_t, 2> Words;
522 static_assert(sizeof(Hash) == sizeof(Words), "Hash must match Words");
523 std::memcpy(Words.data(), Hash.data(), sizeof(Hash));
524 return toString(llvm::APInt(sizeof(Words) * 8, Words), 36, /*Signed=*/false);
525}
526
527void ModuleDepCollector::associateWithContextHash(
528 const CowCompilerInvocation &CI, ModuleDeps &Deps) {
529 Deps.ID.ContextHash =
530 getModuleContextHash(Deps, CI, Service.getOpts().EagerLoadModules,
531 ScanInstance.getVirtualFileSystem());
532 bool Inserted = ModuleDepsByID.insert({Deps.ID, &Deps}).second;
533 (void)Inserted;
534 assert(Inserted && "duplicate module mapping");
535}
536
540 FileID PrevFID,
541 SourceLocation Loc) {
543 return;
544
545 SourceManager &SM = MDC.ScanInstance.getSourceManager();
546
547 // Dependency generation really does want to go all the way to the
548 // file entry for a source location to find out what is depended on.
549 // We do not want #line markers to affect dependency generation!
550 if (std::optional<StringRef> Filename = SM.getNonBuiltinFilenameForID(FID))
551 MDC.addFileDep(llvm::sys::path::remove_leading_dotslash(*Filename));
552}
553
555 bool IsAngled, OptionalFileEntryRef File,
557 if (File)
558 MDC.addFileDep(File->getName());
559}
560
562 SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
563 bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
564 StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,
565 bool ModuleImported, SrcMgr::CharacteristicKind FileType) {
566 if (!File && !ModuleImported) {
567 // This is a non-modular include that HeaderSearch failed to find. Add it
568 // here as `FileChanged` will never see it.
569 MDC.addFileDep(FileName);
570 }
571 handleImport(SuggestedModule);
572}
573
575 ModuleIdPath Path,
576 const Module *Imported) {
577 auto &PP = MDC.ScanInstance.getPreprocessor();
578 if (PP.getLangOpts().CPlusPlusModules && PP.isImportingCXXNamedModules()) {
579 P1689ModuleInfo RequiredModule;
580 RequiredModule.ModuleName = Path[0].getIdentifierInfo()->getName().str();
582 MDC.RequiredStdCXXModules.push_back(std::move(RequiredModule));
583 return;
584 }
585
586 handleImport(Imported);
587}
588
589void ModuleDepCollectorPP::handleImport(const Module *Imported) {
590 if (!Imported)
591 return;
592
593 const Module *TopLevelModule = Imported->getTopLevelModule();
594 const ModuleFileKey *MFKey = TopLevelModule->getASTFileKey();
595 if (!MFKey)
596 return;
598 MDC.ScanInstance.getASTReader()->getModuleManager().lookup(*MFKey);
599
600 if (MDC.isPrebuiltModule(MF))
601 MDC.DirectPrebuiltModularDeps.insert({MF, PrebuiltModuleDep{MF}});
602 else {
603 MDC.DirectModularDeps.insert(MF);
604 MDC.DirectImports.insert(Imported);
605 }
606}
607
609 FileID MainFileID = MDC.ScanInstance.getSourceManager().getMainFileID();
610 MDC.MainFile = std::string(MDC.ScanInstance.getSourceManager()
611 .getFileEntryRefForID(MainFileID)
612 ->getName());
613
614 auto &PP = MDC.ScanInstance.getPreprocessor();
615 if (PP.isInNamedModule()) {
616 P1689ModuleInfo ProvidedModule;
617 ProvidedModule.ModuleName = PP.getNamedModuleName();
619 ProvidedModule.IsStdCXXModuleInterface = PP.isInNamedInterfaceUnit();
620 // Don't put implementation (non partition) unit as Provide.
621 // Put the module as required instead. Since the implementation
622 // unit will import the primary module implicitly.
623 if (PP.isInImplementationUnit())
624 MDC.RequiredStdCXXModules.push_back(ProvidedModule);
625 else
626 MDC.ProvidedStdCXXModule = ProvidedModule;
627 }
628
629 if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
630 MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude);
631
632 for (StringRef VFS : MDC.ScanInstance.getHeaderSearchOpts().VFSOverlayFiles)
633 MDC.addFileDep(VFS);
634
635 if (Module *CurrentModule = PP.getCurrentModuleImplementation()) {
636 if (OptionalFileEntryRef CurrentModuleMap =
637 PP.getHeaderSearchInfo().getModuleMap().getModuleMapFileForUniquing(
638 CurrentModule))
639 MDC.addFileDep(CurrentModuleMap->getName());
640 }
641
642 for (const Module *M :
643 MDC.ScanInstance.getPreprocessor().getAffectingClangModules()) {
645 MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
646 *M->getASTFileKey());
647 if (!MDC.isPrebuiltModule(MF))
648 MDC.DirectModularDeps.insert(MF);
649 }
650
651 if (MDC.Service.getOpts().ReportVisibleModules)
652 MDC.addVisibleModules();
653
654 for (serialization::ModuleFile *MF : MDC.DirectModularDeps)
655 handleTopLevelModule(MF);
656
657 MDC.Consumer.handleContextHash(
658 MDC.ScanInstance.getInvocation().computeContextHash());
659
660 MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
661
662 MDC.Consumer.handleProvidedAndRequiredStdCXXModules(
663 MDC.ProvidedStdCXXModule, MDC.RequiredStdCXXModules);
664
665 for (auto &&I : MDC.ModularDeps)
666 MDC.Consumer.handleModuleDependency(*I.second);
667
668 for (serialization::ModuleFile *MF : MDC.DirectModularDeps) {
669 auto It = MDC.ModularDeps.find(MF);
670 // Only report direct dependencies that were successfully handled.
671 if (It != MDC.ModularDeps.end())
672 MDC.Consumer.handleDirectModuleDependency(It->second->ID);
673 }
674
675 for (auto &&I : MDC.VisibleModules)
676 MDC.Consumer.handleVisibleModule(std::string(I.getKey()));
677
678 for (auto &&I : MDC.FileDeps)
679 MDC.Consumer.handleFileDependency(I);
680
681 for (auto &&I : MDC.DirectPrebuiltModularDeps)
682 MDC.Consumer.handlePrebuiltModuleDependency(I.second);
683}
684
686 StringRef Path,
687 SmallVectorImpl<char> &Storage) {
688 // FIXME: Consider skipping if path is already absolute & canonicalized.
689
690 Storage.assign(Path.begin(), Path.end());
691 CI.getFileManager().makeAbsolutePath(Storage, /*Canonicalize=*/true);
692 return StringRef(Storage.data(), Storage.size());
693}
694
695std::optional<ModuleID>
696ModuleDepCollectorPP::handleTopLevelModule(serialization::ModuleFile *MF) {
697 // If this module has been handled already, just return its ID.
698 if (auto ModI = MDC.ModularDeps.find(MF); ModI != MDC.ModularDeps.end())
699 return ModI->second->ID;
700
701 Module *M = MDC.ScanInstance.getPreprocessor()
702 .getHeaderSearchInfo()
703 .getModuleMap()
704 .findModule(MF->ModuleName);
705 assert(M && M == M->getTopLevelModule() &&
706 "ModuleFile without top-level Module");
707
708 auto OwnedMD = std::make_unique<ModuleDeps>();
709 ModuleDeps &MD = *OwnedMD;
710
711 MD.ID.ModuleName = MF->ModuleName;
712 MD.IsSystem = M->IsSystem;
713
714 // Start off with the assumption that this module is shareable when there
715 // are stable directories. As more dependencies are discovered, check if those
716 // come from the provided directories.
717 MD.IsInStableDirectories = !MDC.StableDirs.empty();
718
719 // For modules which use export_as link name, the linked product that of the
720 // corresponding export_as-named module.
723
724 ModuleMap &ModMapInfo =
725 MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
726
727 if (auto ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M)) {
728 SmallString<128> Path = ModuleMap->getNameAsRequested();
729 ModMapInfo.canonicalizeModuleMapPath(Path);
730 MD.ClangModuleMapFile = std::string(Path);
731 }
732
733 llvm::SmallString<256> Storage;
734 MD.FileDepsBaseDir =
735 makeAbsoluteAndCanonicalize(MDC.ScanInstance, MF->BaseDirectory, Storage);
736 MDC.ScanInstance.getASTReader()->visitInputFileInfos(
737 *MF, /*IncludeSystem=*/true,
738 [&](const serialization::InputFileInfo &IFI, bool IsSystem) {
739 // The __inferred_module.map file is an insignificant implementation
740 // detail of implicitly-built modules. The PCM will also report the
741 // actual on-disk module map file that allowed inferring the module,
742 // which is what we need for building the module explicitly
743 // Let's ignore this file.
744 if (IFI.UnresolvedImportedFilename.ends_with("__inferred_module.map"))
745 return;
746 MDC.addFileDep(MD, IFI.UnresolvedImportedFilename);
747 });
748
749 addAllModuleDeps(*MF, MD);
750
751 SmallString<0> PathBuf;
752 PathBuf.reserve(256);
753 MDC.ScanInstance.getASTReader()->visitInputFileInfos(
754 *MF, /*IncludeSystem=*/true,
755 [&](const serialization::InputFileInfo &IFI, bool IsSystem) {
756 if (MD.IsInStableDirectories) {
757 auto FullFilePath = ASTReader::ResolveImportedPath(
758 PathBuf, IFI.UnresolvedImportedFilename, MF->BaseDirectory);
760 isPathInStableDir(MDC.StableDirs, *FullFilePath);
761 }
762 if (!(IFI.TopLevel && IFI.ModuleMap))
763 return;
765 "__inferred_module.map"))
766 return;
767 auto ResolvedFilenameAsRequested = ASTReader::ResolveImportedPath(
769 MF->BaseDirectory);
770 MD.ModuleMapFileDeps.emplace_back(*ResolvedFilenameAsRequested);
771 });
772
773 bool IgnoreCWD = false;
774 CowCompilerInvocation CI =
775 MDC.getInvocationAdjustedForModuleBuildWithoutOutputs(
776 MD, [&](CowCompilerInvocation &BuildInvocation) {
777 if (any(MDC.Service.getOpts().OptimizeArgs &
781 *MDC.ScanInstance.getASTReader(), *MF,
782 MDC.PrebuiltModulesASTMap,
783 MDC.Service.getOpts().OptimizeArgs);
784
785 if (any(MDC.Service.getOpts().OptimizeArgs &
788 BuildInvocation.getMutDiagnosticOpts(),
789 BuildInvocation.getFrontendOpts().IsSystemModule);
790
791 IgnoreCWD = any(MDC.Service.getOpts().OptimizeArgs &
793 isSafeToIgnoreCWD(BuildInvocation);
794 if (IgnoreCWD) {
795 llvm::ErrorOr<std::string> CWD =
796 MDC.ScanInstance.getVirtualFileSystem()
797 .getCurrentWorkingDirectory();
798 if (CWD)
799 optimizeCWD(BuildInvocation, *CWD);
800 }
801 });
802
803 // FIXME: Propagate errors up.
804 (void)MDC.Controller.finalizeModuleInvocation(MDC.ScanInstance, CI, MD);
805
806 // Check provided input paths from the invocation for determining
807 // IsInStableDirectories.
810 areOptionsInStableDir(MDC.StableDirs, CI.getHeaderSearchOpts());
811
812 MD.IgnoreCWD = IgnoreCWD;
813 MDC.associateWithContextHash(CI, MD);
814
815 // Finish the compiler invocation. Requires dependencies and the context hash.
816 MDC.addOutputPaths(CI, MD);
817
818 MD.BuildInfo = std::move(CI);
819
820 MDC.ModularDeps.insert({MF, std::move(OwnedMD)});
821
822 return MD.ID;
823}
824
825void ModuleDepCollectorPP::addAllModuleDeps(serialization::ModuleFile &MF,
826 ModuleDeps &MD) {
827 llvm::DenseSet<const Module *> Seen;
828 for (serialization::ModuleFile *Import : MF.Imports) {
829 if (MDC.isPrebuiltModule(Import)) {
830 MD.PrebuiltModuleDeps.emplace_back(Import);
831 if (MD.IsInStableDirectories) {
832 auto It = MDC.PrebuiltModulesASTMap.find(
833 MD.PrebuiltModuleDeps.back().PCMFile);
835 It != MDC.PrebuiltModulesASTMap.end() && It->second.isInStableDir();
836 }
837 } else {
838 if (auto ID = handleTopLevelModule(Import)) {
839 MD.ClangModuleDeps.push_back(std::move(*ID));
842 MDC.ModularDeps[Import]->IsInStableDirectories;
843 }
844 }
845 }
846}
847
850 std::unique_ptr<DependencyOutputOptions> Opts,
851 CompilerInstance &ScanInstance, DependencyConsumer &C,
852 DependencyActionController &Controller, CompilerInvocation OriginalCI,
853 const PrebuiltModulesAttrsMap PrebuiltModulesASTMap,
854 const ArrayRef<StringRef> StableDirs)
855 : Service(Service), ScanInstance(ScanInstance), Consumer(C),
856 Controller(Controller),
857 PrebuiltModulesASTMap(std::move(PrebuiltModulesASTMap)),
858 StableDirs(StableDirs), Opts(std::move(Opts)),
859 CommonInvocation(
860 makeCommonInvocationForModuleBuild(std::move(OriginalCI))) {}
861
863 auto CollectorPP = std::make_unique<ModuleDepCollectorPP>(*this);
864 CollectorPPPtr = CollectorPP.get();
865 PP.addPPCallbacks(std::move(CollectorPP));
866}
867
869
870bool ModuleDepCollector::isPrebuiltModule(const serialization::ModuleFile *MF) {
871 const auto &PrebuiltModuleFiles =
873 auto PrebuiltModuleFileIt = PrebuiltModuleFiles.find(MF->ModuleName);
874 if (PrebuiltModuleFileIt == PrebuiltModuleFiles.end())
875 return false;
876 assert("Prebuilt module came from the expected AST file" &&
877 PrebuiltModuleFileIt->second == MF->FileName.str());
878 return true;
879}
880
881void ModuleDepCollector::addVisibleModules() {
882 llvm::DenseSet<const Module *> ImportedModules;
883 auto InsertVisibleModules = [&](const Module *M) {
884 if (ImportedModules.contains(M))
885 return;
886
887 VisibleModules.insert(M->getTopLevelModuleName());
889 M->getExportedModules(Stack);
890 while (!Stack.empty()) {
891 const Module *CurrModule = Stack.pop_back_val();
892 if (ImportedModules.contains(CurrModule))
893 continue;
894 ImportedModules.insert(CurrModule);
895 VisibleModules.insert(CurrModule->getTopLevelModuleName());
896 CurrModule->getExportedModules(Stack);
897 }
898 };
899
900 for (const Module *Import : DirectImports)
901 InsertVisibleModules(Import);
902}
903
904void ModuleDepCollector::addFileDep(StringRef Path) {
905 if (!Service.getOpts().ReportAbsolutePaths) {
906 FileDeps.emplace_back(Path);
907 return;
908 }
909
910 llvm::SmallString<256> Storage;
911 Path = makeAbsoluteAndCanonicalize(ScanInstance, Path, Storage);
912 FileDeps.emplace_back(Path);
913}
914
915void ModuleDepCollector::addFileDep(ModuleDeps &MD, StringRef Path) {
916 MD.FileDeps.emplace_back(Path);
917}
Result
Implement __builtin_bit_cast and related operations.
static std::vector< std::string > splitString(std::string S, char Separator)
static std::string getModuleContextHash(const ModuleDeps &MD, const CowCompilerInvocation &CI, bool EagerLoadModules, llvm::vfs::FileSystem &VFS)
static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts, ASTReader &Reader, const serialization::ModuleFile &MF, const PrebuiltModulesAttrsMap &PrebuiltModulesASTMap, ScanningOptimizations OptimizeArgs)
static void optimizeDiagnosticOpts(DiagnosticOptions &Opts, bool IsSystemModule)
static CowCompilerInvocation makeCommonInvocationForModuleBuild(CompilerInvocation CI)
static bool needsModules(FrontendInputFile FIF)
static bool isSafeToIgnoreCWD(const CowCompilerInvocation &CI)
static void optimizeCWD(CowCompilerInvocation &BuildInvocation, StringRef CWD)
static StringRef makeAbsoluteAndCanonicalize(CompilerInstance &CI, StringRef Path, SmallVectorImpl< char > &Storage)
#define SM(sm)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Reads an AST files chain containing the contents of a translation unit.
Definition ASTReader.h:427
static TemporarilyOwnedStringRef ResolveImportedPath(SmallString< 0 > &Buf, StringRef Path, ModuleFile &ModF)
Resolve Path in the context of module file M.
Represents a byte-granular source range.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string ProfileInstrumentUsePath
Name of the profile file to use as input for -fprofile-instr-use.
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
std::string MainFileName
The user provided name for the "main file", if non-empty.
std::string CoverageCompilationDir
The string to embed in coverage mapping as the current working directory.
std::string ProfileRemappingFile
Name of the profile remapping file to apply to the profile data supplied by -fprofile-sample-use or -...
std::string DwarfDebugFlags
The string to embed in the debug information for the compile unit, if non-empty.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
FileManager & getFileManager() const
Return the current file manager to the caller.
IntrusiveRefCntPtr< ASTReader > getASTReader() const
HeaderSearchOptions & getHeaderSearchOpts()
const FrontendOptions & getFrontendOpts() const
void visitPaths(llvm::function_ref< bool(StringRef)> Callback) const
Visitation.
void generateCC1CommandLine(llvm::SmallVectorImpl< const char * > &Args, StringAllocator SA) const
Generate cc1-compatible command line arguments from this instance.
const DependencyOutputOptions & getDependencyOutputOpts() const
const HeaderSearchOptions & getHeaderSearchOpts() const
const DiagnosticOptions & getDiagnosticOpts() const
Helper class for holding the data necessary to invoke the compiler.
PreprocessorOptions & getPreprocessorOpts()
void clearImplicitModuleBuildOptions()
Disable implicit modules and canonicalize options that are only used by implicit modules.
LangOptions & getLangOpts()
Mutable getters.
DependencyOutputOptions & getDependencyOutputOpts()
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
FrontendOptions & getFrontendOpts()
CodeGenOptions & getCodeGenOpts()
HeaderSearchOptions & getHeaderSearchOpts()
DiagnosticOptions & getDiagnosticOpts()
Same as CompilerInvocation, but with copy-on-write optimization.
LangOptions & getMutLangOpts()
Mutable getters.
HeaderSearchOptions & getMutHeaderSearchOpts()
FileSystemOptions & getMutFileSystemOpts()
DiagnosticOptions & getMutDiagnosticOpts()
DependencyOutputOptions & getMutDependencyOutputOpts()
std::string OutputFile
The file to write dependency output to.
std::vector< std::string > Targets
A list of names to use as the targets in the dependency file; this list must contain at least one ent...
unsigned IncludeModuleFiles
Include module file dependencies.
Options for controlling the compiler diagnostics engine.
std::vector< std::string > Remarks
The list of -R... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > Warnings
The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > UndefPrefixes
The list of prefixes from -Wundef-prefix=... used to generate warnings for undefined macros.
std::vector< std::string > SystemHeaderWarningsModules
The list of -Wsystem-headers-in-module=... options used to override whether -Wsystem-headers is enabl...
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool makeAbsolutePath(SmallVectorImpl< char > &Path, bool Canonicalize=false) const
Makes Path absolute taking into account FileSystemOptions and the working directory option,...
std::string WorkingDir
If set, paths are resolved as if the working directory was set to the value of WorkingDir.
An input file for the front end.
InputKind getKind() const
InputKind DashX
The input kind, either specified via -x argument or deduced from the input file name.
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input.
unsigned IsSystemModule
When using -emit-module, treat the modulemap as a system module.
std::vector< std::string > LLVMArgs
A list of arguments to forward to LLVM's option processing; this should only be used for debugging an...
std::string OutputFile
The output file, if any.
unsigned GenReducedBMI
Whether to generate reduced BMI for C++20 named modules.
std::string ModuleOutputPath
Output Path for module output file.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::vector< std::string > ModuleMapFiles
The list of module map files to load before processing the input.
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
unsigned ModulesPruneNonAffectingModuleMaps
Whether to prune non-affecting module map files from PCM files.
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
unsigned ModulesSkipHeaderSearchPaths
Whether to entirely skip writing header search paths.
std::vector< SystemHeaderPrefix > SystemHeaderPrefixes
User-specified system header prefixes.
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.
llvm::SmallSetVector< llvm::CachedHashString, 16 > ModulesIgnoreMacros
The set of macro names that should be ignored for the purposes of computing the module hash.
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
std::vector< Entry > UserEntries
User specified include entries.
std::string ResourceDir
The directory which holds the compiler resource files (builtin includes, etc.).
ModuleMap & getModuleMap()
Retrieve the module map.
Language getLanguage() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Deduplication key for a loaded module file in ModuleManager.
Definition Module.h:77
StringRef str() const
Returns the plain module file name.
Definition Module.h:149
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
Describes a module or submodule.
Definition Module.h:301
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Definition Module.h:911
const ModuleFileKey * getASTFileKey() const
The serialized AST file key for this module, if one was created.
Definition Module.h:922
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition Module.h:550
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
Definition Module.h:681
void getExportedModules(SmallVectorImpl< Module * > &Exported) const
Appends this module's list of exported modules to Exported.
Definition Module.cpp:379
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition Module.h:901
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
Definition Module.h:685
std::vector< std::pair< std::string, bool > > Macros
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
HeaderSearch & getHeaderSearchInfo() const
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Token - This structure provides full information about a lexed token.
Definition Token.h:36
Dependency scanner callbacks that are used during scanning to influence the behaviour of the scan - f...
The dependency scanning service contains shared configuration and state that is used by the individua...
void EndOfMainFile() override
Callback invoked when the end of the main file is reached.
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, bool ModuleImported, SrcMgr::CharacteristicKind FileType) override
Callback invoked whenever an inclusion directive of any kind (#include, #import, etc....
void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, OptionalFileEntryRef File, SrcMgr::CharacteristicKind FileType) override
Hook called when a '__has_include' or '__has_include_next' directive is read.
void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID, SourceLocation Loc) override
Callback invoked whenever the Lexer moves to a different file for lexing.
void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported) override
Callback invoked whenever there was an explicit module-import syntax.
ModuleDepCollector(DependencyScanningService &Service, std::unique_ptr< DependencyOutputOptions > Opts, CompilerInstance &ScanInstance, DependencyConsumer &C, DependencyActionController &Controller, CompilerInvocation OriginalCI, const PrebuiltModulesAttrsMap PrebuiltModulesASTMap, const ArrayRef< StringRef > StableDirs)
void applyDiscoveredDependencies(CompilerInvocation &CI)
Apply any changes implied by the discovered dependencies to the given invocation, (e....
void attachToPreprocessor(Preprocessor &PP) override
void attachToASTReader(ASTReader &R) override
void updateDependentsNotInStableDirs(PrebuiltModulesAttrsMap &PrebuiltModulesMap)
When a module is discovered to not be in stable directories, traverse & update all modules that depen...
bool isInStableDir() const
Read-only access to whether the module is made up of dependencies in stable directories.
void setInStableDir(bool V=false)
Update whether the prebuilt module resolves entirely in a stable directories.
Information about a module that has been loaded by the ASTReader.
Definition ModuleFile.h:158
llvm::SetVector< ModuleFile * > Imports
List of modules which this module directly imported.
Definition ModuleFile.h:555
llvm::BitVector SearchPathUsage
The bit vector denoting usage of each header search entry (true = used).
Definition ModuleFile.h:234
ModuleFileName FileName
The file name of the module file.
Definition ModuleFile.h:177
llvm::BitVector VFSUsage
The bit vector denoting usage of each VFS entry (true = used).
Definition ModuleFile.h:237
ModuleKind Kind
The type of this module.
Definition ModuleFile.h:174
std::string ModuleName
The name of the module.
Definition ModuleFile.h:183
std::string BaseDirectory
The base directory of the module.
Definition ModuleFile.h:186
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool areOptionsInStableDir(const ArrayRef< StringRef > Directories, const HeaderSearchOptions &HSOpts)
Determine if options collected from a module's compilation can safely be considered as stable.
@ VFS
Remove unused -ivfsoverlay arguments.
@ IgnoreCWD
Ignore the compiler's working directory if it is safe.
@ SystemWarnings
Remove warnings from system modules.
@ HeaderSearch
Remove unused header search paths including header maps.
@ DiagnosticSerializationFile
The path of the serialized diagnostic file (.dia), if any.
@ DependencyFile
The path of the dependency file (.d), if any.
@ DependencyTargets
The null-separated list of names to use as the targets in the dependency file, if any.
@ ModuleFile
The module file (.pcm). Required.
llvm::StringMap< PrebuiltModuleASTAttrs > PrebuiltModulesAttrsMap
Attributes loaded from AST files of prebuilt modules collected prior to ModuleDepCollector creation.
bool isPathInStableDir(const ArrayRef< StringRef > Directories, const StringRef Input)
Determine if Input can be resolved within a stable directory.
void resetBenignCodeGenOptions(frontend::ActionKind ProgramAction, const LangOptions &LangOpts, CodeGenOptions &CGOpts)
Resets codegen options that don't affect modules/PCH.
@ GeneratePCH
Generate pre-compiled header.
@ GenerateModule
Generate pre-compiled module from a module map.
const unsigned VERSION_MINOR
AST file minor version number supported by this version of Clang.
Definition ASTBitCodes.h:57
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
Definition ASTBitCodes.h:47
@ MK_ImplicitModule
File is an implicitly-loaded module.
Definition ModuleFile.h:46
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:208
void quoteMakeTarget(StringRef Target, SmallVectorImpl< char > &Res)
Quote target names for inclusion in GNU Make dependency files.
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
Definition Linkage.h:54
@ Asm
Assembly: we accept this only so that we can preprocess it.
@ MFDK_Direct
Include only directly imported module file dependencies.
std::string getClangFullRepositoryVersion()
Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...
Definition Version.cpp:68
int const char * function
Definition c++config.h:31
int __ovld __cnfn any(char)
Returns 1 if the most significant bit in any component of x is set; otherwise returns 0.
std::vector< std::string > ModuleMapFileDeps
A collection of absolute paths to module map files that this module needs to know about.
bool IsInStableDirectories
Whether this module is fully composed of file & module inputs from locations likely to stay the same ...
ModuleID ID
The identifier of the module.
bool IgnoreCWD
Whether current working directory is ignored.
void forEachFileDep(llvm::function_ref< void(StringRef)> Cb) const
Invokes Cb for all file dependencies of this module.
std::vector< PrebuiltModuleDep > PrebuiltModuleDeps
A collection of prebuilt modular dependencies this module directly depends on, not including transiti...
llvm::SmallVector< Module::LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
std::vector< ModuleID > ClangModuleDeps
A list of module identifiers this module directly depends on, not including transitive dependencies.
const std::vector< std::string > & getBuildArguments() const
Get (or compute) the compiler invocation that can be used to build this module.
std::string ClangModuleMapFile
The path to the modulemap file which defines this module.
bool IsSystem
Whether this is a "system" module.
std::string ModuleName
The name of the module.
std::string ContextHash
The context hash of a module represents the compiler options that affect the resulting command-line i...
P1689ModuleInfo - Represents the needed information of standard C++20 modules for P1689 format.
bool IsStdCXXModuleInterface
If this module is a standard c++ interface unit.
std::string ModuleName
The name of the module. This may include : for partitions.
Modular dependency that has already been built prior to the dependency scan.