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), 4790b0a1fcSJordan Rose NoUndeclaredIncludes(false), ModuleMapIsPrivate(false), 4890b0a1fcSJordan Rose NameVisibility(Hidden) { 49eb90e830SDouglas Gregor if (Parent) { 50eb90e830SDouglas Gregor if (!Parent->isAvailable()) 51eb90e830SDouglas Gregor IsAvailable = false; 523ec6663bSDouglas Gregor if (Parent->IsSystem) 533ec6663bSDouglas Gregor IsSystem = true; 549bca298fSRichard Smith if (Parent->IsExternC) 559bca298fSRichard Smith IsExternC = true; 56ed84df00SBruno Cardoso Lopes if (Parent->NoUndeclaredIncludes) 57ed84df00SBruno Cardoso Lopes NoUndeclaredIncludes = true; 5890b0a1fcSJordan Rose if (Parent->ModuleMapIsPrivate) 5990b0a1fcSJordan Rose ModuleMapIsPrivate = true; 60993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 61eb90e830SDouglas Gregor 62eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 63eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 64eb90e830SDouglas Gregor } 65eb90e830SDouglas Gregor } 66eb90e830SDouglas Gregor 67de3ef502SDouglas Gregor Module::~Module() { 68eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 69de3ef502SDouglas Gregor I != IEnd; ++I) { 70eb90e830SDouglas Gregor delete *I; 71de3ef502SDouglas Gregor } 72de3ef502SDouglas Gregor } 73de3ef502SDouglas Gregor 749fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current 751fb5c3a6SDouglas Gregor /// language options has the given feature. 7689929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 7789929282SDouglas Gregor const TargetInfo &Target) { 78532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 790070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 801fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 81e38cea02SEric Fiselier .Case("coroutines", LangOpts.CoroutinesTS) 821fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 832bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 846d9cf8aaSBruno Cardoso Lopes .Case("cplusplus14", LangOpts.CPlusPlus14) 856d9cf8aaSBruno Cardoso Lopes .Case("cplusplus17", LangOpts.CPlusPlus17) 866d9cf8aaSBruno Cardoso Lopes .Case("c99", LangOpts.C99) 876d9cf8aaSBruno Cardoso Lopes .Case("c11", LangOpts.C11) 886d9cf8aaSBruno Cardoso Lopes .Case("c17", LangOpts.C17) 89fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 906736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 911fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 921fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 930070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 940070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 953c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 960070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 97532d2104SBen Langmuir if (!HasFeature) 98532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 99532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 100532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 101532d2104SBen Langmuir return HasFeature; 1021fb5c3a6SDouglas Gregor } 1031fb5c3a6SDouglas Gregor 1043c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 1053c1a41adSRichard Smith Requirement &Req, 1068587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader, 1078587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const { 1081fb5c3a6SDouglas Gregor if (IsAvailable) 1091fb5c3a6SDouglas Gregor return true; 1101fb5c3a6SDouglas Gregor 1111fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 1128587dfd9SBruno Cardoso Lopes if (Current->ShadowingModule) { 1138587dfd9SBruno Cardoso Lopes ShadowingModule = Current->ShadowingModule; 1148587dfd9SBruno Cardoso Lopes return false; 1158587dfd9SBruno Cardoso Lopes } 116a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 117a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 118a3feee2aSRichard Smith Current->Requirements[I].second) { 119a3feee2aSRichard Smith Req = Current->Requirements[I]; 1201fb5c3a6SDouglas Gregor return false; 1211fb5c3a6SDouglas Gregor } 1221fb5c3a6SDouglas Gregor } 12375a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 12475a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 12575a7e435SBen Langmuir return false; 12675a7e435SBen Langmuir } 1271fb5c3a6SDouglas Gregor } 1281fb5c3a6SDouglas Gregor 1291fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1301fb5c3a6SDouglas Gregor } 1311fb5c3a6SDouglas Gregor 13262bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 133f5eedd05SDouglas Gregor const Module *This = this; 134f5eedd05SDouglas Gregor do { 135f5eedd05SDouglas Gregor if (This == Other) 136f5eedd05SDouglas Gregor return true; 137f5eedd05SDouglas Gregor 138f5eedd05SDouglas Gregor This = This->Parent; 139f5eedd05SDouglas Gregor } while (This); 140f5eedd05SDouglas Gregor 141f5eedd05SDouglas Gregor return false; 142f5eedd05SDouglas Gregor } 143f5eedd05SDouglas Gregor 14473441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 14573441091SDouglas Gregor const Module *Result = this; 14673441091SDouglas Gregor while (Result->Parent) 14773441091SDouglas Gregor Result = Result->Parent; 14873441091SDouglas Gregor 14973441091SDouglas Gregor return Result; 15073441091SDouglas Gregor } 15173441091SDouglas Gregor 1529565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1539565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1549565c75bSRichard Smith return IdComponent.first; 1559565c75bSRichard Smith } 156918e0ca7SEugene Zelenko 1579565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1589565c75bSRichard Smith 1599565c75bSRichard Smith template<typename InputIter> 1609565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1619565c75bSRichard Smith bool AllowStringLiterals = true) { 1629565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1639565c75bSRichard Smith if (It != Begin) 1649565c75bSRichard Smith OS << "."; 1659565c75bSRichard Smith 1669565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1679565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 1689565c75bSRichard Smith OS << Name; 1699565c75bSRichard Smith else { 1709565c75bSRichard Smith OS << '"'; 1719565c75bSRichard Smith OS.write_escaped(Name); 1729565c75bSRichard Smith OS << '"'; 1739565c75bSRichard Smith } 1749565c75bSRichard Smith } 1759565c75bSRichard Smith } 1769565c75bSRichard Smith 1779565c75bSRichard Smith template<typename Container> 1789565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 1799565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 1809565c75bSRichard Smith } 1819565c75bSRichard Smith 1829565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 183f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 184de3ef502SDouglas Gregor 185de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 186de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 187de3ef502SDouglas Gregor Names.push_back(M->Name); 188de3ef502SDouglas Gregor 189de3ef502SDouglas Gregor std::string Result; 190de3ef502SDouglas Gregor 1919565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 1929565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 1939565c75bSRichard Smith Out.flush(); 194de3ef502SDouglas Gregor 195de3ef502SDouglas Gregor return Result; 196de3ef502SDouglas Gregor } 197de3ef502SDouglas Gregor 1987ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1997ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 2007ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 2017ff29148SBen Langmuir return false; 2027ff29148SBen Langmuir nameParts = nameParts.drop_back(); 2037ff29148SBen Langmuir } 2047ff29148SBen Langmuir return nameParts.empty(); 2057ff29148SBen Langmuir } 2067ff29148SBen Langmuir 2072b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 2082b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 2092b63d15fSRichard Smith return {"", U.Entry->getDir()}; 21073141fa9SDouglas Gregor 2112b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 21273141fa9SDouglas Gregor } 21373141fa9SDouglas Gregor 2143c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2153c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2163c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2173c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2183c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 2193c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 2203c5305c1SArgyrios Kyrtzidis } 2213c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2223c5305c1SArgyrios Kyrtzidis } 2233c5305c1SArgyrios Kyrtzidis 2243c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2253c5305c1SArgyrios Kyrtzidis } 2263c5305c1SArgyrios Kyrtzidis 2278f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2288f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2298f4d3ff1SRichard Smith 2308f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2318f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2328f4d3ff1SRichard Smith return true; 2338f4d3ff1SRichard Smith 2348f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2358f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2368f4d3ff1SRichard Smith return true; 237ed84df00SBruno Cardoso Lopes 238ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 239ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 240ed84df00SBruno Cardoso Lopes return true; 241ed84df00SBruno Cardoso Lopes 2428f4d3ff1SRichard Smith return false; 2438f4d3ff1SRichard Smith } 2448f4d3ff1SRichard Smith 245a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 246a3feee2aSRichard Smith const LangOptions &LangOpts, 24789929282SDouglas Gregor const TargetInfo &Target) { 248a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 2491fb5c3a6SDouglas Gregor 2501fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 251a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2521fb5c3a6SDouglas Gregor return; 2531fb5c3a6SDouglas Gregor 254993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 255ec8c9752SBen Langmuir } 256ec8c9752SBen Langmuir 257993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 25875a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 25975a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 26075a7e435SBen Langmuir }; 26175a7e435SBen Langmuir 26275a7e435SBen Langmuir if (!needUpdate(this)) 2631fb5c3a6SDouglas Gregor return; 2641fb5c3a6SDouglas Gregor 265f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2661fb5c3a6SDouglas Gregor Stack.push_back(this); 2671fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2681fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2691fb5c3a6SDouglas Gregor Stack.pop_back(); 2701fb5c3a6SDouglas Gregor 27175a7e435SBen Langmuir if (!needUpdate(Current)) 2721fb5c3a6SDouglas Gregor continue; 2731fb5c3a6SDouglas Gregor 2741fb5c3a6SDouglas Gregor Current->IsAvailable = false; 275993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 276eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 277eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2781fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 27975a7e435SBen Langmuir if (needUpdate(*Sub)) 280eb90e830SDouglas Gregor Stack.push_back(*Sub); 2811fb5c3a6SDouglas Gregor } 2821fb5c3a6SDouglas Gregor } 2831fb5c3a6SDouglas Gregor } 2841fb5c3a6SDouglas Gregor 285eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 286eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 287eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 288f1186c5aSCraig Topper return nullptr; 289eb90e830SDouglas Gregor 290eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 291eb90e830SDouglas Gregor } 292eb90e830SDouglas Gregor 2938739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 294e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 295e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 296e9bcf5b7SDmitri Gribenko E = SubModules.end(); 297e9bcf5b7SDmitri Gribenko I != E; ++I) { 298e9bcf5b7SDmitri Gribenko Module *Mod = *I; 299e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 300e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 301e9bcf5b7SDmitri Gribenko } 302e9bcf5b7SDmitri Gribenko 303e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 3048739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 3058739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 3068739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 3078739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 3088739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 3098739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 3108739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 3118739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3128739f7b7SArgyrios Kyrtzidis 3138739f7b7SArgyrios Kyrtzidis continue; 3148739f7b7SArgyrios Kyrtzidis } 3158739f7b7SArgyrios Kyrtzidis 3168739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3178739f7b7SArgyrios Kyrtzidis // the given pattern. 3188739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3198739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3208739f7b7SArgyrios Kyrtzidis continue; 3218739f7b7SArgyrios Kyrtzidis 3228739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3238739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3248739f7b7SArgyrios Kyrtzidis else { 3258739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3268739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3278739f7b7SArgyrios Kyrtzidis } 3288739f7b7SArgyrios Kyrtzidis } 3298739f7b7SArgyrios Kyrtzidis 3308739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3318739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3328739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3338739f7b7SArgyrios Kyrtzidis return; 3348739f7b7SArgyrios Kyrtzidis 3358739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3368739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3378739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3388739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3398739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3408739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3418739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3428739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3438739f7b7SArgyrios Kyrtzidis Acceptable = true; 3448739f7b7SArgyrios Kyrtzidis break; 3458739f7b7SArgyrios Kyrtzidis } 3468739f7b7SArgyrios Kyrtzidis } 3478739f7b7SArgyrios Kyrtzidis } 3488739f7b7SArgyrios Kyrtzidis 3498739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3508739f7b7SArgyrios Kyrtzidis continue; 3518739f7b7SArgyrios Kyrtzidis 3528739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3538739f7b7SArgyrios Kyrtzidis } 3548739f7b7SArgyrios Kyrtzidis } 3558739f7b7SArgyrios Kyrtzidis 3560e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3570e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3580e5d7b8cSRichard Smith 3590e5d7b8cSRichard Smith // This module is visible to itself. 3600e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3610e5d7b8cSRichard Smith 3620e5d7b8cSRichard Smith // Every imported module is visible. 363dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 364dc360d57SDmitri Gribenko while (!Stack.empty()) { 365dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 366dc360d57SDmitri Gribenko 367dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 368dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 369dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3700e5d7b8cSRichard Smith } 3710e5d7b8cSRichard Smith } 3720e5d7b8cSRichard Smith 373f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 374de3ef502SDouglas Gregor OS.indent(Indent); 375de3ef502SDouglas Gregor if (IsFramework) 376de3ef502SDouglas Gregor OS << "framework "; 377de3ef502SDouglas Gregor if (IsExplicit) 378de3ef502SDouglas Gregor OS << "explicit "; 3799565c75bSRichard Smith OS << "module "; 3809565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 381a686e1b0SDouglas Gregor 3827615f00eSBen Langmuir if (IsSystem || IsExternC) { 383a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3847615f00eSBen Langmuir if (IsSystem) 385a686e1b0SDouglas Gregor OS << " [system]"; 3867615f00eSBen Langmuir if (IsExternC) 3877615f00eSBen Langmuir OS << " [extern_c]"; 388a686e1b0SDouglas Gregor } 389a686e1b0SDouglas Gregor 390a686e1b0SDouglas Gregor OS << " {\n"; 391de3ef502SDouglas Gregor 392a3feee2aSRichard Smith if (!Requirements.empty()) { 3931fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3941fb5c3a6SDouglas Gregor OS << "requires "; 395a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3961fb5c3a6SDouglas Gregor if (I) 3971fb5c3a6SDouglas Gregor OS << ", "; 398a3feee2aSRichard Smith if (!Requirements[I].second) 399a3feee2aSRichard Smith OS << "!"; 400a3feee2aSRichard Smith OS << Requirements[I].first; 4011fb5c3a6SDouglas Gregor } 4021fb5c3a6SDouglas Gregor OS << "\n"; 4031fb5c3a6SDouglas Gregor } 4041fb5c3a6SDouglas Gregor 4052b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 406de3ef502SDouglas Gregor OS.indent(Indent + 2); 407322f633cSDouglas Gregor OS << "umbrella header \""; 4082b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 409de3ef502SDouglas Gregor OS << "\"\n"; 4102b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 411322f633cSDouglas Gregor OS.indent(Indent + 2); 412322f633cSDouglas Gregor OS << "umbrella \""; 4132b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 414322f633cSDouglas Gregor OS << "\"\n"; 415de3ef502SDouglas Gregor } 416de3ef502SDouglas Gregor 41735b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 41835b13eceSDouglas Gregor OS.indent(Indent + 2); 41935b13eceSDouglas Gregor OS << "config_macros "; 42035b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4218d932427SDouglas Gregor OS << "[exhaustive]"; 42235b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 42335b13eceSDouglas Gregor if (I) 42435b13eceSDouglas Gregor OS << ", "; 42535b13eceSDouglas Gregor OS << ConfigMacros[I]; 42635b13eceSDouglas Gregor } 4278d932427SDouglas Gregor OS << "\n"; 42835b13eceSDouglas Gregor } 42935b13eceSDouglas Gregor 4303c1a41adSRichard Smith struct { 431306d8920SRichard Smith StringRef Prefix; 4323c1a41adSRichard Smith HeaderKind Kind; 4333c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4343c1a41adSRichard Smith {"textual ", HK_Textual}, 4353c1a41adSRichard Smith {"private ", HK_Private}, 4363c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4373c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 438306d8920SRichard Smith 439306d8920SRichard Smith for (auto &K : Kinds) { 440040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4413c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 442de3ef502SDouglas Gregor OS.indent(Indent + 2); 443306d8920SRichard Smith OS << K.Prefix << "header \""; 4443c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 445040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 446040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 447040e1266SRichard Smith } 448040e1266SRichard Smith } 449040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 450040e1266SRichard Smith for (auto &U : *Unresolved) { 451040e1266SRichard Smith OS.indent(Indent + 2); 452040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 453040e1266SRichard Smith OS.write_escaped(U.FileName); 454040e1266SRichard Smith OS << "\""; 455040e1266SRichard Smith if (U.Size || U.ModTime) { 456040e1266SRichard Smith OS << " {"; 457040e1266SRichard Smith if (U.Size) 458040e1266SRichard Smith OS << " size " << *U.Size; 459040e1266SRichard Smith if (U.ModTime) 460040e1266SRichard Smith OS << " mtime " << *U.ModTime; 461040e1266SRichard Smith OS << " }"; 462040e1266SRichard Smith } 463040e1266SRichard Smith OS << "\n"; 464de3ef502SDouglas Gregor } 465b53e5483SLawrence Crowl } 466b53e5483SLawrence Crowl 467f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 468f0b11de2SDouglas Gregor OS.indent(Indent + 2); 469f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 470f0b11de2SDouglas Gregor } 471f0b11de2SDouglas Gregor 472eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 473de3ef502SDouglas Gregor MI != MIEnd; ++MI) 4749d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4759d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4769d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4779d6448b1SBen Langmuir // those header files anyway. 4789d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 479eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 480de3ef502SDouglas Gregor 48124bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 48224bb923aSDouglas Gregor OS.indent(Indent + 2); 4838c7c8352SDouglas Gregor OS << "export "; 4848c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4859565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 48624bb923aSDouglas Gregor if (Exports[I].getInt()) 48724bb923aSDouglas Gregor OS << ".*"; 4888c7c8352SDouglas Gregor } else { 4898c7c8352SDouglas Gregor OS << "*"; 4908c7c8352SDouglas Gregor } 49124bb923aSDouglas Gregor OS << "\n"; 49224bb923aSDouglas Gregor } 49324bb923aSDouglas Gregor 49424bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 49524bb923aSDouglas Gregor OS.indent(Indent + 2); 49624bb923aSDouglas Gregor OS << "export "; 49724bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4987f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4997f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 50024bb923aSDouglas Gregor OS << "\n"; 50124bb923aSDouglas Gregor } 50224bb923aSDouglas Gregor 503ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 504ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 505ba7f2f71SDaniel Jasper OS << "use "; 5069565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 507ba7f2f71SDaniel Jasper OS << "\n"; 508ba7f2f71SDaniel Jasper } 509ba7f2f71SDaniel Jasper 510ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 511ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 512ba7f2f71SDaniel Jasper OS << "use "; 513ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 514ba7f2f71SDaniel Jasper OS << "\n"; 515ba7f2f71SDaniel Jasper } 516ba7f2f71SDaniel Jasper 5176ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5186ddfca91SDouglas Gregor OS.indent(Indent + 2); 5196ddfca91SDouglas Gregor OS << "link "; 5206ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5216ddfca91SDouglas Gregor OS << "framework "; 5226ddfca91SDouglas Gregor OS << "\""; 5236ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5246ddfca91SDouglas Gregor OS << "\""; 5256ddfca91SDouglas Gregor } 5266ddfca91SDouglas Gregor 527fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 528fb912657SDouglas Gregor OS.indent(Indent + 2); 529fb912657SDouglas Gregor OS << "conflict "; 530fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 531fb912657SDouglas Gregor OS << ", \""; 532fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 533fb912657SDouglas Gregor OS << "\"\n"; 534fb912657SDouglas Gregor } 535fb912657SDouglas Gregor 536fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 537fb912657SDouglas Gregor OS.indent(Indent + 2); 538fb912657SDouglas Gregor OS << "conflict "; 5399565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 540fb912657SDouglas Gregor OS << ", \""; 541fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 542fb912657SDouglas Gregor OS << "\"\n"; 543fb912657SDouglas Gregor } 544fb912657SDouglas Gregor 54573441091SDouglas Gregor if (InferSubmodules) { 54673441091SDouglas Gregor OS.indent(Indent + 2); 54773441091SDouglas Gregor if (InferExplicitSubmodules) 54873441091SDouglas Gregor OS << "explicit "; 54973441091SDouglas Gregor OS << "module * {\n"; 55073441091SDouglas Gregor if (InferExportWildcard) { 55173441091SDouglas Gregor OS.indent(Indent + 4); 55273441091SDouglas Gregor OS << "export *\n"; 55373441091SDouglas Gregor } 55473441091SDouglas Gregor OS.indent(Indent + 2); 55573441091SDouglas Gregor OS << "}\n"; 55673441091SDouglas Gregor } 55773441091SDouglas Gregor 558de3ef502SDouglas Gregor OS.indent(Indent); 559de3ef502SDouglas Gregor OS << "}\n"; 560de3ef502SDouglas Gregor } 561de3ef502SDouglas Gregor 562cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 563de3ef502SDouglas Gregor print(llvm::errs()); 564de3ef502SDouglas Gregor } 565de3ef502SDouglas Gregor 566a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 567a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 5686d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 569a7e2cc68SRichard Smith if (isVisible(M)) 570a7e2cc68SRichard Smith return; 571de3ef502SDouglas Gregor 572a7e2cc68SRichard Smith ++Generation; 573a7e2cc68SRichard Smith 574a7e2cc68SRichard Smith struct Visiting { 575a7e2cc68SRichard Smith Module *M; 576a7e2cc68SRichard Smith Visiting *ExportedBy; 577a7e2cc68SRichard Smith }; 578a7e2cc68SRichard Smith 579a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 580a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 581a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 582a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 583a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 584a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 585a7e2cc68SRichard Smith return; 586a7e2cc68SRichard Smith 587a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 588a7e2cc68SRichard Smith Vis(M); 589a7e2cc68SRichard Smith 590a7e2cc68SRichard Smith // Make any exported modules visible. 591a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 592a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 593*841dbda3SRichard Smith for (Module *E : Exports) { 594*841dbda3SRichard Smith // Don't recurse to unavailable submodules. 595*841dbda3SRichard Smith if (E->isAvailable()) 596a7e2cc68SRichard Smith VisitModule({E, &V}); 597*841dbda3SRichard Smith } 598a7e2cc68SRichard Smith 599a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 600a7e2cc68SRichard Smith if (isVisible(C.Other)) { 601a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 602a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 603a7e2cc68SRichard Smith Path.push_back(I->M); 604a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 605a7e2cc68SRichard Smith } 606a7e2cc68SRichard Smith } 607a7e2cc68SRichard Smith }; 608a7e2cc68SRichard Smith VisitModule({M, nullptr}); 609a7e2cc68SRichard Smith } 610