20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringMap.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/Support/Compiler.h"
26#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/Path.h"
28#include "llvm/Support/raw_ostream.h"
64 StringRef Platform =
Target.getPlatformName();
65 StringRef Env =
Target.getTriple().getEnvironmentName();
72 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
73 auto Pos = LHS.find(
'-');
74 if (Pos == StringRef::npos)
77 NewLHS += LHS.slice(Pos+1, LHS.size());
88 if (
Target.getTriple().isOSDarwin() && PlatformEnv.ends_with(
"simulator"))
89 return PlatformEnv ==
Feature || CmpPlatformEnv(PlatformEnv,
Feature);
99 .Case(
"altivec", LangOpts.AltiVec)
100 .Case(
"blocks", LangOpts.Blocks)
101 .Case(
"coroutines", LangOpts.Coroutines)
102 .Case(
"cplusplus", LangOpts.CPlusPlus)
103 .Case(
"cplusplus11", LangOpts.CPlusPlus11)
104 .Case(
"cplusplus14", LangOpts.CPlusPlus14)
105 .Case(
"cplusplus17", LangOpts.CPlusPlus17)
106 .Case(
"cplusplus20", LangOpts.CPlusPlus20)
107 .Case(
"cplusplus23", LangOpts.CPlusPlus23)
108 .Case(
"cplusplus26", LangOpts.CPlusPlus26)
109 .Case(
"cplusplus29", LangOpts.CPlusPlus29)
110 .Case(
"c99", LangOpts.C99)
111 .Case(
"c11", LangOpts.C11)
112 .Case(
"c17", LangOpts.C17)
113 .Case(
"c23", LangOpts.C23)
114 .Case(
"freestanding", LangOpts.Freestanding)
115 .Case(
"gnuinlineasm", LangOpts.GNUAsm)
116 .Case(
"objc", LangOpts.ObjC)
117 .Case(
"objc_arc", LangOpts.ObjCAutoRefCount)
118 .Case(
"opencl", LangOpts.OpenCL)
119 .Case(
"reflection", LangOpts.Reflection)
120 .Case(
"tls",
Target.isTLSSupported())
121 .Case(
"zvector", LangOpts.ZVector)
135 for (
const Module *Current =
this; Current; Current = Current->Parent) {
136 if (Current->ShadowingModule) {
140 for (
unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
142 Current->Requirements[I].RequiredState) {
143 Req = Current->Requirements[I];
149 llvm_unreachable(
"could not find a reason why module is unimportable");
167 !CurrentModule.ends_with(
"_Private") &&
168 TopLevelName.ends_with(
"_Private"))
169 TopLevelName = TopLevelName.drop_back(8);
171 return TopLevelName == CurrentModule;
186 for (
const Module *Current =
this; Current; Current = Current->Parent) {
187 if (!Current->MissingHeaders.empty()) {
188 MissingHeader = Current->MissingHeaders.front();
193 llvm_unreachable(
"could not find a reason why module is unavailable");
213 const std::pair<std::string, SourceLocation> &IdComponent) {
214 return IdComponent.first;
219template<
typename InputIter>
221 bool AllowStringLiterals =
true) {
222 for (InputIter It = Begin; It != End; ++It) {
231 OS.write_escaped(Name);
237template<
typename Container>
246 for (
const Module *M =
this; M; M = M->Parent)
247 Names.push_back(M->Name);
251 llvm::raw_string_ostream Out(
Result);
252 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
258 for (
const Module *M =
this; M; M = M->Parent) {
259 if (nameParts.empty() || M->Name != nameParts.back())
261 nameParts = nameParts.drop_back();
263 return nameParts.empty();
267 if (
const auto *Hdr = std::get_if<FileEntryRef>(&
Umbrella))
268 return Hdr->getDir();
269 if (
const auto *Dir = std::get_if<DirectoryEntryRef>(&
Umbrella))
276 return Path.starts_with(Ancestor) &&
277 (Path.size() == Ancestor.size() ||
278 llvm::sys::path::is_separator(Path[Ancestor.size()]));
287 for (StringRef Dep : Deps)
291 [&](
const std::string &Dep) {
return coversPath(Path, Dep); });
292 Deps.emplace_back(Path);
297 TopHeaders.insert(
File);
301 if (!TopHeaderNames.empty()) {
302 for (StringRef TopHeaderName : TopHeaderNames)
303 if (
auto FE =
FileMgr.getOptionalFileRef(TopHeaderName))
304 TopHeaders.insert(*FE);
305 TopHeaderNames.clear();
318 for (
auto *Use : Top->DirectUses)
328 if (!Requested->
Parent && Requested->
Name ==
"ptrauth")
350 auto needUpdate = [Unimportable](
Module *M) {
351 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
354 if (!needUpdate(
this))
358 Stack.push_back(
this);
359 while (!Stack.empty()) {
360 Module *Current = Stack.pop_back_val();
362 if (!needUpdate(Current))
368 if (needUpdate(Submodule))
369 Stack.push_back(Submodule);
375 if (
auto It = SubModuleIndex.find(
Name); It != SubModuleIndex.end())
376 return SubModules[It->second];
383 "fragment from the C++20 Named modules");
386 if (SubModule->isExplicitGlobalModule())
394 "fragment from the C++20 Named modules");
397 if (SubModule->isPrivateModule())
406 if (!Mod->IsExplicit)
407 Exported.push_back(Mod);
410 bool AnyWildcard =
false;
411 bool UnrestrictedWildcard =
false;
413 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
417 Exported.push_back(Mod);
425 if (UnrestrictedWildcard)
429 WildcardRestrictions.push_back(Restriction);
431 WildcardRestrictions.clear();
432 UnrestrictedWildcard =
true;
441 for (
unsigned I = 0, N =
Imports.size(); I != N; ++I) {
443 bool Acceptable = UnrestrictedWildcard;
446 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
447 Module *Restriction = WildcardRestrictions[R];
458 Exported.push_back(Mod);
462void Module::buildVisibleModulesCache()
const {
463 assert(VisibleModulesCache.empty() &&
"cache does not need building");
466 VisibleModulesCache.insert(
this);
470 while (!Stack.empty()) {
471 Module *CurrModule = Stack.pop_back_val();
474 if (VisibleModulesCache.insert(CurrModule).second)
501 for (
unsigned I = 0, N =
Requirements.size(); I != N; ++I) {
513 OS <<
"umbrella header \"";
514 OS.write_escaped(H->NameAsWritten);
519 OS.write_escaped(D->NameAsWritten);
525 OS <<
"config_macros ";
527 OS <<
"[exhaustive]";
528 for (
unsigned I = 0, N =
ConfigMacros.size(); I != N; ++I) {
545 for (
auto &K : Kinds) {
546 assert(&K == &Kinds[K.Kind] &&
"kinds in wrong order");
549 OS << K.Prefix <<
"header \"";
550 OS.write_escaped(H.NameAsWritten);
551 OS <<
"\" { size " << H.Entry.getSize()
552 <<
" mtime " << H.Entry.getModificationTime() <<
" }\n";
558 OS << Kinds[
U.Kind].Prefix <<
"header \"";
559 OS.write_escaped(
U.FileName);
561 if (
U.Size ||
U.ModTime) {
564 OS <<
" size " << *
U.Size;
566 OS <<
" mtime " << *
U.ModTime;
583 if (!Submodule->IsInferred || Submodule->IsFramework)
584 Submodule->print(OS,
Indent + 2, Dump);
586 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
590 OS << Restriction->getFullModuleName(
true);
611 llvm::errs() <<
"import " << M->getFullModuleName() <<
"\n";
615 for (
unsigned I = 0, N =
DirectUses.size(); I != N; ++I) {
629 for (
unsigned I = 0, N =
LinkLibraries.size(); I != N; ++I) {
648 for (
unsigned I = 0, N =
Conflicts.size(); I != N; ++I) {
651 OS <<
Conflicts[I].Other->getFullModuleName(
true);
661 OS <<
"module * {\n";
675 print(llvm::errs(), 0,
true);
683 "setVisible expects a valid import location");
691 Visiting *ExportedBy;
696 unsigned ID =
V.M->getVisibilityID();
697 if (ImportLocs.size() <= ID)
698 ImportLocs.resize(ID + 1);
699 else if (ImportLocs[ID].isValid())
702 ImportLocs[ID] = Loc;
706 if (IncludeExports) {
708 V.M->getExportedModules(Exports);
709 for (
Module *E : Exports) {
711 if (!E->isUnimportable())
712 VisitModule({E, &
V});
716 for (
auto &
C :
V.M->Conflicts) {
719 for (Visiting *I = &
V; I; I = I->ExportedBy)
720 Path.push_back(I->M);
721 Cb(Path,
C.Other,
C.Message);
725 VisitModule({M,
nullptr});
Defines the clang::FileManager interface and associated types.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature)
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)
Determine whether a translation unit built using the current language options has the given feature.
static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, bool AllowStringLiterals=true)
static StringRef getModuleNameFromComponent(const std::pair< std::string, SourceLocation > &IdComponent)
static bool coversPath(StringRef Ancestor, StringRef Path)
Whether watching Ancestor recursively also covers Path.
Defines the clang::Module class, which describes a module in the source code.
static bool HasFeature(const Preprocessor &PP, StringRef Feature)
HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...
Defines the clang::SourceLocation class and associated facilities.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Implements support for file system lookup, file system caching, and directory search management.
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.
bool isCompilingModule() const
Are we compiling a module?
std::string CurrentModule
The name of the current module, of which the main source file is a part.
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
Required to construct a Module.
Reference to a module that consists of either an existing/materialized Module object,...
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
unsigned IsExplicit
Whether this is an explicit submodule.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
std::vector< std::string > DirectoryDependencies
Directories this module depends on the listing of.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
NameVisibilityKind NameVisibility
The visibility of names within this particular module.
@ Hidden
All of the names in this module are hidden.
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
bool isNamedModuleUnit() const
Is this a C++20 named module unit.
SourceLocation DefinitionLoc
The location of the module definition.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Module(ModuleConstructorTag, StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)
Construct a new module or submodule.
Module * Parent
The parent of this module.
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
ModuleKind Kind
The kind of this module.
bool isUnimportable() const
Determine whether this module has been declared unimportable.
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
Module * getPrivateModuleFragment() const
Get the Private Module Fragment (sub-module) for this module, it there is one.
void addDirectoryDependency(StringRef Path)
Record that this module depends on the listing of Path, which must name a location in an underlying f...
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
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.
Module * getGlobalModuleFragment() const
Get the Global Module Fragment (sub-module) for this module, it there is one.
llvm::iterator_range< submodule_iterator > submodules()
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
std::optional< Header > getUmbrellaHeaderAsWritten() const
Retrieve the umbrella header as written.
SmallVector< Requirement, 2 > Requirements
The set of language features required to use this module.
llvm::SmallSetVector< const Module *, 2 > UndeclaredUses
When NoUndeclaredIncludes is true, the set of modules this module tried to import but didn't because ...
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
unsigned NamedModuleHasInit
Whether this C++20 named modules doesn't need an initializer.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
ModuleRef findSubmodule(StringRef Name) const
Find the submodule with the given name.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
ArrayRef< Header > getHeaders(HeaderKind HK) const
bool isGlobalModule() const
Does this Module scope describe a fragment of the global module within some C++ module.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
void getExportedModules(SmallVectorImpl< Module * > &Exported) const
Appends this module's list of exported modules to Exported.
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
ArrayRef< FileEntryRef > getTopHeaders(FileManager &FileMgr)
The top-level headers associated with this module.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
std::optional< DirectoryName > getUmbrellaDirAsWritten() const
Retrieve the umbrella directory as written.
unsigned HasIncompatibleModuleFile
Whether we tried and failed to load a module file for this module.
void dump() const
Dump the contents of this module to the given output stream.
Module * ShadowingModule
A module with the same name that shadows this module.
unsigned IsFramework
Whether this is a framework module.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
void addTopHeader(FileEntryRef File)
Add a top-level header associated with this module.
unsigned IsAvailable
Whether this module is available in the current translation unit.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
llvm::SmallVector< ModuleRef, 2 > Imports
The set of modules imported by this module, and on which this module depends.
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
std::vector< Conflict > Conflicts
The list of conflicts.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Exposes information about the current target.
void setVisible(Module *M, SourceLocation Loc, bool IncludeExports=true, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef) {})
Make a specific module visible.
llvm::function_ref< void(Module *M)> VisibleCallback
A callback to call when a module is made visible (directly or indirectly) by a call to setVisible.
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found.
bool isVisible(const Module *M) const
Determine whether a module is visible.
Defines the clang::TargetInfo interface.
Top level wrappers for InstallAPI frontend operations.
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
@ Result
The result type of a method or function.
CustomizableOptional< DirectoryEntryRef > OptionalDirectoryEntryRef
@ Other
Other implicit parameter.
int const char * function