1*918e0ca7SEugene 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" 19*918e0ca7SEugene 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" 23*918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h" 24*918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h" 251fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 26*918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h" 273a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 283a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 29*918e0ca7SEugene Zelenko #include <algorithm> 30*918e0ca7SEugene Zelenko #include <cassert> 31*918e0ca7SEugene Zelenko #include <functional> 32*918e0ca7SEugene Zelenko #include <string> 33*918e0ca7SEugene Zelenko #include <utility> 34*918e0ca7SEugene 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) 40*918e0ca7SEugene Zelenko : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 41*918e0ca7SEugene Zelenko VisibilityID(VisibilityID), IsMissingRequirement(false), 42*918e0ca7SEugene Zelenko HasIncompatibleModuleFile(false), IsAvailable(true), 43*918e0ca7SEugene Zelenko IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), 44*918e0ca7SEugene Zelenko IsSystem(false), IsExternC(false), IsInferred(false), 45*918e0ca7SEugene 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, 983c1a41adSRichard Smith UnresolvedHeaderDirective &MissingHeader) const { 991fb5c3a6SDouglas Gregor if (IsAvailable) 1001fb5c3a6SDouglas Gregor return true; 1011fb5c3a6SDouglas Gregor 1021fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 103a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 104a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 105a3feee2aSRichard Smith Current->Requirements[I].second) { 106a3feee2aSRichard Smith Req = Current->Requirements[I]; 1071fb5c3a6SDouglas Gregor return false; 1081fb5c3a6SDouglas Gregor } 1091fb5c3a6SDouglas Gregor } 11075a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 11175a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 11275a7e435SBen Langmuir return false; 11375a7e435SBen Langmuir } 1141fb5c3a6SDouglas Gregor } 1151fb5c3a6SDouglas Gregor 1161fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1171fb5c3a6SDouglas Gregor } 1181fb5c3a6SDouglas Gregor 11962bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 120f5eedd05SDouglas Gregor const Module *This = this; 121f5eedd05SDouglas Gregor do { 122f5eedd05SDouglas Gregor if (This == Other) 123f5eedd05SDouglas Gregor return true; 124f5eedd05SDouglas Gregor 125f5eedd05SDouglas Gregor This = This->Parent; 126f5eedd05SDouglas Gregor } while (This); 127f5eedd05SDouglas Gregor 128f5eedd05SDouglas Gregor return false; 129f5eedd05SDouglas Gregor } 130f5eedd05SDouglas Gregor 13173441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 13273441091SDouglas Gregor const Module *Result = this; 13373441091SDouglas Gregor while (Result->Parent) 13473441091SDouglas Gregor Result = Result->Parent; 13573441091SDouglas Gregor 13673441091SDouglas Gregor return Result; 13773441091SDouglas Gregor } 13873441091SDouglas Gregor 1399565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1409565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1419565c75bSRichard Smith return IdComponent.first; 1429565c75bSRichard Smith } 143*918e0ca7SEugene Zelenko 1449565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1459565c75bSRichard Smith 1469565c75bSRichard Smith template<typename InputIter> 1479565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1489565c75bSRichard Smith bool AllowStringLiterals = true) { 1499565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1509565c75bSRichard Smith if (It != Begin) 1519565c75bSRichard Smith OS << "."; 1529565c75bSRichard Smith 1539565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1549565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 1559565c75bSRichard Smith OS << Name; 1569565c75bSRichard Smith else { 1579565c75bSRichard Smith OS << '"'; 1589565c75bSRichard Smith OS.write_escaped(Name); 1599565c75bSRichard Smith OS << '"'; 1609565c75bSRichard Smith } 1619565c75bSRichard Smith } 1629565c75bSRichard Smith } 1639565c75bSRichard Smith 1649565c75bSRichard Smith template<typename Container> 1659565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 1669565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 1679565c75bSRichard Smith } 1689565c75bSRichard Smith 1699565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 170f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 171de3ef502SDouglas Gregor 172de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 173de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 174de3ef502SDouglas Gregor Names.push_back(M->Name); 175de3ef502SDouglas Gregor 176de3ef502SDouglas Gregor std::string Result; 177de3ef502SDouglas Gregor 1789565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 1799565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 1809565c75bSRichard Smith Out.flush(); 181de3ef502SDouglas Gregor 182de3ef502SDouglas Gregor return Result; 183de3ef502SDouglas Gregor } 184de3ef502SDouglas Gregor 1857ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1867ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1877ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1887ff29148SBen Langmuir return false; 1897ff29148SBen Langmuir nameParts = nameParts.drop_back(); 1907ff29148SBen Langmuir } 1917ff29148SBen Langmuir return nameParts.empty(); 1927ff29148SBen Langmuir } 1937ff29148SBen Langmuir 1942b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 1952b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 1962b63d15fSRichard Smith return {"", U.Entry->getDir()}; 19773141fa9SDouglas Gregor 1982b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 19973141fa9SDouglas Gregor } 20073141fa9SDouglas Gregor 2013c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2023c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2033c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2043c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2053c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 2063c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 2073c5305c1SArgyrios Kyrtzidis } 2083c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2093c5305c1SArgyrios Kyrtzidis } 2103c5305c1SArgyrios Kyrtzidis 2113c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2123c5305c1SArgyrios Kyrtzidis } 2133c5305c1SArgyrios Kyrtzidis 2148f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2158f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2168f4d3ff1SRichard Smith 2178f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2188f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2198f4d3ff1SRichard Smith return true; 2208f4d3ff1SRichard Smith 2218f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2228f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2238f4d3ff1SRichard Smith return true; 224ed84df00SBruno Cardoso Lopes 225ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 226ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 227ed84df00SBruno Cardoso Lopes return true; 228ed84df00SBruno Cardoso Lopes 2298f4d3ff1SRichard Smith return false; 2308f4d3ff1SRichard Smith } 2318f4d3ff1SRichard Smith 232a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 233a3feee2aSRichard Smith const LangOptions &LangOpts, 23489929282SDouglas Gregor const TargetInfo &Target) { 235a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 2361fb5c3a6SDouglas Gregor 2371fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 238a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2391fb5c3a6SDouglas Gregor return; 2401fb5c3a6SDouglas Gregor 241993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 242ec8c9752SBen Langmuir } 243ec8c9752SBen Langmuir 244993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 24575a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 24675a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 24775a7e435SBen Langmuir }; 24875a7e435SBen Langmuir 24975a7e435SBen Langmuir if (!needUpdate(this)) 2501fb5c3a6SDouglas Gregor return; 2511fb5c3a6SDouglas Gregor 252f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2531fb5c3a6SDouglas Gregor Stack.push_back(this); 2541fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2551fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2561fb5c3a6SDouglas Gregor Stack.pop_back(); 2571fb5c3a6SDouglas Gregor 25875a7e435SBen Langmuir if (!needUpdate(Current)) 2591fb5c3a6SDouglas Gregor continue; 2601fb5c3a6SDouglas Gregor 2611fb5c3a6SDouglas Gregor Current->IsAvailable = false; 262993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 263eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 264eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2651fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 26675a7e435SBen Langmuir if (needUpdate(*Sub)) 267eb90e830SDouglas Gregor Stack.push_back(*Sub); 2681fb5c3a6SDouglas Gregor } 2691fb5c3a6SDouglas Gregor } 2701fb5c3a6SDouglas Gregor } 2711fb5c3a6SDouglas Gregor 272eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 273eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 274eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 275f1186c5aSCraig Topper return nullptr; 276eb90e830SDouglas Gregor 277eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 278eb90e830SDouglas Gregor } 279eb90e830SDouglas Gregor 2808739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 281e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 282e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 283e9bcf5b7SDmitri Gribenko E = SubModules.end(); 284e9bcf5b7SDmitri Gribenko I != E; ++I) { 285e9bcf5b7SDmitri Gribenko Module *Mod = *I; 286e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 287e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 288e9bcf5b7SDmitri Gribenko } 289e9bcf5b7SDmitri Gribenko 290e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2918739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2928739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2938739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2948739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2958739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2968739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2978739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2988739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2998739f7b7SArgyrios Kyrtzidis 3008739f7b7SArgyrios Kyrtzidis continue; 3018739f7b7SArgyrios Kyrtzidis } 3028739f7b7SArgyrios Kyrtzidis 3038739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3048739f7b7SArgyrios Kyrtzidis // the given pattern. 3058739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3068739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3078739f7b7SArgyrios Kyrtzidis continue; 3088739f7b7SArgyrios Kyrtzidis 3098739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3108739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3118739f7b7SArgyrios Kyrtzidis else { 3128739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3138739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3148739f7b7SArgyrios Kyrtzidis } 3158739f7b7SArgyrios Kyrtzidis } 3168739f7b7SArgyrios Kyrtzidis 3178739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3188739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3198739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3208739f7b7SArgyrios Kyrtzidis return; 3218739f7b7SArgyrios Kyrtzidis 3228739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3238739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3248739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3258739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3268739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3278739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3288739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3298739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3308739f7b7SArgyrios Kyrtzidis Acceptable = true; 3318739f7b7SArgyrios Kyrtzidis break; 3328739f7b7SArgyrios Kyrtzidis } 3338739f7b7SArgyrios Kyrtzidis } 3348739f7b7SArgyrios Kyrtzidis } 3358739f7b7SArgyrios Kyrtzidis 3368739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3378739f7b7SArgyrios Kyrtzidis continue; 3388739f7b7SArgyrios Kyrtzidis 3398739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3408739f7b7SArgyrios Kyrtzidis } 3418739f7b7SArgyrios Kyrtzidis } 3428739f7b7SArgyrios Kyrtzidis 3430e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3440e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3450e5d7b8cSRichard Smith 3460e5d7b8cSRichard Smith // This module is visible to itself. 3470e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3480e5d7b8cSRichard Smith 3490e5d7b8cSRichard Smith // Every imported module is visible. 350dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 351dc360d57SDmitri Gribenko while (!Stack.empty()) { 352dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 353dc360d57SDmitri Gribenko 354dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 355dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 356dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3570e5d7b8cSRichard Smith } 3580e5d7b8cSRichard Smith } 3590e5d7b8cSRichard Smith 360f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 361de3ef502SDouglas Gregor OS.indent(Indent); 362de3ef502SDouglas Gregor if (IsFramework) 363de3ef502SDouglas Gregor OS << "framework "; 364de3ef502SDouglas Gregor if (IsExplicit) 365de3ef502SDouglas Gregor OS << "explicit "; 3669565c75bSRichard Smith OS << "module "; 3679565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 368a686e1b0SDouglas Gregor 3697615f00eSBen Langmuir if (IsSystem || IsExternC) { 370a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3717615f00eSBen Langmuir if (IsSystem) 372a686e1b0SDouglas Gregor OS << " [system]"; 3737615f00eSBen Langmuir if (IsExternC) 3747615f00eSBen Langmuir OS << " [extern_c]"; 375a686e1b0SDouglas Gregor } 376a686e1b0SDouglas Gregor 377a686e1b0SDouglas Gregor OS << " {\n"; 378de3ef502SDouglas Gregor 379a3feee2aSRichard Smith if (!Requirements.empty()) { 3801fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3811fb5c3a6SDouglas Gregor OS << "requires "; 382a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3831fb5c3a6SDouglas Gregor if (I) 3841fb5c3a6SDouglas Gregor OS << ", "; 385a3feee2aSRichard Smith if (!Requirements[I].second) 386a3feee2aSRichard Smith OS << "!"; 387a3feee2aSRichard Smith OS << Requirements[I].first; 3881fb5c3a6SDouglas Gregor } 3891fb5c3a6SDouglas Gregor OS << "\n"; 3901fb5c3a6SDouglas Gregor } 3911fb5c3a6SDouglas Gregor 3922b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 393de3ef502SDouglas Gregor OS.indent(Indent + 2); 394322f633cSDouglas Gregor OS << "umbrella header \""; 3952b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 396de3ef502SDouglas Gregor OS << "\"\n"; 3972b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 398322f633cSDouglas Gregor OS.indent(Indent + 2); 399322f633cSDouglas Gregor OS << "umbrella \""; 4002b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 401322f633cSDouglas Gregor OS << "\"\n"; 402de3ef502SDouglas Gregor } 403de3ef502SDouglas Gregor 40435b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 40535b13eceSDouglas Gregor OS.indent(Indent + 2); 40635b13eceSDouglas Gregor OS << "config_macros "; 40735b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4088d932427SDouglas Gregor OS << "[exhaustive]"; 40935b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 41035b13eceSDouglas Gregor if (I) 41135b13eceSDouglas Gregor OS << ", "; 41235b13eceSDouglas Gregor OS << ConfigMacros[I]; 41335b13eceSDouglas Gregor } 4148d932427SDouglas Gregor OS << "\n"; 41535b13eceSDouglas Gregor } 41635b13eceSDouglas Gregor 4173c1a41adSRichard Smith struct { 418306d8920SRichard Smith StringRef Prefix; 4193c1a41adSRichard Smith HeaderKind Kind; 4203c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4213c1a41adSRichard Smith {"textual ", HK_Textual}, 4223c1a41adSRichard Smith {"private ", HK_Private}, 4233c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4243c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 425306d8920SRichard Smith 426306d8920SRichard Smith for (auto &K : Kinds) { 427040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4283c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 429de3ef502SDouglas Gregor OS.indent(Indent + 2); 430306d8920SRichard Smith OS << K.Prefix << "header \""; 4313c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 432040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 433040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 434040e1266SRichard Smith } 435040e1266SRichard Smith } 436040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 437040e1266SRichard Smith for (auto &U : *Unresolved) { 438040e1266SRichard Smith OS.indent(Indent + 2); 439040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 440040e1266SRichard Smith OS.write_escaped(U.FileName); 441040e1266SRichard Smith OS << "\""; 442040e1266SRichard Smith if (U.Size || U.ModTime) { 443040e1266SRichard Smith OS << " {"; 444040e1266SRichard Smith if (U.Size) 445040e1266SRichard Smith OS << " size " << *U.Size; 446040e1266SRichard Smith if (U.ModTime) 447040e1266SRichard Smith OS << " mtime " << *U.ModTime; 448040e1266SRichard Smith OS << " }"; 449040e1266SRichard Smith } 450040e1266SRichard Smith OS << "\n"; 451de3ef502SDouglas Gregor } 452b53e5483SLawrence Crowl } 453b53e5483SLawrence Crowl 454f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 455f0b11de2SDouglas Gregor OS.indent(Indent + 2); 456f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 457f0b11de2SDouglas Gregor } 458f0b11de2SDouglas Gregor 459eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 460de3ef502SDouglas Gregor MI != MIEnd; ++MI) 4619d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4629d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4639d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4649d6448b1SBen Langmuir // those header files anyway. 4659d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 466eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 467de3ef502SDouglas Gregor 46824bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 46924bb923aSDouglas Gregor OS.indent(Indent + 2); 4708c7c8352SDouglas Gregor OS << "export "; 4718c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4729565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 47324bb923aSDouglas Gregor if (Exports[I].getInt()) 47424bb923aSDouglas Gregor OS << ".*"; 4758c7c8352SDouglas Gregor } else { 4768c7c8352SDouglas Gregor OS << "*"; 4778c7c8352SDouglas Gregor } 47824bb923aSDouglas Gregor OS << "\n"; 47924bb923aSDouglas Gregor } 48024bb923aSDouglas Gregor 48124bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 48224bb923aSDouglas Gregor OS.indent(Indent + 2); 48324bb923aSDouglas Gregor OS << "export "; 48424bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4857f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4867f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 48724bb923aSDouglas Gregor OS << "\n"; 48824bb923aSDouglas Gregor } 48924bb923aSDouglas Gregor 490ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 491ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 492ba7f2f71SDaniel Jasper OS << "use "; 4939565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 494ba7f2f71SDaniel Jasper OS << "\n"; 495ba7f2f71SDaniel Jasper } 496ba7f2f71SDaniel Jasper 497ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 498ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 499ba7f2f71SDaniel Jasper OS << "use "; 500ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 501ba7f2f71SDaniel Jasper OS << "\n"; 502ba7f2f71SDaniel Jasper } 503ba7f2f71SDaniel Jasper 5046ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5056ddfca91SDouglas Gregor OS.indent(Indent + 2); 5066ddfca91SDouglas Gregor OS << "link "; 5076ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5086ddfca91SDouglas Gregor OS << "framework "; 5096ddfca91SDouglas Gregor OS << "\""; 5106ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5116ddfca91SDouglas Gregor OS << "\""; 5126ddfca91SDouglas Gregor } 5136ddfca91SDouglas Gregor 514fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 515fb912657SDouglas Gregor OS.indent(Indent + 2); 516fb912657SDouglas Gregor OS << "conflict "; 517fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 518fb912657SDouglas Gregor OS << ", \""; 519fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 520fb912657SDouglas Gregor OS << "\"\n"; 521fb912657SDouglas Gregor } 522fb912657SDouglas Gregor 523fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 524fb912657SDouglas Gregor OS.indent(Indent + 2); 525fb912657SDouglas Gregor OS << "conflict "; 5269565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 527fb912657SDouglas Gregor OS << ", \""; 528fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 529fb912657SDouglas Gregor OS << "\"\n"; 530fb912657SDouglas Gregor } 531fb912657SDouglas Gregor 53273441091SDouglas Gregor if (InferSubmodules) { 53373441091SDouglas Gregor OS.indent(Indent + 2); 53473441091SDouglas Gregor if (InferExplicitSubmodules) 53573441091SDouglas Gregor OS << "explicit "; 53673441091SDouglas Gregor OS << "module * {\n"; 53773441091SDouglas Gregor if (InferExportWildcard) { 53873441091SDouglas Gregor OS.indent(Indent + 4); 53973441091SDouglas Gregor OS << "export *\n"; 54073441091SDouglas Gregor } 54173441091SDouglas Gregor OS.indent(Indent + 2); 54273441091SDouglas Gregor OS << "}\n"; 54373441091SDouglas Gregor } 54473441091SDouglas Gregor 545de3ef502SDouglas Gregor OS.indent(Indent); 546de3ef502SDouglas Gregor OS << "}\n"; 547de3ef502SDouglas Gregor } 548de3ef502SDouglas Gregor 549cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 550de3ef502SDouglas Gregor print(llvm::errs()); 551de3ef502SDouglas Gregor } 552de3ef502SDouglas Gregor 553a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 554a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 5556d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 556a7e2cc68SRichard Smith if (isVisible(M)) 557a7e2cc68SRichard Smith return; 558de3ef502SDouglas Gregor 559a7e2cc68SRichard Smith ++Generation; 560a7e2cc68SRichard Smith 561a7e2cc68SRichard Smith struct Visiting { 562a7e2cc68SRichard Smith Module *M; 563a7e2cc68SRichard Smith Visiting *ExportedBy; 564a7e2cc68SRichard Smith }; 565a7e2cc68SRichard Smith 566a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 567a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 568a7e2cc68SRichard Smith if (!V.M->isAvailable()) 569a7e2cc68SRichard Smith return; 570a7e2cc68SRichard Smith 571a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 572a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 573a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 574a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 575a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 576a7e2cc68SRichard Smith return; 577a7e2cc68SRichard Smith 578a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 579a7e2cc68SRichard Smith Vis(M); 580a7e2cc68SRichard Smith 581a7e2cc68SRichard Smith // Make any exported modules visible. 582a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 583a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 584a7e2cc68SRichard Smith for (Module *E : Exports) 585a7e2cc68SRichard Smith VisitModule({E, &V}); 586a7e2cc68SRichard Smith 587a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 588a7e2cc68SRichard Smith if (isVisible(C.Other)) { 589a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 590a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 591a7e2cc68SRichard Smith Path.push_back(I->M); 592a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 593a7e2cc68SRichard Smith } 594a7e2cc68SRichard Smith } 595a7e2cc68SRichard Smith }; 596a7e2cc68SRichard Smith VisitModule({M, nullptr}); 597a7e2cc68SRichard Smith } 598