1918e0ca7SEugene Zelenko //===- 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" 169565c75bSRichard Smith #include "clang/Basic/CharInfo.h" 17de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h" 181fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h" 19918e0ca7SEugene Zelenko #include "clang/Basic/SourceLocation.h" 200070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 213c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h" 221fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 23918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h" 24918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h" 251fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 26918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h" 273a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 283a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 29918e0ca7SEugene Zelenko #include <algorithm> 30918e0ca7SEugene Zelenko #include <cassert> 31918e0ca7SEugene Zelenko #include <functional> 32918e0ca7SEugene Zelenko #include <string> 33918e0ca7SEugene Zelenko #include <utility> 34918e0ca7SEugene Zelenko #include <vector> 35a3feee2aSRichard Smith 36de3ef502SDouglas Gregor using namespace clang; 37de3ef502SDouglas Gregor 38eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 39a7e2cc68SRichard Smith bool IsFramework, bool IsExplicit, unsigned VisibilityID) 40918e0ca7SEugene Zelenko : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 41918e0ca7SEugene Zelenko VisibilityID(VisibilityID), IsMissingRequirement(false), 42918e0ca7SEugene Zelenko HasIncompatibleModuleFile(false), IsAvailable(true), 43918e0ca7SEugene Zelenko IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), 44918e0ca7SEugene Zelenko IsSystem(false), IsExternC(false), IsInferred(false), 45918e0ca7SEugene Zelenko InferSubmodules(false), InferExplicitSubmodules(false), 468a308ec2SRichard Smith InferExportWildcard(false), ConfigMacrosExhaustive(false), 47e6b7c28dSDavid Blaikie NoUndeclaredIncludes(false), NameVisibility(Hidden) { 48eb90e830SDouglas Gregor if (Parent) { 49eb90e830SDouglas Gregor if (!Parent->isAvailable()) 50eb90e830SDouglas Gregor IsAvailable = false; 513ec6663bSDouglas Gregor if (Parent->IsSystem) 523ec6663bSDouglas Gregor IsSystem = true; 539bca298fSRichard Smith if (Parent->IsExternC) 549bca298fSRichard Smith IsExternC = true; 55ed84df00SBruno Cardoso Lopes if (Parent->NoUndeclaredIncludes) 56ed84df00SBruno Cardoso Lopes NoUndeclaredIncludes = true; 57993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 58eb90e830SDouglas Gregor 59eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 60eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 61eb90e830SDouglas Gregor } 62eb90e830SDouglas Gregor } 63eb90e830SDouglas Gregor 64de3ef502SDouglas Gregor Module::~Module() { 65eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 66de3ef502SDouglas Gregor I != IEnd; ++I) { 67eb90e830SDouglas Gregor delete *I; 68de3ef502SDouglas Gregor } 69de3ef502SDouglas Gregor } 70de3ef502SDouglas Gregor 711fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 721fb5c3a6SDouglas Gregor /// language options has the given feature. 7389929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 7489929282SDouglas Gregor const TargetInfo &Target) { 75532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 760070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 771fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 78e38cea02SEric Fiselier .Case("coroutines", LangOpts.CoroutinesTS) 791fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 802bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 81fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 826736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 831fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 841fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 850070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 860070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 873c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 880070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 89532d2104SBen Langmuir if (!HasFeature) 90532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 91532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 92532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 93532d2104SBen Langmuir return HasFeature; 941fb5c3a6SDouglas Gregor } 951fb5c3a6SDouglas Gregor 963c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 973c1a41adSRichard Smith Requirement &Req, 98*8587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader, 99*8587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const { 1001fb5c3a6SDouglas Gregor if (IsAvailable) 1011fb5c3a6SDouglas Gregor return true; 1021fb5c3a6SDouglas Gregor 1031fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 104*8587dfd9SBruno Cardoso Lopes if (Current->ShadowingModule) { 105*8587dfd9SBruno Cardoso Lopes ShadowingModule = Current->ShadowingModule; 106*8587dfd9SBruno Cardoso Lopes return false; 107*8587dfd9SBruno Cardoso Lopes } 108a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 109a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 110a3feee2aSRichard Smith Current->Requirements[I].second) { 111a3feee2aSRichard Smith Req = Current->Requirements[I]; 1121fb5c3a6SDouglas Gregor return false; 1131fb5c3a6SDouglas Gregor } 1141fb5c3a6SDouglas Gregor } 11575a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 11675a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 11775a7e435SBen Langmuir return false; 11875a7e435SBen Langmuir } 1191fb5c3a6SDouglas Gregor } 1201fb5c3a6SDouglas Gregor 1211fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1221fb5c3a6SDouglas Gregor } 1231fb5c3a6SDouglas Gregor 12462bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 125f5eedd05SDouglas Gregor const Module *This = this; 126f5eedd05SDouglas Gregor do { 127f5eedd05SDouglas Gregor if (This == Other) 128f5eedd05SDouglas Gregor return true; 129f5eedd05SDouglas Gregor 130f5eedd05SDouglas Gregor This = This->Parent; 131f5eedd05SDouglas Gregor } while (This); 132f5eedd05SDouglas Gregor 133f5eedd05SDouglas Gregor return false; 134f5eedd05SDouglas Gregor } 135f5eedd05SDouglas Gregor 13673441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 13773441091SDouglas Gregor const Module *Result = this; 13873441091SDouglas Gregor while (Result->Parent) 13973441091SDouglas Gregor Result = Result->Parent; 14073441091SDouglas Gregor 14173441091SDouglas Gregor return Result; 14273441091SDouglas Gregor } 14373441091SDouglas Gregor 1449565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1459565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1469565c75bSRichard Smith return IdComponent.first; 1479565c75bSRichard Smith } 148918e0ca7SEugene Zelenko 1499565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1509565c75bSRichard Smith 1519565c75bSRichard Smith template<typename InputIter> 1529565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1539565c75bSRichard Smith bool AllowStringLiterals = true) { 1549565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1559565c75bSRichard Smith if (It != Begin) 1569565c75bSRichard Smith OS << "."; 1579565c75bSRichard Smith 1589565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1599565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 1609565c75bSRichard Smith OS << Name; 1619565c75bSRichard Smith else { 1629565c75bSRichard Smith OS << '"'; 1639565c75bSRichard Smith OS.write_escaped(Name); 1649565c75bSRichard Smith OS << '"'; 1659565c75bSRichard Smith } 1669565c75bSRichard Smith } 1679565c75bSRichard Smith } 1689565c75bSRichard Smith 1699565c75bSRichard Smith template<typename Container> 1709565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 1719565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 1729565c75bSRichard Smith } 1739565c75bSRichard Smith 1749565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 175f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 176de3ef502SDouglas Gregor 177de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 178de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 179de3ef502SDouglas Gregor Names.push_back(M->Name); 180de3ef502SDouglas Gregor 181de3ef502SDouglas Gregor std::string Result; 182de3ef502SDouglas Gregor 1839565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 1849565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 1859565c75bSRichard Smith Out.flush(); 186de3ef502SDouglas Gregor 187de3ef502SDouglas Gregor return Result; 188de3ef502SDouglas Gregor } 189de3ef502SDouglas Gregor 1907ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1917ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1927ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1937ff29148SBen Langmuir return false; 1947ff29148SBen Langmuir nameParts = nameParts.drop_back(); 1957ff29148SBen Langmuir } 1967ff29148SBen Langmuir return nameParts.empty(); 1977ff29148SBen Langmuir } 1987ff29148SBen Langmuir 1992b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 2002b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 2012b63d15fSRichard Smith return {"", U.Entry->getDir()}; 20273141fa9SDouglas Gregor 2032b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 20473141fa9SDouglas Gregor } 20573141fa9SDouglas Gregor 2063c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2073c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2083c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2093c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2103c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 2113c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 2123c5305c1SArgyrios Kyrtzidis } 2133c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2143c5305c1SArgyrios Kyrtzidis } 2153c5305c1SArgyrios Kyrtzidis 2163c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2173c5305c1SArgyrios Kyrtzidis } 2183c5305c1SArgyrios Kyrtzidis 2198f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2208f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2218f4d3ff1SRichard Smith 2228f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2238f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2248f4d3ff1SRichard Smith return true; 2258f4d3ff1SRichard Smith 2268f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2278f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2288f4d3ff1SRichard Smith return true; 229ed84df00SBruno Cardoso Lopes 230ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 231ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 232ed84df00SBruno Cardoso Lopes return true; 233ed84df00SBruno Cardoso Lopes 2348f4d3ff1SRichard Smith return false; 2358f4d3ff1SRichard Smith } 2368f4d3ff1SRichard Smith 237a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 238a3feee2aSRichard Smith const LangOptions &LangOpts, 23989929282SDouglas Gregor const TargetInfo &Target) { 240a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 2411fb5c3a6SDouglas Gregor 2421fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 243a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2441fb5c3a6SDouglas Gregor return; 2451fb5c3a6SDouglas Gregor 246993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 247ec8c9752SBen Langmuir } 248ec8c9752SBen Langmuir 249993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 25075a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 25175a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 25275a7e435SBen Langmuir }; 25375a7e435SBen Langmuir 25475a7e435SBen Langmuir if (!needUpdate(this)) 2551fb5c3a6SDouglas Gregor return; 2561fb5c3a6SDouglas Gregor 257f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2581fb5c3a6SDouglas Gregor Stack.push_back(this); 2591fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2601fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2611fb5c3a6SDouglas Gregor Stack.pop_back(); 2621fb5c3a6SDouglas Gregor 26375a7e435SBen Langmuir if (!needUpdate(Current)) 2641fb5c3a6SDouglas Gregor continue; 2651fb5c3a6SDouglas Gregor 2661fb5c3a6SDouglas Gregor Current->IsAvailable = false; 267993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 268eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 269eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2701fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 27175a7e435SBen Langmuir if (needUpdate(*Sub)) 272eb90e830SDouglas Gregor Stack.push_back(*Sub); 2731fb5c3a6SDouglas Gregor } 2741fb5c3a6SDouglas Gregor } 2751fb5c3a6SDouglas Gregor } 2761fb5c3a6SDouglas Gregor 277eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 278eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 279eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 280f1186c5aSCraig Topper return nullptr; 281eb90e830SDouglas Gregor 282eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 283eb90e830SDouglas Gregor } 284eb90e830SDouglas Gregor 2858739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 286e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 287e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 288e9bcf5b7SDmitri Gribenko E = SubModules.end(); 289e9bcf5b7SDmitri Gribenko I != E; ++I) { 290e9bcf5b7SDmitri Gribenko Module *Mod = *I; 291e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 292e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 293e9bcf5b7SDmitri Gribenko } 294e9bcf5b7SDmitri Gribenko 295e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2968739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2978739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2988739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2998739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 3008739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 3018739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 3028739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 3038739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3048739f7b7SArgyrios Kyrtzidis 3058739f7b7SArgyrios Kyrtzidis continue; 3068739f7b7SArgyrios Kyrtzidis } 3078739f7b7SArgyrios Kyrtzidis 3088739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3098739f7b7SArgyrios Kyrtzidis // the given pattern. 3108739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3118739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3128739f7b7SArgyrios Kyrtzidis continue; 3138739f7b7SArgyrios Kyrtzidis 3148739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3158739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3168739f7b7SArgyrios Kyrtzidis else { 3178739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3188739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3198739f7b7SArgyrios Kyrtzidis } 3208739f7b7SArgyrios Kyrtzidis } 3218739f7b7SArgyrios Kyrtzidis 3228739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3238739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3248739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3258739f7b7SArgyrios Kyrtzidis return; 3268739f7b7SArgyrios Kyrtzidis 3278739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3288739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3298739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3308739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3318739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3328739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3338739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3348739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3358739f7b7SArgyrios Kyrtzidis Acceptable = true; 3368739f7b7SArgyrios Kyrtzidis break; 3378739f7b7SArgyrios Kyrtzidis } 3388739f7b7SArgyrios Kyrtzidis } 3398739f7b7SArgyrios Kyrtzidis } 3408739f7b7SArgyrios Kyrtzidis 3418739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3428739f7b7SArgyrios Kyrtzidis continue; 3438739f7b7SArgyrios Kyrtzidis 3448739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3458739f7b7SArgyrios Kyrtzidis } 3468739f7b7SArgyrios Kyrtzidis } 3478739f7b7SArgyrios Kyrtzidis 3480e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3490e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3500e5d7b8cSRichard Smith 3510e5d7b8cSRichard Smith // This module is visible to itself. 3520e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3530e5d7b8cSRichard Smith 3540e5d7b8cSRichard Smith // Every imported module is visible. 355dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 356dc360d57SDmitri Gribenko while (!Stack.empty()) { 357dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 358dc360d57SDmitri Gribenko 359dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 360dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 361dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3620e5d7b8cSRichard Smith } 3630e5d7b8cSRichard Smith } 3640e5d7b8cSRichard Smith 365f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 366de3ef502SDouglas Gregor OS.indent(Indent); 367de3ef502SDouglas Gregor if (IsFramework) 368de3ef502SDouglas Gregor OS << "framework "; 369de3ef502SDouglas Gregor if (IsExplicit) 370de3ef502SDouglas Gregor OS << "explicit "; 3719565c75bSRichard Smith OS << "module "; 3729565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 373a686e1b0SDouglas Gregor 3747615f00eSBen Langmuir if (IsSystem || IsExternC) { 375a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3767615f00eSBen Langmuir if (IsSystem) 377a686e1b0SDouglas Gregor OS << " [system]"; 3787615f00eSBen Langmuir if (IsExternC) 3797615f00eSBen Langmuir OS << " [extern_c]"; 380a686e1b0SDouglas Gregor } 381a686e1b0SDouglas Gregor 382a686e1b0SDouglas Gregor OS << " {\n"; 383de3ef502SDouglas Gregor 384a3feee2aSRichard Smith if (!Requirements.empty()) { 3851fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3861fb5c3a6SDouglas Gregor OS << "requires "; 387a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3881fb5c3a6SDouglas Gregor if (I) 3891fb5c3a6SDouglas Gregor OS << ", "; 390a3feee2aSRichard Smith if (!Requirements[I].second) 391a3feee2aSRichard Smith OS << "!"; 392a3feee2aSRichard Smith OS << Requirements[I].first; 3931fb5c3a6SDouglas Gregor } 3941fb5c3a6SDouglas Gregor OS << "\n"; 3951fb5c3a6SDouglas Gregor } 3961fb5c3a6SDouglas Gregor 3972b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 398de3ef502SDouglas Gregor OS.indent(Indent + 2); 399322f633cSDouglas Gregor OS << "umbrella header \""; 4002b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 401de3ef502SDouglas Gregor OS << "\"\n"; 4022b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 403322f633cSDouglas Gregor OS.indent(Indent + 2); 404322f633cSDouglas Gregor OS << "umbrella \""; 4052b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 406322f633cSDouglas Gregor OS << "\"\n"; 407de3ef502SDouglas Gregor } 408de3ef502SDouglas Gregor 40935b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 41035b13eceSDouglas Gregor OS.indent(Indent + 2); 41135b13eceSDouglas Gregor OS << "config_macros "; 41235b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4138d932427SDouglas Gregor OS << "[exhaustive]"; 41435b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 41535b13eceSDouglas Gregor if (I) 41635b13eceSDouglas Gregor OS << ", "; 41735b13eceSDouglas Gregor OS << ConfigMacros[I]; 41835b13eceSDouglas Gregor } 4198d932427SDouglas Gregor OS << "\n"; 42035b13eceSDouglas Gregor } 42135b13eceSDouglas Gregor 4223c1a41adSRichard Smith struct { 423306d8920SRichard Smith StringRef Prefix; 4243c1a41adSRichard Smith HeaderKind Kind; 4253c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4263c1a41adSRichard Smith {"textual ", HK_Textual}, 4273c1a41adSRichard Smith {"private ", HK_Private}, 4283c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4293c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 430306d8920SRichard Smith 431306d8920SRichard Smith for (auto &K : Kinds) { 432040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4333c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 434de3ef502SDouglas Gregor OS.indent(Indent + 2); 435306d8920SRichard Smith OS << K.Prefix << "header \""; 4363c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 437040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 438040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 439040e1266SRichard Smith } 440040e1266SRichard Smith } 441040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 442040e1266SRichard Smith for (auto &U : *Unresolved) { 443040e1266SRichard Smith OS.indent(Indent + 2); 444040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 445040e1266SRichard Smith OS.write_escaped(U.FileName); 446040e1266SRichard Smith OS << "\""; 447040e1266SRichard Smith if (U.Size || U.ModTime) { 448040e1266SRichard Smith OS << " {"; 449040e1266SRichard Smith if (U.Size) 450040e1266SRichard Smith OS << " size " << *U.Size; 451040e1266SRichard Smith if (U.ModTime) 452040e1266SRichard Smith OS << " mtime " << *U.ModTime; 453040e1266SRichard Smith OS << " }"; 454040e1266SRichard Smith } 455040e1266SRichard Smith OS << "\n"; 456de3ef502SDouglas Gregor } 457b53e5483SLawrence Crowl } 458b53e5483SLawrence Crowl 459f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 460f0b11de2SDouglas Gregor OS.indent(Indent + 2); 461f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 462f0b11de2SDouglas Gregor } 463f0b11de2SDouglas Gregor 464eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 465de3ef502SDouglas Gregor MI != MIEnd; ++MI) 4669d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4679d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4689d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4699d6448b1SBen Langmuir // those header files anyway. 4709d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 471eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 472de3ef502SDouglas Gregor 47324bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 47424bb923aSDouglas Gregor OS.indent(Indent + 2); 4758c7c8352SDouglas Gregor OS << "export "; 4768c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4779565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 47824bb923aSDouglas Gregor if (Exports[I].getInt()) 47924bb923aSDouglas Gregor OS << ".*"; 4808c7c8352SDouglas Gregor } else { 4818c7c8352SDouglas Gregor OS << "*"; 4828c7c8352SDouglas Gregor } 48324bb923aSDouglas Gregor OS << "\n"; 48424bb923aSDouglas Gregor } 48524bb923aSDouglas Gregor 48624bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 48724bb923aSDouglas Gregor OS.indent(Indent + 2); 48824bb923aSDouglas Gregor OS << "export "; 48924bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4907f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4917f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 49224bb923aSDouglas Gregor OS << "\n"; 49324bb923aSDouglas Gregor } 49424bb923aSDouglas Gregor 495ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 496ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 497ba7f2f71SDaniel Jasper OS << "use "; 4989565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 499ba7f2f71SDaniel Jasper OS << "\n"; 500ba7f2f71SDaniel Jasper } 501ba7f2f71SDaniel Jasper 502ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 503ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 504ba7f2f71SDaniel Jasper OS << "use "; 505ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 506ba7f2f71SDaniel Jasper OS << "\n"; 507ba7f2f71SDaniel Jasper } 508ba7f2f71SDaniel Jasper 5096ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5106ddfca91SDouglas Gregor OS.indent(Indent + 2); 5116ddfca91SDouglas Gregor OS << "link "; 5126ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5136ddfca91SDouglas Gregor OS << "framework "; 5146ddfca91SDouglas Gregor OS << "\""; 5156ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5166ddfca91SDouglas Gregor OS << "\""; 5176ddfca91SDouglas Gregor } 5186ddfca91SDouglas Gregor 519fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 520fb912657SDouglas Gregor OS.indent(Indent + 2); 521fb912657SDouglas Gregor OS << "conflict "; 522fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 523fb912657SDouglas Gregor OS << ", \""; 524fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 525fb912657SDouglas Gregor OS << "\"\n"; 526fb912657SDouglas Gregor } 527fb912657SDouglas Gregor 528fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 529fb912657SDouglas Gregor OS.indent(Indent + 2); 530fb912657SDouglas Gregor OS << "conflict "; 5319565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 532fb912657SDouglas Gregor OS << ", \""; 533fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 534fb912657SDouglas Gregor OS << "\"\n"; 535fb912657SDouglas Gregor } 536fb912657SDouglas Gregor 53773441091SDouglas Gregor if (InferSubmodules) { 53873441091SDouglas Gregor OS.indent(Indent + 2); 53973441091SDouglas Gregor if (InferExplicitSubmodules) 54073441091SDouglas Gregor OS << "explicit "; 54173441091SDouglas Gregor OS << "module * {\n"; 54273441091SDouglas Gregor if (InferExportWildcard) { 54373441091SDouglas Gregor OS.indent(Indent + 4); 54473441091SDouglas Gregor OS << "export *\n"; 54573441091SDouglas Gregor } 54673441091SDouglas Gregor OS.indent(Indent + 2); 54773441091SDouglas Gregor OS << "}\n"; 54873441091SDouglas Gregor } 54973441091SDouglas Gregor 550de3ef502SDouglas Gregor OS.indent(Indent); 551de3ef502SDouglas Gregor OS << "}\n"; 552de3ef502SDouglas Gregor } 553de3ef502SDouglas Gregor 554cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 555de3ef502SDouglas Gregor print(llvm::errs()); 556de3ef502SDouglas Gregor } 557de3ef502SDouglas Gregor 558a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 559a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 5606d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 561a7e2cc68SRichard Smith if (isVisible(M)) 562a7e2cc68SRichard Smith return; 563de3ef502SDouglas Gregor 564a7e2cc68SRichard Smith ++Generation; 565a7e2cc68SRichard Smith 566a7e2cc68SRichard Smith struct Visiting { 567a7e2cc68SRichard Smith Module *M; 568a7e2cc68SRichard Smith Visiting *ExportedBy; 569a7e2cc68SRichard Smith }; 570a7e2cc68SRichard Smith 571a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 572a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 573a7e2cc68SRichard Smith if (!V.M->isAvailable()) 574a7e2cc68SRichard Smith return; 575a7e2cc68SRichard Smith 576a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 577a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 578a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 579a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 580a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 581a7e2cc68SRichard Smith return; 582a7e2cc68SRichard Smith 583a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 584a7e2cc68SRichard Smith Vis(M); 585a7e2cc68SRichard Smith 586a7e2cc68SRichard Smith // Make any exported modules visible. 587a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 588a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 589a7e2cc68SRichard Smith for (Module *E : Exports) 590a7e2cc68SRichard Smith VisitModule({E, &V}); 591a7e2cc68SRichard Smith 592a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 593a7e2cc68SRichard Smith if (isVisible(C.Other)) { 594a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 595a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 596a7e2cc68SRichard Smith Path.push_back(I->M); 597a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 598a7e2cc68SRichard Smith } 599a7e2cc68SRichard Smith } 600a7e2cc68SRichard Smith }; 601a7e2cc68SRichard Smith VisitModule({M, nullptr}); 602a7e2cc68SRichard Smith } 603