1918e0ca7SEugene Zelenko //===- Module.cpp - Describe a module -------------------------------------===// 2de3ef502SDouglas Gregor // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6de3ef502SDouglas Gregor // 7de3ef502SDouglas Gregor //===----------------------------------------------------------------------===// 8de3ef502SDouglas Gregor // 9de3ef502SDouglas Gregor // This file defines the Module class, which describes a module in the source 10de3ef502SDouglas Gregor // code. 11de3ef502SDouglas Gregor // 12de3ef502SDouglas Gregor //===----------------------------------------------------------------------===// 13a3feee2aSRichard Smith 14de3ef502SDouglas Gregor #include "clang/Basic/Module.h" 159565c75bSRichard Smith #include "clang/Basic/CharInfo.h" 16de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h" 171fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h" 18918e0ca7SEugene Zelenko #include "clang/Basic/SourceLocation.h" 190070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 203c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h" 211fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 22918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h" 23918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h" 241fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 25918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h" 263a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 273a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 28918e0ca7SEugene Zelenko #include <algorithm> 29918e0ca7SEugene Zelenko #include <cassert> 30918e0ca7SEugene Zelenko #include <functional> 31918e0ca7SEugene Zelenko #include <string> 32918e0ca7SEugene Zelenko #include <utility> 33918e0ca7SEugene Zelenko #include <vector> 34a3feee2aSRichard Smith 35de3ef502SDouglas Gregor using namespace clang; 36de3ef502SDouglas Gregor 37eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 38a7e2cc68SRichard Smith bool IsFramework, bool IsExplicit, unsigned VisibilityID) 39918e0ca7SEugene Zelenko : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 40918e0ca7SEugene Zelenko VisibilityID(VisibilityID), IsMissingRequirement(false), 41918e0ca7SEugene Zelenko HasIncompatibleModuleFile(false), IsAvailable(true), 42918e0ca7SEugene Zelenko IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), 43918e0ca7SEugene Zelenko IsSystem(false), IsExternC(false), IsInferred(false), 44918e0ca7SEugene Zelenko InferSubmodules(false), InferExplicitSubmodules(false), 458a308ec2SRichard Smith InferExportWildcard(false), ConfigMacrosExhaustive(false), 4690b0a1fcSJordan Rose NoUndeclaredIncludes(false), ModuleMapIsPrivate(false), 4790b0a1fcSJordan Rose 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; 5790b0a1fcSJordan Rose if (Parent->ModuleMapIsPrivate) 5890b0a1fcSJordan Rose ModuleMapIsPrivate = true; 59993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 60eb90e830SDouglas Gregor 61eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 62eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 63eb90e830SDouglas Gregor } 64eb90e830SDouglas Gregor } 65eb90e830SDouglas Gregor 66de3ef502SDouglas Gregor Module::~Module() { 67eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 68de3ef502SDouglas Gregor I != IEnd; ++I) { 69eb90e830SDouglas Gregor delete *I; 70de3ef502SDouglas Gregor } 71de3ef502SDouglas Gregor } 72de3ef502SDouglas Gregor 73e7240f02SBruno Cardoso Lopes static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { 74e7240f02SBruno Cardoso Lopes StringRef Platform = Target.getPlatformName(); 75e7240f02SBruno Cardoso Lopes StringRef Env = Target.getTriple().getEnvironmentName(); 76e7240f02SBruno Cardoso Lopes 77e7240f02SBruno Cardoso Lopes // Attempt to match platform and environment. 78e7240f02SBruno Cardoso Lopes if (Platform == Feature || Target.getTriple().getOSName() == Feature || 79e7240f02SBruno Cardoso Lopes Env == Feature) 80e7240f02SBruno Cardoso Lopes return true; 81e7240f02SBruno Cardoso Lopes 82e7240f02SBruno Cardoso Lopes auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) { 83e7240f02SBruno Cardoso Lopes auto Pos = LHS.find("-"); 84e7240f02SBruno Cardoso Lopes if (Pos == StringRef::npos) 85e7240f02SBruno Cardoso Lopes return false; 86e7240f02SBruno Cardoso Lopes SmallString<128> NewLHS = LHS.slice(0, Pos); 87e7240f02SBruno Cardoso Lopes NewLHS += LHS.slice(Pos+1, LHS.size()); 88e7240f02SBruno Cardoso Lopes return NewLHS == RHS; 89e7240f02SBruno Cardoso Lopes }; 90e7240f02SBruno Cardoso Lopes 91e7240f02SBruno Cardoso Lopes SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName(); 92e7240f02SBruno Cardoso Lopes // Darwin has different but equivalent variants for simulators, example: 93e7240f02SBruno Cardoso Lopes // 1. x86_64-apple-ios-simulator 94e7240f02SBruno Cardoso Lopes // 2. x86_64-apple-iossimulator 95e7240f02SBruno Cardoso Lopes // where both are valid examples of the same platform+environment but in the 96e7240f02SBruno Cardoso Lopes // variant (2) the simulator is hardcoded as part of the platform name. Both 97e7240f02SBruno Cardoso Lopes // forms above should match for "iossimulator" requirement. 98e7240f02SBruno Cardoso Lopes if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")) 99e7240f02SBruno Cardoso Lopes return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); 100e7240f02SBruno Cardoso Lopes 101e7240f02SBruno Cardoso Lopes return PlatformEnv == Feature; 102e7240f02SBruno Cardoso Lopes } 103e7240f02SBruno Cardoso Lopes 1049fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current 1051fb5c3a6SDouglas Gregor /// language options has the given feature. 10689929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 10789929282SDouglas Gregor const TargetInfo &Target) { 108532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 1090070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 1101fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 11110ab78e8SRichard Smith .Case("coroutines", LangOpts.Coroutines) 1121fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 1132bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 1146d9cf8aaSBruno Cardoso Lopes .Case("cplusplus14", LangOpts.CPlusPlus14) 1156d9cf8aaSBruno Cardoso Lopes .Case("cplusplus17", LangOpts.CPlusPlus17) 1166d9cf8aaSBruno Cardoso Lopes .Case("c99", LangOpts.C99) 1176d9cf8aaSBruno Cardoso Lopes .Case("c11", LangOpts.C11) 1186d9cf8aaSBruno Cardoso Lopes .Case("c17", LangOpts.C17) 119fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 1206736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 121fa98390bSErik Pilkington .Case("objc", LangOpts.ObjC) 1221fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 1230070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 1240070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 1253c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 126e7240f02SBruno Cardoso Lopes .Default(Target.hasFeature(Feature) || 127e7240f02SBruno Cardoso Lopes isPlatformEnvironment(Target, Feature)); 128532d2104SBen Langmuir if (!HasFeature) 129532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 130532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 131532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 132532d2104SBen Langmuir return HasFeature; 1331fb5c3a6SDouglas Gregor } 1341fb5c3a6SDouglas Gregor 1353c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 1363c1a41adSRichard Smith Requirement &Req, 1378587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader, 1388587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const { 1391fb5c3a6SDouglas Gregor if (IsAvailable) 1401fb5c3a6SDouglas Gregor return true; 1411fb5c3a6SDouglas Gregor 1421fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 1438587dfd9SBruno Cardoso Lopes if (Current->ShadowingModule) { 1448587dfd9SBruno Cardoso Lopes ShadowingModule = Current->ShadowingModule; 1458587dfd9SBruno Cardoso Lopes return false; 1468587dfd9SBruno Cardoso Lopes } 147a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 148a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 149a3feee2aSRichard Smith Current->Requirements[I].second) { 150a3feee2aSRichard Smith Req = Current->Requirements[I]; 1511fb5c3a6SDouglas Gregor return false; 1521fb5c3a6SDouglas Gregor } 1531fb5c3a6SDouglas Gregor } 15475a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 15575a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 15675a7e435SBen Langmuir return false; 15775a7e435SBen Langmuir } 1581fb5c3a6SDouglas Gregor } 1591fb5c3a6SDouglas Gregor 1601fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1611fb5c3a6SDouglas Gregor } 1621fb5c3a6SDouglas Gregor 16362bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 164f5eedd05SDouglas Gregor const Module *This = this; 165f5eedd05SDouglas Gregor do { 166f5eedd05SDouglas Gregor if (This == Other) 167f5eedd05SDouglas Gregor return true; 168f5eedd05SDouglas Gregor 169f5eedd05SDouglas Gregor This = This->Parent; 170f5eedd05SDouglas Gregor } while (This); 171f5eedd05SDouglas Gregor 172f5eedd05SDouglas Gregor return false; 173f5eedd05SDouglas Gregor } 174f5eedd05SDouglas Gregor 17573441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 17673441091SDouglas Gregor const Module *Result = this; 17773441091SDouglas Gregor while (Result->Parent) 17873441091SDouglas Gregor Result = Result->Parent; 17973441091SDouglas Gregor 18073441091SDouglas Gregor return Result; 18173441091SDouglas Gregor } 18273441091SDouglas Gregor 1839565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1849565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1859565c75bSRichard Smith return IdComponent.first; 1869565c75bSRichard Smith } 187918e0ca7SEugene Zelenko 1889565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1899565c75bSRichard Smith 1909565c75bSRichard Smith template<typename InputIter> 1919565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1929565c75bSRichard Smith bool AllowStringLiterals = true) { 1939565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1949565c75bSRichard Smith if (It != Begin) 1959565c75bSRichard Smith OS << "."; 1969565c75bSRichard Smith 1979565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1989565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 1999565c75bSRichard Smith OS << Name; 2009565c75bSRichard Smith else { 2019565c75bSRichard Smith OS << '"'; 2029565c75bSRichard Smith OS.write_escaped(Name); 2039565c75bSRichard Smith OS << '"'; 2049565c75bSRichard Smith } 2059565c75bSRichard Smith } 2069565c75bSRichard Smith } 2079565c75bSRichard Smith 2089565c75bSRichard Smith template<typename Container> 2099565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 2109565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 2119565c75bSRichard Smith } 2129565c75bSRichard Smith 2139565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 214f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 215de3ef502SDouglas Gregor 216de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 217de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 218de3ef502SDouglas Gregor Names.push_back(M->Name); 219de3ef502SDouglas Gregor 220de3ef502SDouglas Gregor std::string Result; 221de3ef502SDouglas Gregor 2229565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 2239565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 2249565c75bSRichard Smith Out.flush(); 225de3ef502SDouglas Gregor 226de3ef502SDouglas Gregor return Result; 227de3ef502SDouglas Gregor } 228de3ef502SDouglas Gregor 2297ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 2307ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 2317ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 2327ff29148SBen Langmuir return false; 2337ff29148SBen Langmuir nameParts = nameParts.drop_back(); 2347ff29148SBen Langmuir } 2357ff29148SBen Langmuir return nameParts.empty(); 2367ff29148SBen Langmuir } 2377ff29148SBen Langmuir 2382b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 2392b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 2402b63d15fSRichard Smith return {"", U.Entry->getDir()}; 24173141fa9SDouglas Gregor 2422b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 24373141fa9SDouglas Gregor } 24473141fa9SDouglas Gregor 2453c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2463c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2473c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2483c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2498d323d15SHarlan Haskins if (auto FE = FileMgr.getFile(*I)) 2508d323d15SHarlan Haskins TopHeaders.insert(*FE); 2513c5305c1SArgyrios Kyrtzidis } 2523c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2533c5305c1SArgyrios Kyrtzidis } 2543c5305c1SArgyrios Kyrtzidis 2553c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2563c5305c1SArgyrios Kyrtzidis } 2573c5305c1SArgyrios Kyrtzidis 2588f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2598f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2608f4d3ff1SRichard Smith 2618f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2628f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2638f4d3ff1SRichard Smith return true; 2648f4d3ff1SRichard Smith 2658f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2668f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2678f4d3ff1SRichard Smith return true; 268ed84df00SBruno Cardoso Lopes 269ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 270ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 271ed84df00SBruno Cardoso Lopes return true; 272ed84df00SBruno Cardoso Lopes 2738f4d3ff1SRichard Smith return false; 2748f4d3ff1SRichard Smith } 2758f4d3ff1SRichard Smith 276a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 277a3feee2aSRichard Smith const LangOptions &LangOpts, 27889929282SDouglas Gregor const TargetInfo &Target) { 279*bb39b529SBenjamin Kramer Requirements.push_back(Requirement(std::string(Feature), RequiredState)); 2801fb5c3a6SDouglas Gregor 2811fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 282a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2831fb5c3a6SDouglas Gregor return; 2841fb5c3a6SDouglas Gregor 285993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 286ec8c9752SBen Langmuir } 287ec8c9752SBen Langmuir 288993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 28975a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 29075a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 29175a7e435SBen Langmuir }; 29275a7e435SBen Langmuir 29375a7e435SBen Langmuir if (!needUpdate(this)) 2941fb5c3a6SDouglas Gregor return; 2951fb5c3a6SDouglas Gregor 296f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2971fb5c3a6SDouglas Gregor Stack.push_back(this); 2981fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2991fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 3001fb5c3a6SDouglas Gregor Stack.pop_back(); 3011fb5c3a6SDouglas Gregor 30275a7e435SBen Langmuir if (!needUpdate(Current)) 3031fb5c3a6SDouglas Gregor continue; 3041fb5c3a6SDouglas Gregor 3051fb5c3a6SDouglas Gregor Current->IsAvailable = false; 306993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 307eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 308eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 3091fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 31075a7e435SBen Langmuir if (needUpdate(*Sub)) 311eb90e830SDouglas Gregor Stack.push_back(*Sub); 3121fb5c3a6SDouglas Gregor } 3131fb5c3a6SDouglas Gregor } 3141fb5c3a6SDouglas Gregor } 3151fb5c3a6SDouglas Gregor 316eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 317eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 318eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 319f1186c5aSCraig Topper return nullptr; 320eb90e830SDouglas Gregor 321eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 322eb90e830SDouglas Gregor } 323eb90e830SDouglas Gregor 32489e58ddbSDavid Blaikie Module *Module::findOrInferSubmodule(StringRef Name) { 32589e58ddbSDavid Blaikie llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 32689e58ddbSDavid Blaikie if (Pos != SubModuleIndex.end()) 32789e58ddbSDavid Blaikie return SubModules[Pos->getValue()]; 32889e58ddbSDavid Blaikie if (!InferSubmodules) 32989e58ddbSDavid Blaikie return nullptr; 33089e58ddbSDavid Blaikie Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0); 33189e58ddbSDavid Blaikie Result->InferExplicitSubmodules = InferExplicitSubmodules; 33289e58ddbSDavid Blaikie Result->InferSubmodules = InferSubmodules; 33389e58ddbSDavid Blaikie Result->InferExportWildcard = InferExportWildcard; 33489e58ddbSDavid Blaikie if (Result->InferExportWildcard) 33589e58ddbSDavid Blaikie Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 33689e58ddbSDavid Blaikie return Result; 33789e58ddbSDavid Blaikie } 33889e58ddbSDavid Blaikie 3398739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 340e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 341e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 342e9bcf5b7SDmitri Gribenko E = SubModules.end(); 343e9bcf5b7SDmitri Gribenko I != E; ++I) { 344e9bcf5b7SDmitri Gribenko Module *Mod = *I; 345e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 346e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 347e9bcf5b7SDmitri Gribenko } 348e9bcf5b7SDmitri Gribenko 349e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 3508739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 3518739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 3528739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 3538739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 3548739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 3558739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 3568739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 3578739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3588739f7b7SArgyrios Kyrtzidis 3598739f7b7SArgyrios Kyrtzidis continue; 3608739f7b7SArgyrios Kyrtzidis } 3618739f7b7SArgyrios Kyrtzidis 3628739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3638739f7b7SArgyrios Kyrtzidis // the given pattern. 3648739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3658739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3668739f7b7SArgyrios Kyrtzidis continue; 3678739f7b7SArgyrios Kyrtzidis 3688739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3698739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3708739f7b7SArgyrios Kyrtzidis else { 3718739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3728739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3738739f7b7SArgyrios Kyrtzidis } 3748739f7b7SArgyrios Kyrtzidis } 3758739f7b7SArgyrios Kyrtzidis 3768739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3778739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3788739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3798739f7b7SArgyrios Kyrtzidis return; 3808739f7b7SArgyrios Kyrtzidis 3818739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3828739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3838739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3848739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3858739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3868739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3878739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3888739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3898739f7b7SArgyrios Kyrtzidis Acceptable = true; 3908739f7b7SArgyrios Kyrtzidis break; 3918739f7b7SArgyrios Kyrtzidis } 3928739f7b7SArgyrios Kyrtzidis } 3938739f7b7SArgyrios Kyrtzidis } 3948739f7b7SArgyrios Kyrtzidis 3958739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3968739f7b7SArgyrios Kyrtzidis continue; 3978739f7b7SArgyrios Kyrtzidis 3988739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3998739f7b7SArgyrios Kyrtzidis } 4008739f7b7SArgyrios Kyrtzidis } 4018739f7b7SArgyrios Kyrtzidis 4020e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 4030e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 4040e5d7b8cSRichard Smith 4050e5d7b8cSRichard Smith // This module is visible to itself. 4060e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 4070e5d7b8cSRichard Smith 4080e5d7b8cSRichard Smith // Every imported module is visible. 409dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 410dc360d57SDmitri Gribenko while (!Stack.empty()) { 411dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 412dc360d57SDmitri Gribenko 413dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 414dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 415dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 4160e5d7b8cSRichard Smith } 4170e5d7b8cSRichard Smith } 4180e5d7b8cSRichard Smith 419f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 420de3ef502SDouglas Gregor OS.indent(Indent); 421de3ef502SDouglas Gregor if (IsFramework) 422de3ef502SDouglas Gregor OS << "framework "; 423de3ef502SDouglas Gregor if (IsExplicit) 424de3ef502SDouglas Gregor OS << "explicit "; 4259565c75bSRichard Smith OS << "module "; 4269565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 427a686e1b0SDouglas Gregor 4287615f00eSBen Langmuir if (IsSystem || IsExternC) { 429a686e1b0SDouglas Gregor OS.indent(Indent + 2); 4307615f00eSBen Langmuir if (IsSystem) 431a686e1b0SDouglas Gregor OS << " [system]"; 4327615f00eSBen Langmuir if (IsExternC) 4337615f00eSBen Langmuir OS << " [extern_c]"; 434a686e1b0SDouglas Gregor } 435a686e1b0SDouglas Gregor 436a686e1b0SDouglas Gregor OS << " {\n"; 437de3ef502SDouglas Gregor 438a3feee2aSRichard Smith if (!Requirements.empty()) { 4391fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 4401fb5c3a6SDouglas Gregor OS << "requires "; 441a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 4421fb5c3a6SDouglas Gregor if (I) 4431fb5c3a6SDouglas Gregor OS << ", "; 444a3feee2aSRichard Smith if (!Requirements[I].second) 445a3feee2aSRichard Smith OS << "!"; 446a3feee2aSRichard Smith OS << Requirements[I].first; 4471fb5c3a6SDouglas Gregor } 4481fb5c3a6SDouglas Gregor OS << "\n"; 4491fb5c3a6SDouglas Gregor } 4501fb5c3a6SDouglas Gregor 4512b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 452de3ef502SDouglas Gregor OS.indent(Indent + 2); 453322f633cSDouglas Gregor OS << "umbrella header \""; 4542b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 455de3ef502SDouglas Gregor OS << "\"\n"; 4562b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 457322f633cSDouglas Gregor OS.indent(Indent + 2); 458322f633cSDouglas Gregor OS << "umbrella \""; 4592b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 460322f633cSDouglas Gregor OS << "\"\n"; 461de3ef502SDouglas Gregor } 462de3ef502SDouglas Gregor 46335b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 46435b13eceSDouglas Gregor OS.indent(Indent + 2); 46535b13eceSDouglas Gregor OS << "config_macros "; 46635b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4678d932427SDouglas Gregor OS << "[exhaustive]"; 46835b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 46935b13eceSDouglas Gregor if (I) 47035b13eceSDouglas Gregor OS << ", "; 47135b13eceSDouglas Gregor OS << ConfigMacros[I]; 47235b13eceSDouglas Gregor } 4738d932427SDouglas Gregor OS << "\n"; 47435b13eceSDouglas Gregor } 47535b13eceSDouglas Gregor 4763c1a41adSRichard Smith struct { 477306d8920SRichard Smith StringRef Prefix; 4783c1a41adSRichard Smith HeaderKind Kind; 4793c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4803c1a41adSRichard Smith {"textual ", HK_Textual}, 4813c1a41adSRichard Smith {"private ", HK_Private}, 4823c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4833c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 484306d8920SRichard Smith 485306d8920SRichard Smith for (auto &K : Kinds) { 486040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4873c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 488de3ef502SDouglas Gregor OS.indent(Indent + 2); 489306d8920SRichard Smith OS << K.Prefix << "header \""; 4903c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 491040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 492040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 493040e1266SRichard Smith } 494040e1266SRichard Smith } 495040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 496040e1266SRichard Smith for (auto &U : *Unresolved) { 497040e1266SRichard Smith OS.indent(Indent + 2); 498040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 499040e1266SRichard Smith OS.write_escaped(U.FileName); 500040e1266SRichard Smith OS << "\""; 501040e1266SRichard Smith if (U.Size || U.ModTime) { 502040e1266SRichard Smith OS << " {"; 503040e1266SRichard Smith if (U.Size) 504040e1266SRichard Smith OS << " size " << *U.Size; 505040e1266SRichard Smith if (U.ModTime) 506040e1266SRichard Smith OS << " mtime " << *U.ModTime; 507040e1266SRichard Smith OS << " }"; 508040e1266SRichard Smith } 509040e1266SRichard Smith OS << "\n"; 510de3ef502SDouglas Gregor } 511b53e5483SLawrence Crowl } 512b53e5483SLawrence Crowl 513f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 514f0b11de2SDouglas Gregor OS.indent(Indent + 2); 515f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 516f0b11de2SDouglas Gregor } 517f0b11de2SDouglas Gregor 518eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 519de3ef502SDouglas Gregor MI != MIEnd; ++MI) 5209d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 5219d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 5229d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 5239d6448b1SBen Langmuir // those header files anyway. 5249d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 525eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 526de3ef502SDouglas Gregor 52724bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 52824bb923aSDouglas Gregor OS.indent(Indent + 2); 5298c7c8352SDouglas Gregor OS << "export "; 5308c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 5319565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 53224bb923aSDouglas Gregor if (Exports[I].getInt()) 53324bb923aSDouglas Gregor OS << ".*"; 5348c7c8352SDouglas Gregor } else { 5358c7c8352SDouglas Gregor OS << "*"; 5368c7c8352SDouglas Gregor } 53724bb923aSDouglas Gregor OS << "\n"; 53824bb923aSDouglas Gregor } 53924bb923aSDouglas Gregor 54024bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 54124bb923aSDouglas Gregor OS.indent(Indent + 2); 54224bb923aSDouglas Gregor OS << "export "; 54324bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 5447f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 5457f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 54624bb923aSDouglas Gregor OS << "\n"; 54724bb923aSDouglas Gregor } 54824bb923aSDouglas Gregor 549ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 550ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 551ba7f2f71SDaniel Jasper OS << "use "; 5529565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 553ba7f2f71SDaniel Jasper OS << "\n"; 554ba7f2f71SDaniel Jasper } 555ba7f2f71SDaniel Jasper 556ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 557ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 558ba7f2f71SDaniel Jasper OS << "use "; 559ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 560ba7f2f71SDaniel Jasper OS << "\n"; 561ba7f2f71SDaniel Jasper } 562ba7f2f71SDaniel Jasper 5636ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5646ddfca91SDouglas Gregor OS.indent(Indent + 2); 5656ddfca91SDouglas Gregor OS << "link "; 5666ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5676ddfca91SDouglas Gregor OS << "framework "; 5686ddfca91SDouglas Gregor OS << "\""; 5696ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5706ddfca91SDouglas Gregor OS << "\""; 5716ddfca91SDouglas Gregor } 5726ddfca91SDouglas Gregor 573fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 574fb912657SDouglas Gregor OS.indent(Indent + 2); 575fb912657SDouglas Gregor OS << "conflict "; 576fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 577fb912657SDouglas Gregor OS << ", \""; 578fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 579fb912657SDouglas Gregor OS << "\"\n"; 580fb912657SDouglas Gregor } 581fb912657SDouglas Gregor 582fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 583fb912657SDouglas Gregor OS.indent(Indent + 2); 584fb912657SDouglas Gregor OS << "conflict "; 5859565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 586fb912657SDouglas Gregor OS << ", \""; 587fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 588fb912657SDouglas Gregor OS << "\"\n"; 589fb912657SDouglas Gregor } 590fb912657SDouglas Gregor 59173441091SDouglas Gregor if (InferSubmodules) { 59273441091SDouglas Gregor OS.indent(Indent + 2); 59373441091SDouglas Gregor if (InferExplicitSubmodules) 59473441091SDouglas Gregor OS << "explicit "; 59573441091SDouglas Gregor OS << "module * {\n"; 59673441091SDouglas Gregor if (InferExportWildcard) { 59773441091SDouglas Gregor OS.indent(Indent + 4); 59873441091SDouglas Gregor OS << "export *\n"; 59973441091SDouglas Gregor } 60073441091SDouglas Gregor OS.indent(Indent + 2); 60173441091SDouglas Gregor OS << "}\n"; 60273441091SDouglas Gregor } 60373441091SDouglas Gregor 604de3ef502SDouglas Gregor OS.indent(Indent); 605de3ef502SDouglas Gregor OS << "}\n"; 606de3ef502SDouglas Gregor } 607de3ef502SDouglas Gregor 608cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 609de3ef502SDouglas Gregor print(llvm::errs()); 610de3ef502SDouglas Gregor } 611de3ef502SDouglas Gregor 612a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 613a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 6146d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 615a7e2cc68SRichard Smith if (isVisible(M)) 616a7e2cc68SRichard Smith return; 617de3ef502SDouglas Gregor 618a7e2cc68SRichard Smith ++Generation; 619a7e2cc68SRichard Smith 620a7e2cc68SRichard Smith struct Visiting { 621a7e2cc68SRichard Smith Module *M; 622a7e2cc68SRichard Smith Visiting *ExportedBy; 623a7e2cc68SRichard Smith }; 624a7e2cc68SRichard Smith 625a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 626a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 627a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 628a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 629a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 630a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 631a7e2cc68SRichard Smith return; 632a7e2cc68SRichard Smith 633a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 634a7e2cc68SRichard Smith Vis(M); 635a7e2cc68SRichard Smith 636a7e2cc68SRichard Smith // Make any exported modules visible. 637a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 638a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 639841dbda3SRichard Smith for (Module *E : Exports) { 640841dbda3SRichard Smith // Don't recurse to unavailable submodules. 641841dbda3SRichard Smith if (E->isAvailable()) 642a7e2cc68SRichard Smith VisitModule({E, &V}); 643841dbda3SRichard Smith } 644a7e2cc68SRichard Smith 645a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 646a7e2cc68SRichard Smith if (isVisible(C.Other)) { 647a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 648a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 649a7e2cc68SRichard Smith Path.push_back(I->M); 650a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 651a7e2cc68SRichard Smith } 652a7e2cc68SRichard Smith } 653a7e2cc68SRichard Smith }; 654a7e2cc68SRichard Smith VisitModule({M, nullptr}); 655a7e2cc68SRichard Smith } 656