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 74e7240f02SBruno Cardoso Lopes static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { 75e7240f02SBruno Cardoso Lopes StringRef Platform = Target.getPlatformName(); 76e7240f02SBruno Cardoso Lopes StringRef Env = Target.getTriple().getEnvironmentName(); 77e7240f02SBruno Cardoso Lopes 78e7240f02SBruno Cardoso Lopes // Attempt to match platform and environment. 79e7240f02SBruno Cardoso Lopes if (Platform == Feature || Target.getTriple().getOSName() == Feature || 80e7240f02SBruno Cardoso Lopes Env == Feature) 81e7240f02SBruno Cardoso Lopes return true; 82e7240f02SBruno Cardoso Lopes 83e7240f02SBruno Cardoso Lopes auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) { 84e7240f02SBruno Cardoso Lopes auto Pos = LHS.find("-"); 85e7240f02SBruno Cardoso Lopes if (Pos == StringRef::npos) 86e7240f02SBruno Cardoso Lopes return false; 87e7240f02SBruno Cardoso Lopes SmallString<128> NewLHS = LHS.slice(0, Pos); 88e7240f02SBruno Cardoso Lopes NewLHS += LHS.slice(Pos+1, LHS.size()); 89e7240f02SBruno Cardoso Lopes return NewLHS == RHS; 90e7240f02SBruno Cardoso Lopes }; 91e7240f02SBruno Cardoso Lopes 92e7240f02SBruno Cardoso Lopes SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName(); 93e7240f02SBruno Cardoso Lopes // Darwin has different but equivalent variants for simulators, example: 94e7240f02SBruno Cardoso Lopes // 1. x86_64-apple-ios-simulator 95e7240f02SBruno Cardoso Lopes // 2. x86_64-apple-iossimulator 96e7240f02SBruno Cardoso Lopes // where both are valid examples of the same platform+environment but in the 97e7240f02SBruno Cardoso Lopes // variant (2) the simulator is hardcoded as part of the platform name. Both 98e7240f02SBruno Cardoso Lopes // forms above should match for "iossimulator" requirement. 99e7240f02SBruno Cardoso Lopes if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")) 100e7240f02SBruno Cardoso Lopes return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); 101e7240f02SBruno Cardoso Lopes 102e7240f02SBruno Cardoso Lopes return PlatformEnv == Feature; 103e7240f02SBruno Cardoso Lopes } 104e7240f02SBruno Cardoso Lopes 1059fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current 1061fb5c3a6SDouglas Gregor /// language options has the given feature. 10789929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 10889929282SDouglas Gregor const TargetInfo &Target) { 109532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 1100070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 1111fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 112e38cea02SEric Fiselier .Case("coroutines", LangOpts.CoroutinesTS) 1131fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 1142bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 1156d9cf8aaSBruno Cardoso Lopes .Case("cplusplus14", LangOpts.CPlusPlus14) 1166d9cf8aaSBruno Cardoso Lopes .Case("cplusplus17", LangOpts.CPlusPlus17) 1176d9cf8aaSBruno Cardoso Lopes .Case("c99", LangOpts.C99) 1186d9cf8aaSBruno Cardoso Lopes .Case("c11", LangOpts.C11) 1196d9cf8aaSBruno Cardoso Lopes .Case("c17", LangOpts.C17) 120fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 1216736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 122*fa98390bSErik Pilkington .Case("objc", LangOpts.ObjC) 1231fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 1240070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 1250070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 1263c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 127e7240f02SBruno Cardoso Lopes .Default(Target.hasFeature(Feature) || 128e7240f02SBruno Cardoso Lopes isPlatformEnvironment(Target, Feature)); 129532d2104SBen Langmuir if (!HasFeature) 130532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 131532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 132532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 133532d2104SBen Langmuir return HasFeature; 1341fb5c3a6SDouglas Gregor } 1351fb5c3a6SDouglas Gregor 1363c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 1373c1a41adSRichard Smith Requirement &Req, 1388587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader, 1398587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const { 1401fb5c3a6SDouglas Gregor if (IsAvailable) 1411fb5c3a6SDouglas Gregor return true; 1421fb5c3a6SDouglas Gregor 1431fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 1448587dfd9SBruno Cardoso Lopes if (Current->ShadowingModule) { 1458587dfd9SBruno Cardoso Lopes ShadowingModule = Current->ShadowingModule; 1468587dfd9SBruno Cardoso Lopes return false; 1478587dfd9SBruno Cardoso Lopes } 148a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 149a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 150a3feee2aSRichard Smith Current->Requirements[I].second) { 151a3feee2aSRichard Smith Req = Current->Requirements[I]; 1521fb5c3a6SDouglas Gregor return false; 1531fb5c3a6SDouglas Gregor } 1541fb5c3a6SDouglas Gregor } 15575a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 15675a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 15775a7e435SBen Langmuir return false; 15875a7e435SBen Langmuir } 1591fb5c3a6SDouglas Gregor } 1601fb5c3a6SDouglas Gregor 1611fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1621fb5c3a6SDouglas Gregor } 1631fb5c3a6SDouglas Gregor 16462bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 165f5eedd05SDouglas Gregor const Module *This = this; 166f5eedd05SDouglas Gregor do { 167f5eedd05SDouglas Gregor if (This == Other) 168f5eedd05SDouglas Gregor return true; 169f5eedd05SDouglas Gregor 170f5eedd05SDouglas Gregor This = This->Parent; 171f5eedd05SDouglas Gregor } while (This); 172f5eedd05SDouglas Gregor 173f5eedd05SDouglas Gregor return false; 174f5eedd05SDouglas Gregor } 175f5eedd05SDouglas Gregor 17673441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 17773441091SDouglas Gregor const Module *Result = this; 17873441091SDouglas Gregor while (Result->Parent) 17973441091SDouglas Gregor Result = Result->Parent; 18073441091SDouglas Gregor 18173441091SDouglas Gregor return Result; 18273441091SDouglas Gregor } 18373441091SDouglas Gregor 1849565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1859565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1869565c75bSRichard Smith return IdComponent.first; 1879565c75bSRichard Smith } 188918e0ca7SEugene Zelenko 1899565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1909565c75bSRichard Smith 1919565c75bSRichard Smith template<typename InputIter> 1929565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1939565c75bSRichard Smith bool AllowStringLiterals = true) { 1949565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1959565c75bSRichard Smith if (It != Begin) 1969565c75bSRichard Smith OS << "."; 1979565c75bSRichard Smith 1989565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1999565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 2009565c75bSRichard Smith OS << Name; 2019565c75bSRichard Smith else { 2029565c75bSRichard Smith OS << '"'; 2039565c75bSRichard Smith OS.write_escaped(Name); 2049565c75bSRichard Smith OS << '"'; 2059565c75bSRichard Smith } 2069565c75bSRichard Smith } 2079565c75bSRichard Smith } 2089565c75bSRichard Smith 2099565c75bSRichard Smith template<typename Container> 2109565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 2119565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 2129565c75bSRichard Smith } 2139565c75bSRichard Smith 2149565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 215f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 216de3ef502SDouglas Gregor 217de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 218de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 219de3ef502SDouglas Gregor Names.push_back(M->Name); 220de3ef502SDouglas Gregor 221de3ef502SDouglas Gregor std::string Result; 222de3ef502SDouglas Gregor 2239565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 2249565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 2259565c75bSRichard Smith Out.flush(); 226de3ef502SDouglas Gregor 227de3ef502SDouglas Gregor return Result; 228de3ef502SDouglas Gregor } 229de3ef502SDouglas Gregor 2307ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 2317ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 2327ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 2337ff29148SBen Langmuir return false; 2347ff29148SBen Langmuir nameParts = nameParts.drop_back(); 2357ff29148SBen Langmuir } 2367ff29148SBen Langmuir return nameParts.empty(); 2377ff29148SBen Langmuir } 2387ff29148SBen Langmuir 2392b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 2402b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 2412b63d15fSRichard Smith return {"", U.Entry->getDir()}; 24273141fa9SDouglas Gregor 2432b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 24473141fa9SDouglas Gregor } 24573141fa9SDouglas Gregor 2463c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2473c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2483c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2493c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2503c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 2513c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 2523c5305c1SArgyrios Kyrtzidis } 2533c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2543c5305c1SArgyrios Kyrtzidis } 2553c5305c1SArgyrios Kyrtzidis 2563c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2573c5305c1SArgyrios Kyrtzidis } 2583c5305c1SArgyrios Kyrtzidis 2598f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2608f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2618f4d3ff1SRichard Smith 2628f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2638f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2648f4d3ff1SRichard Smith return true; 2658f4d3ff1SRichard Smith 2668f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2678f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2688f4d3ff1SRichard Smith return true; 269ed84df00SBruno Cardoso Lopes 270ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 271ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 272ed84df00SBruno Cardoso Lopes return true; 273ed84df00SBruno Cardoso Lopes 2748f4d3ff1SRichard Smith return false; 2758f4d3ff1SRichard Smith } 2768f4d3ff1SRichard Smith 277a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 278a3feee2aSRichard Smith const LangOptions &LangOpts, 27989929282SDouglas Gregor const TargetInfo &Target) { 280a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 2811fb5c3a6SDouglas Gregor 2821fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 283a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2841fb5c3a6SDouglas Gregor return; 2851fb5c3a6SDouglas Gregor 286993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 287ec8c9752SBen Langmuir } 288ec8c9752SBen Langmuir 289993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 29075a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 29175a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 29275a7e435SBen Langmuir }; 29375a7e435SBen Langmuir 29475a7e435SBen Langmuir if (!needUpdate(this)) 2951fb5c3a6SDouglas Gregor return; 2961fb5c3a6SDouglas Gregor 297f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2981fb5c3a6SDouglas Gregor Stack.push_back(this); 2991fb5c3a6SDouglas Gregor while (!Stack.empty()) { 3001fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 3011fb5c3a6SDouglas Gregor Stack.pop_back(); 3021fb5c3a6SDouglas Gregor 30375a7e435SBen Langmuir if (!needUpdate(Current)) 3041fb5c3a6SDouglas Gregor continue; 3051fb5c3a6SDouglas Gregor 3061fb5c3a6SDouglas Gregor Current->IsAvailable = false; 307993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 308eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 309eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 3101fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 31175a7e435SBen Langmuir if (needUpdate(*Sub)) 312eb90e830SDouglas Gregor Stack.push_back(*Sub); 3131fb5c3a6SDouglas Gregor } 3141fb5c3a6SDouglas Gregor } 3151fb5c3a6SDouglas Gregor } 3161fb5c3a6SDouglas Gregor 317eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 318eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 319eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 320f1186c5aSCraig Topper return nullptr; 321eb90e830SDouglas Gregor 322eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 323eb90e830SDouglas Gregor } 324eb90e830SDouglas Gregor 3258739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 326e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 327e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 328e9bcf5b7SDmitri Gribenko E = SubModules.end(); 329e9bcf5b7SDmitri Gribenko I != E; ++I) { 330e9bcf5b7SDmitri Gribenko Module *Mod = *I; 331e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 332e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 333e9bcf5b7SDmitri Gribenko } 334e9bcf5b7SDmitri Gribenko 335e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 3368739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 3378739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 3388739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 3398739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 3408739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 3418739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 3428739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 3438739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3448739f7b7SArgyrios Kyrtzidis 3458739f7b7SArgyrios Kyrtzidis continue; 3468739f7b7SArgyrios Kyrtzidis } 3478739f7b7SArgyrios Kyrtzidis 3488739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3498739f7b7SArgyrios Kyrtzidis // the given pattern. 3508739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3518739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3528739f7b7SArgyrios Kyrtzidis continue; 3538739f7b7SArgyrios Kyrtzidis 3548739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3558739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3568739f7b7SArgyrios Kyrtzidis else { 3578739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3588739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3598739f7b7SArgyrios Kyrtzidis } 3608739f7b7SArgyrios Kyrtzidis } 3618739f7b7SArgyrios Kyrtzidis 3628739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3638739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3648739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3658739f7b7SArgyrios Kyrtzidis return; 3668739f7b7SArgyrios Kyrtzidis 3678739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3688739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3698739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3708739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3718739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3728739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3738739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3748739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3758739f7b7SArgyrios Kyrtzidis Acceptable = true; 3768739f7b7SArgyrios Kyrtzidis break; 3778739f7b7SArgyrios Kyrtzidis } 3788739f7b7SArgyrios Kyrtzidis } 3798739f7b7SArgyrios Kyrtzidis } 3808739f7b7SArgyrios Kyrtzidis 3818739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3828739f7b7SArgyrios Kyrtzidis continue; 3838739f7b7SArgyrios Kyrtzidis 3848739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3858739f7b7SArgyrios Kyrtzidis } 3868739f7b7SArgyrios Kyrtzidis } 3878739f7b7SArgyrios Kyrtzidis 3880e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3890e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3900e5d7b8cSRichard Smith 3910e5d7b8cSRichard Smith // This module is visible to itself. 3920e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3930e5d7b8cSRichard Smith 3940e5d7b8cSRichard Smith // Every imported module is visible. 395dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 396dc360d57SDmitri Gribenko while (!Stack.empty()) { 397dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 398dc360d57SDmitri Gribenko 399dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 400dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 401dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 4020e5d7b8cSRichard Smith } 4030e5d7b8cSRichard Smith } 4040e5d7b8cSRichard Smith 405f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 406de3ef502SDouglas Gregor OS.indent(Indent); 407de3ef502SDouglas Gregor if (IsFramework) 408de3ef502SDouglas Gregor OS << "framework "; 409de3ef502SDouglas Gregor if (IsExplicit) 410de3ef502SDouglas Gregor OS << "explicit "; 4119565c75bSRichard Smith OS << "module "; 4129565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 413a686e1b0SDouglas Gregor 4147615f00eSBen Langmuir if (IsSystem || IsExternC) { 415a686e1b0SDouglas Gregor OS.indent(Indent + 2); 4167615f00eSBen Langmuir if (IsSystem) 417a686e1b0SDouglas Gregor OS << " [system]"; 4187615f00eSBen Langmuir if (IsExternC) 4197615f00eSBen Langmuir OS << " [extern_c]"; 420a686e1b0SDouglas Gregor } 421a686e1b0SDouglas Gregor 422a686e1b0SDouglas Gregor OS << " {\n"; 423de3ef502SDouglas Gregor 424a3feee2aSRichard Smith if (!Requirements.empty()) { 4251fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 4261fb5c3a6SDouglas Gregor OS << "requires "; 427a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 4281fb5c3a6SDouglas Gregor if (I) 4291fb5c3a6SDouglas Gregor OS << ", "; 430a3feee2aSRichard Smith if (!Requirements[I].second) 431a3feee2aSRichard Smith OS << "!"; 432a3feee2aSRichard Smith OS << Requirements[I].first; 4331fb5c3a6SDouglas Gregor } 4341fb5c3a6SDouglas Gregor OS << "\n"; 4351fb5c3a6SDouglas Gregor } 4361fb5c3a6SDouglas Gregor 4372b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 438de3ef502SDouglas Gregor OS.indent(Indent + 2); 439322f633cSDouglas Gregor OS << "umbrella header \""; 4402b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 441de3ef502SDouglas Gregor OS << "\"\n"; 4422b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 443322f633cSDouglas Gregor OS.indent(Indent + 2); 444322f633cSDouglas Gregor OS << "umbrella \""; 4452b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 446322f633cSDouglas Gregor OS << "\"\n"; 447de3ef502SDouglas Gregor } 448de3ef502SDouglas Gregor 44935b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 45035b13eceSDouglas Gregor OS.indent(Indent + 2); 45135b13eceSDouglas Gregor OS << "config_macros "; 45235b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4538d932427SDouglas Gregor OS << "[exhaustive]"; 45435b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 45535b13eceSDouglas Gregor if (I) 45635b13eceSDouglas Gregor OS << ", "; 45735b13eceSDouglas Gregor OS << ConfigMacros[I]; 45835b13eceSDouglas Gregor } 4598d932427SDouglas Gregor OS << "\n"; 46035b13eceSDouglas Gregor } 46135b13eceSDouglas Gregor 4623c1a41adSRichard Smith struct { 463306d8920SRichard Smith StringRef Prefix; 4643c1a41adSRichard Smith HeaderKind Kind; 4653c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4663c1a41adSRichard Smith {"textual ", HK_Textual}, 4673c1a41adSRichard Smith {"private ", HK_Private}, 4683c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4693c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 470306d8920SRichard Smith 471306d8920SRichard Smith for (auto &K : Kinds) { 472040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4733c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 474de3ef502SDouglas Gregor OS.indent(Indent + 2); 475306d8920SRichard Smith OS << K.Prefix << "header \""; 4763c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 477040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 478040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 479040e1266SRichard Smith } 480040e1266SRichard Smith } 481040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 482040e1266SRichard Smith for (auto &U : *Unresolved) { 483040e1266SRichard Smith OS.indent(Indent + 2); 484040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 485040e1266SRichard Smith OS.write_escaped(U.FileName); 486040e1266SRichard Smith OS << "\""; 487040e1266SRichard Smith if (U.Size || U.ModTime) { 488040e1266SRichard Smith OS << " {"; 489040e1266SRichard Smith if (U.Size) 490040e1266SRichard Smith OS << " size " << *U.Size; 491040e1266SRichard Smith if (U.ModTime) 492040e1266SRichard Smith OS << " mtime " << *U.ModTime; 493040e1266SRichard Smith OS << " }"; 494040e1266SRichard Smith } 495040e1266SRichard Smith OS << "\n"; 496de3ef502SDouglas Gregor } 497b53e5483SLawrence Crowl } 498b53e5483SLawrence Crowl 499f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 500f0b11de2SDouglas Gregor OS.indent(Indent + 2); 501f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 502f0b11de2SDouglas Gregor } 503f0b11de2SDouglas Gregor 504eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 505de3ef502SDouglas Gregor MI != MIEnd; ++MI) 5069d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 5079d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 5089d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 5099d6448b1SBen Langmuir // those header files anyway. 5109d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 511eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 512de3ef502SDouglas Gregor 51324bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 51424bb923aSDouglas Gregor OS.indent(Indent + 2); 5158c7c8352SDouglas Gregor OS << "export "; 5168c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 5179565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 51824bb923aSDouglas Gregor if (Exports[I].getInt()) 51924bb923aSDouglas Gregor OS << ".*"; 5208c7c8352SDouglas Gregor } else { 5218c7c8352SDouglas Gregor OS << "*"; 5228c7c8352SDouglas Gregor } 52324bb923aSDouglas Gregor OS << "\n"; 52424bb923aSDouglas Gregor } 52524bb923aSDouglas Gregor 52624bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 52724bb923aSDouglas Gregor OS.indent(Indent + 2); 52824bb923aSDouglas Gregor OS << "export "; 52924bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 5307f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 5317f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 53224bb923aSDouglas Gregor OS << "\n"; 53324bb923aSDouglas Gregor } 53424bb923aSDouglas Gregor 535ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 536ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 537ba7f2f71SDaniel Jasper OS << "use "; 5389565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 539ba7f2f71SDaniel Jasper OS << "\n"; 540ba7f2f71SDaniel Jasper } 541ba7f2f71SDaniel Jasper 542ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 543ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 544ba7f2f71SDaniel Jasper OS << "use "; 545ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 546ba7f2f71SDaniel Jasper OS << "\n"; 547ba7f2f71SDaniel Jasper } 548ba7f2f71SDaniel Jasper 5496ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5506ddfca91SDouglas Gregor OS.indent(Indent + 2); 5516ddfca91SDouglas Gregor OS << "link "; 5526ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5536ddfca91SDouglas Gregor OS << "framework "; 5546ddfca91SDouglas Gregor OS << "\""; 5556ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5566ddfca91SDouglas Gregor OS << "\""; 5576ddfca91SDouglas Gregor } 5586ddfca91SDouglas Gregor 559fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 560fb912657SDouglas Gregor OS.indent(Indent + 2); 561fb912657SDouglas Gregor OS << "conflict "; 562fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 563fb912657SDouglas Gregor OS << ", \""; 564fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 565fb912657SDouglas Gregor OS << "\"\n"; 566fb912657SDouglas Gregor } 567fb912657SDouglas Gregor 568fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 569fb912657SDouglas Gregor OS.indent(Indent + 2); 570fb912657SDouglas Gregor OS << "conflict "; 5719565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 572fb912657SDouglas Gregor OS << ", \""; 573fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 574fb912657SDouglas Gregor OS << "\"\n"; 575fb912657SDouglas Gregor } 576fb912657SDouglas Gregor 57773441091SDouglas Gregor if (InferSubmodules) { 57873441091SDouglas Gregor OS.indent(Indent + 2); 57973441091SDouglas Gregor if (InferExplicitSubmodules) 58073441091SDouglas Gregor OS << "explicit "; 58173441091SDouglas Gregor OS << "module * {\n"; 58273441091SDouglas Gregor if (InferExportWildcard) { 58373441091SDouglas Gregor OS.indent(Indent + 4); 58473441091SDouglas Gregor OS << "export *\n"; 58573441091SDouglas Gregor } 58673441091SDouglas Gregor OS.indent(Indent + 2); 58773441091SDouglas Gregor OS << "}\n"; 58873441091SDouglas Gregor } 58973441091SDouglas Gregor 590de3ef502SDouglas Gregor OS.indent(Indent); 591de3ef502SDouglas Gregor OS << "}\n"; 592de3ef502SDouglas Gregor } 593de3ef502SDouglas Gregor 594cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 595de3ef502SDouglas Gregor print(llvm::errs()); 596de3ef502SDouglas Gregor } 597de3ef502SDouglas Gregor 598a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 599a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 6006d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 601a7e2cc68SRichard Smith if (isVisible(M)) 602a7e2cc68SRichard Smith return; 603de3ef502SDouglas Gregor 604a7e2cc68SRichard Smith ++Generation; 605a7e2cc68SRichard Smith 606a7e2cc68SRichard Smith struct Visiting { 607a7e2cc68SRichard Smith Module *M; 608a7e2cc68SRichard Smith Visiting *ExportedBy; 609a7e2cc68SRichard Smith }; 610a7e2cc68SRichard Smith 611a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 612a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 613a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 614a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 615a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 616a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 617a7e2cc68SRichard Smith return; 618a7e2cc68SRichard Smith 619a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 620a7e2cc68SRichard Smith Vis(M); 621a7e2cc68SRichard Smith 622a7e2cc68SRichard Smith // Make any exported modules visible. 623a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 624a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 625841dbda3SRichard Smith for (Module *E : Exports) { 626841dbda3SRichard Smith // Don't recurse to unavailable submodules. 627841dbda3SRichard Smith if (E->isAvailable()) 628a7e2cc68SRichard Smith VisitModule({E, &V}); 629841dbda3SRichard Smith } 630a7e2cc68SRichard Smith 631a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 632a7e2cc68SRichard Smith if (isVisible(C.Other)) { 633a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 634a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 635a7e2cc68SRichard Smith Path.push_back(I->M); 636a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 637a7e2cc68SRichard Smith } 638a7e2cc68SRichard Smith } 639a7e2cc68SRichard Smith }; 640a7e2cc68SRichard Smith VisitModule({M, nullptr}); 641a7e2cc68SRichard Smith } 642