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(), 3060fa2888SDuncan P. N. Exon Smith Umbrella(), 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), 36e6b7c28dSDavid Blaikie NoUndeclaredIncludes(false), 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; 44ed84df00SBruno Cardoso Lopes if (Parent->NoUndeclaredIncludes) 45ed84df00SBruno Cardoso Lopes NoUndeclaredIncludes = true; 46993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 47eb90e830SDouglas Gregor 48eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 49eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 50eb90e830SDouglas Gregor } 51eb90e830SDouglas Gregor } 52eb90e830SDouglas Gregor 53de3ef502SDouglas Gregor Module::~Module() { 54eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 55de3ef502SDouglas Gregor I != IEnd; ++I) { 56eb90e830SDouglas Gregor delete *I; 57de3ef502SDouglas Gregor } 58de3ef502SDouglas Gregor } 59de3ef502SDouglas Gregor 601fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 611fb5c3a6SDouglas Gregor /// language options has the given feature. 6289929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 6389929282SDouglas Gregor const TargetInfo &Target) { 64532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 650070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 661fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 67e38cea02SEric Fiselier .Case("coroutines", LangOpts.CoroutinesTS) 681fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 692bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 70fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 716736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 721fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 731fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 740070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 750070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 763c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 770070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 78532d2104SBen Langmuir if (!HasFeature) 79532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 80532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 81532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 82532d2104SBen Langmuir return HasFeature; 831fb5c3a6SDouglas Gregor } 841fb5c3a6SDouglas Gregor 853c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 863c1a41adSRichard Smith Requirement &Req, 873c1a41adSRichard Smith UnresolvedHeaderDirective &MissingHeader) const { 881fb5c3a6SDouglas Gregor if (IsAvailable) 891fb5c3a6SDouglas Gregor return true; 901fb5c3a6SDouglas Gregor 911fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 92a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 93a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 94a3feee2aSRichard Smith Current->Requirements[I].second) { 95a3feee2aSRichard Smith Req = Current->Requirements[I]; 961fb5c3a6SDouglas Gregor return false; 971fb5c3a6SDouglas Gregor } 981fb5c3a6SDouglas Gregor } 9975a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 10075a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 10175a7e435SBen Langmuir return false; 10275a7e435SBen Langmuir } 1031fb5c3a6SDouglas Gregor } 1041fb5c3a6SDouglas Gregor 1051fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1061fb5c3a6SDouglas Gregor } 1071fb5c3a6SDouglas Gregor 10862bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 109f5eedd05SDouglas Gregor const Module *This = this; 110f5eedd05SDouglas Gregor do { 111f5eedd05SDouglas Gregor if (This == Other) 112f5eedd05SDouglas Gregor return true; 113f5eedd05SDouglas Gregor 114f5eedd05SDouglas Gregor This = This->Parent; 115f5eedd05SDouglas Gregor } while (This); 116f5eedd05SDouglas Gregor 117f5eedd05SDouglas Gregor return false; 118f5eedd05SDouglas Gregor } 119f5eedd05SDouglas Gregor 12073441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 12173441091SDouglas Gregor const Module *Result = this; 12273441091SDouglas Gregor while (Result->Parent) 12373441091SDouglas Gregor Result = Result->Parent; 12473441091SDouglas Gregor 12573441091SDouglas Gregor return Result; 12673441091SDouglas Gregor } 12773441091SDouglas Gregor 128de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 129f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 130de3ef502SDouglas Gregor 131de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 132de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 133de3ef502SDouglas Gregor Names.push_back(M->Name); 134de3ef502SDouglas Gregor 135de3ef502SDouglas Gregor std::string Result; 13661ac906bSCraig Topper for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(), 137de3ef502SDouglas Gregor IEnd = Names.rend(); 138de3ef502SDouglas Gregor I != IEnd; ++I) { 139de3ef502SDouglas Gregor if (!Result.empty()) 140de3ef502SDouglas Gregor Result += '.'; 141de3ef502SDouglas Gregor 142de3ef502SDouglas Gregor Result += *I; 143de3ef502SDouglas Gregor } 144de3ef502SDouglas Gregor 145de3ef502SDouglas Gregor return Result; 146de3ef502SDouglas Gregor } 147de3ef502SDouglas Gregor 1487ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1497ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1507ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1517ff29148SBen Langmuir return false; 1527ff29148SBen Langmuir nameParts = nameParts.drop_back(); 1537ff29148SBen Langmuir } 1547ff29148SBen Langmuir return nameParts.empty(); 1557ff29148SBen Langmuir } 1567ff29148SBen Langmuir 1572b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 1582b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 1592b63d15fSRichard Smith return {"", U.Entry->getDir()}; 16073141fa9SDouglas Gregor 1612b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 16273141fa9SDouglas Gregor } 16373141fa9SDouglas Gregor 1643c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1653c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1663c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1673c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1683c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1693c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1703c5305c1SArgyrios Kyrtzidis } 1713c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1723c5305c1SArgyrios Kyrtzidis } 1733c5305c1SArgyrios Kyrtzidis 1743c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 1753c5305c1SArgyrios Kyrtzidis } 1763c5305c1SArgyrios Kyrtzidis 1778f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 1788f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 1798f4d3ff1SRichard Smith 1808f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 1818f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 1828f4d3ff1SRichard Smith return true; 1838f4d3ff1SRichard Smith 1848f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 1858f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 1868f4d3ff1SRichard Smith return true; 187ed84df00SBruno Cardoso Lopes 188ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 189ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 190ed84df00SBruno Cardoso Lopes return true; 191ed84df00SBruno Cardoso Lopes 1928f4d3ff1SRichard Smith return false; 1938f4d3ff1SRichard Smith } 1948f4d3ff1SRichard Smith 195a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 196a3feee2aSRichard Smith const LangOptions &LangOpts, 19789929282SDouglas Gregor const TargetInfo &Target) { 198a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 1991fb5c3a6SDouglas Gregor 2001fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 201a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2021fb5c3a6SDouglas Gregor return; 2031fb5c3a6SDouglas Gregor 204993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 205ec8c9752SBen Langmuir } 206ec8c9752SBen Langmuir 207993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 20875a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 20975a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 21075a7e435SBen Langmuir }; 21175a7e435SBen Langmuir 21275a7e435SBen Langmuir if (!needUpdate(this)) 2131fb5c3a6SDouglas Gregor return; 2141fb5c3a6SDouglas Gregor 215f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2161fb5c3a6SDouglas Gregor Stack.push_back(this); 2171fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2181fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2191fb5c3a6SDouglas Gregor Stack.pop_back(); 2201fb5c3a6SDouglas Gregor 22175a7e435SBen Langmuir if (!needUpdate(Current)) 2221fb5c3a6SDouglas Gregor continue; 2231fb5c3a6SDouglas Gregor 2241fb5c3a6SDouglas Gregor Current->IsAvailable = false; 225993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 226eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 227eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2281fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 22975a7e435SBen Langmuir if (needUpdate(*Sub)) 230eb90e830SDouglas Gregor Stack.push_back(*Sub); 2311fb5c3a6SDouglas Gregor } 2321fb5c3a6SDouglas Gregor } 2331fb5c3a6SDouglas Gregor } 2341fb5c3a6SDouglas Gregor 235eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 236eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 237eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 238f1186c5aSCraig Topper return nullptr; 239eb90e830SDouglas Gregor 240eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 241eb90e830SDouglas Gregor } 242eb90e830SDouglas Gregor 243f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 24424bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 24524bb923aSDouglas Gregor if (I) 24624bb923aSDouglas Gregor OS << "."; 24724bb923aSDouglas Gregor OS << Id[I].first; 24824bb923aSDouglas Gregor } 24924bb923aSDouglas Gregor } 25024bb923aSDouglas Gregor 2518739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 252e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 253e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 254e9bcf5b7SDmitri Gribenko E = SubModules.end(); 255e9bcf5b7SDmitri Gribenko I != E; ++I) { 256e9bcf5b7SDmitri Gribenko Module *Mod = *I; 257e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 258e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 259e9bcf5b7SDmitri Gribenko } 260e9bcf5b7SDmitri Gribenko 261e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2628739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2638739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2648739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2658739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2668739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2678739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2688739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2698739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2708739f7b7SArgyrios Kyrtzidis 2718739f7b7SArgyrios Kyrtzidis continue; 2728739f7b7SArgyrios Kyrtzidis } 2738739f7b7SArgyrios Kyrtzidis 2748739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2758739f7b7SArgyrios Kyrtzidis // the given pattern. 2768739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2778739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2788739f7b7SArgyrios Kyrtzidis continue; 2798739f7b7SArgyrios Kyrtzidis 2808739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2818739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 2828739f7b7SArgyrios Kyrtzidis else { 2838739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 2848739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 2858739f7b7SArgyrios Kyrtzidis } 2868739f7b7SArgyrios Kyrtzidis } 2878739f7b7SArgyrios Kyrtzidis 2888739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 2898739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 2908739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 2918739f7b7SArgyrios Kyrtzidis return; 2928739f7b7SArgyrios Kyrtzidis 2938739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2948739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 2958739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 2968739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 2978739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 2988739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 2998739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3008739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3018739f7b7SArgyrios Kyrtzidis Acceptable = true; 3028739f7b7SArgyrios Kyrtzidis break; 3038739f7b7SArgyrios Kyrtzidis } 3048739f7b7SArgyrios Kyrtzidis } 3058739f7b7SArgyrios Kyrtzidis } 3068739f7b7SArgyrios Kyrtzidis 3078739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3088739f7b7SArgyrios Kyrtzidis continue; 3098739f7b7SArgyrios Kyrtzidis 3108739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3118739f7b7SArgyrios Kyrtzidis } 3128739f7b7SArgyrios Kyrtzidis } 3138739f7b7SArgyrios Kyrtzidis 3140e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3150e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3160e5d7b8cSRichard Smith 3170e5d7b8cSRichard Smith // This module is visible to itself. 3180e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3190e5d7b8cSRichard Smith 3200e5d7b8cSRichard Smith // Every imported module is visible. 321dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 322dc360d57SDmitri Gribenko while (!Stack.empty()) { 323dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 324dc360d57SDmitri Gribenko 325dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 326dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 327dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3280e5d7b8cSRichard Smith } 3290e5d7b8cSRichard Smith } 3300e5d7b8cSRichard Smith 331f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 332de3ef502SDouglas Gregor OS.indent(Indent); 333de3ef502SDouglas Gregor if (IsFramework) 334de3ef502SDouglas Gregor OS << "framework "; 335de3ef502SDouglas Gregor if (IsExplicit) 336de3ef502SDouglas Gregor OS << "explicit "; 337a686e1b0SDouglas Gregor OS << "module " << Name; 338a686e1b0SDouglas Gregor 3397615f00eSBen Langmuir if (IsSystem || IsExternC) { 340a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3417615f00eSBen Langmuir if (IsSystem) 342a686e1b0SDouglas Gregor OS << " [system]"; 3437615f00eSBen Langmuir if (IsExternC) 3447615f00eSBen Langmuir OS << " [extern_c]"; 345a686e1b0SDouglas Gregor } 346a686e1b0SDouglas Gregor 347a686e1b0SDouglas Gregor OS << " {\n"; 348de3ef502SDouglas Gregor 349a3feee2aSRichard Smith if (!Requirements.empty()) { 3501fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3511fb5c3a6SDouglas Gregor OS << "requires "; 352a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3531fb5c3a6SDouglas Gregor if (I) 3541fb5c3a6SDouglas Gregor OS << ", "; 355a3feee2aSRichard Smith if (!Requirements[I].second) 356a3feee2aSRichard Smith OS << "!"; 357a3feee2aSRichard Smith OS << Requirements[I].first; 3581fb5c3a6SDouglas Gregor } 3591fb5c3a6SDouglas Gregor OS << "\n"; 3601fb5c3a6SDouglas Gregor } 3611fb5c3a6SDouglas Gregor 3622b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 363de3ef502SDouglas Gregor OS.indent(Indent + 2); 364322f633cSDouglas Gregor OS << "umbrella header \""; 3652b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 366de3ef502SDouglas Gregor OS << "\"\n"; 3672b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 368322f633cSDouglas Gregor OS.indent(Indent + 2); 369322f633cSDouglas Gregor OS << "umbrella \""; 3702b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 371322f633cSDouglas Gregor OS << "\"\n"; 372de3ef502SDouglas Gregor } 373de3ef502SDouglas Gregor 37435b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 37535b13eceSDouglas Gregor OS.indent(Indent + 2); 37635b13eceSDouglas Gregor OS << "config_macros "; 37735b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 3788d932427SDouglas Gregor OS << "[exhaustive]"; 37935b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 38035b13eceSDouglas Gregor if (I) 38135b13eceSDouglas Gregor OS << ", "; 38235b13eceSDouglas Gregor OS << ConfigMacros[I]; 38335b13eceSDouglas Gregor } 3848d932427SDouglas Gregor OS << "\n"; 38535b13eceSDouglas Gregor } 38635b13eceSDouglas Gregor 3873c1a41adSRichard Smith struct { 388306d8920SRichard Smith StringRef Prefix; 3893c1a41adSRichard Smith HeaderKind Kind; 3903c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 3913c1a41adSRichard Smith {"textual ", HK_Textual}, 3923c1a41adSRichard Smith {"private ", HK_Private}, 3933c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 3943c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 395306d8920SRichard Smith 396306d8920SRichard Smith for (auto &K : Kinds) { 397*040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 3983c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 399de3ef502SDouglas Gregor OS.indent(Indent + 2); 400306d8920SRichard Smith OS << K.Prefix << "header \""; 4013c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 402*040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 403*040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 404*040e1266SRichard Smith } 405*040e1266SRichard Smith } 406*040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 407*040e1266SRichard Smith for (auto &U : *Unresolved) { 408*040e1266SRichard Smith OS.indent(Indent + 2); 409*040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 410*040e1266SRichard Smith OS.write_escaped(U.FileName); 411*040e1266SRichard Smith OS << "\""; 412*040e1266SRichard Smith if (U.Size || U.ModTime) { 413*040e1266SRichard Smith OS << " {"; 414*040e1266SRichard Smith if (U.Size) 415*040e1266SRichard Smith OS << " size " << *U.Size; 416*040e1266SRichard Smith if (U.ModTime) 417*040e1266SRichard Smith OS << " mtime " << *U.ModTime; 418*040e1266SRichard Smith OS << " }"; 419*040e1266SRichard Smith } 420*040e1266SRichard Smith OS << "\n"; 421de3ef502SDouglas Gregor } 422b53e5483SLawrence Crowl } 423b53e5483SLawrence Crowl 424eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 425de3ef502SDouglas Gregor MI != MIEnd; ++MI) 4269d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4279d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4289d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4299d6448b1SBen Langmuir // those header files anyway. 4309d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 431eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 432de3ef502SDouglas Gregor 43324bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 43424bb923aSDouglas Gregor OS.indent(Indent + 2); 4358c7c8352SDouglas Gregor OS << "export "; 4368c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4378c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 43824bb923aSDouglas Gregor if (Exports[I].getInt()) 43924bb923aSDouglas Gregor OS << ".*"; 4408c7c8352SDouglas Gregor } else { 4418c7c8352SDouglas Gregor OS << "*"; 4428c7c8352SDouglas Gregor } 44324bb923aSDouglas Gregor OS << "\n"; 44424bb923aSDouglas Gregor } 44524bb923aSDouglas Gregor 44624bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 44724bb923aSDouglas Gregor OS.indent(Indent + 2); 44824bb923aSDouglas Gregor OS << "export "; 44924bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4507f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4517f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 45224bb923aSDouglas Gregor OS << "\n"; 45324bb923aSDouglas Gregor } 45424bb923aSDouglas Gregor 455ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 456ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 457ba7f2f71SDaniel Jasper OS << "use "; 458ba7f2f71SDaniel Jasper OS << DirectUses[I]->getFullModuleName(); 459ba7f2f71SDaniel Jasper OS << "\n"; 460ba7f2f71SDaniel Jasper } 461ba7f2f71SDaniel Jasper 462ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 463ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 464ba7f2f71SDaniel Jasper OS << "use "; 465ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 466ba7f2f71SDaniel Jasper OS << "\n"; 467ba7f2f71SDaniel Jasper } 468ba7f2f71SDaniel Jasper 4696ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 4706ddfca91SDouglas Gregor OS.indent(Indent + 2); 4716ddfca91SDouglas Gregor OS << "link "; 4726ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 4736ddfca91SDouglas Gregor OS << "framework "; 4746ddfca91SDouglas Gregor OS << "\""; 4756ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 4766ddfca91SDouglas Gregor OS << "\""; 4776ddfca91SDouglas Gregor } 4786ddfca91SDouglas Gregor 479fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 480fb912657SDouglas Gregor OS.indent(Indent + 2); 481fb912657SDouglas Gregor OS << "conflict "; 482fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 483fb912657SDouglas Gregor OS << ", \""; 484fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 485fb912657SDouglas Gregor OS << "\"\n"; 486fb912657SDouglas Gregor } 487fb912657SDouglas Gregor 488fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 489fb912657SDouglas Gregor OS.indent(Indent + 2); 490fb912657SDouglas Gregor OS << "conflict "; 491fb912657SDouglas Gregor OS << Conflicts[I].Other->getFullModuleName(); 492fb912657SDouglas Gregor OS << ", \""; 493fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 494fb912657SDouglas Gregor OS << "\"\n"; 495fb912657SDouglas Gregor } 496fb912657SDouglas Gregor 49773441091SDouglas Gregor if (InferSubmodules) { 49873441091SDouglas Gregor OS.indent(Indent + 2); 49973441091SDouglas Gregor if (InferExplicitSubmodules) 50073441091SDouglas Gregor OS << "explicit "; 50173441091SDouglas Gregor OS << "module * {\n"; 50273441091SDouglas Gregor if (InferExportWildcard) { 50373441091SDouglas Gregor OS.indent(Indent + 4); 50473441091SDouglas Gregor OS << "export *\n"; 50573441091SDouglas Gregor } 50673441091SDouglas Gregor OS.indent(Indent + 2); 50773441091SDouglas Gregor OS << "}\n"; 50873441091SDouglas Gregor } 50973441091SDouglas Gregor 510de3ef502SDouglas Gregor OS.indent(Indent); 511de3ef502SDouglas Gregor OS << "}\n"; 512de3ef502SDouglas Gregor } 513de3ef502SDouglas Gregor 514cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 515de3ef502SDouglas Gregor print(llvm::errs()); 516de3ef502SDouglas Gregor } 517de3ef502SDouglas Gregor 518a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 519a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 5206d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 521a7e2cc68SRichard Smith if (isVisible(M)) 522a7e2cc68SRichard Smith return; 523de3ef502SDouglas Gregor 524a7e2cc68SRichard Smith ++Generation; 525a7e2cc68SRichard Smith 526a7e2cc68SRichard Smith struct Visiting { 527a7e2cc68SRichard Smith Module *M; 528a7e2cc68SRichard Smith Visiting *ExportedBy; 529a7e2cc68SRichard Smith }; 530a7e2cc68SRichard Smith 531a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 532a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 533a7e2cc68SRichard Smith if (!V.M->isAvailable()) 534a7e2cc68SRichard Smith return; 535a7e2cc68SRichard Smith 536a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 537a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 538a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 539a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 540a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 541a7e2cc68SRichard Smith return; 542a7e2cc68SRichard Smith 543a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 544a7e2cc68SRichard Smith Vis(M); 545a7e2cc68SRichard Smith 546a7e2cc68SRichard Smith // Make any exported modules visible. 547a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 548a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 549a7e2cc68SRichard Smith for (Module *E : Exports) 550a7e2cc68SRichard Smith VisitModule({E, &V}); 551a7e2cc68SRichard Smith 552a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 553a7e2cc68SRichard Smith if (isVisible(C.Other)) { 554a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 555a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 556a7e2cc68SRichard Smith Path.push_back(I->M); 557a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 558a7e2cc68SRichard Smith } 559a7e2cc68SRichard Smith } 560a7e2cc68SRichard Smith }; 561a7e2cc68SRichard Smith VisitModule({M, nullptr}); 562a7e2cc68SRichard Smith } 563