15#include "llvm/ADT/STLExtras.h"
16#include "llvm/Support/BLAKE3.h"
25 for (StringRef FileDep : FileDeps) {
26 auto ResolvedFileDep =
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);
45 for (
const auto Dep : ModuleFileDependents) {
48 PrebuiltModulesMap[Dep].updateDependentsNotInStableDirs(PrebuiltModulesMap);
59 std::vector<HeaderSearchOptions::Entry> Entries;
62 llvm::BitVector SearchPathUsage(Entries.size());
63 llvm::DenseSet<const serialization::ModuleFile *> Visited;
69 if (!Visited.contains(Import))
74 if (SearchPathUsage.size() != Entries.size())
75 llvm::report_fatal_error(
76 "Inconsistent search path options between modules detected");
78 for (
auto Idx : SearchPathUsage.set_bits())
79 Opts.
UserEntries.push_back(std::move(Entries[Idx]));
82 std::vector<std::string> VFSOverlayFiles;
85 llvm::BitVector VFSUsage(VFSOverlayFiles.size());
86 llvm::DenseSet<const serialization::ModuleFile *> Visited;
95 if (!Visited.contains(Import))
100 auto PrebuiltModulePropIt =
101 PrebuiltModulesASTMap.find(MF->
FileName);
102 if (PrebuiltModulePropIt == PrebuiltModulesASTMap.end())
104 for (std::size_t I = 0, E = VFSOverlayFiles.size(); I != E; ++I) {
105 if (PrebuiltModulePropIt->second.getVFS().contains(
113 if (VFSUsage.size() != VFSOverlayFiles.size())
114 llvm::report_fatal_error(
115 "Inconsistent -ivfsoverlay options between modules detected");
117 for (
auto Idx : VFSUsage.set_bits())
123 bool IsSystemModule) {
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;
150static std::vector<std::string>
splitString(std::string S,
char Separator) {
152 StringRef(S).split(Segments, Separator, -1,
false);
153 std::vector<std::string> Result;
154 Result.reserve(Segments.size());
155 for (StringRef Segment : Segments)
156 Result.push_back(Segment.str());
160void ModuleDepCollector::addOutputPaths(CowCompilerInvocation &CI,
166 Controller.lookupModuleOutput(
206 const StringRef Input) {
207 using namespace llvm::sys;
209 if (!path::is_absolute(Input))
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)
219 return PrefixIt == PrefixEnd;
222 return any_of(Directories, [&](StringRef Dir) {
223 return !Dir.empty() && PathStartsWith(Dir, Input);
230 "Sysroots differ between module dependencies and current TU");
233 "ResourceDirs differ between module dependencies and current TU");
236 if (!Entry.IgnoreSysRoot)
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));
304ModuleDepCollector::getInvocationAdjustedForModuleBuildWithoutOutputs(
306 llvm::function_ref<
void(CowCompilerInvocation &)> Optimize)
const {
307 CowCompilerInvocation CI = CommonInvocation;
318 auto CurrentModuleMapEntry =
320 assert(CurrentModuleMapEntry &&
"module map file entry not found");
329 auto ModuleMapEntry =
330 ScanInstance.getFileManager().getOptionalFileRef(ModuleMapFile);
331 assert(ModuleMapEntry &&
"module map file entry not found");
338 if (Service.getOpts().EagerLoadModules &&
339 DepModuleMapFiles.contains(*ModuleMapEntry))
344 if (*ModuleMapEntry == *CurrentModuleMapEntry &&
345 !DepModuleMapFiles.contains(*ModuleMapEntry))
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");
379 auto FE = ScanInstance.getFileManager().getOptionalFileRef(
381 assert(FE &&
"Missing module map file that was previously found");
382 ModuleMapFiles.insert(*FE);
384 return ModuleMapFiles;
387void ModuleDepCollector::addModuleMapFiles(
388 CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps)
const {
389 if (Service.getOpts().EagerLoadModules)
392 for (
const ModuleID &MID : ClangModuleDeps) {
393 ModuleDeps *MD = ModuleDepsByID.lookup(MID);
394 assert(MD &&
"Inconsistent dependency info");
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 =
406 if (Service.getOpts().EagerLoadModules)
410 {MID.ModuleName, std::move(PCMPath)});
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 =
421 if (Service.getOpts().EagerLoadModules)
425 {MID.ModuleName, std::move(PCMPath)});
454 CurrentModuleMap->getNameAsRequested());
457 for (
const auto &KV : ModularDeps)
458 if (DirectModularDeps.contains(KV.first))
459 DirectDeps.push_back(KV.second->ID);
462 addModuleMapFiles(CI, DirectDeps);
464 addModuleFiles(CI, DirectDeps);
466 for (
const auto &KV : DirectPrebuiltModularDeps)
475 bool AnyRelative =
false;
477 assert(!AnyRelative &&
"Continuing path visitation despite returning true");
478 AnyRelative |= !Path.empty() && !llvm::sys::path::is_absolute(Path);
486 bool EagerLoadModules,
487 llvm::vfs::FileSystem &
VFS) {
488 llvm::HashBuilder<llvm::TruncatedBLAKE3<16>, llvm::endianness::native>
495 llvm::ErrorOr<std::string> CWD =
VFS.getCurrentWorkingDirectory();
497 HashBuilder.add(*CWD);
501 ArgVec.reserve(4096);
503 Arg.toVector(ArgVec);
504 ArgVec.push_back(
'\0');
506 HashBuilder.add(ArgVec);
514 HashBuilder.add(ID.ModuleName);
515 HashBuilder.add(ID.ContextHash);
518 HashBuilder.add(EagerLoadModules);
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,
false);
527void ModuleDepCollector::associateWithContextHash(
528 const CowCompilerInvocation &CI,
ModuleDeps &Deps) {
531 ScanInstance.getVirtualFileSystem());
532 bool Inserted = ModuleDepsByID.insert({Deps.
ID, &Deps}).second;
534 assert(Inserted &&
"duplicate module mapping");
550 if (std::optional<StringRef> Filename =
SM.getNonBuiltinFilenameForID(FID))
551 MDC.addFileDep(llvm::sys::path::remove_leading_dotslash(*Filename));
557 StringRef SearchPath, StringRef RelativePath,
const Module *SuggestedModule,
559 if (!
File && !ModuleImported) {
564 handleImport(SuggestedModule);
570 auto &PP = MDC.ScanInstance.getPreprocessor();
571 if (PP.getLangOpts().CPlusPlusModules && PP.isImportingCXXNamedModules()) {
573 RequiredModule.
ModuleName = Path[0].getIdentifierInfo()->getName().str();
575 MDC.RequiredStdCXXModules.push_back(std::move(RequiredModule));
579 handleImport(Imported);
582void ModuleDepCollectorPP::handleImport(
const Module *Imported) {
588 if (MDC.isPrebuiltModule(TopLevelModule))
589 MDC.DirectPrebuiltModularDeps.insert(
592 MDC.DirectModularDeps.insert(TopLevelModule);
593 MDC.DirectImports.insert(Imported);
598 FileID MainFileID = MDC.ScanInstance.getSourceManager().getMainFileID();
599 MDC.MainFile = std::string(MDC.ScanInstance.getSourceManager()
600 .getFileEntryRefForID(MainFileID)
603 auto &PP = MDC.ScanInstance.getPreprocessor();
604 if (PP.isInNamedModule()) {
606 ProvidedModule.
ModuleName = PP.getNamedModuleName();
612 if (PP.isInImplementationUnit())
613 MDC.RequiredStdCXXModules.push_back(ProvidedModule);
615 MDC.ProvidedStdCXXModule = ProvidedModule;
618 if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
619 MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude);
621 for (StringRef
VFS : MDC.ScanInstance.getHeaderSearchOpts().VFSOverlayFiles)
624 if (
Module *CurrentModule = PP.getCurrentModuleImplementation()) {
626 PP.getHeaderSearchInfo().getModuleMap().getModuleMapFileForUniquing(
628 MDC.addFileDep(CurrentModuleMap->getName());
632 MDC.ScanInstance.getPreprocessor().getAffectingClangModules())
633 if (!MDC.isPrebuiltModule(M))
634 MDC.DirectModularDeps.insert(M);
636 MDC.addVisibleModules();
638 for (
const Module *M : MDC.DirectModularDeps)
639 handleTopLevelModule(M);
641 MDC.Consumer.handleContextHash(
642 MDC.ScanInstance.getInvocation().computeContextHash());
644 MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
646 MDC.Consumer.handleProvidedAndRequiredStdCXXModules(
647 MDC.ProvidedStdCXXModule, MDC.RequiredStdCXXModules);
649 for (
auto &&I : MDC.ModularDeps)
650 MDC.Consumer.handleModuleDependency(*I.second);
652 for (
const Module *M : MDC.DirectModularDeps) {
653 auto It = MDC.ModularDeps.find(M);
655 if (It != MDC.ModularDeps.end())
656 MDC.Consumer.handleDirectModuleDependency(It->second->ID);
659 for (
auto &&I : MDC.VisibleModules)
660 MDC.Consumer.handleVisibleModule(std::string(I.getKey()));
662 for (
auto &&I : MDC.FileDeps)
663 MDC.Consumer.handleFileDependency(I);
665 for (
auto &&I : MDC.DirectPrebuiltModularDeps)
666 MDC.Consumer.handlePrebuiltModuleDependency(I.second);
674 Storage.assign(Path.begin(), Path.end());
676 return StringRef(Storage.data(), Storage.size());
679std::optional<ModuleID>
680ModuleDepCollectorPP::handleTopLevelModule(
const Module *M) {
691 if (
auto ModI = MDC.ModularDeps.find(M); ModI != MDC.ModularDeps.end())
692 return ModI->second->ID;
694 auto OwnedMD = std::make_unique<ModuleDeps>();
695 ModuleDeps &MD = *OwnedMD;
710 ModuleMap &ModMapInfo =
711 MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
714 SmallString<128> Path = ModuleMap->getNameAsRequested();
719 serialization::ModuleFile *MF =
720 MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
723 llvm::SmallString<256>
Storage;
726 MDC.ScanInstance.getASTReader()->visitInputFileInfos(
728 [&](
const serialization::InputFileInfo &IFI,
bool IsSystem) {
739 llvm::DenseSet<const Module *> SeenDeps;
740 addAllSubmodulePrebuiltDeps(M, MD, SeenDeps);
741 addAllSubmoduleDeps(M, MD, SeenDeps);
742 addAllAffectingClangModules(M, MD, SeenDeps);
744 SmallString<0> PathBuf;
745 PathBuf.reserve(256);
746 MDC.ScanInstance.getASTReader()->visitInputFileInfos(
748 [&](
const serialization::InputFileInfo &IFI,
bool IsSystem) {
758 "__inferred_module.map"))
767 CowCompilerInvocation CI =
768 MDC.getInvocationAdjustedForModuleBuildWithoutOutputs(
769 MD, [&](CowCompilerInvocation &BuildInvocation) {
770 if (
any(MDC.Service.getOpts().OptimizeArgs &
774 *MDC.ScanInstance.getASTReader(), *MF,
775 MDC.PrebuiltModulesASTMap,
776 MDC.Service.getOpts().OptimizeArgs);
778 if (
any(MDC.Service.getOpts().OptimizeArgs &
788 llvm::ErrorOr<std::string> CWD =
789 MDC.ScanInstance.getVirtualFileSystem()
790 .getCurrentWorkingDirectory();
797 (void)MDC.Controller.finalizeModuleInvocation(MDC.ScanInstance, CI, MD);
806 MDC.associateWithContextHash(CI, MD);
809 MDC.addOutputPaths(CI, MD);
811 MD.BuildInfo = std::move(CI);
813 MDC.ModularDeps.insert({M, std::move(OwnedMD)});
819 llvm::function_ref<
void(
const Module *)> F) {
824 llvm::stable_sort(Submodules, [](
const Module *A,
const Module *B) {
827 for (
const Module *SubM : Submodules)
831void ModuleDepCollectorPP::addAllSubmodulePrebuiltDeps(
833 llvm::DenseSet<const Module *> &SeenSubmodules) {
834 addModulePrebuiltDeps(M, MD, SeenSubmodules);
837 addAllSubmodulePrebuiltDeps(SubM, MD, SeenSubmodules);
841void ModuleDepCollectorPP::addModulePrebuiltDeps(
843 llvm::DenseSet<const Module *> &SeenSubmodules) {
846 if (MDC.isPrebuiltModule(
Import->getTopLevelModule()))
847 if (SeenSubmodules.insert(
Import->getTopLevelModule()).second) {
850 auto PrebuiltModulePropIt = MDC.PrebuiltModulesASTMap.find(
853 (PrebuiltModulePropIt != MDC.PrebuiltModulesASTMap.end()) &&
854 PrebuiltModulePropIt->second.isInStableDir();
859void ModuleDepCollectorPP::addAllSubmoduleDeps(
861 llvm::DenseSet<const Module *> &AddedModules) {
862 addModuleDep(M, MD, AddedModules);
865 addAllSubmoduleDeps(SubM, MD, AddedModules);
869void ModuleDepCollectorPP::addOneModuleDep(
const Module *M,
const ModuleID ID,
876void ModuleDepCollectorPP::addModuleDep(
878 llvm::DenseSet<const Module *> &AddedModules) {
881 !MDC.isPrebuiltModule(Import)) {
882 if (
auto ImportID = handleTopLevelModule(
Import->getTopLevelModule()))
883 if (AddedModules.insert(
Import->getTopLevelModule()).second)
884 addOneModuleDep(
Import->getTopLevelModule(), *ImportID, MD);
889void ModuleDepCollectorPP::addAllAffectingClangModules(
891 llvm::DenseSet<const Module *> &AddedModules) {
892 addAffectingClangModule(M, MD, AddedModules);
895 addAllAffectingClangModules(SubM, MD, AddedModules);
898void ModuleDepCollectorPP::addAffectingClangModule(
900 llvm::DenseSet<const Module *> &AddedModules) {
903 "Not quite import not top-level module");
905 !MDC.isPrebuiltModule(Affecting)) {
906 if (
auto ImportID = handleTopLevelModule(Affecting))
907 if (AddedModules.insert(Affecting).second)
908 addOneModuleDep(Affecting, *ImportID, MD);
915 std::unique_ptr<DependencyOutputOptions> Opts,
920 : Service(Service), ScanInstance(ScanInstance), Consumer(
C),
921 Controller(Controller),
922 PrebuiltModulesASTMap(
std::move(PrebuiltModulesASTMap)),
923 StableDirs(StableDirs), Opts(
std::move(Opts)),
928 auto CollectorPP = std::make_unique<ModuleDepCollectorPP>(*
this);
929 CollectorPPPtr = CollectorPP.get();
935bool ModuleDepCollector::isPrebuiltModule(
const Module *M) {
937 const auto &PrebuiltModuleFiles =
939 auto PrebuiltModuleFileIt = PrebuiltModuleFiles.find(Name);
940 if (PrebuiltModuleFileIt == PrebuiltModuleFiles.end())
942 assert(
"Prebuilt module came from the expected AST file" &&
947void ModuleDepCollector::addVisibleModules() {
948 llvm::DenseSet<const Module *> ImportedModules;
949 auto InsertVisibleModules = [&](
const Module *M) {
950 if (ImportedModules.contains(M))
956 while (!Stack.empty()) {
957 const Module *CurrModule = Stack.pop_back_val();
958 if (ImportedModules.contains(CurrModule))
960 ImportedModules.insert(CurrModule);
966 for (
const Module *Import : DirectImports)
967 InsertVisibleModules(Import);
970void ModuleDepCollector::addFileDep(StringRef Path) {
971 if (!Service.getOpts().ReportAbsolutePaths) {
972 FileDeps.emplace_back(Path);
976 llvm::SmallString<256>
Storage;
978 FileDeps.emplace_back(Path);
981void ModuleDepCollector::addFileDep(
ModuleDeps &MD, StringRef Path) {
982 MD.FileDeps.emplace_back(Path);
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 void forEachSubmoduleSorted(const Module *M, llvm::function_ref< void(const Module *)> F)
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)
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.
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.
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.
FrontendOptions & getMutFrontendOpts()
LangOptions & getMutLangOpts()
Mutable getters.
HeaderSearchOptions & getMutHeaderSearchOpts()
CodeGenOptions & getMutCodeGenOpts()
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.
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.
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.
StringRef str() const
Returns the plain module file name.
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.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
const ModuleFileKey * getASTFileKey() const
The serialized AST file key for this module, if one was created.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
const ModuleFileName * getASTFileName() const
The serialized AST file name for this module, if one was created.
llvm::iterator_range< submodule_iterator > submodules()
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
llvm::SmallSetVector< Module *, 2 > AffectingClangModules
The set of top-level modules that affected the compilation of this module, but were not imported.
void getExportedModules(SmallVectorImpl< Module * > &Exported) const
Appends this module's list of exported modules to Exported.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
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.
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 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.
llvm::SetVector< ModuleFile * > Imports
List of modules which this module directly imported.
llvm::BitVector SearchPathUsage
The bit vector denoting usage of each header search entry (true = used).
ModuleFileName FileName
The file name of the module file.
llvm::BitVector VFSUsage
The bit vector denoting usage of each VFS entry (true = used).
ModuleKind Kind
The type of this module.
std::string BaseDirectory
The base directory of the module.
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.
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
@ MK_ImplicitModule
File is an implicitly-loaded module.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
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...
@ 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...
int const char * function
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.
This is used to identify a specific 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.