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), 40*fc76b4adSRichard Smith VisibilityID(VisibilityID), IsUnimportable(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), 47bc883665SReid Kleckner HasUmbrellaDir(false), NameVisibility(Hidden) { 48eb90e830SDouglas Gregor if (Parent) { 49*fc76b4adSRichard Smith IsAvailable = Parent->isAvailable(); 50*fc76b4adSRichard Smith IsUnimportable = Parent->isUnimportable(); 51*fc76b4adSRichard Smith IsSystem = Parent->IsSystem; 52*fc76b4adSRichard Smith IsExternC = Parent->IsExternC; 53*fc76b4adSRichard Smith NoUndeclaredIncludes = Parent->NoUndeclaredIncludes; 54*fc76b4adSRichard Smith ModuleMapIsPrivate = Parent->ModuleMapIsPrivate; 55eb90e830SDouglas Gregor 56eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 57eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 58eb90e830SDouglas Gregor } 59eb90e830SDouglas Gregor } 60eb90e830SDouglas Gregor 61de3ef502SDouglas Gregor Module::~Module() { 62eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 63de3ef502SDouglas Gregor I != IEnd; ++I) { 64eb90e830SDouglas Gregor delete *I; 65de3ef502SDouglas Gregor } 66de3ef502SDouglas Gregor } 67de3ef502SDouglas Gregor 68e7240f02SBruno Cardoso Lopes static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { 69e7240f02SBruno Cardoso Lopes StringRef Platform = Target.getPlatformName(); 70e7240f02SBruno Cardoso Lopes StringRef Env = Target.getTriple().getEnvironmentName(); 71e7240f02SBruno Cardoso Lopes 72e7240f02SBruno Cardoso Lopes // Attempt to match platform and environment. 73e7240f02SBruno Cardoso Lopes if (Platform == Feature || Target.getTriple().getOSName() == Feature || 74e7240f02SBruno Cardoso Lopes Env == Feature) 75e7240f02SBruno Cardoso Lopes return true; 76e7240f02SBruno Cardoso Lopes 77e7240f02SBruno Cardoso Lopes auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) { 78e7240f02SBruno Cardoso Lopes auto Pos = LHS.find("-"); 79e7240f02SBruno Cardoso Lopes if (Pos == StringRef::npos) 80e7240f02SBruno Cardoso Lopes return false; 81e7240f02SBruno Cardoso Lopes SmallString<128> NewLHS = LHS.slice(0, Pos); 82e7240f02SBruno Cardoso Lopes NewLHS += LHS.slice(Pos+1, LHS.size()); 83e7240f02SBruno Cardoso Lopes return NewLHS == RHS; 84e7240f02SBruno Cardoso Lopes }; 85e7240f02SBruno Cardoso Lopes 86e7240f02SBruno Cardoso Lopes SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName(); 87e7240f02SBruno Cardoso Lopes // Darwin has different but equivalent variants for simulators, example: 88e7240f02SBruno Cardoso Lopes // 1. x86_64-apple-ios-simulator 89e7240f02SBruno Cardoso Lopes // 2. x86_64-apple-iossimulator 90e7240f02SBruno Cardoso Lopes // where both are valid examples of the same platform+environment but in the 91e7240f02SBruno Cardoso Lopes // variant (2) the simulator is hardcoded as part of the platform name. Both 92e7240f02SBruno Cardoso Lopes // forms above should match for "iossimulator" requirement. 93e7240f02SBruno Cardoso Lopes if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")) 94e7240f02SBruno Cardoso Lopes return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); 95e7240f02SBruno Cardoso Lopes 96e7240f02SBruno Cardoso Lopes return PlatformEnv == Feature; 97e7240f02SBruno Cardoso Lopes } 98e7240f02SBruno Cardoso Lopes 999fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current 1001fb5c3a6SDouglas Gregor /// language options has the given feature. 10189929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 10289929282SDouglas Gregor const TargetInfo &Target) { 103532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 1040070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 1051fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 10610ab78e8SRichard Smith .Case("coroutines", LangOpts.Coroutines) 1071fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 1082bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 1096d9cf8aaSBruno Cardoso Lopes .Case("cplusplus14", LangOpts.CPlusPlus14) 1106d9cf8aaSBruno Cardoso Lopes .Case("cplusplus17", LangOpts.CPlusPlus17) 1116d9cf8aaSBruno Cardoso Lopes .Case("c99", LangOpts.C99) 1126d9cf8aaSBruno Cardoso Lopes .Case("c11", LangOpts.C11) 1136d9cf8aaSBruno Cardoso Lopes .Case("c17", LangOpts.C17) 114fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 1156736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 116fa98390bSErik Pilkington .Case("objc", LangOpts.ObjC) 1171fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 1180070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 1190070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 1203c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 121e7240f02SBruno Cardoso Lopes .Default(Target.hasFeature(Feature) || 122e7240f02SBruno Cardoso Lopes isPlatformEnvironment(Target, Feature)); 123532d2104SBen Langmuir if (!HasFeature) 124532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 125532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 126532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 127532d2104SBen Langmuir return HasFeature; 1281fb5c3a6SDouglas Gregor } 1291fb5c3a6SDouglas Gregor 130*fc76b4adSRichard Smith bool Module::isUnimportable(const LangOptions &LangOpts, 131*fc76b4adSRichard Smith const TargetInfo &Target, Requirement &Req, 132*fc76b4adSRichard Smith Module *&ShadowingModule) const { 133*fc76b4adSRichard Smith if (!IsUnimportable) 134*fc76b4adSRichard Smith return false; 135*fc76b4adSRichard Smith 136*fc76b4adSRichard Smith for (const Module *Current = this; Current; Current = Current->Parent) { 137*fc76b4adSRichard Smith if (Current->ShadowingModule) { 138*fc76b4adSRichard Smith ShadowingModule = Current->ShadowingModule; 139*fc76b4adSRichard Smith return true; 140*fc76b4adSRichard Smith } 141*fc76b4adSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 142*fc76b4adSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 143*fc76b4adSRichard Smith Current->Requirements[I].second) { 144*fc76b4adSRichard Smith Req = Current->Requirements[I]; 145*fc76b4adSRichard Smith return true; 146*fc76b4adSRichard Smith } 147*fc76b4adSRichard Smith } 148*fc76b4adSRichard Smith } 149*fc76b4adSRichard Smith 150*fc76b4adSRichard Smith llvm_unreachable("could not find a reason why module is unimportable"); 151*fc76b4adSRichard Smith } 152*fc76b4adSRichard Smith 1533c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 1543c1a41adSRichard Smith Requirement &Req, 1558587dfd9SBruno Cardoso Lopes UnresolvedHeaderDirective &MissingHeader, 1568587dfd9SBruno Cardoso Lopes Module *&ShadowingModule) const { 1571fb5c3a6SDouglas Gregor if (IsAvailable) 1581fb5c3a6SDouglas Gregor return true; 1591fb5c3a6SDouglas Gregor 160*fc76b4adSRichard Smith if (isUnimportable(LangOpts, Target, Req, ShadowingModule)) 161*fc76b4adSRichard Smith return false; 162*fc76b4adSRichard Smith 163*fc76b4adSRichard Smith // FIXME: All missing headers are listed on the top-level module. Should we 164*fc76b4adSRichard Smith // just look there? 1651fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 16675a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 16775a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 16875a7e435SBen Langmuir return false; 16975a7e435SBen Langmuir } 1701fb5c3a6SDouglas Gregor } 1711fb5c3a6SDouglas Gregor 1721fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1731fb5c3a6SDouglas Gregor } 1741fb5c3a6SDouglas Gregor 17562bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 176f5eedd05SDouglas Gregor const Module *This = this; 177f5eedd05SDouglas Gregor do { 178f5eedd05SDouglas Gregor if (This == Other) 179f5eedd05SDouglas Gregor return true; 180f5eedd05SDouglas Gregor 181f5eedd05SDouglas Gregor This = This->Parent; 182f5eedd05SDouglas Gregor } while (This); 183f5eedd05SDouglas Gregor 184f5eedd05SDouglas Gregor return false; 185f5eedd05SDouglas Gregor } 186f5eedd05SDouglas Gregor 18773441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 18873441091SDouglas Gregor const Module *Result = this; 18973441091SDouglas Gregor while (Result->Parent) 19073441091SDouglas Gregor Result = Result->Parent; 19173441091SDouglas Gregor 19273441091SDouglas Gregor return Result; 19373441091SDouglas Gregor } 19473441091SDouglas Gregor 1959565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1969565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1979565c75bSRichard Smith return IdComponent.first; 1989565c75bSRichard Smith } 199918e0ca7SEugene Zelenko 2009565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 2019565c75bSRichard Smith 2029565c75bSRichard Smith template<typename InputIter> 2039565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 2049565c75bSRichard Smith bool AllowStringLiterals = true) { 2059565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 2069565c75bSRichard Smith if (It != Begin) 2079565c75bSRichard Smith OS << "."; 2089565c75bSRichard Smith 2099565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 2109565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 2119565c75bSRichard Smith OS << Name; 2129565c75bSRichard Smith else { 2139565c75bSRichard Smith OS << '"'; 2149565c75bSRichard Smith OS.write_escaped(Name); 2159565c75bSRichard Smith OS << '"'; 2169565c75bSRichard Smith } 2179565c75bSRichard Smith } 2189565c75bSRichard Smith } 2199565c75bSRichard Smith 2209565c75bSRichard Smith template<typename Container> 2219565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 2229565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 2239565c75bSRichard Smith } 2249565c75bSRichard Smith 2259565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 226f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 227de3ef502SDouglas Gregor 228de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 229de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 230de3ef502SDouglas Gregor Names.push_back(M->Name); 231de3ef502SDouglas Gregor 232de3ef502SDouglas Gregor std::string Result; 233de3ef502SDouglas Gregor 2349565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 2359565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 2369565c75bSRichard Smith Out.flush(); 237de3ef502SDouglas Gregor 238de3ef502SDouglas Gregor return Result; 239de3ef502SDouglas Gregor } 240de3ef502SDouglas Gregor 2417ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 2427ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 2437ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 2447ff29148SBen Langmuir return false; 2457ff29148SBen Langmuir nameParts = nameParts.drop_back(); 2467ff29148SBen Langmuir } 2477ff29148SBen Langmuir return nameParts.empty(); 2487ff29148SBen Langmuir } 2497ff29148SBen Langmuir 2502b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 2512b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 2522b63d15fSRichard Smith return {"", U.Entry->getDir()}; 25373141fa9SDouglas Gregor 254bc883665SReid Kleckner return {UmbrellaAsWritten, static_cast<const DirectoryEntry *>(Umbrella)}; 255bc883665SReid Kleckner } 256bc883665SReid Kleckner 257bc883665SReid Kleckner void Module::addTopHeader(const FileEntry *File) { 258bc883665SReid Kleckner assert(File); 259bc883665SReid Kleckner TopHeaders.insert(File); 26073141fa9SDouglas Gregor } 26173141fa9SDouglas Gregor 2623c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 2633c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 2643c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 2653c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 2668d323d15SHarlan Haskins if (auto FE = FileMgr.getFile(*I)) 2678d323d15SHarlan Haskins TopHeaders.insert(*FE); 2683c5305c1SArgyrios Kyrtzidis } 2693c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 2703c5305c1SArgyrios Kyrtzidis } 2713c5305c1SArgyrios Kyrtzidis 2723c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2733c5305c1SArgyrios Kyrtzidis } 2743c5305c1SArgyrios Kyrtzidis 2758f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2768f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2778f4d3ff1SRichard Smith 2788f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2798f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2808f4d3ff1SRichard Smith return true; 2818f4d3ff1SRichard Smith 2828f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2838f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2848f4d3ff1SRichard Smith return true; 285ed84df00SBruno Cardoso Lopes 286ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 287ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 288ed84df00SBruno Cardoso Lopes return true; 289ed84df00SBruno Cardoso Lopes 2908f4d3ff1SRichard Smith return false; 2918f4d3ff1SRichard Smith } 2928f4d3ff1SRichard Smith 293a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 294a3feee2aSRichard Smith const LangOptions &LangOpts, 29589929282SDouglas Gregor const TargetInfo &Target) { 296bb39b529SBenjamin Kramer Requirements.push_back(Requirement(std::string(Feature), RequiredState)); 2971fb5c3a6SDouglas Gregor 2981fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 299a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 3001fb5c3a6SDouglas Gregor return; 3011fb5c3a6SDouglas Gregor 302*fc76b4adSRichard Smith markUnavailable(/*Unimportable*/true); 303ec8c9752SBen Langmuir } 304ec8c9752SBen Langmuir 305*fc76b4adSRichard Smith void Module::markUnavailable(bool Unimportable) { 306*fc76b4adSRichard Smith auto needUpdate = [Unimportable](Module *M) { 307*fc76b4adSRichard Smith return M->IsAvailable || (!M->IsUnimportable && Unimportable); 30875a7e435SBen Langmuir }; 30975a7e435SBen Langmuir 31075a7e435SBen Langmuir if (!needUpdate(this)) 3111fb5c3a6SDouglas Gregor return; 3121fb5c3a6SDouglas Gregor 313f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 3141fb5c3a6SDouglas Gregor Stack.push_back(this); 3151fb5c3a6SDouglas Gregor while (!Stack.empty()) { 3161fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 3171fb5c3a6SDouglas Gregor Stack.pop_back(); 3181fb5c3a6SDouglas Gregor 31975a7e435SBen Langmuir if (!needUpdate(Current)) 3201fb5c3a6SDouglas Gregor continue; 3211fb5c3a6SDouglas Gregor 3221fb5c3a6SDouglas Gregor Current->IsAvailable = false; 323*fc76b4adSRichard Smith Current->IsUnimportable |= Unimportable; 324eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 325eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 3261fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 32775a7e435SBen Langmuir if (needUpdate(*Sub)) 328eb90e830SDouglas Gregor Stack.push_back(*Sub); 3291fb5c3a6SDouglas Gregor } 3301fb5c3a6SDouglas Gregor } 3311fb5c3a6SDouglas Gregor } 3321fb5c3a6SDouglas Gregor 333eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 334eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 335eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 336f1186c5aSCraig Topper return nullptr; 337eb90e830SDouglas Gregor 338eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 339eb90e830SDouglas Gregor } 340eb90e830SDouglas Gregor 34189e58ddbSDavid Blaikie Module *Module::findOrInferSubmodule(StringRef Name) { 34289e58ddbSDavid Blaikie llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 34389e58ddbSDavid Blaikie if (Pos != SubModuleIndex.end()) 34489e58ddbSDavid Blaikie return SubModules[Pos->getValue()]; 34589e58ddbSDavid Blaikie if (!InferSubmodules) 34689e58ddbSDavid Blaikie return nullptr; 34789e58ddbSDavid Blaikie Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0); 34889e58ddbSDavid Blaikie Result->InferExplicitSubmodules = InferExplicitSubmodules; 34989e58ddbSDavid Blaikie Result->InferSubmodules = InferSubmodules; 35089e58ddbSDavid Blaikie Result->InferExportWildcard = InferExportWildcard; 35189e58ddbSDavid Blaikie if (Result->InferExportWildcard) 35289e58ddbSDavid Blaikie Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 35389e58ddbSDavid Blaikie return Result; 35489e58ddbSDavid Blaikie } 35589e58ddbSDavid Blaikie 3568739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 357e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 358e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 359e9bcf5b7SDmitri Gribenko E = SubModules.end(); 360e9bcf5b7SDmitri Gribenko I != E; ++I) { 361e9bcf5b7SDmitri Gribenko Module *Mod = *I; 362e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 363e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 364e9bcf5b7SDmitri Gribenko } 365e9bcf5b7SDmitri Gribenko 366e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 3678739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 3688739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 3698739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 3708739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 3718739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 3728739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 3738739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 3748739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3758739f7b7SArgyrios Kyrtzidis 3768739f7b7SArgyrios Kyrtzidis continue; 3778739f7b7SArgyrios Kyrtzidis } 3788739f7b7SArgyrios Kyrtzidis 3798739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 3808739f7b7SArgyrios Kyrtzidis // the given pattern. 3818739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 3828739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 3838739f7b7SArgyrios Kyrtzidis continue; 3848739f7b7SArgyrios Kyrtzidis 3858739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 3868739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3878739f7b7SArgyrios Kyrtzidis else { 3888739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3898739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3908739f7b7SArgyrios Kyrtzidis } 3918739f7b7SArgyrios Kyrtzidis } 3928739f7b7SArgyrios Kyrtzidis 3938739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3948739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3958739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3968739f7b7SArgyrios Kyrtzidis return; 3978739f7b7SArgyrios Kyrtzidis 3988739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3998739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 4008739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 4018739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 4028739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 4038739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 4048739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 4058739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 4068739f7b7SArgyrios Kyrtzidis Acceptable = true; 4078739f7b7SArgyrios Kyrtzidis break; 4088739f7b7SArgyrios Kyrtzidis } 4098739f7b7SArgyrios Kyrtzidis } 4108739f7b7SArgyrios Kyrtzidis } 4118739f7b7SArgyrios Kyrtzidis 4128739f7b7SArgyrios Kyrtzidis if (!Acceptable) 4138739f7b7SArgyrios Kyrtzidis continue; 4148739f7b7SArgyrios Kyrtzidis 4158739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 4168739f7b7SArgyrios Kyrtzidis } 4178739f7b7SArgyrios Kyrtzidis } 4188739f7b7SArgyrios Kyrtzidis 4190e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 4200e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 4210e5d7b8cSRichard Smith 4220e5d7b8cSRichard Smith // This module is visible to itself. 4230e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 4240e5d7b8cSRichard Smith 4250e5d7b8cSRichard Smith // Every imported module is visible. 426dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 427dc360d57SDmitri Gribenko while (!Stack.empty()) { 428dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 429dc360d57SDmitri Gribenko 430dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 431dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 432dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 4330e5d7b8cSRichard Smith } 4340e5d7b8cSRichard Smith } 4350e5d7b8cSRichard Smith 436f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 437de3ef502SDouglas Gregor OS.indent(Indent); 438de3ef502SDouglas Gregor if (IsFramework) 439de3ef502SDouglas Gregor OS << "framework "; 440de3ef502SDouglas Gregor if (IsExplicit) 441de3ef502SDouglas Gregor OS << "explicit "; 4429565c75bSRichard Smith OS << "module "; 4439565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 444a686e1b0SDouglas Gregor 4457615f00eSBen Langmuir if (IsSystem || IsExternC) { 446a686e1b0SDouglas Gregor OS.indent(Indent + 2); 4477615f00eSBen Langmuir if (IsSystem) 448a686e1b0SDouglas Gregor OS << " [system]"; 4497615f00eSBen Langmuir if (IsExternC) 4507615f00eSBen Langmuir OS << " [extern_c]"; 451a686e1b0SDouglas Gregor } 452a686e1b0SDouglas Gregor 453a686e1b0SDouglas Gregor OS << " {\n"; 454de3ef502SDouglas Gregor 455a3feee2aSRichard Smith if (!Requirements.empty()) { 4561fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 4571fb5c3a6SDouglas Gregor OS << "requires "; 458a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 4591fb5c3a6SDouglas Gregor if (I) 4601fb5c3a6SDouglas Gregor OS << ", "; 461a3feee2aSRichard Smith if (!Requirements[I].second) 462a3feee2aSRichard Smith OS << "!"; 463a3feee2aSRichard Smith OS << Requirements[I].first; 4641fb5c3a6SDouglas Gregor } 4651fb5c3a6SDouglas Gregor OS << "\n"; 4661fb5c3a6SDouglas Gregor } 4671fb5c3a6SDouglas Gregor 4682b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 469de3ef502SDouglas Gregor OS.indent(Indent + 2); 470322f633cSDouglas Gregor OS << "umbrella header \""; 4712b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 472de3ef502SDouglas Gregor OS << "\"\n"; 4732b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 474322f633cSDouglas Gregor OS.indent(Indent + 2); 475322f633cSDouglas Gregor OS << "umbrella \""; 4762b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 477322f633cSDouglas Gregor OS << "\"\n"; 478de3ef502SDouglas Gregor } 479de3ef502SDouglas Gregor 48035b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 48135b13eceSDouglas Gregor OS.indent(Indent + 2); 48235b13eceSDouglas Gregor OS << "config_macros "; 48335b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 4848d932427SDouglas Gregor OS << "[exhaustive]"; 48535b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 48635b13eceSDouglas Gregor if (I) 48735b13eceSDouglas Gregor OS << ", "; 48835b13eceSDouglas Gregor OS << ConfigMacros[I]; 48935b13eceSDouglas Gregor } 4908d932427SDouglas Gregor OS << "\n"; 49135b13eceSDouglas Gregor } 49235b13eceSDouglas Gregor 4933c1a41adSRichard Smith struct { 494306d8920SRichard Smith StringRef Prefix; 4953c1a41adSRichard Smith HeaderKind Kind; 4963c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4973c1a41adSRichard Smith {"textual ", HK_Textual}, 4983c1a41adSRichard Smith {"private ", HK_Private}, 4993c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 5003c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 501306d8920SRichard Smith 502306d8920SRichard Smith for (auto &K : Kinds) { 503040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 5043c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 505de3ef502SDouglas Gregor OS.indent(Indent + 2); 506306d8920SRichard Smith OS << K.Prefix << "header \""; 5073c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 508040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 509040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 510040e1266SRichard Smith } 511040e1266SRichard Smith } 512040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 513040e1266SRichard Smith for (auto &U : *Unresolved) { 514040e1266SRichard Smith OS.indent(Indent + 2); 515040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 516040e1266SRichard Smith OS.write_escaped(U.FileName); 517040e1266SRichard Smith OS << "\""; 518040e1266SRichard Smith if (U.Size || U.ModTime) { 519040e1266SRichard Smith OS << " {"; 520040e1266SRichard Smith if (U.Size) 521040e1266SRichard Smith OS << " size " << *U.Size; 522040e1266SRichard Smith if (U.ModTime) 523040e1266SRichard Smith OS << " mtime " << *U.ModTime; 524040e1266SRichard Smith OS << " }"; 525040e1266SRichard Smith } 526040e1266SRichard Smith OS << "\n"; 527de3ef502SDouglas Gregor } 528b53e5483SLawrence Crowl } 529b53e5483SLawrence Crowl 530f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 531f0b11de2SDouglas Gregor OS.indent(Indent + 2); 532f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 533f0b11de2SDouglas Gregor } 534f0b11de2SDouglas Gregor 535eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 536de3ef502SDouglas Gregor MI != MIEnd; ++MI) 5379d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 5389d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 5399d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 5409d6448b1SBen Langmuir // those header files anyway. 5419d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 542eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 543de3ef502SDouglas Gregor 54424bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 54524bb923aSDouglas Gregor OS.indent(Indent + 2); 5468c7c8352SDouglas Gregor OS << "export "; 5478c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 5489565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 54924bb923aSDouglas Gregor if (Exports[I].getInt()) 55024bb923aSDouglas Gregor OS << ".*"; 5518c7c8352SDouglas Gregor } else { 5528c7c8352SDouglas Gregor OS << "*"; 5538c7c8352SDouglas Gregor } 55424bb923aSDouglas Gregor OS << "\n"; 55524bb923aSDouglas Gregor } 55624bb923aSDouglas Gregor 55724bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 55824bb923aSDouglas Gregor OS.indent(Indent + 2); 55924bb923aSDouglas Gregor OS << "export "; 56024bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 5617f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 5627f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 56324bb923aSDouglas Gregor OS << "\n"; 56424bb923aSDouglas Gregor } 56524bb923aSDouglas Gregor 566ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 567ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 568ba7f2f71SDaniel Jasper OS << "use "; 5699565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 570ba7f2f71SDaniel Jasper OS << "\n"; 571ba7f2f71SDaniel Jasper } 572ba7f2f71SDaniel Jasper 573ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 574ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 575ba7f2f71SDaniel Jasper OS << "use "; 576ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 577ba7f2f71SDaniel Jasper OS << "\n"; 578ba7f2f71SDaniel Jasper } 579ba7f2f71SDaniel Jasper 5806ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 5816ddfca91SDouglas Gregor OS.indent(Indent + 2); 5826ddfca91SDouglas Gregor OS << "link "; 5836ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 5846ddfca91SDouglas Gregor OS << "framework "; 5856ddfca91SDouglas Gregor OS << "\""; 5866ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5876ddfca91SDouglas Gregor OS << "\""; 5886ddfca91SDouglas Gregor } 5896ddfca91SDouglas Gregor 590fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 591fb912657SDouglas Gregor OS.indent(Indent + 2); 592fb912657SDouglas Gregor OS << "conflict "; 593fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 594fb912657SDouglas Gregor OS << ", \""; 595fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 596fb912657SDouglas Gregor OS << "\"\n"; 597fb912657SDouglas Gregor } 598fb912657SDouglas Gregor 599fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 600fb912657SDouglas Gregor OS.indent(Indent + 2); 601fb912657SDouglas Gregor OS << "conflict "; 6029565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 603fb912657SDouglas Gregor OS << ", \""; 604fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 605fb912657SDouglas Gregor OS << "\"\n"; 606fb912657SDouglas Gregor } 607fb912657SDouglas Gregor 60873441091SDouglas Gregor if (InferSubmodules) { 60973441091SDouglas Gregor OS.indent(Indent + 2); 61073441091SDouglas Gregor if (InferExplicitSubmodules) 61173441091SDouglas Gregor OS << "explicit "; 61273441091SDouglas Gregor OS << "module * {\n"; 61373441091SDouglas Gregor if (InferExportWildcard) { 61473441091SDouglas Gregor OS.indent(Indent + 4); 61573441091SDouglas Gregor OS << "export *\n"; 61673441091SDouglas Gregor } 61773441091SDouglas Gregor OS.indent(Indent + 2); 61873441091SDouglas Gregor OS << "}\n"; 61973441091SDouglas Gregor } 62073441091SDouglas Gregor 621de3ef502SDouglas Gregor OS.indent(Indent); 622de3ef502SDouglas Gregor OS << "}\n"; 623de3ef502SDouglas Gregor } 624de3ef502SDouglas Gregor 625cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 626de3ef502SDouglas Gregor print(llvm::errs()); 627de3ef502SDouglas Gregor } 628de3ef502SDouglas Gregor 629a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 630a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 6316d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 632a7e2cc68SRichard Smith if (isVisible(M)) 633a7e2cc68SRichard Smith return; 634de3ef502SDouglas Gregor 635a7e2cc68SRichard Smith ++Generation; 636a7e2cc68SRichard Smith 637a7e2cc68SRichard Smith struct Visiting { 638a7e2cc68SRichard Smith Module *M; 639a7e2cc68SRichard Smith Visiting *ExportedBy; 640a7e2cc68SRichard Smith }; 641a7e2cc68SRichard Smith 642a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 643a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 644a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 645a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 646a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 647a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 648a7e2cc68SRichard Smith return; 649a7e2cc68SRichard Smith 650a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 651a7e2cc68SRichard Smith Vis(M); 652a7e2cc68SRichard Smith 653a7e2cc68SRichard Smith // Make any exported modules visible. 654a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 655a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 656841dbda3SRichard Smith for (Module *E : Exports) { 657841dbda3SRichard Smith // Don't recurse to unavailable submodules. 658841dbda3SRichard Smith if (E->isAvailable()) 659a7e2cc68SRichard Smith VisitModule({E, &V}); 660841dbda3SRichard Smith } 661a7e2cc68SRichard Smith 662a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 663a7e2cc68SRichard Smith if (isVisible(C.Other)) { 664a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 665a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 666a7e2cc68SRichard Smith Path.push_back(I->M); 667a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 668a7e2cc68SRichard Smith } 669a7e2cc68SRichard Smith } 670a7e2cc68SRichard Smith }; 671a7e2cc68SRichard Smith VisitModule({M, nullptr}); 672a7e2cc68SRichard Smith } 673c915cb95SReid Kleckner 674f4754ea0SAdrian Prantl ASTSourceDescriptor::ASTSourceDescriptor(Module &M) 675c915cb95SReid Kleckner : Signature(M.Signature), ClangModule(&M) { 676c915cb95SReid Kleckner if (M.Directory) 677c915cb95SReid Kleckner Path = M.Directory->getName(); 678c915cb95SReid Kleckner if (auto *File = M.getASTFile()) 679c915cb95SReid Kleckner ASTFile = File->getName(); 680c915cb95SReid Kleckner } 681c915cb95SReid Kleckner 682c915cb95SReid Kleckner std::string ASTSourceDescriptor::getModuleName() const { 683c915cb95SReid Kleckner if (ClangModule) 684c915cb95SReid Kleckner return ClangModule->Name; 685c915cb95SReid Kleckner else 686c915cb95SReid Kleckner return std::string(PCHModuleName); 687c915cb95SReid Kleckner } 688