21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringMap.h" 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/ADT/StringSwitch.h" 26 #include "llvm/Support/Compiler.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/raw_ostream.h" 36 using namespace clang;
39 bool IsFramework,
bool IsExplicit,
unsigned VisibilityID)
40 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
41 VisibilityID(VisibilityID), IsMissingRequirement(
false),
42 HasIncompatibleModuleFile(
false), IsAvailable(
true),
43 IsFromModuleFile(
false), IsFramework(IsFramework), IsExplicit(IsExplicit),
45 InferSubmodules(
false), InferExplicitSubmodules(
false),
46 InferExportWildcard(
false), ConfigMacrosExhaustive(
false),
47 NoUndeclaredIncludes(
false), NameVisibility(Hidden) {
59 Parent->SubModuleIndex[
Name] = Parent->SubModules.size();
60 Parent->SubModules.push_back(
this);
75 bool HasFeature = llvm::StringSwitch<bool>(Feature)
76 .Case(
"altivec", LangOpts.AltiVec)
77 .Case(
"blocks", LangOpts.Blocks)
78 .Case(
"coroutines", LangOpts.CoroutinesTS)
79 .Case(
"cplusplus", LangOpts.CPlusPlus)
80 .Case(
"cplusplus11", LangOpts.CPlusPlus11)
81 .Case(
"freestanding", LangOpts.Freestanding)
82 .Case(
"gnuinlineasm", LangOpts.GNUAsm)
83 .Case(
"objc", LangOpts.ObjC1)
84 .Case(
"objc_arc", LangOpts.ObjCAutoRefCount)
85 .Case(
"opencl", LangOpts.OpenCL)
87 .Case(
"zvector", LangOpts.ZVector)
102 for (
const Module *Current =
this; Current; Current = Current->Parent) {
103 for (
unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
104 if (
hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
105 Current->Requirements[I].second) {
106 Req = Current->Requirements[I];
110 if (!Current->MissingHeaders.empty()) {
111 MissingHeader = Current->MissingHeaders.front();
116 llvm_unreachable(
"could not find a reason why module is unavailable");
120 const Module *This =
this;
140 const std::pair<std::string, SourceLocation> &IdComponent) {
141 return IdComponent.first;
146 template<
typename InputIter>
148 bool AllowStringLiterals =
true) {
149 for (InputIter It = Begin; It !=
End; ++It) {
158 OS.write_escaped(Name);
164 template<
typename Container>
174 Names.push_back(M->Name);
178 llvm::raw_string_ostream Out(Result);
179 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
187 if (nameParts.empty() || M->Name != nameParts.back())
189 nameParts = nameParts.drop_back();
191 return nameParts.empty();
196 return {
"", U.
Entry->getDir()};
202 if (!TopHeaderNames.empty()) {
203 for (std::vector<std::string>::iterator
204 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
206 TopHeaders.insert(FE);
208 TopHeaderNames.clear();
211 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
221 for (
auto *Use : Top->DirectUses)
226 if (!Requested->
Parent && Requested->
Name ==
"_Builtin_stddef_max_align_t")
238 if (
hasFeature(Feature, LangOpts, Target) == RequiredState)
245 auto needUpdate = [MissingRequirement](
Module *M) {
246 return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
249 if (!needUpdate(
this))
253 Stack.push_back(
this);
254 while (!Stack.empty()) {
255 Module *Current = Stack.back();
258 if (!needUpdate(Current))
265 Sub != SubEnd; ++Sub) {
266 if (needUpdate(*Sub))
267 Stack.push_back(*Sub);
273 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
274 if (Pos == SubModuleIndex.end())
277 return SubModules[Pos->getValue()];
282 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
283 E = SubModules.end();
287 Exported.push_back(Mod);
291 bool AnyWildcard =
false;
292 bool UnrestrictedWildcard =
false;
294 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
298 Exported.push_back(Mod);
306 if (UnrestrictedWildcard)
310 WildcardRestrictions.push_back(Restriction);
312 WildcardRestrictions.clear();
313 UnrestrictedWildcard =
true;
322 for (
unsigned I = 0, N =
Imports.size(); I != N; ++I) {
324 bool Acceptable = UnrestrictedWildcard;
327 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
328 Module *Restriction = WildcardRestrictions[R];
339 Exported.push_back(Mod);
343 void Module::buildVisibleModulesCache()
const {
344 assert(VisibleModulesCache.empty() &&
"cache does not need building");
347 VisibleModulesCache.insert(
this);
351 while (!Stack.empty()) {
352 Module *CurrModule = Stack.pop_back_val();
355 if (VisibleModulesCache.insert(CurrModule).second)
370 OS.indent(Indent + 2);
380 OS.indent(Indent + 2);
382 for (
unsigned I = 0, N =
Requirements.size(); I != N; ++I) {
393 OS.indent(Indent + 2);
394 OS <<
"umbrella header \"";
395 OS.write_escaped(H.NameAsWritten);
398 OS.indent(Indent + 2);
400 OS.write_escaped(D.NameAsWritten);
405 OS.indent(Indent + 2);
406 OS <<
"config_macros ";
408 OS <<
"[exhaustive]";
409 for (
unsigned I = 0, N =
ConfigMacros.size(); I != N; ++I) {
426 for (
auto &K : Kinds) {
427 assert(&K == &Kinds[K.Kind] &&
"kinds in wrong order");
428 for (
auto &H :
Headers[K.Kind]) {
429 OS.indent(Indent + 2);
430 OS << K.Prefix <<
"header \"";
431 OS.write_escaped(H.NameAsWritten);
432 OS <<
"\" { size " << H.Entry->getSize()
433 <<
" mtime " << H.Entry->getModificationTime() <<
" }\n";
437 for (
auto &U : *Unresolved) {
438 OS.indent(Indent + 2);
439 OS << Kinds[U.Kind].Prefix <<
"header \"";
440 OS.write_escaped(U.FileName);
442 if (U.Size || U.ModTime) {
445 OS <<
" size " << *U.Size;
447 OS <<
" mtime " << *U.ModTime;
455 OS.indent(Indent + 2);
465 if (!(*MI)->IsInferred || (*MI)->IsFramework)
466 (*MI)->print(OS, Indent + 2);
468 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
469 OS.indent(Indent + 2);
472 OS << Restriction->getFullModuleName(
true);
482 OS.indent(Indent + 2);
490 for (
unsigned I = 0, N =
DirectUses.size(); I != N; ++I) {
491 OS.indent(Indent + 2);
498 OS.indent(Indent + 2);
504 for (
unsigned I = 0, N =
LinkLibraries.size(); I != N; ++I) {
505 OS.indent(Indent + 2);
515 OS.indent(Indent + 2);
523 for (
unsigned I = 0, N =
Conflicts.size(); I != N; ++I) {
524 OS.indent(Indent + 2);
526 OS <<
Conflicts[I].Other->getFullModuleName(
true);
533 OS.indent(Indent + 2);
536 OS <<
"module * {\n";
538 OS.indent(Indent + 4);
541 OS.indent(Indent + 2);
555 assert(Loc.
isValid() &&
"setVisible expects a valid import location");
563 Visiting *ExportedBy;
566 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
568 if (!V.M->isAvailable())
572 unsigned ID = V.M->getVisibilityID();
573 if (ImportLocs.size() <=
ID)
574 ImportLocs.resize(ID + 1);
575 else if (ImportLocs[ID].isValid())
578 ImportLocs[
ID] = Loc;
583 V.M->getExportedModules(Exports);
585 VisitModule({E, &V});
587 for (
auto &
C : V.M->Conflicts) {
588 if (isVisible(
C.Other)) {
590 for (Visiting *I = &V; I; I = I->ExportedBy)
591 Path.push_back(I->M);
592 Cb(Path,
C.Other,
C.Message);
596 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"...
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.
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.
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)...
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.
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.
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.
LLVM_READONLY bool isValidIdentifier(StringRef S)
Return true if this is a valid ASCII identifier.
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.
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.
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.
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that 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 ...
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.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
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.
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...
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
unsigned IsExplicit
Whether this is an explicit submodule.
std::vector< Module * >::const_iterator submodule_const_iterator
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.