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), IsMissingRequirement(
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) {
61 Parent->SubModuleIndex[
Name] = Parent->SubModules.size();
62 Parent->SubModules.push_back(
this);
75 StringRef Env = Target.
getTriple().getEnvironmentName();
78 if (Platform == Feature || Target.
getTriple().getOSName() == Feature ||
82 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
83 auto Pos = LHS.find(
"-");
84 if (Pos == StringRef::npos)
87 NewLHS += LHS.slice(Pos+1, LHS.size());
98 if (Target.
getTriple().isOSDarwin() && PlatformEnv.endswith(
"simulator"))
99 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
101 return PlatformEnv == Feature;
108 bool HasFeature = llvm::StringSwitch<bool>(Feature)
109 .Case(
"altivec", LangOpts.AltiVec)
110 .Case(
"blocks", LangOpts.Blocks)
111 .Case(
"coroutines", LangOpts.Coroutines)
112 .Case(
"cplusplus", LangOpts.CPlusPlus)
113 .Case(
"cplusplus11", LangOpts.CPlusPlus11)
114 .Case(
"cplusplus14", LangOpts.CPlusPlus14)
115 .Case(
"cplusplus17", LangOpts.CPlusPlus17)
116 .Case(
"c99", LangOpts.C99)
117 .Case(
"c11", LangOpts.C11)
118 .Case(
"c17", LangOpts.C17)
119 .Case(
"freestanding", LangOpts.Freestanding)
120 .Case(
"gnuinlineasm", LangOpts.GNUAsm)
121 .Case(
"objc", LangOpts.ObjC)
122 .Case(
"objc_arc", LangOpts.ObjCAutoRefCount)
123 .Case(
"opencl", LangOpts.OpenCL)
125 .Case(
"zvector", LangOpts.ZVector)
142 for (
const Module *Current =
this; Current; Current = Current->Parent) {
143 if (Current->ShadowingModule) {
144 ShadowingModule = Current->ShadowingModule;
147 for (
unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
148 if (
hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
149 Current->Requirements[I].second) {
150 Req = Current->Requirements[I];
154 if (!Current->MissingHeaders.empty()) {
155 MissingHeader = Current->MissingHeaders.front();
160 llvm_unreachable(
"could not find a reason why module is unavailable");
184 const std::pair<std::string, SourceLocation> &IdComponent) {
185 return IdComponent.first;
190 template<
typename InputIter>
192 bool AllowStringLiterals =
true) {
193 for (InputIter It = Begin; It !=
End; ++It) {
202 OS.write_escaped(Name);
208 template<
typename Container>
218 Names.push_back(M->Name);
222 llvm::raw_string_ostream Out(Result);
223 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
231 if (nameParts.empty() || M->Name != nameParts.back())
233 nameParts = nameParts.drop_back();
235 return nameParts.empty();
240 return {
"", U.
Entry->getDir()};
246 if (!TopHeaderNames.empty()) {
247 for (std::vector<std::string>::iterator
248 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
249 if (
auto FE = FileMgr.
getFile(*I))
250 TopHeaders.insert(*FE);
252 TopHeaderNames.clear();
255 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
265 for (
auto *Use : Top->DirectUses)
270 if (!Requested->
Parent && Requested->
Name ==
"_Builtin_stddef_max_align_t")
282 if (
hasFeature(Feature, LangOpts, Target) == RequiredState)
289 auto needUpdate = [MissingRequirement](
Module *M) {
290 return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
293 if (!needUpdate(
this))
297 Stack.push_back(
this);
298 while (!Stack.empty()) {
299 Module *Current = Stack.back();
302 if (!needUpdate(Current))
310 if (needUpdate(*
Sub))
311 Stack.push_back(*
Sub);
317 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
318 if (Pos == SubModuleIndex.end())
321 return SubModules[Pos->getValue()];
325 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
326 if (Pos != SubModuleIndex.end())
327 return SubModules[Pos->getValue()];
341 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
342 E = SubModules.end();
346 Exported.push_back(Mod);
350 bool AnyWildcard =
false;
351 bool UnrestrictedWildcard =
false;
353 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
357 Exported.push_back(Mod);
365 if (UnrestrictedWildcard)
369 WildcardRestrictions.push_back(Restriction);
371 WildcardRestrictions.clear();
372 UnrestrictedWildcard =
true;
381 for (
unsigned I = 0, N =
Imports.size(); I != N; ++I) {
383 bool Acceptable = UnrestrictedWildcard;
386 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
387 Module *Restriction = WildcardRestrictions[R];
398 Exported.push_back(Mod);
402 void Module::buildVisibleModulesCache()
const {
403 assert(VisibleModulesCache.empty() &&
"cache does not need building");
406 VisibleModulesCache.insert(
this);
410 while (!Stack.empty()) {
411 Module *CurrModule = Stack.pop_back_val();
414 if (VisibleModulesCache.insert(CurrModule).second)
429 OS.indent(Indent + 2);
439 OS.indent(Indent + 2);
441 for (
unsigned I = 0, N =
Requirements.size(); I != N; ++I) {
452 OS.indent(Indent + 2);
453 OS <<
"umbrella header \"";
454 OS.write_escaped(H.NameAsWritten);
457 OS.indent(Indent + 2);
459 OS.write_escaped(D.NameAsWritten);
464 OS.indent(Indent + 2);
465 OS <<
"config_macros ";
467 OS <<
"[exhaustive]";
468 for (
unsigned I = 0, N =
ConfigMacros.size(); I != N; ++I) {
485 for (
auto &K : Kinds) {
486 assert(&K == &Kinds[K.Kind] &&
"kinds in wrong order");
487 for (
auto &H :
Headers[K.Kind]) {
488 OS.indent(Indent + 2);
489 OS << K.Prefix <<
"header \"";
490 OS.write_escaped(H.NameAsWritten);
491 OS <<
"\" { size " << H.Entry->getSize()
492 <<
" mtime " << H.Entry->getModificationTime() <<
" }\n";
497 OS.indent(Indent + 2);
498 OS << Kinds[U.Kind].Prefix <<
"header \"";
499 OS.write_escaped(U.FileName);
501 if (U.Size || U.ModTime) {
504 OS <<
" size " << *U.Size;
506 OS <<
" mtime " << *U.ModTime;
514 OS.indent(Indent + 2);
524 if (!(*MI)->IsInferred || (*MI)->IsFramework)
525 (*MI)->print(OS, Indent + 2);
527 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
528 OS.indent(Indent + 2);
531 OS << Restriction->getFullModuleName(
true);
541 OS.indent(Indent + 2);
549 for (
unsigned I = 0, N =
DirectUses.size(); I != N; ++I) {
550 OS.indent(Indent + 2);
557 OS.indent(Indent + 2);
563 for (
unsigned I = 0, N =
LinkLibraries.size(); I != N; ++I) {
564 OS.indent(Indent + 2);
574 OS.indent(Indent + 2);
582 for (
unsigned I = 0, N =
Conflicts.size(); I != N; ++I) {
583 OS.indent(Indent + 2);
585 OS <<
Conflicts[I].Other->getFullModuleName(
true);
592 OS.indent(Indent + 2);
595 OS <<
"module * {\n";
597 OS.indent(Indent + 4);
600 OS.indent(Indent + 2);
614 assert(Loc.
isValid() &&
"setVisible expects a valid import location");
622 Visiting *ExportedBy;
625 std::function<void(Visiting)> VisitModule = [&](Visiting
V) {
627 unsigned ID =
V.M->getVisibilityID();
628 if (ImportLocs.size() <=
ID)
629 ImportLocs.resize(ID + 1);
630 else if (ImportLocs[ID].isValid())
633 ImportLocs[
ID] = Loc;
638 V.M->getExportedModules(Exports);
639 for (
Module *E : Exports) {
641 if (E->isAvailable())
642 VisitModule({E, &
V});
645 for (
auto &
C :
V.M->Conflicts) {
646 if (isVisible(
C.Other)) {
648 for (Visiting *I = &
V; I; I = I->ExportedBy)
649 Path.push_back(I->M);
650 Cb(Path,
C.Other,
C.Message);
654 VisitModule({M,
nullptr});
unsigned IsAvailable
Whether this module is available in the current translation unit.
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
std::string Name
The name of this module.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system...
std::vector< Module * >::iterator submodule_iterator
Implements support for file system lookup, file system caching, and directory search management...
Defines the clang::FileManager interface and associated types.
submodule_iterator submodule_begin()
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
unsigned IsFramework
Whether this is a framework 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.
bool This(InterpState &S, CodePtr OpPC)
static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature)
ModuleKind Kind
The kind of this module.
void markUnavailable(bool MissingRequirement=false)
Mark this module and all of its submodules as unavailable.
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< Requirement, 2 > Requirements
The set of language features required to use this module.
Header getUmbrellaHeader() const
Retrieve the header that serves as the umbrella header for this module.
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module *>, Module *, StringRef) {})
Make a specific module visible.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e...
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, bool AllowStringLiterals=true)
bool isSubModuleOf(const Module *Other) const
Determine whether this module is a submodule of the given other module.
Module * Parent
The parent of this module.
submodule_iterator submodule_end()
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules...
void getExportedModules(SmallVectorImpl< Module *> &Exported) const
Appends this module's list of exported modules to Exported.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
const DirectoryEntry * Entry
Exposes information about the current target.
Defines the clang::LangOptions interface.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
ArrayRef< const FileEntry * > getTopHeaders(FileManager &FileMgr)
The top-level headers associated with this module.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used...
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)
Construct a new module or submodule.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
The result type of a method or function.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found.
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
LLVM_READONLY bool isValidIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
Encodes a location in the source.
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed, for use in "private" modules.
Module * findOrInferSubmodule(StringRef Name)
Information about a directory name as found in the module map file.
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
Defines the clang::Module class, which describes a module in the source code.
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
static StringRef getModuleNameFromComponent(const std::pair< std::string, SourceLocation > &IdComponent)
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned IsMissingRequirement
Whether this module is missing a feature from Requirements.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
Module * ShadowingModule
A module with the same name that shadows this module.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map...
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
std::vector< Conflict > Conflicts
The list of conflicts.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
void dump() const
Dump the contents of this module to the given output stream.
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Cached information about one directory (either on disk or in the virtual file system).
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...
Defines the clang::SourceLocation class and associated facilities.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
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...
bool isTLSSupported() const
Whether the target supports thread-local storage.
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
Defines the clang::TargetInfo interface.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned IsExplicit
Whether this is an explicit submodule.
bool Sub(InterpState &S, CodePtr OpPC)
std::vector< Module * >::const_iterator submodule_const_iterator
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.