13a02247dSChandler Carruth //===--- Module.cpp - Describe a module -----------------------------------===// 2de3ef502SDouglas Gregor // 3de3ef502SDouglas Gregor // The LLVM Compiler Infrastructure 4de3ef502SDouglas Gregor // 5de3ef502SDouglas Gregor // This file is distributed under the University of Illinois Open Source 6de3ef502SDouglas Gregor // License. See LICENSE.TXT for details. 7de3ef502SDouglas Gregor // 8de3ef502SDouglas Gregor //===----------------------------------------------------------------------===// 9de3ef502SDouglas Gregor // 10de3ef502SDouglas Gregor // This file defines the Module class, which describes a module in the source 11de3ef502SDouglas Gregor // code. 12de3ef502SDouglas Gregor // 13de3ef502SDouglas Gregor //===----------------------------------------------------------------------===// 14a3feee2aSRichard Smith 15de3ef502SDouglas Gregor #include "clang/Basic/Module.h" 16de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h" 171fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h" 180070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 193c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h" 201fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 211fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 223a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 233a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 24a3feee2aSRichard Smith 25de3ef502SDouglas Gregor using namespace clang; 26de3ef502SDouglas Gregor 27eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 28a7e2cc68SRichard Smith bool IsFramework, bool IsExplicit, unsigned VisibilityID) 293c1a41adSRichard Smith : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), 3015bcf70cSAdrian Prantl Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID), 31*8a308ec2SRichard Smith IsMissingRequirement(false), HasIncompatibleModuleFile(false), 32*8a308ec2SRichard Smith IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), 33*8a308ec2SRichard Smith IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), 34*8a308ec2SRichard Smith IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), 35*8a308ec2SRichard Smith InferExportWildcard(false), ConfigMacrosExhaustive(false), 36*8a308ec2SRichard Smith NameVisibility(Hidden) { 37eb90e830SDouglas Gregor if (Parent) { 38eb90e830SDouglas Gregor if (!Parent->isAvailable()) 39eb90e830SDouglas Gregor IsAvailable = false; 403ec6663bSDouglas Gregor if (Parent->IsSystem) 413ec6663bSDouglas Gregor IsSystem = true; 429bca298fSRichard Smith if (Parent->IsExternC) 439bca298fSRichard Smith IsExternC = true; 44993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 45eb90e830SDouglas Gregor 46eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 47eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 48eb90e830SDouglas Gregor } 49eb90e830SDouglas Gregor } 50eb90e830SDouglas Gregor 51de3ef502SDouglas Gregor Module::~Module() { 52eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 53de3ef502SDouglas Gregor I != IEnd; ++I) { 54eb90e830SDouglas Gregor delete *I; 55de3ef502SDouglas Gregor } 56de3ef502SDouglas Gregor } 57de3ef502SDouglas Gregor 581fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 591fb5c3a6SDouglas Gregor /// language options has the given feature. 6089929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 6189929282SDouglas Gregor const TargetInfo &Target) { 62532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 630070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 641fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 651fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 662bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 671fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 681fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 690070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 700070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 713c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 720070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 73532d2104SBen Langmuir if (!HasFeature) 74532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 75532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 76532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 77532d2104SBen Langmuir return HasFeature; 781fb5c3a6SDouglas Gregor } 791fb5c3a6SDouglas Gregor 803c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 813c1a41adSRichard Smith Requirement &Req, 823c1a41adSRichard Smith UnresolvedHeaderDirective &MissingHeader) const { 831fb5c3a6SDouglas Gregor if (IsAvailable) 841fb5c3a6SDouglas Gregor return true; 851fb5c3a6SDouglas Gregor 861fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 87a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 88a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 89a3feee2aSRichard Smith Current->Requirements[I].second) { 90a3feee2aSRichard Smith Req = Current->Requirements[I]; 911fb5c3a6SDouglas Gregor return false; 921fb5c3a6SDouglas Gregor } 931fb5c3a6SDouglas Gregor } 9475a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 9575a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 9675a7e435SBen Langmuir return false; 9775a7e435SBen Langmuir } 981fb5c3a6SDouglas Gregor } 991fb5c3a6SDouglas Gregor 1001fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1011fb5c3a6SDouglas Gregor } 1021fb5c3a6SDouglas Gregor 10362bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 104f5eedd05SDouglas Gregor const Module *This = this; 105f5eedd05SDouglas Gregor do { 106f5eedd05SDouglas Gregor if (This == Other) 107f5eedd05SDouglas Gregor return true; 108f5eedd05SDouglas Gregor 109f5eedd05SDouglas Gregor This = This->Parent; 110f5eedd05SDouglas Gregor } while (This); 111f5eedd05SDouglas Gregor 112f5eedd05SDouglas Gregor return false; 113f5eedd05SDouglas Gregor } 114f5eedd05SDouglas Gregor 11573441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 11673441091SDouglas Gregor const Module *Result = this; 11773441091SDouglas Gregor while (Result->Parent) 11873441091SDouglas Gregor Result = Result->Parent; 11973441091SDouglas Gregor 12073441091SDouglas Gregor return Result; 12173441091SDouglas Gregor } 12273441091SDouglas Gregor 123de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 124f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 125de3ef502SDouglas Gregor 126de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 127de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 128de3ef502SDouglas Gregor Names.push_back(M->Name); 129de3ef502SDouglas Gregor 130de3ef502SDouglas Gregor std::string Result; 13161ac906bSCraig Topper for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(), 132de3ef502SDouglas Gregor IEnd = Names.rend(); 133de3ef502SDouglas Gregor I != IEnd; ++I) { 134de3ef502SDouglas Gregor if (!Result.empty()) 135de3ef502SDouglas Gregor Result += '.'; 136de3ef502SDouglas Gregor 137de3ef502SDouglas Gregor Result += *I; 138de3ef502SDouglas Gregor } 139de3ef502SDouglas Gregor 140de3ef502SDouglas Gregor return Result; 141de3ef502SDouglas Gregor } 142de3ef502SDouglas Gregor 1437ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1447ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1457ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1467ff29148SBen Langmuir return false; 1477ff29148SBen Langmuir nameParts = nameParts.drop_back(); 1487ff29148SBen Langmuir } 1497ff29148SBen Langmuir return nameParts.empty(); 1507ff29148SBen Langmuir } 1517ff29148SBen Langmuir 1522b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 1532b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 1542b63d15fSRichard Smith return {"", U.Entry->getDir()}; 15573141fa9SDouglas Gregor 1562b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 15773141fa9SDouglas Gregor } 15873141fa9SDouglas Gregor 1593c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1603c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1613c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1623c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1633c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1643c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1653c5305c1SArgyrios Kyrtzidis } 1663c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1673c5305c1SArgyrios Kyrtzidis } 1683c5305c1SArgyrios Kyrtzidis 1693c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 1703c5305c1SArgyrios Kyrtzidis } 1713c5305c1SArgyrios Kyrtzidis 1728f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 1738f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 1748f4d3ff1SRichard Smith 1758f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 1768f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 1778f4d3ff1SRichard Smith return true; 1788f4d3ff1SRichard Smith 1798f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 1808f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 1818f4d3ff1SRichard Smith return true; 1828f4d3ff1SRichard Smith return false; 1838f4d3ff1SRichard Smith } 1848f4d3ff1SRichard Smith 185a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 186a3feee2aSRichard Smith const LangOptions &LangOpts, 18789929282SDouglas Gregor const TargetInfo &Target) { 188a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 1891fb5c3a6SDouglas Gregor 1901fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 191a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 1921fb5c3a6SDouglas Gregor return; 1931fb5c3a6SDouglas Gregor 194993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 195ec8c9752SBen Langmuir } 196ec8c9752SBen Langmuir 197993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 19875a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 19975a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 20075a7e435SBen Langmuir }; 20175a7e435SBen Langmuir 20275a7e435SBen Langmuir if (!needUpdate(this)) 2031fb5c3a6SDouglas Gregor return; 2041fb5c3a6SDouglas Gregor 205f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2061fb5c3a6SDouglas Gregor Stack.push_back(this); 2071fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2081fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2091fb5c3a6SDouglas Gregor Stack.pop_back(); 2101fb5c3a6SDouglas Gregor 21175a7e435SBen Langmuir if (!needUpdate(Current)) 2121fb5c3a6SDouglas Gregor continue; 2131fb5c3a6SDouglas Gregor 2141fb5c3a6SDouglas Gregor Current->IsAvailable = false; 215993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 216eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 217eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2181fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 21975a7e435SBen Langmuir if (needUpdate(*Sub)) 220eb90e830SDouglas Gregor Stack.push_back(*Sub); 2211fb5c3a6SDouglas Gregor } 2221fb5c3a6SDouglas Gregor } 2231fb5c3a6SDouglas Gregor } 2241fb5c3a6SDouglas Gregor 225eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 226eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 227eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 228f1186c5aSCraig Topper return nullptr; 229eb90e830SDouglas Gregor 230eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 231eb90e830SDouglas Gregor } 232eb90e830SDouglas Gregor 233f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 23424bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 23524bb923aSDouglas Gregor if (I) 23624bb923aSDouglas Gregor OS << "."; 23724bb923aSDouglas Gregor OS << Id[I].first; 23824bb923aSDouglas Gregor } 23924bb923aSDouglas Gregor } 24024bb923aSDouglas Gregor 2418739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 242e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 243e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 244e9bcf5b7SDmitri Gribenko E = SubModules.end(); 245e9bcf5b7SDmitri Gribenko I != E; ++I) { 246e9bcf5b7SDmitri Gribenko Module *Mod = *I; 247e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 248e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 249e9bcf5b7SDmitri Gribenko } 250e9bcf5b7SDmitri Gribenko 251e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2528739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2538739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2548739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2558739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2568739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2578739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2588739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2598739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2608739f7b7SArgyrios Kyrtzidis 2618739f7b7SArgyrios Kyrtzidis continue; 2628739f7b7SArgyrios Kyrtzidis } 2638739f7b7SArgyrios Kyrtzidis 2648739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2658739f7b7SArgyrios Kyrtzidis // the given pattern. 2668739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2678739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2688739f7b7SArgyrios Kyrtzidis continue; 2698739f7b7SArgyrios Kyrtzidis 2708739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2718739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 2728739f7b7SArgyrios Kyrtzidis else { 2738739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 2748739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 2758739f7b7SArgyrios Kyrtzidis } 2768739f7b7SArgyrios Kyrtzidis } 2778739f7b7SArgyrios Kyrtzidis 2788739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 2798739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 2808739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 2818739f7b7SArgyrios Kyrtzidis return; 2828739f7b7SArgyrios Kyrtzidis 2838739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2848739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 2858739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 2868739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 2878739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 2888739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 2898739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 2908739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 2918739f7b7SArgyrios Kyrtzidis Acceptable = true; 2928739f7b7SArgyrios Kyrtzidis break; 2938739f7b7SArgyrios Kyrtzidis } 2948739f7b7SArgyrios Kyrtzidis } 2958739f7b7SArgyrios Kyrtzidis } 2968739f7b7SArgyrios Kyrtzidis 2978739f7b7SArgyrios Kyrtzidis if (!Acceptable) 2988739f7b7SArgyrios Kyrtzidis continue; 2998739f7b7SArgyrios Kyrtzidis 3008739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3018739f7b7SArgyrios Kyrtzidis } 3028739f7b7SArgyrios Kyrtzidis } 3038739f7b7SArgyrios Kyrtzidis 3040e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3050e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3060e5d7b8cSRichard Smith 3070e5d7b8cSRichard Smith // This module is visible to itself. 3080e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3090e5d7b8cSRichard Smith 3100e5d7b8cSRichard Smith // Every imported module is visible. 311dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 312dc360d57SDmitri Gribenko while (!Stack.empty()) { 313dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 314dc360d57SDmitri Gribenko 315dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 316dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 317dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3180e5d7b8cSRichard Smith } 3190e5d7b8cSRichard Smith } 3200e5d7b8cSRichard Smith 321f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 322de3ef502SDouglas Gregor OS.indent(Indent); 323de3ef502SDouglas Gregor if (IsFramework) 324de3ef502SDouglas Gregor OS << "framework "; 325de3ef502SDouglas Gregor if (IsExplicit) 326de3ef502SDouglas Gregor OS << "explicit "; 327a686e1b0SDouglas Gregor OS << "module " << Name; 328a686e1b0SDouglas Gregor 3297615f00eSBen Langmuir if (IsSystem || IsExternC) { 330a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3317615f00eSBen Langmuir if (IsSystem) 332a686e1b0SDouglas Gregor OS << " [system]"; 3337615f00eSBen Langmuir if (IsExternC) 3347615f00eSBen Langmuir OS << " [extern_c]"; 335a686e1b0SDouglas Gregor } 336a686e1b0SDouglas Gregor 337a686e1b0SDouglas Gregor OS << " {\n"; 338de3ef502SDouglas Gregor 339a3feee2aSRichard Smith if (!Requirements.empty()) { 3401fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3411fb5c3a6SDouglas Gregor OS << "requires "; 342a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3431fb5c3a6SDouglas Gregor if (I) 3441fb5c3a6SDouglas Gregor OS << ", "; 345a3feee2aSRichard Smith if (!Requirements[I].second) 346a3feee2aSRichard Smith OS << "!"; 347a3feee2aSRichard Smith OS << Requirements[I].first; 3481fb5c3a6SDouglas Gregor } 3491fb5c3a6SDouglas Gregor OS << "\n"; 3501fb5c3a6SDouglas Gregor } 3511fb5c3a6SDouglas Gregor 3522b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 353de3ef502SDouglas Gregor OS.indent(Indent + 2); 354322f633cSDouglas Gregor OS << "umbrella header \""; 3552b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 356de3ef502SDouglas Gregor OS << "\"\n"; 3572b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 358322f633cSDouglas Gregor OS.indent(Indent + 2); 359322f633cSDouglas Gregor OS << "umbrella \""; 3602b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 361322f633cSDouglas Gregor OS << "\"\n"; 362de3ef502SDouglas Gregor } 363de3ef502SDouglas Gregor 36435b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 36535b13eceSDouglas Gregor OS.indent(Indent + 2); 36635b13eceSDouglas Gregor OS << "config_macros "; 36735b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 3688d932427SDouglas Gregor OS << "[exhaustive]"; 36935b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 37035b13eceSDouglas Gregor if (I) 37135b13eceSDouglas Gregor OS << ", "; 37235b13eceSDouglas Gregor OS << ConfigMacros[I]; 37335b13eceSDouglas Gregor } 3748d932427SDouglas Gregor OS << "\n"; 37535b13eceSDouglas Gregor } 37635b13eceSDouglas Gregor 3773c1a41adSRichard Smith struct { 378306d8920SRichard Smith StringRef Prefix; 3793c1a41adSRichard Smith HeaderKind Kind; 3803c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 3813c1a41adSRichard Smith {"textual ", HK_Textual}, 3823c1a41adSRichard Smith {"private ", HK_Private}, 3833c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 3843c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 385306d8920SRichard Smith 386306d8920SRichard Smith for (auto &K : Kinds) { 3873c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 388de3ef502SDouglas Gregor OS.indent(Indent + 2); 389306d8920SRichard Smith OS << K.Prefix << "header \""; 3903c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 391de3ef502SDouglas Gregor OS << "\"\n"; 392de3ef502SDouglas Gregor } 393b53e5483SLawrence Crowl } 394b53e5483SLawrence Crowl 395eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 396de3ef502SDouglas Gregor MI != MIEnd; ++MI) 3979d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 3989d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 3999d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4009d6448b1SBen Langmuir // those header files anyway. 4019d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 402eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 403de3ef502SDouglas Gregor 40424bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 40524bb923aSDouglas Gregor OS.indent(Indent + 2); 4068c7c8352SDouglas Gregor OS << "export "; 4078c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4088c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 40924bb923aSDouglas Gregor if (Exports[I].getInt()) 41024bb923aSDouglas Gregor OS << ".*"; 4118c7c8352SDouglas Gregor } else { 4128c7c8352SDouglas Gregor OS << "*"; 4138c7c8352SDouglas Gregor } 41424bb923aSDouglas Gregor OS << "\n"; 41524bb923aSDouglas Gregor } 41624bb923aSDouglas Gregor 41724bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 41824bb923aSDouglas Gregor OS.indent(Indent + 2); 41924bb923aSDouglas Gregor OS << "export "; 42024bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4218c7c8352SDouglas Gregor if (UnresolvedExports[I].Wildcard) { 4228c7c8352SDouglas Gregor if (UnresolvedExports[I].Id.empty()) 4238c7c8352SDouglas Gregor OS << "*"; 4248c7c8352SDouglas Gregor else 42524bb923aSDouglas Gregor OS << ".*"; 4268c7c8352SDouglas Gregor } 42724bb923aSDouglas Gregor OS << "\n"; 42824bb923aSDouglas Gregor } 42924bb923aSDouglas Gregor 430ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 431ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 432ba7f2f71SDaniel Jasper OS << "use "; 433ba7f2f71SDaniel Jasper OS << DirectUses[I]->getFullModuleName(); 434ba7f2f71SDaniel Jasper OS << "\n"; 435ba7f2f71SDaniel Jasper } 436ba7f2f71SDaniel Jasper 437ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 438ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 439ba7f2f71SDaniel Jasper OS << "use "; 440ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 441ba7f2f71SDaniel Jasper OS << "\n"; 442ba7f2f71SDaniel Jasper } 443ba7f2f71SDaniel Jasper 4446ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 4456ddfca91SDouglas Gregor OS.indent(Indent + 2); 4466ddfca91SDouglas Gregor OS << "link "; 4476ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 4486ddfca91SDouglas Gregor OS << "framework "; 4496ddfca91SDouglas Gregor OS << "\""; 4506ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 4516ddfca91SDouglas Gregor OS << "\""; 4526ddfca91SDouglas Gregor } 4536ddfca91SDouglas Gregor 454fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 455fb912657SDouglas Gregor OS.indent(Indent + 2); 456fb912657SDouglas Gregor OS << "conflict "; 457fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 458fb912657SDouglas Gregor OS << ", \""; 459fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 460fb912657SDouglas Gregor OS << "\"\n"; 461fb912657SDouglas Gregor } 462fb912657SDouglas Gregor 463fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 464fb912657SDouglas Gregor OS.indent(Indent + 2); 465fb912657SDouglas Gregor OS << "conflict "; 466fb912657SDouglas Gregor OS << Conflicts[I].Other->getFullModuleName(); 467fb912657SDouglas Gregor OS << ", \""; 468fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 469fb912657SDouglas Gregor OS << "\"\n"; 470fb912657SDouglas Gregor } 471fb912657SDouglas Gregor 47273441091SDouglas Gregor if (InferSubmodules) { 47373441091SDouglas Gregor OS.indent(Indent + 2); 47473441091SDouglas Gregor if (InferExplicitSubmodules) 47573441091SDouglas Gregor OS << "explicit "; 47673441091SDouglas Gregor OS << "module * {\n"; 47773441091SDouglas Gregor if (InferExportWildcard) { 47873441091SDouglas Gregor OS.indent(Indent + 4); 47973441091SDouglas Gregor OS << "export *\n"; 48073441091SDouglas Gregor } 48173441091SDouglas Gregor OS.indent(Indent + 2); 48273441091SDouglas Gregor OS << "}\n"; 48373441091SDouglas Gregor } 48473441091SDouglas Gregor 485de3ef502SDouglas Gregor OS.indent(Indent); 486de3ef502SDouglas Gregor OS << "}\n"; 487de3ef502SDouglas Gregor } 488de3ef502SDouglas Gregor 489de3ef502SDouglas Gregor void Module::dump() const { 490de3ef502SDouglas Gregor print(llvm::errs()); 491de3ef502SDouglas Gregor } 492de3ef502SDouglas Gregor 493a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 494a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 495a7e2cc68SRichard Smith if (isVisible(M)) 496a7e2cc68SRichard Smith return; 497de3ef502SDouglas Gregor 498a7e2cc68SRichard Smith ++Generation; 499a7e2cc68SRichard Smith 500a7e2cc68SRichard Smith struct Visiting { 501a7e2cc68SRichard Smith Module *M; 502a7e2cc68SRichard Smith Visiting *ExportedBy; 503a7e2cc68SRichard Smith }; 504a7e2cc68SRichard Smith 505a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 506a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 507a7e2cc68SRichard Smith if (!V.M->isAvailable()) 508a7e2cc68SRichard Smith return; 509a7e2cc68SRichard Smith 510a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 511a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 512a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 513a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 514a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 515a7e2cc68SRichard Smith return; 516a7e2cc68SRichard Smith 517a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 518a7e2cc68SRichard Smith Vis(M); 519a7e2cc68SRichard Smith 520a7e2cc68SRichard Smith // Make any exported modules visible. 521a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 522a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 523a7e2cc68SRichard Smith for (Module *E : Exports) 524a7e2cc68SRichard Smith VisitModule({E, &V}); 525a7e2cc68SRichard Smith 526a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 527a7e2cc68SRichard Smith if (isVisible(C.Other)) { 528a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 529a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 530a7e2cc68SRichard Smith Path.push_back(I->M); 531a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 532a7e2cc68SRichard Smith } 533a7e2cc68SRichard Smith } 534a7e2cc68SRichard Smith }; 535a7e2cc68SRichard Smith VisitModule({M, nullptr}); 536a7e2cc68SRichard Smith } 537