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"
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");
165 !CurrentModule.endswith(
"_Private") && TopLevelName.endswith(
"_Private"))
166 TopLevelName = TopLevelName.drop_back(8);
168 return TopLevelName == CurrentModule;
174 Module *&ShadowingModule)
const {
183 for (
const Module *Current =
this; Current; Current = Current->Parent) {
184 if (!Current->MissingHeaders.empty()) {
185 MissingHeader = Current->MissingHeaders.front();
190 llvm_unreachable(
"could not find a reason why module is unavailable");
210 const std::pair<std::string, SourceLocation> &IdComponent) {
211 return IdComponent.first;
216template<
typename InputIter>
218 bool AllowStringLiterals =
true) {
219 for (InputIter It =
Begin; It != End; ++It) {
228 OS.write_escaped(Name);
234template<
typename Container>
244 Names.push_back(M->Name);
248 llvm::raw_string_ostream Out(
Result);
249 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
257 if (nameParts.empty() || M->Name != nameParts.back())
259 nameParts = nameParts.drop_back();
261 return nameParts.empty();
266 return {
"",
"",
U.Entry->getDir()};
274 TopHeaders.insert(
File);
278 if (!TopHeaderNames.empty()) {
279 for (std::vector<std::string>::iterator
280 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
281 if (
auto FE = FileMgr.
getFile(*I))
282 TopHeaders.insert(*FE);
284 TopHeaderNames.clear();
297 for (
auto *Use : Top->DirectUses)
302 if (!Requested->
Parent && Requested->
Name ==
"_Builtin_stddef_max_align_t")
324 auto needUpdate = [Unimportable](
Module *M) {
325 return M->IsAvailable || (!M->IsUnimportable && Unimportable);
328 if (!needUpdate(
this))
332 Stack.push_back(
this);
333 while (!Stack.empty()) {
334 Module *Current = Stack.back();
337 if (!needUpdate(Current))
340 Current->IsAvailable =
false;
341 Current->IsUnimportable |= Unimportable;
343 SubEnd = Current->submodule_end();
344 Sub != SubEnd; ++Sub) {
345 if (needUpdate(*Sub))
346 Stack.push_back(*Sub);
352 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(
Name);
353 if (Pos == SubModuleIndex.end())
356 return SubModules[Pos->getValue()];
360 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(
Name);
361 if (Pos != SubModuleIndex.end())
362 return SubModules[Pos->getValue()];
369 if (
Result->InferExportWildcard)
376 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
377 E = SubModules.end();
381 Exported.push_back(Mod);
385 bool AnyWildcard =
false;
386 bool UnrestrictedWildcard =
false;
388 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
392 Exported.push_back(Mod);
400 if (UnrestrictedWildcard)
404 WildcardRestrictions.push_back(Restriction);
406 WildcardRestrictions.clear();
407 UnrestrictedWildcard =
true;
416 for (
unsigned I = 0, N =
Imports.size(); I != N; ++I) {
418 bool Acceptable = UnrestrictedWildcard;
421 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
422 Module *Restriction = WildcardRestrictions[R];
433 Exported.push_back(Mod);
437void Module::buildVisibleModulesCache()
const {
438 assert(VisibleModulesCache.empty() &&
"cache does not need building");
441 VisibleModulesCache.insert(
this);
445 while (!Stack.empty()) {
446 Module *CurrModule = Stack.pop_back_val();
449 if (VisibleModulesCache.insert(CurrModule).second)
464 OS.indent(Indent + 2);
474 OS.indent(Indent + 2);
476 for (
unsigned I = 0, N =
Requirements.size(); I != N; ++I) {
487 OS.indent(Indent + 2);
488 OS <<
"umbrella header \"";
489 OS.write_escaped(H.NameAsWritten);
492 OS.indent(Indent + 2);
494 OS.write_escaped(D.NameAsWritten);
499 OS.indent(Indent + 2);
500 OS <<
"config_macros ";
502 OS <<
"[exhaustive]";
503 for (
unsigned I = 0, N =
ConfigMacros.size(); I != N; ++I) {
520 for (
auto &K : Kinds) {
521 assert(&K == &Kinds[K.Kind] &&
"kinds in wrong order");
522 for (
auto &H :
Headers[K.Kind]) {
523 OS.indent(Indent + 2);
524 OS << K.Prefix <<
"header \"";
525 OS.write_escaped(H.NameAsWritten);
526 OS <<
"\" { size " << H.Entry->getSize()
527 <<
" mtime " << H.Entry->getModificationTime() <<
" }\n";
532 OS.indent(Indent + 2);
533 OS << Kinds[
U.Kind].Prefix <<
"header \"";
534 OS.write_escaped(
U.FileName);
536 if (
U.Size ||
U.ModTime) {
539 OS <<
" size " << *
U.Size;
541 OS <<
" mtime " << *
U.ModTime;
549 OS.indent(Indent + 2);
559 if (!(*MI)->IsInferred || (*MI)->IsFramework)
560 (*MI)->print(OS, Indent + 2, Dump);
562 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
563 OS.indent(Indent + 2);
566 OS << Restriction->getFullModuleName(
true);
576 OS.indent(Indent + 2);
586 OS.indent(Indent + 2);
587 llvm::errs() <<
"import " << M->getFullModuleName() <<
"\n";
591 for (
unsigned I = 0, N =
DirectUses.size(); I != N; ++I) {
592 OS.indent(Indent + 2);
599 OS.indent(Indent + 2);
605 for (
unsigned I = 0, N =
LinkLibraries.size(); I != N; ++I) {
606 OS.indent(Indent + 2);
616 OS.indent(Indent + 2);
624 for (
unsigned I = 0, N =
Conflicts.size(); I != N; ++I) {
625 OS.indent(Indent + 2);
627 OS <<
Conflicts[I].Other->getFullModuleName(
true);
634 OS.indent(Indent + 2);
637 OS <<
"module * {\n";
639 OS.indent(Indent + 4);
642 OS.indent(Indent + 2);
651 print(llvm::errs(), 0,
true);
658 "setVisible expects a valid import location");
666 Visiting *ExportedBy;
669 std::function<void(Visiting)> VisitModule = [&](Visiting
V) {
671 unsigned ID =
V.M->getVisibilityID();
672 if (ImportLocs.size() <= ID)
673 ImportLocs.resize(ID + 1);
674 else if (ImportLocs[ID].isValid())
677 ImportLocs[ID] = Loc;
682 V.M->getExportedModules(Exports);
683 for (
Module *E : Exports) {
685 if (!E->isUnimportable())
686 VisitModule({E, &
V});
689 for (
auto &
C :
V.M->Conflicts) {
692 for (Visiting *I = &
V; I; I = I->ExportedBy)
693 Path.push_back(I->M);
694 Cb(Path,
C.Other,
C.Message);
698 VisitModule({M,
nullptr});
702 : Signature(M.Signature), ClangModule(&M) {
706 ASTFile =
File->getName();
711 return ClangModule->
Name;
713 return std::string(PCHModuleName);
Defines the clang::FileManager interface and associated types.
Defines the clang::LangOptions interface.
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)
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.
std::string getModuleName() const
ASTSourceDescriptor()=default
Cached information about one directory (either on disk or in the virtual file system).
StringRef getName() const
Cached information about one file (either on disk or in the virtual file system).
Implements support for file system lookup, file system caching, and directory search management.
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
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.
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 ...
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.
Module * findOrInferSubmodule(StringRef Name)
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
llvm::PointerUnion< const FileEntryRef::MapEntry *, const DirectoryEntry * > Umbrella
The umbrella header or directory.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
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 ...
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
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.
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
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.
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.
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
ArrayRef< const FileEntry * > getTopHeaders(FileManager &FileMgr)
The top-level headers associated with this module.
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 ...
std::string UmbrellaRelativeToRootModuleDirectory
std::vector< Module * >::iterator submodule_iterator
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
const DirectoryEntry * Directory
The build directory of this module.
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
submodule_iterator submodule_begin()
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::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature.
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const
The serialized AST file for this module, if one was created.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported 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.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
std::vector< Module * >::const_iterator submodule_const_iterator
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.
submodule_iterator submodule_end()
Header getUmbrellaHeader() const
Retrieve the header that serves as the umbrella header for this 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.
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found.
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.
bool isVisible(const Module *M) const
Determine whether a module is visible.
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef) {})
Make a specific module visible.
Defines the clang::TargetInfo interface.
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
Information about a directory name as found in the module map file.