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) 81*6d9cf8aaSBruno Cardoso Lopes .Case("cplusplus14", LangOpts.CPlusPlus14) 82*6d9cf8aaSBruno Cardoso Lopes .Case("cplusplus17", LangOpts.CPlusPlus17) 83*6d9cf8aaSBruno Cardoso Lopes .Case("c99", LangOpts.C99) 84*6d9cf8aaSBruno Cardoso Lopes .Case("c11", LangOpts.C11) 85*6d9cf8aaSBruno Cardoso Lopes .Case("c17", LangOpts.C17) 86fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 876736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 881fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 891fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 900070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 910070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 923c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 930070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 94532d2104SBen Langmuir if (!HasFeature) 95532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 96532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 97532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 98532d2104SBen Langmuir return HasFeature; 991fb5c3a6SDouglas Gregor } 1001fb5c3a6SDouglas Gregor 1013c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 1023c1a41adSRichard Smith Requirement &Req, 1038587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader, 1048587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const { 1051fb5c3a6SDouglas Gregor if (IsAvailable) 1061fb5c3a6SDouglas Gregor return true; 1071fb5c3a6SDouglas Gregor 1081fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 1098587dfd9SBruno Cardoso Lopes if (Current->ShadowingModule) { 1108587dfd9SBruno Cardoso Lopes ShadowingModule = Current->ShadowingModule; 1118587dfd9SBruno Cardoso Lopes return false; 1128587dfd9SBruno Cardoso Lopes } 113a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 114a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 115a3feee2aSRichard Smith Current->Requirements[I].second) { 116a3feee2aSRichard Smith Req = Current->Requirements[I]; 1171fb5c3a6SDouglas Gregor return false; 1181fb5c3a6SDouglas Gregor } 1191fb5c3a6SDouglas Gregor } 12075a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 12175a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 12275a7e435SBen Langmuir return false; 12375a7e435SBen Langmuir } 1241fb5c3a6SDouglas Gregor } 1251fb5c3a6SDouglas Gregor 1261fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1271fb5c3a6SDouglas Gregor } 1281fb5c3a6SDouglas Gregor 12962bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 130f5eedd05SDouglas Gregor const Module *This = this; 131f5eedd05SDouglas Gregor do { 132f5eedd05SDouglas Gregor if (This == Other) 133f5eedd05SDouglas Gregor return true; 134f5eedd05SDouglas Gregor 135f5eedd05SDouglas Gregor This = This->Parent; 136f5eedd05SDouglas Gregor } while (This); 137f5eedd05SDouglas Gregor 138f5eedd05SDouglas Gregor return false; 139f5eedd05SDouglas Gregor } 140f5eedd05SDouglas Gregor 14173441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 14273441091SDouglas Gregor const Module *Result = this; 14373441091SDouglas Gregor while (Result->Parent) 14473441091SDouglas Gregor Result = Result->Parent; 14573441091SDouglas Gregor 14673441091SDouglas Gregor return Result; 14773441091SDouglas Gregor } 14873441091SDouglas Gregor 1499565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1509565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1519565c75bSRichard Smith return IdComponent.first; 1529565c75bSRichard Smith } 153918e0ca7SEugene Zelenko 1549565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1559565c75bSRichard Smith 1569565c75bSRichard Smith template<typename InputIter> 1579565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1589565c75bSRichard Smith bool AllowStringLiterals = true) { 1599565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1609565c75bSRichard Smith if (It != Begin) 1619565c75bSRichard Smith OS << "."; 1629565c75bSRichard Smith 1639565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1649565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 1659565c75bSRichard Smith OS << Name; 1669565c75bSRichard Smith else { 1679565c75bSRichard Smith OS << '"'; 1689565c75bSRichard Smith OS.write_escaped(Name); 1699565c75bSRichard Smith OS << '"'; 1709565c75bSRichard Smith } 1719565c75bSRichard Smith } 1729565c75bSRichard Smith } 1739565c75bSRichard Smith 1749565c75bSRichard Smith template<typename Container> 1759565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 1769565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 1779565c75bSRichard Smith } 1789565c75bSRichard Smith 1799565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 180f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 181de3ef502SDouglas Gregor 182de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 183de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 184de3ef502SDouglas Gregor Names.push_back(M->Name); 185de3ef502SDouglas Gregor 186de3ef502SDouglas Gregor std::string Result; 187de3ef502SDouglas Gregor 1889565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 1899565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 1909565c75bSRichard Smith Out.flush(); 191de3ef502SDouglas Gregor 192de3ef502SDouglas Gregor return Result; 193de3ef502SDouglas Gregor } 194de3ef502SDouglas Gregor 1957ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1967ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1977ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1987ff29148SBen Langmuir return false; 1997ff29148SBen Langmuir nameParts = nameParts.drop_back(); 2007ff29148SBen Langmuir } 2017ff29148SBen Langmuir return nameParts.empty(); 2027ff29148SBen Langmuir } 2037ff29148SBen Langmuir 2042b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 2052b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 2062b63d15fSRichard Smith return {"", U.Entry->getDir()}; 20773141fa9SDouglas Gregor 2082b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 20973141fa9SDouglas Gregor } 21073141fa9SDouglas Gregor 2113c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2123c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2133c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2143c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2153c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 2163c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 2173c5305c1SArgyrios Kyrtzidis } 2183c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2193c5305c1SArgyrios Kyrtzidis } 2203c5305c1SArgyrios Kyrtzidis 2213c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2223c5305c1SArgyrios Kyrtzidis } 2233c5305c1SArgyrios Kyrtzidis 2248f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2258f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2268f4d3ff1SRichard Smith 2278f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2288f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2298f4d3ff1SRichard Smith return true; 2308f4d3ff1SRichard Smith 2318f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2328f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2338f4d3ff1SRichard Smith return true; 234ed84df00SBruno Cardoso Lopes 235ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 236ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 237ed84df00SBruno Cardoso Lopes return true; 238ed84df00SBruno Cardoso Lopes 2398f4d3ff1SRichard Smith return false; 2408f4d3ff1SRichard Smith } 2418f4d3ff1SRichard Smith 242a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 243a3feee2aSRichard Smith const LangOptions &LangOpts, 24489929282SDouglas Gregor const TargetInfo &Target) { 245a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 2461fb5c3a6SDouglas Gregor 2471fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 248a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2491fb5c3a6SDouglas Gregor return; 2501fb5c3a6SDouglas Gregor 251993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 252ec8c9752SBen Langmuir } 253ec8c9752SBen Langmuir 254993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 25575a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 25675a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 25775a7e435SBen Langmuir }; 25875a7e435SBen Langmuir 25975a7e435SBen Langmuir if (!needUpdate(this)) 2601fb5c3a6SDouglas Gregor return; 2611fb5c3a6SDouglas Gregor 262f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2631fb5c3a6SDouglas Gregor Stack.push_back(this); 2641fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2651fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2661fb5c3a6SDouglas Gregor Stack.pop_back(); 2671fb5c3a6SDouglas Gregor 26875a7e435SBen Langmuir if (!needUpdate(Current)) 2691fb5c3a6SDouglas Gregor continue; 2701fb5c3a6SDouglas Gregor 2711fb5c3a6SDouglas Gregor Current->IsAvailable = false; 272993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 273eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 274eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2751fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 27675a7e435SBen Langmuir if (needUpdate(*Sub)) 277eb90e830SDouglas Gregor Stack.push_back(*Sub); 2781fb5c3a6SDouglas Gregor } 2791fb5c3a6SDouglas Gregor } 2801fb5c3a6SDouglas Gregor } 2811fb5c3a6SDouglas Gregor 282eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 283eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 284eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 285f1186c5aSCraig Topper return nullptr; 286eb90e830SDouglas Gregor 287eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 288eb90e830SDouglas Gregor } 289eb90e830SDouglas Gregor 2908739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 291e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 292e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 293e9bcf5b7SDmitri Gribenko E = SubModules.end(); 294e9bcf5b7SDmitri Gribenko I != E; ++I) { 295e9bcf5b7SDmitri Gribenko Module *Mod = *I; 296e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 297e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 298e9bcf5b7SDmitri Gribenko } 299e9bcf5b7SDmitri Gribenko 300e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 3018739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 3028739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 3038739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 3048739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 3058739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 3068739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 3078739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 3088739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3098739f7b7SArgyrios Kyrtzidis 3108739f7b7SArgyrios Kyrtzidis continue; 3118739f7b7SArgyrios Kyrtzidis } 3128739f7b7SArgyrios Kyrtzidis 3138739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3148739f7b7SArgyrios Kyrtzidis // the given pattern. 3158739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3168739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3178739f7b7SArgyrios Kyrtzidis continue; 3188739f7b7SArgyrios Kyrtzidis 3198739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3208739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3218739f7b7SArgyrios Kyrtzidis else { 3228739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3238739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3248739f7b7SArgyrios Kyrtzidis } 3258739f7b7SArgyrios Kyrtzidis } 3268739f7b7SArgyrios Kyrtzidis 3278739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3288739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3298739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3308739f7b7SArgyrios Kyrtzidis return; 3318739f7b7SArgyrios Kyrtzidis 3328739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3338739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3348739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3358739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3368739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3378739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3388739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3398739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3408739f7b7SArgyrios Kyrtzidis Acceptable = true; 3418739f7b7SArgyrios Kyrtzidis break; 3428739f7b7SArgyrios Kyrtzidis } 3438739f7b7SArgyrios Kyrtzidis } 3448739f7b7SArgyrios Kyrtzidis } 3458739f7b7SArgyrios Kyrtzidis 3468739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3478739f7b7SArgyrios Kyrtzidis continue; 3488739f7b7SArgyrios Kyrtzidis 3498739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3508739f7b7SArgyrios Kyrtzidis } 3518739f7b7SArgyrios Kyrtzidis } 3528739f7b7SArgyrios Kyrtzidis 3530e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3540e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3550e5d7b8cSRichard Smith 3560e5d7b8cSRichard Smith // This module is visible to itself. 3570e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3580e5d7b8cSRichard Smith 3590e5d7b8cSRichard Smith // Every imported module is visible. 360dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 361dc360d57SDmitri Gribenko while (!Stack.empty()) { 362dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 363dc360d57SDmitri Gribenko 364dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 365dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 366dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3670e5d7b8cSRichard Smith } 3680e5d7b8cSRichard Smith } 3690e5d7b8cSRichard Smith 370f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 371de3ef502SDouglas Gregor OS.indent(Indent); 372de3ef502SDouglas Gregor if (IsFramework) 373de3ef502SDouglas Gregor OS << "framework "; 374de3ef502SDouglas Gregor if (IsExplicit) 375de3ef502SDouglas Gregor OS << "explicit "; 3769565c75bSRichard Smith OS << "module "; 3779565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 378a686e1b0SDouglas Gregor 3797615f00eSBen Langmuir if (IsSystem || IsExternC) { 380a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3817615f00eSBen Langmuir if (IsSystem) 382a686e1b0SDouglas Gregor OS << " [system]"; 3837615f00eSBen Langmuir if (IsExternC) 3847615f00eSBen Langmuir OS << " [extern_c]"; 385a686e1b0SDouglas Gregor } 386a686e1b0SDouglas Gregor 387a686e1b0SDouglas Gregor OS << " {\n"; 388de3ef502SDouglas Gregor 389a3feee2aSRichard Smith if (!Requirements.empty()) { 3901fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3911fb5c3a6SDouglas Gregor OS << "requires "; 392a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3931fb5c3a6SDouglas Gregor if (I) 3941fb5c3a6SDouglas Gregor OS << ", "; 395a3feee2aSRichard Smith if (!Requirements[I].second) 396a3feee2aSRichard Smith OS << "!"; 397a3feee2aSRichard Smith OS << Requirements[I].first; 3981fb5c3a6SDouglas Gregor } 3991fb5c3a6SDouglas Gregor OS << "\n"; 4001fb5c3a6SDouglas Gregor } 4011fb5c3a6SDouglas Gregor 4022b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 403de3ef502SDouglas Gregor OS.indent(Indent + 2); 404322f633cSDouglas Gregor OS << "umbrella header \""; 4052b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 406de3ef502SDouglas Gregor OS << "\"\n"; 4072b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 408322f633cSDouglas Gregor OS.indent(Indent + 2); 409322f633cSDouglas Gregor OS << "umbrella \""; 4102b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 411322f633cSDouglas Gregor OS << "\"\n"; 412de3ef502SDouglas Gregor } 413de3ef502SDouglas Gregor 41435b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 41535b13eceSDouglas Gregor OS.indent(Indent + 2); 41635b13eceSDouglas Gregor OS << "config_macros "; 41735b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4188d932427SDouglas Gregor OS << "[exhaustive]"; 41935b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 42035b13eceSDouglas Gregor if (I) 42135b13eceSDouglas Gregor OS << ", "; 42235b13eceSDouglas Gregor OS << ConfigMacros[I]; 42335b13eceSDouglas Gregor } 4248d932427SDouglas Gregor OS << "\n"; 42535b13eceSDouglas Gregor } 42635b13eceSDouglas Gregor 4273c1a41adSRichard Smith struct { 428306d8920SRichard Smith StringRef Prefix; 4293c1a41adSRichard Smith HeaderKind Kind; 4303c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4313c1a41adSRichard Smith {"textual ", HK_Textual}, 4323c1a41adSRichard Smith {"private ", HK_Private}, 4333c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4343c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 435306d8920SRichard Smith 436306d8920SRichard Smith for (auto &K : Kinds) { 437040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4383c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 439de3ef502SDouglas Gregor OS.indent(Indent + 2); 440306d8920SRichard Smith OS << K.Prefix << "header \""; 4413c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 442040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 443040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 444040e1266SRichard Smith } 445040e1266SRichard Smith } 446040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 447040e1266SRichard Smith for (auto &U : *Unresolved) { 448040e1266SRichard Smith OS.indent(Indent + 2); 449040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 450040e1266SRichard Smith OS.write_escaped(U.FileName); 451040e1266SRichard Smith OS << "\""; 452040e1266SRichard Smith if (U.Size || U.ModTime) { 453040e1266SRichard Smith OS << " {"; 454040e1266SRichard Smith if (U.Size) 455040e1266SRichard Smith OS << " size " << *U.Size; 456040e1266SRichard Smith if (U.ModTime) 457040e1266SRichard Smith OS << " mtime " << *U.ModTime; 458040e1266SRichard Smith OS << " }"; 459040e1266SRichard Smith } 460040e1266SRichard Smith OS << "\n"; 461de3ef502SDouglas Gregor } 462b53e5483SLawrence Crowl } 463b53e5483SLawrence Crowl 464f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 465f0b11de2SDouglas Gregor OS.indent(Indent + 2); 466f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 467f0b11de2SDouglas Gregor } 468f0b11de2SDouglas Gregor 469eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 470de3ef502SDouglas Gregor MI != MIEnd; ++MI) 4719d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4729d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4739d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4749d6448b1SBen Langmuir // those header files anyway. 4759d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 476eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 477de3ef502SDouglas Gregor 47824bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 47924bb923aSDouglas Gregor OS.indent(Indent + 2); 4808c7c8352SDouglas Gregor OS << "export "; 4818c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4829565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 48324bb923aSDouglas Gregor if (Exports[I].getInt()) 48424bb923aSDouglas Gregor OS << ".*"; 4858c7c8352SDouglas Gregor } else { 4868c7c8352SDouglas Gregor OS << "*"; 4878c7c8352SDouglas Gregor } 48824bb923aSDouglas Gregor OS << "\n"; 48924bb923aSDouglas Gregor } 49024bb923aSDouglas Gregor 49124bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 49224bb923aSDouglas Gregor OS.indent(Indent + 2); 49324bb923aSDouglas Gregor OS << "export "; 49424bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4957f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4967f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 49724bb923aSDouglas Gregor OS << "\n"; 49824bb923aSDouglas Gregor } 49924bb923aSDouglas Gregor 500ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 501ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 502ba7f2f71SDaniel Jasper OS << "use "; 5039565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 504ba7f2f71SDaniel Jasper OS << "\n"; 505ba7f2f71SDaniel Jasper } 506ba7f2f71SDaniel Jasper 507ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 508ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 509ba7f2f71SDaniel Jasper OS << "use "; 510ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 511ba7f2f71SDaniel Jasper OS << "\n"; 512ba7f2f71SDaniel Jasper } 513ba7f2f71SDaniel Jasper 5146ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5156ddfca91SDouglas Gregor OS.indent(Indent + 2); 5166ddfca91SDouglas Gregor OS << "link "; 5176ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5186ddfca91SDouglas Gregor OS << "framework "; 5196ddfca91SDouglas Gregor OS << "\""; 5206ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5216ddfca91SDouglas Gregor OS << "\""; 5226ddfca91SDouglas Gregor } 5236ddfca91SDouglas Gregor 524fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 525fb912657SDouglas Gregor OS.indent(Indent + 2); 526fb912657SDouglas Gregor OS << "conflict "; 527fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 528fb912657SDouglas Gregor OS << ", \""; 529fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 530fb912657SDouglas Gregor OS << "\"\n"; 531fb912657SDouglas Gregor } 532fb912657SDouglas Gregor 533fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 534fb912657SDouglas Gregor OS.indent(Indent + 2); 535fb912657SDouglas Gregor OS << "conflict "; 5369565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 537fb912657SDouglas Gregor OS << ", \""; 538fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 539fb912657SDouglas Gregor OS << "\"\n"; 540fb912657SDouglas Gregor } 541fb912657SDouglas Gregor 54273441091SDouglas Gregor if (InferSubmodules) { 54373441091SDouglas Gregor OS.indent(Indent + 2); 54473441091SDouglas Gregor if (InferExplicitSubmodules) 54573441091SDouglas Gregor OS << "explicit "; 54673441091SDouglas Gregor OS << "module * {\n"; 54773441091SDouglas Gregor if (InferExportWildcard) { 54873441091SDouglas Gregor OS.indent(Indent + 4); 54973441091SDouglas Gregor OS << "export *\n"; 55073441091SDouglas Gregor } 55173441091SDouglas Gregor OS.indent(Indent + 2); 55273441091SDouglas Gregor OS << "}\n"; 55373441091SDouglas Gregor } 55473441091SDouglas Gregor 555de3ef502SDouglas Gregor OS.indent(Indent); 556de3ef502SDouglas Gregor OS << "}\n"; 557de3ef502SDouglas Gregor } 558de3ef502SDouglas Gregor 559cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 560de3ef502SDouglas Gregor print(llvm::errs()); 561de3ef502SDouglas Gregor } 562de3ef502SDouglas Gregor 563a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 564a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 5656d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 566a7e2cc68SRichard Smith if (isVisible(M)) 567a7e2cc68SRichard Smith return; 568de3ef502SDouglas Gregor 569a7e2cc68SRichard Smith ++Generation; 570a7e2cc68SRichard Smith 571a7e2cc68SRichard Smith struct Visiting { 572a7e2cc68SRichard Smith Module *M; 573a7e2cc68SRichard Smith Visiting *ExportedBy; 574a7e2cc68SRichard Smith }; 575a7e2cc68SRichard Smith 576a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 577a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 578a7e2cc68SRichard Smith if (!V.M->isAvailable()) 579a7e2cc68SRichard Smith return; 580a7e2cc68SRichard Smith 581a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 582a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 583a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 584a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 585a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 586a7e2cc68SRichard Smith return; 587a7e2cc68SRichard Smith 588a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 589a7e2cc68SRichard Smith Vis(M); 590a7e2cc68SRichard Smith 591a7e2cc68SRichard Smith // Make any exported modules visible. 592a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 593a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 594a7e2cc68SRichard Smith for (Module *E : Exports) 595a7e2cc68SRichard Smith VisitModule({E, &V}); 596a7e2cc68SRichard Smith 597a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 598a7e2cc68SRichard Smith if (isVisible(C.Other)) { 599a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 600a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 601a7e2cc68SRichard Smith Path.push_back(I->M); 602a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 603a7e2cc68SRichard Smith } 604a7e2cc68SRichard Smith } 605a7e2cc68SRichard Smith }; 606a7e2cc68SRichard Smith VisitModule({M, nullptr}); 607a7e2cc68SRichard Smith } 608