20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringSwitch.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
29 bool IsFramework,
bool IsExplicit,
unsigned VisibilityID)
30 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
31 Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID),
32 IsMissingRequirement(
false), HasIncompatibleModuleFile(
false),
33 IsAvailable(
true), IsFromModuleFile(
false), IsFramework(IsFramework),
34 IsExplicit(IsExplicit), IsSystem(
false), IsExternC(
false),
35 IsInferred(
false), InferSubmodules(
false), InferExplicitSubmodules(
false),
36 InferExportWildcard(
false), ConfigMacrosExhaustive(
false),
37 NoUndeclaredIncludes(
false), NameVisibility(Hidden) {
49 Parent->SubModuleIndex[
Name] = Parent->SubModules.size();
50 Parent->SubModules.push_back(
this);
65 bool HasFeature = llvm::StringSwitch<bool>(Feature)
66 .Case(
"altivec", LangOpts.AltiVec)
67 .Case(
"blocks", LangOpts.Blocks)
68 .Case(
"coroutines", LangOpts.CoroutinesTS)
69 .Case(
"cplusplus", LangOpts.CPlusPlus)
70 .Case(
"cplusplus11", LangOpts.CPlusPlus11)
71 .Case(
"freestanding", LangOpts.Freestanding)
72 .Case(
"gnuinlineasm", LangOpts.GNUAsm)
73 .Case(
"objc", LangOpts.ObjC1)
74 .Case(
"objc_arc", LangOpts.ObjCAutoRefCount)
75 .Case(
"opencl", LangOpts.OpenCL)
77 .Case(
"zvector", LangOpts.ZVector)
93 for (
unsigned I = 0, N =
Current->Requirements.size();
I != N; ++
I) {
100 if (!
Current->MissingHeaders.empty()) {
101 MissingHeader =
Current->MissingHeaders.front();
106 llvm_unreachable(
"could not find a reason why module is unavailable");
110 const Module *This =
this;
130 const std::pair<std::string, SourceLocation> &IdComponent) {
131 return IdComponent.first;
135 template<
typename InputIter>
137 bool AllowStringLiterals =
true) {
138 for (InputIter It = Begin; It !=
End; ++It) {
147 OS.write_escaped(Name);
153 template<
typename Container>
163 Names.push_back(M->Name);
167 llvm::raw_string_ostream Out(Result);
168 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
176 if (nameParts.empty() || M->Name != nameParts.back())
178 nameParts = nameParts.drop_back();
180 return nameParts.empty();
185 return {
"", U.
Entry->getDir()};
191 if (!TopHeaderNames.empty()) {
192 for (std::vector<std::string>::iterator
193 I = TopHeaderNames.begin(),
E = TopHeaderNames.end();
I !=
E; ++
I) {
195 TopHeaders.insert(FE);
197 TopHeaderNames.clear();
200 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
210 for (
auto *Use : Top->DirectUses)
215 if (!Requested->
Parent && Requested->
Name ==
"_Builtin_stddef_max_align_t")
227 if (
hasFeature(Feature, LangOpts, Target) == RequiredState)
234 auto needUpdate = [MissingRequirement](
Module *M) {
235 return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
238 if (!needUpdate(
this))
242 Stack.push_back(
this);
243 while (!Stack.empty()) {
247 if (!needUpdate(Current))
254 Sub != SubEnd; ++Sub) {
255 if (needUpdate(*Sub))
256 Stack.push_back(*Sub);
262 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
263 if (Pos == SubModuleIndex.end())
266 return SubModules[Pos->getValue()];
271 for (std::vector<Module *>::const_iterator
I = SubModules.begin(),
272 E = SubModules.end();
276 Exported.push_back(Mod);
280 bool AnyWildcard =
false;
281 bool UnrestrictedWildcard =
false;
283 for (
unsigned I = 0, N =
Exports.size();
I != N; ++
I) {
287 Exported.push_back(Mod);
295 if (UnrestrictedWildcard)
299 WildcardRestrictions.push_back(Restriction);
301 WildcardRestrictions.clear();
302 UnrestrictedWildcard =
true;
311 for (
unsigned I = 0, N =
Imports.size();
I != N; ++
I) {
313 bool Acceptable = UnrestrictedWildcard;
316 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
317 Module *Restriction = WildcardRestrictions[R];
328 Exported.push_back(Mod);
332 void Module::buildVisibleModulesCache()
const {
333 assert(VisibleModulesCache.empty() &&
"cache does not need building");
336 VisibleModulesCache.insert(
this);
340 while (!
Stack.empty()) {
344 if (VisibleModulesCache.insert(CurrModule).second)
359 OS.indent(Indent + 2);
369 OS.indent(Indent + 2);
382 OS.indent(Indent + 2);
383 OS <<
"umbrella header \"";
384 OS.write_escaped(H.NameAsWritten);
387 OS.indent(Indent + 2);
389 OS.write_escaped(D.NameAsWritten);
394 OS.indent(Indent + 2);
395 OS <<
"config_macros ";
397 OS <<
"[exhaustive]";
415 for (
auto &K : Kinds) {
416 assert(&K == &Kinds[K.Kind] &&
"kinds in wrong order");
417 for (
auto &H :
Headers[K.Kind]) {
418 OS.indent(Indent + 2);
419 OS << K.Prefix <<
"header \"";
420 OS.write_escaped(H.NameAsWritten);
421 OS <<
"\" { size " << H.Entry->getSize()
422 <<
" mtime " << H.Entry->getModificationTime() <<
" }\n";
426 for (
auto &U : *Unresolved) {
427 OS.indent(Indent + 2);
428 OS << Kinds[U.Kind].Prefix <<
"header \"";
429 OS.write_escaped(U.FileName);
431 if (U.Size || U.ModTime) {
434 OS <<
" size " << *U.Size;
436 OS <<
" mtime " << *U.ModTime;
449 if (!(*MI)->IsInferred || (*MI)->IsFramework)
450 (*MI)->print(OS, Indent + 2);
452 for (
unsigned I = 0, N =
Exports.size();
I != N; ++
I) {
453 OS.indent(Indent + 2);
456 OS << Restriction->getFullModuleName(
true);
466 OS.indent(Indent + 2);
475 OS.indent(Indent + 2);
482 OS.indent(Indent + 2);
489 OS.indent(Indent + 2);
499 OS.indent(Indent + 2);
507 for (
unsigned I = 0, N =
Conflicts.size();
I != N; ++
I) {
508 OS.indent(Indent + 2);
510 OS <<
Conflicts[
I].Other->getFullModuleName(
true);
517 OS.indent(Indent + 2);
520 OS <<
"module * {\n";
522 OS.indent(Indent + 4);
525 OS.indent(Indent + 2);
539 assert(Loc.
isValid() &&
"setVisible expects a valid import location");
547 Visiting *ExportedBy;
550 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
552 if (!V.M->isAvailable())
556 unsigned ID = V.M->getVisibilityID();
557 if (ImportLocs.size() <=
ID)
558 ImportLocs.resize(ID + 1);
559 else if (ImportLocs[ID].isValid())
562 ImportLocs[
ID] = Loc;
567 V.M->getExportedModules(Exports);
569 VisitModule({
E, &V});
571 for (
auto &C : V.M->Conflicts) {
572 if (isVisible(C.Other)) {
574 for (Visiting *
I = &V;
I;
I =
I->ExportedBy)
575 Path.push_back(
I->M);
576 Cb(Path, C.Other, C.Message);
580 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.
Header getUmbrellaHeader() const
Retrieve the header that serves as the umbrella header for this module.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system...
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 "...
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.
Defines the clang::Module class, which describes a module in the source code.
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...
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.
void getExportedModules(SmallVectorImpl< Module * > &Exported) const
Appends this module's list of exported modules to Exported.
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...
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...
void dump() const
Dump the contents of this module to the given output stream.
SmallVector< Requirement, 2 > Requirements
The set of language features required to use this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
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.
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e...
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
Module * Parent
The parent of this module.
submodule_iterator submodule_end()
detail::InMemoryDirectory::const_iterator I
std::vector< Module * >::iterator submodule_iterator
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...
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
static LLVM_READONLY bool isValidIdentifier(StringRef S)
Return true if this is a valid ASCII identifier.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
std::vector< bool > & Stack
const DirectoryEntry * Entry
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *){}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef){})
Make a specific module visible.
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.
static StringRef getModuleNameFromComponent(const std::pair< std::string, SourceLocation > &IdComponent)
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 isSubModuleOf(const Module *Other) const
Determine whether this module is a submodule of the given other module.
std::vector< Module * >::const_iterator submodule_const_iterator
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
The result type of a method or function.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Information about a directory name as found in the module map file.
Cached information about one file (either on disk or in the virtual file system). ...
static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, bool AllowStringLiterals=true)
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
unsigned IsMissingRequirement
Whether this module is missing a feature from Requirements.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
detail::InMemoryDirectory::const_iterator E
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found.
std::vector< Conflict > Conflicts
The list of conflicts.
SmallVector< Module *, 2 > DirectUses
The directly used modules.
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
Cached information about one directory (either on disk or in the virtual file system).
bool isTLSSupported() const
Whether the target supports thread-local storage.
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
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...
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned IsExplicit
Whether this is an explicit submodule.
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.