clang 17.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/Support/BLAKE3.h"
16#include "llvm/Support/StringSaver.h"
17#include <optional>
18
19using namespace clang;
20using namespace tooling;
21using namespace dependencies;
22
24 ASTReader &Reader,
25 const serialization::ModuleFile &MF) {
26 // Only preserve search paths that were used during the dependency scan.
27 std::vector<HeaderSearchOptions::Entry> Entries = Opts.UserEntries;
28 Opts.UserEntries.clear();
29
30 llvm::BitVector SearchPathUsage(Entries.size());
32 std::function<void(const serialization::ModuleFile *)> VisitMF =
33 [&](const serialization::ModuleFile *MF) {
34 SearchPathUsage |= MF->SearchPathUsage;
35 Visited.insert(MF);
37 if (!Visited.contains(Import))
38 VisitMF(Import);
39 };
40 VisitMF(&MF);
41
42 for (auto Idx : SearchPathUsage.set_bits())
43 Opts.UserEntries.push_back(Entries[Idx]);
44}
45
46static std::vector<std::string> splitString(std::string S, char Separator) {
48 StringRef(S).split(Segments, Separator, /*MaxSplit=*/-1, /*KeepEmpty=*/false);
49 std::vector<std::string> Result;
50 Result.reserve(Segments.size());
51 for (StringRef Segment : Segments)
52 Result.push_back(Segment.str());
53 return Result;
54}
55
56void ModuleDepCollector::addOutputPaths(CompilerInvocation &CI,
57 ModuleDeps &Deps) {
62 Controller.lookupModuleOutput(
64 if (!CI.getDependencyOutputOpts().OutputFile.empty()) {
70 '\0');
71 if (!CI.getDependencyOutputOpts().OutputFile.empty() &&
72 CI.getDependencyOutputOpts().Targets.empty()) {
73 // Fallback to -o as dependency target, as in the driver.
76 CI.getDependencyOutputOpts().Targets.push_back(std::string(Target));
77 }
78 }
79}
80
82ModuleDepCollector::makeInvocationForModuleBuildWithoutOutputs(
83 const ModuleDeps &Deps,
84 llvm::function_ref<void(CompilerInvocation &)> Optimize) const {
85 // Make a deep copy of the original Clang invocation.
86 CompilerInvocation CI(OriginalInvocation);
87
90
91 // Remove options incompatible with explicit module build or are likely to
92 // differ between identical modules discovered from different translation
93 // units.
94 CI.getFrontendOpts().Inputs.clear();
95 CI.getFrontendOpts().OutputFile.clear();
96
97 // TODO: Figure out better way to set options to their default value.
98 CI.getCodeGenOpts().MainFileName.clear();
100 if (!CI.getLangOpts()->ModulesCodegen) {
103 CI.getCodeGenOpts().CoverageDataFile.clear();
105 }
106
107 // Map output paths that affect behaviour to "-" so their existence is in the
108 // context hash. The final path will be computed in addOutputPaths.
111 if (!CI.getDependencyOutputOpts().OutputFile.empty())
113 CI.getDependencyOutputOpts().Targets.clear();
114
118 CI.getFrontendOpts().MTMigrateDir.clear();
119 CI.getLangOpts()->ModuleName = Deps.ID.ModuleName;
121
122 // Inputs
123 InputKind ModuleMapInputKind(CI.getFrontendOpts().DashX.getLanguage(),
125 CI.getFrontendOpts().Inputs.emplace_back(Deps.ClangModuleMapFile,
126 ModuleMapInputKind);
127
128 auto CurrentModuleMapEntry =
129 ScanInstance.getFileManager().getFile(Deps.ClangModuleMapFile);
130 assert(CurrentModuleMapEntry && "module map file entry not found");
131
132 auto DepModuleMapFiles = collectModuleMapFiles(Deps.ClangModuleDeps);
133 for (StringRef ModuleMapFile : Deps.ModuleMapFileDeps) {
134 // TODO: Track these as `FileEntryRef` to simplify the equality check below.
135 auto ModuleMapEntry = ScanInstance.getFileManager().getFile(ModuleMapFile);
136 assert(ModuleMapEntry && "module map file entry not found");
137
138 // Don't report module maps describing eagerly-loaded dependency. This
139 // information will be deserialized from the PCM.
140 // TODO: Verify this works fine when modulemap for module A is eagerly
141 // loaded from A.pcm, and module map passed on the command line contains
142 // definition of a submodule: "explicit module A.Private { ... }".
143 if (EagerLoadModules && DepModuleMapFiles.contains(*ModuleMapEntry))
144 continue;
145
146 // Don't report module map file of the current module unless it also
147 // describes a dependency (for symmetry).
148 if (*ModuleMapEntry == *CurrentModuleMapEntry &&
149 !DepModuleMapFiles.contains(*ModuleMapEntry))
150 continue;
151
152 CI.getFrontendOpts().ModuleMapFiles.emplace_back(ModuleMapFile);
153 }
154
155 // Report the prebuilt modules this module uses.
156 for (const auto &PrebuiltModule : Deps.PrebuiltModuleDeps)
157 CI.getFrontendOpts().ModuleFiles.push_back(PrebuiltModule.PCMFile);
158
159 // Add module file inputs from dependencies.
160 addModuleFiles(CI, Deps.ClangModuleDeps);
161
162 // Remove any macro definitions that are explicitly ignored.
163 if (!CI.getHeaderSearchOpts().ModulesIgnoreMacros.empty()) {
164 llvm::erase_if(
166 [&CI](const std::pair<std::string, bool> &Def) {
167 StringRef MacroDef = Def.first;
168 return CI.getHeaderSearchOpts().ModulesIgnoreMacros.contains(
169 llvm::CachedHashString(MacroDef.split('=').first));
170 });
171 // Remove the now unused option.
173 }
174
175 Optimize(CI);
176
177 return CI;
178}
179
180llvm::DenseSet<const FileEntry *> ModuleDepCollector::collectModuleMapFiles(
181 ArrayRef<ModuleID> ClangModuleDeps) const {
183 for (const ModuleID &MID : ClangModuleDeps) {
184 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
185 assert(MD && "Inconsistent dependency info");
186 // TODO: Track ClangModuleMapFile as `FileEntryRef`.
187 auto FE = ScanInstance.getFileManager().getFile(MD->ClangModuleMapFile);
188 assert(FE && "Missing module map file that was previously found");
189 ModuleMapFiles.insert(*FE);
190 }
191 return ModuleMapFiles;
192}
193
194void ModuleDepCollector::addModuleMapFiles(
195 CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
196 if (EagerLoadModules)
197 return; // Only pcm is needed for eager load.
198
199 for (const ModuleID &MID : ClangModuleDeps) {
200 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
201 assert(MD && "Inconsistent dependency info");
203 }
204}
205
206void ModuleDepCollector::addModuleFiles(
207 CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
208 for (const ModuleID &MID : ClangModuleDeps) {
209 std::string PCMPath =
211 if (EagerLoadModules)
212 CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
213 else
215 {MID.ModuleName, std::move(PCMPath)});
216 }
217}
218
220 switch (FIF.getKind().getLanguage()) {
222 case Language::Asm:
224 return false;
225 default:
226 return true;
227 }
228}
229
232
233 if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
234 Preprocessor &PP = ScanInstance.getPreprocessor();
235 if (Module *CurrentModule = PP.getCurrentModuleImplementation())
236 if (OptionalFileEntryRef CurrentModuleMap =
238 .getModuleMap()
239 .getModuleMapFileForUniquing(CurrentModule))
240 CI.getFrontendOpts().ModuleMapFiles.emplace_back(
241 CurrentModuleMap->getNameAsRequested());
242
243 SmallVector<ModuleID> DirectDeps;
244 for (const auto &KV : ModularDeps)
245 if (KV.second->ImportedByMainFile)
246 DirectDeps.push_back(KV.second->ID);
247
248 // TODO: Report module maps the same way it's done for modular dependencies.
249 addModuleMapFiles(CI, DirectDeps);
250
251 addModuleFiles(CI, DirectDeps);
252
253 for (const auto &KV : DirectPrebuiltModularDeps)
254 CI.getFrontendOpts().ModuleFiles.push_back(KV.second.PCMFile);
255 }
256}
257
258static std::string getModuleContextHash(const ModuleDeps &MD,
259 const CompilerInvocation &CI,
260 bool EagerLoadModules) {
261 llvm::HashBuilder<llvm::TruncatedBLAKE3<16>,
262 llvm::support::endianness::native>
263 HashBuilder;
264 SmallString<32> Scratch;
265
266 // Hash the compiler version and serialization version to ensure the module
267 // will be readable.
268 HashBuilder.add(getClangFullRepositoryVersion());
270
271 // Hash the BuildInvocation without any input files.
273 llvm::BumpPtrAllocator Alloc;
274 llvm::StringSaver Saver(Alloc);
276 Args, [&](const Twine &Arg) { return Saver.save(Arg).data(); });
277 HashBuilder.addRange(Args);
278
279 // Hash the module dependencies. These paths may differ even if the invocation
280 // is identical if they depend on the contents of the files in the TU -- for
281 // example, case-insensitive paths to modulemap files. Usually such a case
282 // would indicate a missed optimization to canonicalize, but it may be
283 // difficult to canonicalize all cases when there is a VFS.
284 for (const auto &ID : MD.ClangModuleDeps) {
285 HashBuilder.add(ID.ModuleName);
286 HashBuilder.add(ID.ContextHash);
287 }
288
289 HashBuilder.add(EagerLoadModules);
290
291 llvm::BLAKE3Result<16> Hash = HashBuilder.final();
292 std::array<uint64_t, 2> Words;
293 static_assert(sizeof(Hash) == sizeof(Words), "Hash must match Words");
294 std::memcpy(Words.data(), Hash.data(), sizeof(Hash));
295 return toString(llvm::APInt(sizeof(Words) * 8, Words), 36, /*Signed=*/false);
296}
297
298void ModuleDepCollector::associateWithContextHash(const CompilerInvocation &CI,
299 ModuleDeps &Deps) {
300 Deps.ID.ContextHash = getModuleContextHash(Deps, CI, EagerLoadModules);
301 bool Inserted = ModuleDepsByID.insert({Deps.ID, &Deps}).second;
302 (void)Inserted;
303 assert(Inserted && "duplicate module mapping");
304}
305
309 FileID PrevFID,
310 SourceLocation Loc) {
312 return;
313
314 // This has to be delayed as the context hash can change at the start of
315 // `CompilerInstance::ExecuteAction`.
316 if (MDC.ContextHash.empty()) {
317 MDC.ContextHash = MDC.ScanInstance.getInvocation().getModuleHash();
318 MDC.Consumer.handleContextHash(MDC.ContextHash);
319 }
320
321 SourceManager &SM = MDC.ScanInstance.getSourceManager();
322
323 // Dependency generation really does want to go all the way to the
324 // file entry for a source location to find out what is depended on.
325 // We do not want #line markers to affect dependency generation!
326 if (std::optional<StringRef> Filename = SM.getNonBuiltinFilenameForID(FID))
327 MDC.addFileDep(llvm::sys::path::remove_leading_dotslash(*Filename));
328}
329
331 SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
332 bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
333 StringRef SearchPath, StringRef RelativePath, const Module *Imported,
335 if (!File && !Imported) {
336 // This is a non-modular include that HeaderSearch failed to find. Add it
337 // here as `FileChanged` will never see it.
338 MDC.addFileDep(FileName);
339 }
340 handleImport(Imported);
341}
342
344 ModuleIdPath Path,
345 const Module *Imported) {
346 if (MDC.ScanInstance.getPreprocessor().isInImportingCXXNamedModules()) {
347 P1689ModuleInfo RequiredModule;
348 RequiredModule.ModuleName = Path[0].first->getName().str();
350 MDC.RequiredStdCXXModules.push_back(RequiredModule);
351 return;
352 }
353
354 handleImport(Imported);
355}
356
357void ModuleDepCollectorPP::handleImport(const Module *Imported) {
358 if (!Imported)
359 return;
360
361 const Module *TopLevelModule = Imported->getTopLevelModule();
362
363 if (MDC.isPrebuiltModule(TopLevelModule))
364 MDC.DirectPrebuiltModularDeps.insert(
365 {TopLevelModule, PrebuiltModuleDep{TopLevelModule}});
366 else
367 DirectModularDeps.insert(TopLevelModule);
368}
369
371 FileID MainFileID = MDC.ScanInstance.getSourceManager().getMainFileID();
372 MDC.MainFile = std::string(MDC.ScanInstance.getSourceManager()
373 .getFileEntryForID(MainFileID)
374 ->getName());
375
376 auto &PP = MDC.ScanInstance.getPreprocessor();
377 if (PP.isInNamedModule()) {
378 P1689ModuleInfo ProvidedModule;
379 ProvidedModule.ModuleName = PP.getNamedModuleName();
381 ProvidedModule.IsStdCXXModuleInterface = PP.isInNamedInterfaceUnit();
382 // Don't put implementation (non partition) unit as Provide.
383 // Put the module as required instead. Since the implementation
384 // unit will import the primary module implicitly.
385 if (PP.isInImplementationUnit())
386 MDC.RequiredStdCXXModules.push_back(ProvidedModule);
387 else
388 MDC.ProvidedStdCXXModule = ProvidedModule;
389 }
390
391 if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
392 MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude);
393
394 for (const Module *M :
395 MDC.ScanInstance.getPreprocessor().getAffectingClangModules())
396 if (!MDC.isPrebuiltModule(M))
397 DirectModularDeps.insert(M);
398
399 for (const Module *M : DirectModularDeps)
400 handleTopLevelModule(M);
401
402 MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
403
404 if (MDC.IsStdModuleP1689Format)
406 MDC.ProvidedStdCXXModule, MDC.RequiredStdCXXModules);
407
408 for (auto &&I : MDC.ModularDeps)
409 MDC.Consumer.handleModuleDependency(*I.second);
410
411 for (auto &&I : MDC.FileDeps)
412 MDC.Consumer.handleFileDependency(I);
413
414 for (auto &&I : MDC.DirectPrebuiltModularDeps)
415 MDC.Consumer.handlePrebuiltModuleDependency(I.second);
416}
417
418std::optional<ModuleID>
419ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
420 assert(M == M->getTopLevelModule() && "Expected top level module!");
421
422 // A top-level module might not be actually imported as a module when
423 // -fmodule-name is used to compile a translation unit that imports this
424 // module. In that case it can be skipped. The appropriate header
425 // dependencies will still be reported as expected.
426 if (!M->getASTFile())
427 return {};
428
429 // If this module has been handled already, just return its ID.
430 auto ModI = MDC.ModularDeps.insert({M, nullptr});
431 if (!ModI.second)
432 return ModI.first->second->ID;
433
434 ModI.first->second = std::make_unique<ModuleDeps>();
435 ModuleDeps &MD = *ModI.first->second;
436
438 MD.ImportedByMainFile = DirectModularDeps.contains(M);
439 MD.IsSystem = M->IsSystem;
440
441 ModuleMap &ModMapInfo =
442 MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
443
445
446 if (ModuleMap) {
447 SmallString<128> Path = ModuleMap->getNameAsRequested();
448 ModMapInfo.canonicalizeModuleMapPath(Path);
449 MD.ClangModuleMapFile = std::string(Path);
450 }
451
453 MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
454 M->getASTFile());
455 MDC.ScanInstance.getASTReader()->visitInputFiles(
456 *MF, true, true, [&](const serialization::InputFile &IF, bool isSystem) {
457 // __inferred_module.map is the result of the way in which an implicit
458 // module build handles inferred modules. It adds an overlay VFS with
459 // this file in the proper directory and relies on the rest of Clang to
460 // handle it like normal. With explicitly built modules we don't need
461 // to play VFS tricks, so replace it with the correct module map.
462 if (IF.getFile()->getName().endswith("__inferred_module.map")) {
463 MDC.addFileDep(MD, ModuleMap->getName());
464 return;
465 }
466 MDC.addFileDep(MD, IF.getFile()->getName());
467 });
468
470 addAllSubmodulePrebuiltDeps(M, MD, SeenDeps);
471 addAllSubmoduleDeps(M, MD, SeenDeps);
472 addAllAffectingClangModules(M, MD, SeenDeps);
473
474 MDC.ScanInstance.getASTReader()->visitTopLevelModuleMaps(
475 *MF, [&](FileEntryRef FE) {
476 if (FE.getNameAsRequested().endswith("__inferred_module.map"))
477 return;
478 MD.ModuleMapFileDeps.emplace_back(FE.getNameAsRequested());
479 });
480
481 CompilerInvocation CI = MDC.makeInvocationForModuleBuildWithoutOutputs(
482 MD, [&](CompilerInvocation &BuildInvocation) {
483 if (MDC.OptimizeArgs)
485 *MDC.ScanInstance.getASTReader(), *MF);
486 });
487
488 MDC.associateWithContextHash(CI, MD);
489
490 // Finish the compiler invocation. Requires dependencies and the context hash.
491 MDC.addOutputPaths(CI, MD);
492
494
495 return MD.ID;
496}
497
498static void forEachSubmoduleSorted(const Module *M,
499 llvm::function_ref<void(const Module *)> F) {
500 // Submodule order depends on order of header includes for inferred submodules
501 // we don't care about the exact order, so sort so that it's consistent across
502 // TUs to improve sharing.
504 llvm::stable_sort(Submodules, [](const Module *A, const Module *B) {
505 return A->Name < B->Name;
506 });
507 for (const Module *SubM : Submodules)
508 F(SubM);
509}
510
511void ModuleDepCollectorPP::addAllSubmodulePrebuiltDeps(
512 const Module *M, ModuleDeps &MD,
513 llvm::DenseSet<const Module *> &SeenSubmodules) {
514 addModulePrebuiltDeps(M, MD, SeenSubmodules);
515
516 forEachSubmoduleSorted(M, [&](const Module *SubM) {
517 addAllSubmodulePrebuiltDeps(SubM, MD, SeenSubmodules);
518 });
519}
520
521void ModuleDepCollectorPP::addModulePrebuiltDeps(
522 const Module *M, ModuleDeps &MD,
523 llvm::DenseSet<const Module *> &SeenSubmodules) {
524 for (const Module *Import : M->Imports)
525 if (Import->getTopLevelModule() != M->getTopLevelModule())
526 if (MDC.isPrebuiltModule(Import->getTopLevelModule()))
527 if (SeenSubmodules.insert(Import->getTopLevelModule()).second)
528 MD.PrebuiltModuleDeps.emplace_back(Import->getTopLevelModule());
529}
530
531void ModuleDepCollectorPP::addAllSubmoduleDeps(
532 const Module *M, ModuleDeps &MD,
533 llvm::DenseSet<const Module *> &AddedModules) {
534 addModuleDep(M, MD, AddedModules);
535
536 forEachSubmoduleSorted(M, [&](const Module *SubM) {
537 addAllSubmoduleDeps(SubM, MD, AddedModules);
538 });
539}
540
541void ModuleDepCollectorPP::addModuleDep(
542 const Module *M, ModuleDeps &MD,
543 llvm::DenseSet<const Module *> &AddedModules) {
544 for (const Module *Import : M->Imports) {
545 if (Import->getTopLevelModule() != M->getTopLevelModule() &&
546 !MDC.isPrebuiltModule(Import)) {
547 if (auto ImportID = handleTopLevelModule(Import->getTopLevelModule()))
548 if (AddedModules.insert(Import->getTopLevelModule()).second)
549 MD.ClangModuleDeps.push_back(*ImportID);
550 }
551 }
552}
553
554void ModuleDepCollectorPP::addAllAffectingClangModules(
555 const Module *M, ModuleDeps &MD,
556 llvm::DenseSet<const Module *> &AddedModules) {
557 addAffectingClangModule(M, MD, AddedModules);
558
559 for (const Module *SubM : M->submodules())
560 addAllAffectingClangModules(SubM, MD, AddedModules);
561}
562
563void ModuleDepCollectorPP::addAffectingClangModule(
564 const Module *M, ModuleDeps &MD,
565 llvm::DenseSet<const Module *> &AddedModules) {
566 for (const Module *Affecting : M->AffectingClangModules) {
567 assert(Affecting == Affecting->getTopLevelModule() &&
568 "Not quite import not top-level module");
569 if (Affecting != M->getTopLevelModule() &&
570 !MDC.isPrebuiltModule(Affecting)) {
571 if (auto ImportID = handleTopLevelModule(Affecting))
572 if (AddedModules.insert(Affecting).second)
573 MD.ClangModuleDeps.push_back(*ImportID);
574 }
575 }
576}
577
579 std::unique_ptr<DependencyOutputOptions> Opts,
580 CompilerInstance &ScanInstance, DependencyConsumer &C,
581 DependencyActionController &Controller, CompilerInvocation OriginalCI,
582 bool OptimizeArgs, bool EagerLoadModules, bool IsStdModuleP1689Format)
583 : ScanInstance(ScanInstance), Consumer(C), Controller(Controller),
584 Opts(std::move(Opts)), OriginalInvocation(std::move(OriginalCI)),
585 OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules),
586 IsStdModuleP1689Format(IsStdModuleP1689Format) {}
587
589 PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(*this));
590}
591
593
594bool ModuleDepCollector::isPrebuiltModule(const Module *M) {
595 std::string Name(M->getTopLevelModuleName());
596 const auto &PrebuiltModuleFiles =
598 auto PrebuiltModuleFileIt = PrebuiltModuleFiles.find(Name);
599 if (PrebuiltModuleFileIt == PrebuiltModuleFiles.end())
600 return false;
601 assert("Prebuilt module came from the expected AST file" &&
602 PrebuiltModuleFileIt->second == M->getASTFile()->getName());
603 return true;
604}
605
606static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path,
607 SmallVectorImpl<char> &Storage) {
608 if (llvm::sys::path::is_absolute(Path) &&
609 !llvm::sys::path::is_style_windows(llvm::sys::path::Style::native))
610 return Path;
611 Storage.assign(Path.begin(), Path.end());
612 CI.getFileManager().makeAbsolutePath(Storage);
613 llvm::sys::path::make_preferred(Storage);
614 return StringRef(Storage.data(), Storage.size());
615}
616
617void ModuleDepCollector::addFileDep(StringRef Path) {
619 Path = makeAbsoluteAndPreferred(ScanInstance, Path, Storage);
620 FileDeps.push_back(std::string(Path));
621}
622
623void ModuleDepCollector::addFileDep(ModuleDeps &MD, StringRef Path) {
625 Path = makeAbsoluteAndPreferred(ScanInstance, Path, Storage);
626 MD.FileDeps.insert(Path);
627}
#define SM(sm)
Definition: Cuda.cpp:80
StringRef Filename
Definition: Format.cpp:2795
llvm::DenseSet< const void * > Visited
Definition: HTMLLogger.cpp:168
static std::vector< std::string > splitString(std::string S, char Separator)
static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path, SmallVectorImpl< char > &Storage)
static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts, ASTReader &Reader, const serialization::ModuleFile &MF)
static std::string getModuleContextHash(const ModuleDeps &MD, const CompilerInvocation &CI, bool EagerLoadModules)
static void forEachSubmoduleSorted(const Module *M, llvm::function_ref< void(const Module *)> F)
static bool needsModules(FrontendInputFile FIF)
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:366
Represents a character-granular source range.
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
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 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
Preprocessor & getPreprocessor() const
Return the current preprocessor.
HeaderSearchOptions & getHeaderSearchOpts()
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
SourceManager & getSourceManager() const
Return the current source manager.
PreprocessorOptions & getPreprocessorOpts()
DiagnosticOptions & getDiagnosticOpts() const
HeaderSearchOptions & getHeaderSearchOpts()
DependencyOutputOptions & getDependencyOutputOpts()
Helper class for holding the data necessary to invoke the compiler.
void clearImplicitModuleBuildOptions()
Disable implicit modules and canonicalize options that are only used by implicit modules.
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
void generateCC1CommandLine(llvm::SmallVectorImpl< const char * > &Args, StringAllocator SA) const
Generate cc1-compatible command line arguments from this instance.
std::string getModuleHash() const
Retrieve a module hash string that is suitable for uniquely identifying the conditions under which th...
std::vector< std::string > getCC1CommandLine() const
Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...
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...
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
StringRef getNameAsRequested() const
The name of this FileEntry, as originally requested without applying any remappings for VFS 'use-exte...
Definition: FileEntry.h:68
StringRef getName() const
Definition: FileEntry.h:384
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
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::string OutputFile
The output file, if any.
enum clang::FrontendOptions::@191 ARCMTAction
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...
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
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< Entry > UserEntries
User specified include entries.
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:795
The kind of a file that we've been handed as an input.
Language getLanguage() const
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:430
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
Definition: ModuleMap.cpp:1305
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
Definition: ModuleMap.cpp:1320
Describes a module or submodule.
Definition: Module.h:98
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Definition: Module.h:640
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Module.h:378
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition: Module.h:322
std::string Name
The name of this module.
Definition: Module.h:101
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:749
llvm::SmallSetVector< Module *, 2 > AffectingClangModules
The set of top-level modules that affected the compilation of this module, but were not imported.
Definition: Module.h:382
OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const
The serialized AST file for this module, if one was created.
Definition: Module.h:645
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition: Module.cpp:241
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition: Module.h:630
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
std::vector< std::pair< std::string, bool > > Macros
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
bool isInImportingCXXNamedModules() const
If we're importing a standard C++20 Named Modules.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
HeaderSearch & getHeaderSearchInfo() const
const llvm::SmallSetVector< Module *, 2 > & getAffectingClangModules() const
Get the set of top-level clang modules that affected preprocessing, but were not imported.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
FileID getMainFileID() const
Returns the FileID of the main source file.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
The input file that has been loaded from this AST file, along with bools indicating whether this was ...
Definition: ModuleFile.h:76
OptionalFileEntryRefDegradesToFileEntryPtr getFile() const
Definition: ModuleFile.h:105
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:122
llvm::SetVector< ModuleFile * > Imports
List of modules which this module depends on.
Definition: ModuleFile.h:511
llvm::BitVector SearchPathUsage
The bit vector denoting usage of each header search entry (true = used).
Definition: ModuleFile.h:188
Dependency scanner callbacks that are used during scanning to influence the behaviour of the scan - f...
virtual std::string lookupModuleOutput(const ModuleID &ID, ModuleOutputKind Kind)=0
virtual void handleModuleDependency(ModuleDeps MD)=0
virtual void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD)=0
virtual void handleDependencyOutputOpts(const DependencyOutputOptions &Opts)=0
virtual void handleProvidedAndRequiredStdCXXModules(std::optional< P1689ModuleInfo > Provided, std::vector< P1689ModuleInfo > Requires)
virtual void handleFileDependency(StringRef Filename)=0
virtual void handleContextHash(std::string Hash)=0
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 *Imported, SrcMgr::CharacteristicKind FileType) override
Callback invoked whenever an inclusion directive of any kind (#include, #import, etc....
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.
void applyDiscoveredDependencies(CompilerInvocation &CI)
Apply any changes implied by the discovered dependencies to the given invocation, (e....
ModuleDepCollector(std::unique_ptr< DependencyOutputOptions > Opts, CompilerInstance &ScanInstance, DependencyConsumer &C, DependencyActionController &Controller, CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules, bool IsStdModuleP1689Format)
void attachToPreprocessor(Preprocessor &PP) override
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:80
@ 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:54
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
Definition: ASTBitCodes.h:44
@ 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.
void quoteMakeTarget(StringRef Target, SmallVectorImpl< char > &Res)
Quote target names for inclusion in GNU Make dependency files.
Definition: MakeSupport.cpp:11
@ C
Languages that the frontend can parse and compile.
@ LLVM_IR
LLVM IR: we accept this so that we can run the optimizer on it, and compile it to assembly or object ...
@ Asm
Assembly: we accept this only so that we can preprocess it.
std::string getClangFullRepositoryVersion()
Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...
Definition: Version.cpp:60
Definition: Format.h:4756
std::string ClangModuleMapFile
The path to the modulemap file which defines this module.
std::vector< std::string > ModuleMapFileDeps
A collection of absolute paths to module map files that this module needs to know about.
std::vector< std::string > BuildArguments
Compiler invocation that can be used to build this module.
std::vector< PrebuiltModuleDep > PrebuiltModuleDeps
A collection of prebuilt modular dependencies this module directly depends on, not including transiti...
std::vector< ModuleID > ClangModuleDeps
A list of module identifiers this module directly depends on, not including transitive dependencies.
ModuleID ID
The identifier of the module.
llvm::StringSet FileDeps
A collection of absolute paths to files that this module directly depends on, not including transitiv...
bool IsSystem
Whether this is a "system" module.
This is used to identify a specific module.
std::string ContextHash
The context hash of a module represents the compiler options that affect the resulting command-line i...
std::string ModuleName
The name of the module.
P1689ModuleInfo - Represents the needed information of standard C++20 modules for P1689 format.
std::string ModuleName
The name of the module. This may include : for partitions.
bool IsStdCXXModuleInterface
If this module is a standard c++ interface unit.
Modular dependency that has already been built prior to the dependency scan.