Go to the documentation of this file.
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/raw_ostream.h"
35 using namespace clang;
38 bool IsFramework,
bool IsExplicit,
unsigned VisibilityID)
39 : Name(Name), DefinitionLoc(DefinitionLoc),
Parent(
Parent),
40 VisibilityID(VisibilityID), IsUnimportable(
false),
41 HasIncompatibleModuleFile(
false), IsAvailable(
true),
42 IsFromModuleFile(
false), IsFramework(IsFramework), IsExplicit(IsExplicit),
44 InferSubmodules(
false), InferExplicitSubmodules(
false),
45 InferExportWildcard(
false), ConfigMacrosExhaustive(
false),
46 NoUndeclaredIncludes(
false), ModuleMapIsPrivate(
false),
47 NameVisibility(Hidden) {
57 Parent->SubModules.push_back(
this);
69 StringRef Platform =
Target.getPlatformName();
70 StringRef Env =
Target.getTriple().getEnvironmentName();
73 if (Platform == Feature ||
Target.getTriple().getOSName() == Feature ||
77 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
78 auto Pos = LHS.find(
'-');
79 if (Pos == StringRef::npos)
82 NewLHS += LHS.slice(Pos+1, LHS.size());
93 if (
Target.getTriple().isOSDarwin() && PlatformEnv.endswith(
"simulator"))
94 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
96 return PlatformEnv == Feature;
103 bool HasFeature = llvm::StringSwitch<bool>(Feature)
104 .Case(
"altivec", LangOpts.AltiVec)
105 .Case(
"blocks", LangOpts.Blocks)
106 .Case(
"coroutines", LangOpts.Coroutines)
107 .Case(
"cplusplus", LangOpts.CPlusPlus)
108 .Case(
"cplusplus11", LangOpts.CPlusPlus11)
109 .Case(
"cplusplus14", LangOpts.CPlusPlus14)
110 .Case(
"cplusplus17", LangOpts.CPlusPlus17)
111 .Case(
"c99", LangOpts.C99)
112 .Case(
"c11", LangOpts.C11)
113 .Case(
"c17", LangOpts.C17)
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(
"tls",
Target.isTLSSupported())
120 .Case(
"zvector", LangOpts.ZVector)
121 .Default(
Target.hasFeature(Feature) ||
130 Module *&ShadowingModule)
const {
134 for (
const Module *Current =
this; Current; Current = Current->Parent) {
135 if (Current->ShadowingModule) {
139 for (
unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
141 Current->Requirements[I].second) {
142 Req = Current->Requirements[I];
148 llvm_unreachable(
"could not find a reason why module is unimportable");
154 Module *&ShadowingModule)
const {
163 for (
const Module *Current =
this; Current; Current = Current->Parent) {
164 if (!Current->MissingHeaders.empty()) {
165 MissingHeader = Current->MissingHeaders.front();
170 llvm_unreachable(
"could not find a reason why module is unavailable");
182 const Module *Result =
this;
183 while (Result->Parent)
184 Result = Result->Parent;
190 const std::pair<std::string, SourceLocation> &IdComponent) {
191 return IdComponent.first;
196 template<
typename InputIter>
198 bool AllowStringLiterals =
true) {
199 for (InputIter It =
Begin; It !=
End; ++It) {
208 OS.write_escaped(Name);
214 template<
typename Container>
224 Names.push_back(M->Name);
228 llvm::raw_string_ostream Out(Result);
229 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
237 if (nameParts.empty() || M->Name != nameParts.back())
239 nameParts = nameParts.drop_back();
241 return nameParts.empty();
246 return {
"",
"",
U.Entry->getDir()};
254 TopHeaders.insert(
File);
258 if (!TopHeaderNames.empty()) {
259 for (std::vector<std::string>::iterator
260 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
261 if (
auto FE = FileMgr.
getFile(*I))
262 TopHeaders.insert(*FE);
264 TopHeaderNames.clear();
267 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
277 for (
auto *Use : Top->DirectUses)
282 if (!Requested->
Parent && Requested->
Name ==
"_Builtin_stddef_max_align_t")
304 auto needUpdate = [Unimportable](
Module *M) {
305 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
308 if (!needUpdate(
this))
312 Stack.push_back(
this);
313 while (!Stack.empty()) {
314 Module *Current = Stack.back();
317 if (!needUpdate(Current))
320 Current->IsAvailable =
false;
321 Current->IsUnimportable |= Unimportable;
323 SubEnd = Current->submodule_end();
325 if (needUpdate(*
Sub))
326 Stack.push_back(*
Sub);
332 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(
Name);
333 if (Pos == SubModuleIndex.end())
336 return SubModules[Pos->getValue()];
340 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(
Name);
341 if (Pos != SubModuleIndex.end())
342 return SubModules[Pos->getValue()];
349 if (Result->InferExportWildcard)
356 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
357 E = SubModules.end();
361 Exported.push_back(Mod);
365 bool AnyWildcard =
false;
366 bool UnrestrictedWildcard =
false;
368 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
372 Exported.push_back(Mod);
380 if (UnrestrictedWildcard)
384 WildcardRestrictions.push_back(Restriction);
386 WildcardRestrictions.clear();
387 UnrestrictedWildcard =
true;
396 for (
unsigned I = 0, N =
Imports.size(); I != N; ++I) {
398 bool Acceptable = UnrestrictedWildcard;
401 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
402 Module *Restriction = WildcardRestrictions[R];
413 Exported.push_back(Mod);
417 void Module::buildVisibleModulesCache()
const {
418 assert(VisibleModulesCache.empty() &&
"cache does not need building");
421 VisibleModulesCache.insert(
this);
425 while (!Stack.empty()) {
426 Module *CurrModule = Stack.pop_back_val();
429 if (VisibleModulesCache.insert(CurrModule).second)
456 for (
unsigned I = 0, N =
Requirements.size(); I != N; ++I) {
468 OS <<
"umbrella header \"";
469 OS.write_escaped(H.NameAsWritten);
474 OS.write_escaped(D.NameAsWritten);
480 OS <<
"config_macros ";
482 OS <<
"[exhaustive]";
483 for (
unsigned I = 0, N =
ConfigMacros.size(); I != N; ++I) {
500 for (
auto &K : Kinds) {
501 assert(&K == &Kinds[K.Kind] &&
"kinds in wrong order");
502 for (
auto &H :
Headers[K.Kind]) {
504 OS << K.Prefix <<
"header \"";
505 OS.write_escaped(H.NameAsWritten);
506 OS <<
"\" { size " << H.Entry->getSize()
507 <<
" mtime " << H.Entry->getModificationTime() <<
" }\n";
513 OS << Kinds[
U.Kind].Prefix <<
"header \"";
514 OS.write_escaped(
U.FileName);
516 if (
U.Size ||
U.ModTime) {
519 OS <<
" size " << *
U.Size;
521 OS <<
" mtime " << *
U.ModTime;
539 if (!(*MI)->IsInferred || (*MI)->IsFramework)
540 (*MI)->print(OS,
Indent + 2, Dump);
542 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
546 OS << Restriction->getFullModuleName(
true);
567 llvm::errs() <<
"import " << M->getFullModuleName() <<
"\n";
571 for (
unsigned I = 0, N =
DirectUses.size(); I != N; ++I) {
585 for (
unsigned I = 0, N =
LinkLibraries.size(); I != N; ++I) {
604 for (
unsigned I = 0, N =
Conflicts.size(); I != N; ++I) {
607 OS <<
Conflicts[I].Other->getFullModuleName(
true);
617 OS <<
"module * {\n";
631 print(llvm::errs(), 0,
true);
636 assert(Loc.
isValid() &&
"setVisible expects a valid import location");
644 Visiting *ExportedBy;
647 std::function<void(Visiting)> VisitModule = [&](Visiting
V) {
649 unsigned ID =
V.M->getVisibilityID();
650 if (ImportLocs.size() <=
ID)
651 ImportLocs.resize(
ID + 1);
652 else if (ImportLocs[
ID].isValid())
655 ImportLocs[
ID] = Loc;
660 V.M->getExportedModules(Exports);
661 for (
Module *E : Exports) {
663 if (!E->isUnimportable())
664 VisitModule({E, &
V});
667 for (
auto &C :
V.M->Conflicts) {
670 for (Visiting *I = &
V; I; I = I->ExportedBy)
671 Path.push_back(I->M);
672 Cb(Path, C.Other, C.Message);
676 VisitModule({M,
nullptr});
680 : Signature(M.Signature), ClangModule(&M) {
684 ASTFile =
File->getName();
689 return ClangModule->
Name;
SmallVector< Module *, 2 > DirectUses
The directly used modules.
static StringRef getModuleNameFromComponent(const std::pair< std::string, SourceLocation > &IdComponent)
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
SmallVector< Requirement, 2 > Requirements
The set of language features required to use this module.
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Encodes a location in the source.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
StringRef getName() const
static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, bool AllowStringLiterals=true)
submodule_iterator submodule_begin()
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)
Construct a new module or submodule.
Exposes information about the current target.
std::string Name
The name of this module.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map.
bool isVisible(const Module *M) const
Determine whether a module is visible.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
ArrayRef< const FileEntry * > getTopHeaders(FileManager &FileMgr)
The top-level headers associated with this module.
std::vector< Module * >::const_iterator submodule_const_iterator
bool isUnimportable() const
Determine whether this module has been declared unimportable.
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
Describes a module or submodule.
Module * findOrInferSubmodule(StringRef Name)
Cached information about one directory (either on disk or in the virtual file system).
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
unsigned IsFramework
Whether this is a framework module.
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
std::vector< Conflict > Conflicts
The list of conflicts.
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
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...
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
unsigned IsExplicit
Whether this is an explicit submodule.
OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const
The serialized AST file for this module, if one was created.
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef) {})
Make a specific module visible.
Cached information about one file (either on disk or in the virtual file system).
std::string getModuleName() const
Module * Parent
The parent of this module.
std::vector< Module * >::iterator submodule_iterator
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
const DirectoryEntry * Directory
The build directory of this module.
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature)
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
llvm::PointerUnion< const FileEntry *, const DirectoryEntry * > Umbrella
The umbrella header or directory.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
unsigned IsAvailable
Whether this module is available in the current translation unit.
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ModuleKind Kind
The kind of this module.
Information about a directory name as found in the module map file.
llvm::SmallSetVector< const Module *, 2 > UndeclaredUses
When NoUndeclaredIncludes is true, the set of modules this module tried to import but didn't because ...
Implements support for file system lookup, file system caching, and directory search management.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
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.
ASTSourceDescriptor()=default
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
Header getUmbrellaHeader() const
Retrieve the header that serves as the umbrella header for this module.
bool isValid() const
Return true if this is a valid SourceLocation object.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
void dump() const
Dump the contents of this module to the given output stream.
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
submodule_iterator submodule_end()
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
void getExportedModules(SmallVectorImpl< Module * > &Exported) const
Appends this module's list of exported modules to Exported.
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.
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
Module * ShadowingModule
A module with the same name that shadows this module.
std::string UmbrellaRelativeToRootModuleDirectory
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
bool Sub(InterpState &S, CodePtr OpPC)
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.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...