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), 318a308ec2SRichard Smith IsMissingRequirement(false), HasIncompatibleModuleFile(false), 328a308ec2SRichard Smith IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), 338a308ec2SRichard Smith IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), 348a308ec2SRichard Smith IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), 358a308ec2SRichard Smith InferExportWildcard(false), ConfigMacrosExhaustive(false), 368a308ec2SRichard 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) 67*fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 686736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 691fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 701fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 710070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 720070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 733c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 740070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 75532d2104SBen Langmuir if (!HasFeature) 76532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 77532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 78532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 79532d2104SBen Langmuir return HasFeature; 801fb5c3a6SDouglas Gregor } 811fb5c3a6SDouglas Gregor 823c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 833c1a41adSRichard Smith Requirement &Req, 843c1a41adSRichard Smith UnresolvedHeaderDirective &MissingHeader) const { 851fb5c3a6SDouglas Gregor if (IsAvailable) 861fb5c3a6SDouglas Gregor return true; 871fb5c3a6SDouglas Gregor 881fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 89a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 90a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 91a3feee2aSRichard Smith Current->Requirements[I].second) { 92a3feee2aSRichard Smith Req = Current->Requirements[I]; 931fb5c3a6SDouglas Gregor return false; 941fb5c3a6SDouglas Gregor } 951fb5c3a6SDouglas Gregor } 9675a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 9775a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 9875a7e435SBen Langmuir return false; 9975a7e435SBen Langmuir } 1001fb5c3a6SDouglas Gregor } 1011fb5c3a6SDouglas Gregor 1021fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1031fb5c3a6SDouglas Gregor } 1041fb5c3a6SDouglas Gregor 10562bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 106f5eedd05SDouglas Gregor const Module *This = this; 107f5eedd05SDouglas Gregor do { 108f5eedd05SDouglas Gregor if (This == Other) 109f5eedd05SDouglas Gregor return true; 110f5eedd05SDouglas Gregor 111f5eedd05SDouglas Gregor This = This->Parent; 112f5eedd05SDouglas Gregor } while (This); 113f5eedd05SDouglas Gregor 114f5eedd05SDouglas Gregor return false; 115f5eedd05SDouglas Gregor } 116f5eedd05SDouglas Gregor 11773441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 11873441091SDouglas Gregor const Module *Result = this; 11973441091SDouglas Gregor while (Result->Parent) 12073441091SDouglas Gregor Result = Result->Parent; 12173441091SDouglas Gregor 12273441091SDouglas Gregor return Result; 12373441091SDouglas Gregor } 12473441091SDouglas Gregor 125de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 126f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 127de3ef502SDouglas Gregor 128de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 129de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 130de3ef502SDouglas Gregor Names.push_back(M->Name); 131de3ef502SDouglas Gregor 132de3ef502SDouglas Gregor std::string Result; 13361ac906bSCraig Topper for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(), 134de3ef502SDouglas Gregor IEnd = Names.rend(); 135de3ef502SDouglas Gregor I != IEnd; ++I) { 136de3ef502SDouglas Gregor if (!Result.empty()) 137de3ef502SDouglas Gregor Result += '.'; 138de3ef502SDouglas Gregor 139de3ef502SDouglas Gregor Result += *I; 140de3ef502SDouglas Gregor } 141de3ef502SDouglas Gregor 142de3ef502SDouglas Gregor return Result; 143de3ef502SDouglas Gregor } 144de3ef502SDouglas Gregor 1457ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1467ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1477ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1487ff29148SBen Langmuir return false; 1497ff29148SBen Langmuir nameParts = nameParts.drop_back(); 1507ff29148SBen Langmuir } 1517ff29148SBen Langmuir return nameParts.empty(); 1527ff29148SBen Langmuir } 1537ff29148SBen Langmuir 1542b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 1552b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 1562b63d15fSRichard Smith return {"", U.Entry->getDir()}; 15773141fa9SDouglas Gregor 1582b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 15973141fa9SDouglas Gregor } 16073141fa9SDouglas Gregor 1613c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1623c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1633c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1643c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1653c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1663c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1673c5305c1SArgyrios Kyrtzidis } 1683c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1693c5305c1SArgyrios Kyrtzidis } 1703c5305c1SArgyrios Kyrtzidis 1713c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 1723c5305c1SArgyrios Kyrtzidis } 1733c5305c1SArgyrios Kyrtzidis 1748f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 1758f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 1768f4d3ff1SRichard Smith 1778f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 1788f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 1798f4d3ff1SRichard Smith return true; 1808f4d3ff1SRichard Smith 1818f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 1828f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 1838f4d3ff1SRichard Smith return true; 1848f4d3ff1SRichard Smith return false; 1858f4d3ff1SRichard Smith } 1868f4d3ff1SRichard Smith 187a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 188a3feee2aSRichard Smith const LangOptions &LangOpts, 18989929282SDouglas Gregor const TargetInfo &Target) { 190a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 1911fb5c3a6SDouglas Gregor 1921fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 193a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 1941fb5c3a6SDouglas Gregor return; 1951fb5c3a6SDouglas Gregor 196993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 197ec8c9752SBen Langmuir } 198ec8c9752SBen Langmuir 199993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 20075a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 20175a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 20275a7e435SBen Langmuir }; 20375a7e435SBen Langmuir 20475a7e435SBen Langmuir if (!needUpdate(this)) 2051fb5c3a6SDouglas Gregor return; 2061fb5c3a6SDouglas Gregor 207f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2081fb5c3a6SDouglas Gregor Stack.push_back(this); 2091fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2101fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2111fb5c3a6SDouglas Gregor Stack.pop_back(); 2121fb5c3a6SDouglas Gregor 21375a7e435SBen Langmuir if (!needUpdate(Current)) 2141fb5c3a6SDouglas Gregor continue; 2151fb5c3a6SDouglas Gregor 2161fb5c3a6SDouglas Gregor Current->IsAvailable = false; 217993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 218eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 219eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2201fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 22175a7e435SBen Langmuir if (needUpdate(*Sub)) 222eb90e830SDouglas Gregor Stack.push_back(*Sub); 2231fb5c3a6SDouglas Gregor } 2241fb5c3a6SDouglas Gregor } 2251fb5c3a6SDouglas Gregor } 2261fb5c3a6SDouglas Gregor 227eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 228eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 229eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 230f1186c5aSCraig Topper return nullptr; 231eb90e830SDouglas Gregor 232eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 233eb90e830SDouglas Gregor } 234eb90e830SDouglas Gregor 235f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 23624bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 23724bb923aSDouglas Gregor if (I) 23824bb923aSDouglas Gregor OS << "."; 23924bb923aSDouglas Gregor OS << Id[I].first; 24024bb923aSDouglas Gregor } 24124bb923aSDouglas Gregor } 24224bb923aSDouglas Gregor 2438739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 244e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 245e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 246e9bcf5b7SDmitri Gribenko E = SubModules.end(); 247e9bcf5b7SDmitri Gribenko I != E; ++I) { 248e9bcf5b7SDmitri Gribenko Module *Mod = *I; 249e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 250e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 251e9bcf5b7SDmitri Gribenko } 252e9bcf5b7SDmitri Gribenko 253e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2548739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2558739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2568739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2578739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2588739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2598739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2608739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2618739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2628739f7b7SArgyrios Kyrtzidis 2638739f7b7SArgyrios Kyrtzidis continue; 2648739f7b7SArgyrios Kyrtzidis } 2658739f7b7SArgyrios Kyrtzidis 2668739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2678739f7b7SArgyrios Kyrtzidis // the given pattern. 2688739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2698739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2708739f7b7SArgyrios Kyrtzidis continue; 2718739f7b7SArgyrios Kyrtzidis 2728739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2738739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 2748739f7b7SArgyrios Kyrtzidis else { 2758739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 2768739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 2778739f7b7SArgyrios Kyrtzidis } 2788739f7b7SArgyrios Kyrtzidis } 2798739f7b7SArgyrios Kyrtzidis 2808739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 2818739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 2828739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 2838739f7b7SArgyrios Kyrtzidis return; 2848739f7b7SArgyrios Kyrtzidis 2858739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2868739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 2878739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 2888739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 2898739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 2908739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 2918739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 2928739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 2938739f7b7SArgyrios Kyrtzidis Acceptable = true; 2948739f7b7SArgyrios Kyrtzidis break; 2958739f7b7SArgyrios Kyrtzidis } 2968739f7b7SArgyrios Kyrtzidis } 2978739f7b7SArgyrios Kyrtzidis } 2988739f7b7SArgyrios Kyrtzidis 2998739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3008739f7b7SArgyrios Kyrtzidis continue; 3018739f7b7SArgyrios Kyrtzidis 3028739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3038739f7b7SArgyrios Kyrtzidis } 3048739f7b7SArgyrios Kyrtzidis } 3058739f7b7SArgyrios Kyrtzidis 3060e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3070e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3080e5d7b8cSRichard Smith 3090e5d7b8cSRichard Smith // This module is visible to itself. 3100e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3110e5d7b8cSRichard Smith 3120e5d7b8cSRichard Smith // Every imported module is visible. 313dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 314dc360d57SDmitri Gribenko while (!Stack.empty()) { 315dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 316dc360d57SDmitri Gribenko 317dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 318dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 319dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3200e5d7b8cSRichard Smith } 3210e5d7b8cSRichard Smith } 3220e5d7b8cSRichard Smith 323f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 324de3ef502SDouglas Gregor OS.indent(Indent); 325de3ef502SDouglas Gregor if (IsFramework) 326de3ef502SDouglas Gregor OS << "framework "; 327de3ef502SDouglas Gregor if (IsExplicit) 328de3ef502SDouglas Gregor OS << "explicit "; 329a686e1b0SDouglas Gregor OS << "module " << Name; 330a686e1b0SDouglas Gregor 3317615f00eSBen Langmuir if (IsSystem || IsExternC) { 332a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3337615f00eSBen Langmuir if (IsSystem) 334a686e1b0SDouglas Gregor OS << " [system]"; 3357615f00eSBen Langmuir if (IsExternC) 3367615f00eSBen Langmuir OS << " [extern_c]"; 337a686e1b0SDouglas Gregor } 338a686e1b0SDouglas Gregor 339a686e1b0SDouglas Gregor OS << " {\n"; 340de3ef502SDouglas Gregor 341a3feee2aSRichard Smith if (!Requirements.empty()) { 3421fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3431fb5c3a6SDouglas Gregor OS << "requires "; 344a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3451fb5c3a6SDouglas Gregor if (I) 3461fb5c3a6SDouglas Gregor OS << ", "; 347a3feee2aSRichard Smith if (!Requirements[I].second) 348a3feee2aSRichard Smith OS << "!"; 349a3feee2aSRichard Smith OS << Requirements[I].first; 3501fb5c3a6SDouglas Gregor } 3511fb5c3a6SDouglas Gregor OS << "\n"; 3521fb5c3a6SDouglas Gregor } 3531fb5c3a6SDouglas Gregor 3542b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 355de3ef502SDouglas Gregor OS.indent(Indent + 2); 356322f633cSDouglas Gregor OS << "umbrella header \""; 3572b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 358de3ef502SDouglas Gregor OS << "\"\n"; 3592b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 360322f633cSDouglas Gregor OS.indent(Indent + 2); 361322f633cSDouglas Gregor OS << "umbrella \""; 3622b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 363322f633cSDouglas Gregor OS << "\"\n"; 364de3ef502SDouglas Gregor } 365de3ef502SDouglas Gregor 36635b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 36735b13eceSDouglas Gregor OS.indent(Indent + 2); 36835b13eceSDouglas Gregor OS << "config_macros "; 36935b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 3708d932427SDouglas Gregor OS << "[exhaustive]"; 37135b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 37235b13eceSDouglas Gregor if (I) 37335b13eceSDouglas Gregor OS << ", "; 37435b13eceSDouglas Gregor OS << ConfigMacros[I]; 37535b13eceSDouglas Gregor } 3768d932427SDouglas Gregor OS << "\n"; 37735b13eceSDouglas Gregor } 37835b13eceSDouglas Gregor 3793c1a41adSRichard Smith struct { 380306d8920SRichard Smith StringRef Prefix; 3813c1a41adSRichard Smith HeaderKind Kind; 3823c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 3833c1a41adSRichard Smith {"textual ", HK_Textual}, 3843c1a41adSRichard Smith {"private ", HK_Private}, 3853c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 3863c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 387306d8920SRichard Smith 388306d8920SRichard Smith for (auto &K : Kinds) { 3893c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 390de3ef502SDouglas Gregor OS.indent(Indent + 2); 391306d8920SRichard Smith OS << K.Prefix << "header \""; 3923c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 393de3ef502SDouglas Gregor OS << "\"\n"; 394de3ef502SDouglas Gregor } 395b53e5483SLawrence Crowl } 396b53e5483SLawrence Crowl 397eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 398de3ef502SDouglas Gregor MI != MIEnd; ++MI) 3999d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4009d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4019d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4029d6448b1SBen Langmuir // those header files anyway. 4039d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 404eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 405de3ef502SDouglas Gregor 40624bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 40724bb923aSDouglas Gregor OS.indent(Indent + 2); 4088c7c8352SDouglas Gregor OS << "export "; 4098c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4108c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 41124bb923aSDouglas Gregor if (Exports[I].getInt()) 41224bb923aSDouglas Gregor OS << ".*"; 4138c7c8352SDouglas Gregor } else { 4148c7c8352SDouglas Gregor OS << "*"; 4158c7c8352SDouglas Gregor } 41624bb923aSDouglas Gregor OS << "\n"; 41724bb923aSDouglas Gregor } 41824bb923aSDouglas Gregor 41924bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 42024bb923aSDouglas Gregor OS.indent(Indent + 2); 42124bb923aSDouglas Gregor OS << "export "; 42224bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4237f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4247f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 42524bb923aSDouglas Gregor OS << "\n"; 42624bb923aSDouglas Gregor } 42724bb923aSDouglas Gregor 428ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 429ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 430ba7f2f71SDaniel Jasper OS << "use "; 431ba7f2f71SDaniel Jasper OS << DirectUses[I]->getFullModuleName(); 432ba7f2f71SDaniel Jasper OS << "\n"; 433ba7f2f71SDaniel Jasper } 434ba7f2f71SDaniel Jasper 435ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 436ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 437ba7f2f71SDaniel Jasper OS << "use "; 438ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 439ba7f2f71SDaniel Jasper OS << "\n"; 440ba7f2f71SDaniel Jasper } 441ba7f2f71SDaniel Jasper 4426ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 4436ddfca91SDouglas Gregor OS.indent(Indent + 2); 4446ddfca91SDouglas Gregor OS << "link "; 4456ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 4466ddfca91SDouglas Gregor OS << "framework "; 4476ddfca91SDouglas Gregor OS << "\""; 4486ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 4496ddfca91SDouglas Gregor OS << "\""; 4506ddfca91SDouglas Gregor } 4516ddfca91SDouglas Gregor 452fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 453fb912657SDouglas Gregor OS.indent(Indent + 2); 454fb912657SDouglas Gregor OS << "conflict "; 455fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 456fb912657SDouglas Gregor OS << ", \""; 457fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 458fb912657SDouglas Gregor OS << "\"\n"; 459fb912657SDouglas Gregor } 460fb912657SDouglas Gregor 461fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 462fb912657SDouglas Gregor OS.indent(Indent + 2); 463fb912657SDouglas Gregor OS << "conflict "; 464fb912657SDouglas Gregor OS << Conflicts[I].Other->getFullModuleName(); 465fb912657SDouglas Gregor OS << ", \""; 466fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 467fb912657SDouglas Gregor OS << "\"\n"; 468fb912657SDouglas Gregor } 469fb912657SDouglas Gregor 47073441091SDouglas Gregor if (InferSubmodules) { 47173441091SDouglas Gregor OS.indent(Indent + 2); 47273441091SDouglas Gregor if (InferExplicitSubmodules) 47373441091SDouglas Gregor OS << "explicit "; 47473441091SDouglas Gregor OS << "module * {\n"; 47573441091SDouglas Gregor if (InferExportWildcard) { 47673441091SDouglas Gregor OS.indent(Indent + 4); 47773441091SDouglas Gregor OS << "export *\n"; 47873441091SDouglas Gregor } 47973441091SDouglas Gregor OS.indent(Indent + 2); 48073441091SDouglas Gregor OS << "}\n"; 48173441091SDouglas Gregor } 48273441091SDouglas Gregor 483de3ef502SDouglas Gregor OS.indent(Indent); 484de3ef502SDouglas Gregor OS << "}\n"; 485de3ef502SDouglas Gregor } 486de3ef502SDouglas Gregor 487cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 488de3ef502SDouglas Gregor print(llvm::errs()); 489de3ef502SDouglas Gregor } 490de3ef502SDouglas Gregor 491a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 492a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 4936d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 494a7e2cc68SRichard Smith if (isVisible(M)) 495a7e2cc68SRichard Smith return; 496de3ef502SDouglas Gregor 497a7e2cc68SRichard Smith ++Generation; 498a7e2cc68SRichard Smith 499a7e2cc68SRichard Smith struct Visiting { 500a7e2cc68SRichard Smith Module *M; 501a7e2cc68SRichard Smith Visiting *ExportedBy; 502a7e2cc68SRichard Smith }; 503a7e2cc68SRichard Smith 504a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 505a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 506a7e2cc68SRichard Smith if (!V.M->isAvailable()) 507a7e2cc68SRichard Smith return; 508a7e2cc68SRichard Smith 509a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 510a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 511a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 512a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 513a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 514a7e2cc68SRichard Smith return; 515a7e2cc68SRichard Smith 516a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 517a7e2cc68SRichard Smith Vis(M); 518a7e2cc68SRichard Smith 519a7e2cc68SRichard Smith // Make any exported modules visible. 520a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 521a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 522a7e2cc68SRichard Smith for (Module *E : Exports) 523a7e2cc68SRichard Smith VisitModule({E, &V}); 524a7e2cc68SRichard Smith 525a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 526a7e2cc68SRichard Smith if (isVisible(C.Other)) { 527a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 528a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 529a7e2cc68SRichard Smith Path.push_back(I->M); 530a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 531a7e2cc68SRichard Smith } 532a7e2cc68SRichard Smith } 533a7e2cc68SRichard Smith }; 534a7e2cc68SRichard Smith VisitModule({M, nullptr}); 535a7e2cc68SRichard Smith } 536