19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
28 bool IsFramework,
bool IsExplicit,
unsigned VisibilityID)
29 : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
30 Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID),
31 IsMissingRequirement(
false), IsAvailable(
true), IsFromModuleFile(
false),
32 IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(
false),
34 InferExplicitSubmodules(
false), InferExportWildcard(
false),
35 ConfigMacrosExhaustive(
false), NameVisibility(Hidden) {
45 Parent->SubModuleIndex[
Name] = Parent->SubModules.size();
46 Parent->SubModules.push_back(
this);
61 bool HasFeature = llvm::StringSwitch<bool>(Feature)
62 .Case(
"altivec", LangOpts.AltiVec)
63 .Case(
"blocks", LangOpts.Blocks)
64 .Case(
"cplusplus", LangOpts.CPlusPlus)
65 .Case(
"cplusplus11", LangOpts.CPlusPlus11)
66 .Case(
"objc", LangOpts.ObjC1)
67 .Case(
"objc_arc", LangOpts.ObjCAutoRefCount)
68 .Case(
"opencl", LangOpts.OpenCL)
70 .Case(
"zvector", LangOpts.ZVector)
86 for (
unsigned I = 0, N =
Current->Requirements.size(); I != N; ++I) {
88 Current->Requirements[I].second) {
93 if (!
Current->MissingHeaders.empty()) {
94 MissingHeader =
Current->MissingHeaders.front();
99 llvm_unreachable(
"could not find a reason why module is unavailable");
103 const Module *This =
this;
127 Names.push_back(M->Name);
144 return {
"", U.
Entry->getDir()};
150 if (!TopHeaderNames.empty()) {
151 for (std::vector<std::string>::iterator
152 I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
154 TopHeaders.insert(FE);
156 TopHeaderNames.clear();
159 return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
169 for (
auto *Use : Top->DirectUses)
181 if (
hasFeature(Feature, LangOpts, Target) == RequiredState)
188 auto needUpdate = [MissingRequirement](
Module *M) {
189 return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
192 if (!needUpdate(
this))
196 Stack.push_back(
this);
197 while (!Stack.empty()) {
201 if (!needUpdate(Current))
208 Sub != SubEnd; ++Sub) {
209 if (needUpdate(*Sub))
210 Stack.push_back(*Sub);
216 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
217 if (Pos == SubModuleIndex.end())
220 return SubModules[Pos->getValue()];
224 for (
unsigned I = 0, N = Id.size(); I != N; ++I) {
233 for (std::vector<Module *>::const_iterator I = SubModules.begin(),
234 E = SubModules.end();
238 Exported.push_back(Mod);
242 bool AnyWildcard =
false;
243 bool UnrestrictedWildcard =
false;
245 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
249 Exported.push_back(Mod);
257 if (UnrestrictedWildcard)
261 WildcardRestrictions.push_back(Restriction);
263 WildcardRestrictions.clear();
264 UnrestrictedWildcard =
true;
273 for (
unsigned I = 0, N =
Imports.size(); I != N; ++I) {
275 bool Acceptable = UnrestrictedWildcard;
278 for (
unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
279 Module *Restriction = WildcardRestrictions[R];
290 Exported.push_back(Mod);
294 void Module::buildVisibleModulesCache()
const {
295 assert(VisibleModulesCache.empty() &&
"cache does not need building");
298 VisibleModulesCache.insert(
this);
302 while (!
Stack.empty()) {
306 if (VisibleModulesCache.insert(CurrModule).second)
317 OS <<
"module " <<
Name;
320 OS.indent(Indent + 2);
330 OS.indent(Indent + 2);
332 for (
unsigned I = 0, N =
Requirements.size(); I != N; ++I) {
343 OS.indent(Indent + 2);
344 OS <<
"umbrella header \"";
345 OS.write_escaped(H.NameAsWritten);
348 OS.indent(Indent + 2);
350 OS.write_escaped(D.NameAsWritten);
355 OS.indent(Indent + 2);
356 OS <<
"config_macros ";
358 OS <<
"[exhaustive]";
359 for (
unsigned I = 0, N =
ConfigMacros.size(); I != N; ++I) {
376 for (
auto &K : Kinds) {
377 for (
auto &H :
Headers[K.Kind]) {
378 OS.indent(Indent + 2);
379 OS << K.Prefix <<
"header \"";
380 OS.write_escaped(H.NameAsWritten);
391 if (!(*MI)->IsInferred || (*MI)->IsFramework)
392 (*MI)->print(OS, Indent + 2);
394 for (
unsigned I = 0, N =
Exports.size(); I != N; ++I) {
395 OS.indent(Indent + 2);
398 OS << Restriction->getFullModuleName();
408 OS.indent(Indent + 2);
420 for (
unsigned I = 0, N =
DirectUses.size(); I != N; ++I) {
421 OS.indent(Indent + 2);
428 OS.indent(Indent + 2);
434 for (
unsigned I = 0, N =
LinkLibraries.size(); I != N; ++I) {
435 OS.indent(Indent + 2);
445 OS.indent(Indent + 2);
453 for (
unsigned I = 0, N =
Conflicts.size(); I != N; ++I) {
454 OS.indent(Indent + 2);
456 OS <<
Conflicts[I].Other->getFullModuleName();
463 OS.indent(Indent + 2);
466 OS <<
"module * {\n";
468 OS.indent(Indent + 4);
471 OS.indent(Indent + 2);
492 Visiting *ExportedBy;
495 std::function<void(Visiting)> VisitModule = [&](Visiting V) {
497 if (!V.M->isAvailable())
501 unsigned ID = V.M->getVisibilityID();
502 if (ImportLocs.size() <=
ID)
503 ImportLocs.resize(ID + 1);
504 else if (ImportLocs[ID].isValid())
507 ImportLocs[
ID] = Loc;
512 V.M->getExportedModules(Exports);
514 VisitModule({E, &V});
516 for (
auto &
C : V.M->Conflicts) {
517 if (isVisible(
C.Other)) {
519 for (Visiting *I = &V; I; I = I->ExportedBy)
520 Path.push_back(I->M);
521 Cb(Path,
C.Other,
C.Message);
525 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.
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...
void markUnavailable(bool MissingRequirement=false)
Mark this module and all of its submodules as unavailable.
std::string getFullModuleName() const
Retrieve the full name of this module, including the path from its top-level module.
SmallVector< Requirement, 2 > Requirements
The set of language features required to use this module.
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. This will be NULL for the top-level module.
submodule_iterator submodule_end()
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 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.
static void printModuleId(raw_ostream &OS, const ModuleId &Id)
std::vector< bool > & Stack
ID
Defines the set of possible language-specific address spaces.
const DirectoryEntry * Entry
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *){}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef){})
Make a specific module visible.
void dump() const
Dump the contents of this module to the given output stream.
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.
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.
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
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
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II)
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. The SourceManager can decode this to get at the full include stack...
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). ...
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
unsigned IsMissingRequirement
Whether this module is missing a feature from Requirements.
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found. Path consists of a sequence of modules from the c...
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.