13a02247dSChandler Carruth //===--- 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" 190070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 203c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h" 211fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 221fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 233a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 243a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 25a3feee2aSRichard Smith 26de3ef502SDouglas Gregor using namespace clang; 27de3ef502SDouglas Gregor 28eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 29a7e2cc68SRichard Smith bool IsFramework, bool IsExplicit, unsigned VisibilityID) 303c1a41adSRichard Smith : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), 3160fa2888SDuncan P. N. Exon Smith Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID), 328a308ec2SRichard Smith IsMissingRequirement(false), HasIncompatibleModuleFile(false), 338a308ec2SRichard Smith IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), 348a308ec2SRichard Smith IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), 358a308ec2SRichard Smith IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), 368a308ec2SRichard Smith InferExportWildcard(false), ConfigMacrosExhaustive(false), 37e6b7c28dSDavid Blaikie NoUndeclaredIncludes(false), NameVisibility(Hidden) { 38eb90e830SDouglas Gregor if (Parent) { 39eb90e830SDouglas Gregor if (!Parent->isAvailable()) 40eb90e830SDouglas Gregor IsAvailable = false; 413ec6663bSDouglas Gregor if (Parent->IsSystem) 423ec6663bSDouglas Gregor IsSystem = true; 439bca298fSRichard Smith if (Parent->IsExternC) 449bca298fSRichard Smith IsExternC = true; 45ed84df00SBruno Cardoso Lopes if (Parent->NoUndeclaredIncludes) 46ed84df00SBruno Cardoso Lopes NoUndeclaredIncludes = true; 47993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 48eb90e830SDouglas Gregor 49eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 50eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 51eb90e830SDouglas Gregor } 52eb90e830SDouglas Gregor } 53eb90e830SDouglas Gregor 54de3ef502SDouglas Gregor Module::~Module() { 55eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 56de3ef502SDouglas Gregor I != IEnd; ++I) { 57eb90e830SDouglas Gregor delete *I; 58de3ef502SDouglas Gregor } 59de3ef502SDouglas Gregor } 60de3ef502SDouglas Gregor 611fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 621fb5c3a6SDouglas Gregor /// language options has the given feature. 6389929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 6489929282SDouglas Gregor const TargetInfo &Target) { 65532d2104SBen Langmuir bool HasFeature = llvm::StringSwitch<bool>(Feature) 660070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 671fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 68e38cea02SEric Fiselier .Case("coroutines", LangOpts.CoroutinesTS) 691fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 702bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 71fb6358d2SElad Cohen .Case("freestanding", LangOpts.Freestanding) 726736e199SBruno Cardoso Lopes .Case("gnuinlineasm", LangOpts.GNUAsm) 731fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 741fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 750070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 760070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 773c5038a5SUlrich Weigand .Case("zvector", LangOpts.ZVector) 780070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 79532d2104SBen Langmuir if (!HasFeature) 80532d2104SBen Langmuir HasFeature = std::find(LangOpts.ModuleFeatures.begin(), 81532d2104SBen Langmuir LangOpts.ModuleFeatures.end(), 82532d2104SBen Langmuir Feature) != LangOpts.ModuleFeatures.end(); 83532d2104SBen Langmuir return HasFeature; 841fb5c3a6SDouglas Gregor } 851fb5c3a6SDouglas Gregor 863c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 873c1a41adSRichard Smith Requirement &Req, 883c1a41adSRichard Smith UnresolvedHeaderDirective &MissingHeader) const { 891fb5c3a6SDouglas Gregor if (IsAvailable) 901fb5c3a6SDouglas Gregor return true; 911fb5c3a6SDouglas Gregor 921fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 93a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 94a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 95a3feee2aSRichard Smith Current->Requirements[I].second) { 96a3feee2aSRichard Smith Req = Current->Requirements[I]; 971fb5c3a6SDouglas Gregor return false; 981fb5c3a6SDouglas Gregor } 991fb5c3a6SDouglas Gregor } 10075a7e435SBen Langmuir if (!Current->MissingHeaders.empty()) { 10175a7e435SBen Langmuir MissingHeader = Current->MissingHeaders.front(); 10275a7e435SBen Langmuir return false; 10375a7e435SBen Langmuir } 1041fb5c3a6SDouglas Gregor } 1051fb5c3a6SDouglas Gregor 1061fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 1071fb5c3a6SDouglas Gregor } 1081fb5c3a6SDouglas Gregor 10962bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 110f5eedd05SDouglas Gregor const Module *This = this; 111f5eedd05SDouglas Gregor do { 112f5eedd05SDouglas Gregor if (This == Other) 113f5eedd05SDouglas Gregor return true; 114f5eedd05SDouglas Gregor 115f5eedd05SDouglas Gregor This = This->Parent; 116f5eedd05SDouglas Gregor } while (This); 117f5eedd05SDouglas Gregor 118f5eedd05SDouglas Gregor return false; 119f5eedd05SDouglas Gregor } 120f5eedd05SDouglas Gregor 12173441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 12273441091SDouglas Gregor const Module *Result = this; 12373441091SDouglas Gregor while (Result->Parent) 12473441091SDouglas Gregor Result = Result->Parent; 12573441091SDouglas Gregor 12673441091SDouglas Gregor return Result; 12773441091SDouglas Gregor } 12873441091SDouglas Gregor 1299565c75bSRichard Smith static StringRef getModuleNameFromComponent( 1309565c75bSRichard Smith const std::pair<std::string, SourceLocation> &IdComponent) { 1319565c75bSRichard Smith return IdComponent.first; 1329565c75bSRichard Smith } 1339565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; } 1349565c75bSRichard Smith 1359565c75bSRichard Smith template<typename InputIter> 1369565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 1379565c75bSRichard Smith bool AllowStringLiterals = true) { 1389565c75bSRichard Smith for (InputIter It = Begin; It != End; ++It) { 1399565c75bSRichard Smith if (It != Begin) 1409565c75bSRichard Smith OS << "."; 1419565c75bSRichard Smith 1429565c75bSRichard Smith StringRef Name = getModuleNameFromComponent(*It); 1439565c75bSRichard Smith if (!AllowStringLiterals || isValidIdentifier(Name)) 1449565c75bSRichard Smith OS << Name; 1459565c75bSRichard Smith else { 1469565c75bSRichard Smith OS << '"'; 1479565c75bSRichard Smith OS.write_escaped(Name); 1489565c75bSRichard Smith OS << '"'; 1499565c75bSRichard Smith } 1509565c75bSRichard Smith } 1519565c75bSRichard Smith } 1529565c75bSRichard Smith 1539565c75bSRichard Smith template<typename Container> 1549565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) { 1559565c75bSRichard Smith return printModuleId(OS, C.begin(), C.end()); 1569565c75bSRichard Smith } 1579565c75bSRichard Smith 1589565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const { 159f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 160de3ef502SDouglas Gregor 161de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 162de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 163de3ef502SDouglas Gregor Names.push_back(M->Name); 164de3ef502SDouglas Gregor 165de3ef502SDouglas Gregor std::string Result; 166de3ef502SDouglas Gregor 1679565c75bSRichard Smith llvm::raw_string_ostream Out(Result); 1689565c75bSRichard Smith printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 1699565c75bSRichard Smith Out.flush(); 170de3ef502SDouglas Gregor 171de3ef502SDouglas Gregor return Result; 172de3ef502SDouglas Gregor } 173de3ef502SDouglas Gregor 1747ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 1757ff29148SBen Langmuir for (const Module *M = this; M; M = M->Parent) { 1767ff29148SBen Langmuir if (nameParts.empty() || M->Name != nameParts.back()) 1777ff29148SBen Langmuir return false; 1787ff29148SBen Langmuir nameParts = nameParts.drop_back(); 1797ff29148SBen Langmuir } 1807ff29148SBen Langmuir return nameParts.empty(); 1817ff29148SBen Langmuir } 1827ff29148SBen Langmuir 1832b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const { 1842b63d15fSRichard Smith if (Header U = getUmbrellaHeader()) 1852b63d15fSRichard Smith return {"", U.Entry->getDir()}; 18673141fa9SDouglas Gregor 1872b63d15fSRichard Smith return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; 18873141fa9SDouglas Gregor } 18973141fa9SDouglas Gregor 1903c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1913c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1923c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1933c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1943c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1953c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1963c5305c1SArgyrios Kyrtzidis } 1973c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1983c5305c1SArgyrios Kyrtzidis } 1993c5305c1SArgyrios Kyrtzidis 2003c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 2013c5305c1SArgyrios Kyrtzidis } 2023c5305c1SArgyrios Kyrtzidis 2038f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const { 2048f4d3ff1SRichard Smith auto *Top = getTopLevelModule(); 2058f4d3ff1SRichard Smith 2068f4d3ff1SRichard Smith // A top-level module implicitly uses itself. 2078f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Top)) 2088f4d3ff1SRichard Smith return true; 2098f4d3ff1SRichard Smith 2108f4d3ff1SRichard Smith for (auto *Use : Top->DirectUses) 2118f4d3ff1SRichard Smith if (Requested->isSubModuleOf(Use)) 2128f4d3ff1SRichard Smith return true; 213ed84df00SBruno Cardoso Lopes 214ed84df00SBruno Cardoso Lopes // Anyone is allowed to use our builtin stddef.h and its accompanying module. 215ed84df00SBruno Cardoso Lopes if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") 216ed84df00SBruno Cardoso Lopes return true; 217ed84df00SBruno Cardoso Lopes 2188f4d3ff1SRichard Smith return false; 2198f4d3ff1SRichard Smith } 2208f4d3ff1SRichard Smith 221a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 222a3feee2aSRichard Smith const LangOptions &LangOpts, 22389929282SDouglas Gregor const TargetInfo &Target) { 224a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 2251fb5c3a6SDouglas Gregor 2261fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 227a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 2281fb5c3a6SDouglas Gregor return; 2291fb5c3a6SDouglas Gregor 230993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 231ec8c9752SBen Langmuir } 232ec8c9752SBen Langmuir 233993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 23475a7e435SBen Langmuir auto needUpdate = [MissingRequirement](Module *M) { 23575a7e435SBen Langmuir return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); 23675a7e435SBen Langmuir }; 23775a7e435SBen Langmuir 23875a7e435SBen Langmuir if (!needUpdate(this)) 2391fb5c3a6SDouglas Gregor return; 2401fb5c3a6SDouglas Gregor 241f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 2421fb5c3a6SDouglas Gregor Stack.push_back(this); 2431fb5c3a6SDouglas Gregor while (!Stack.empty()) { 2441fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 2451fb5c3a6SDouglas Gregor Stack.pop_back(); 2461fb5c3a6SDouglas Gregor 24775a7e435SBen Langmuir if (!needUpdate(Current)) 2481fb5c3a6SDouglas Gregor continue; 2491fb5c3a6SDouglas Gregor 2501fb5c3a6SDouglas Gregor Current->IsAvailable = false; 251993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 252eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 253eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 2541fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 25575a7e435SBen Langmuir if (needUpdate(*Sub)) 256eb90e830SDouglas Gregor Stack.push_back(*Sub); 2571fb5c3a6SDouglas Gregor } 2581fb5c3a6SDouglas Gregor } 2591fb5c3a6SDouglas Gregor } 2601fb5c3a6SDouglas Gregor 261eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 262eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 263eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 264f1186c5aSCraig Topper return nullptr; 265eb90e830SDouglas Gregor 266eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 267eb90e830SDouglas Gregor } 268eb90e830SDouglas Gregor 2698739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 270e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 271e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 272e9bcf5b7SDmitri Gribenko E = SubModules.end(); 273e9bcf5b7SDmitri Gribenko I != E; ++I) { 274e9bcf5b7SDmitri Gribenko Module *Mod = *I; 275e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 276e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 277e9bcf5b7SDmitri Gribenko } 278e9bcf5b7SDmitri Gribenko 279e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2808739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2818739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2828739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2838739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2848739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2858739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2868739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2878739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2888739f7b7SArgyrios Kyrtzidis 2898739f7b7SArgyrios Kyrtzidis continue; 2908739f7b7SArgyrios Kyrtzidis } 2918739f7b7SArgyrios Kyrtzidis 2928739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2938739f7b7SArgyrios Kyrtzidis // the given pattern. 2948739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2958739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2968739f7b7SArgyrios Kyrtzidis continue; 2978739f7b7SArgyrios Kyrtzidis 2988739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2998739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 3008739f7b7SArgyrios Kyrtzidis else { 3018739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 3028739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 3038739f7b7SArgyrios Kyrtzidis } 3048739f7b7SArgyrios Kyrtzidis } 3058739f7b7SArgyrios Kyrtzidis 3068739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 3078739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 3088739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 3098739f7b7SArgyrios Kyrtzidis return; 3108739f7b7SArgyrios Kyrtzidis 3118739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 3128739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 3138739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 3148739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 3158739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 3168739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 3178739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 3188739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 3198739f7b7SArgyrios Kyrtzidis Acceptable = true; 3208739f7b7SArgyrios Kyrtzidis break; 3218739f7b7SArgyrios Kyrtzidis } 3228739f7b7SArgyrios Kyrtzidis } 3238739f7b7SArgyrios Kyrtzidis } 3248739f7b7SArgyrios Kyrtzidis 3258739f7b7SArgyrios Kyrtzidis if (!Acceptable) 3268739f7b7SArgyrios Kyrtzidis continue; 3278739f7b7SArgyrios Kyrtzidis 3288739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 3298739f7b7SArgyrios Kyrtzidis } 3308739f7b7SArgyrios Kyrtzidis } 3318739f7b7SArgyrios Kyrtzidis 3320e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 3330e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 3340e5d7b8cSRichard Smith 3350e5d7b8cSRichard Smith // This module is visible to itself. 3360e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 3370e5d7b8cSRichard Smith 3380e5d7b8cSRichard Smith // Every imported module is visible. 339dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 340dc360d57SDmitri Gribenko while (!Stack.empty()) { 341dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 342dc360d57SDmitri Gribenko 343dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 344dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 345dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 3460e5d7b8cSRichard Smith } 3470e5d7b8cSRichard Smith } 3480e5d7b8cSRichard Smith 349f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 350de3ef502SDouglas Gregor OS.indent(Indent); 351de3ef502SDouglas Gregor if (IsFramework) 352de3ef502SDouglas Gregor OS << "framework "; 353de3ef502SDouglas Gregor if (IsExplicit) 354de3ef502SDouglas Gregor OS << "explicit "; 3559565c75bSRichard Smith OS << "module "; 3569565c75bSRichard Smith printModuleId(OS, &Name, &Name + 1); 357a686e1b0SDouglas Gregor 3587615f00eSBen Langmuir if (IsSystem || IsExternC) { 359a686e1b0SDouglas Gregor OS.indent(Indent + 2); 3607615f00eSBen Langmuir if (IsSystem) 361a686e1b0SDouglas Gregor OS << " [system]"; 3627615f00eSBen Langmuir if (IsExternC) 3637615f00eSBen Langmuir OS << " [extern_c]"; 364a686e1b0SDouglas Gregor } 365a686e1b0SDouglas Gregor 366a686e1b0SDouglas Gregor OS << " {\n"; 367de3ef502SDouglas Gregor 368a3feee2aSRichard Smith if (!Requirements.empty()) { 3691fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3701fb5c3a6SDouglas Gregor OS << "requires "; 371a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3721fb5c3a6SDouglas Gregor if (I) 3731fb5c3a6SDouglas Gregor OS << ", "; 374a3feee2aSRichard Smith if (!Requirements[I].second) 375a3feee2aSRichard Smith OS << "!"; 376a3feee2aSRichard Smith OS << Requirements[I].first; 3771fb5c3a6SDouglas Gregor } 3781fb5c3a6SDouglas Gregor OS << "\n"; 3791fb5c3a6SDouglas Gregor } 3801fb5c3a6SDouglas Gregor 3812b63d15fSRichard Smith if (Header H = getUmbrellaHeader()) { 382de3ef502SDouglas Gregor OS.indent(Indent + 2); 383322f633cSDouglas Gregor OS << "umbrella header \""; 3842b63d15fSRichard Smith OS.write_escaped(H.NameAsWritten); 385de3ef502SDouglas Gregor OS << "\"\n"; 3862b63d15fSRichard Smith } else if (DirectoryName D = getUmbrellaDir()) { 387322f633cSDouglas Gregor OS.indent(Indent + 2); 388322f633cSDouglas Gregor OS << "umbrella \""; 3892b63d15fSRichard Smith OS.write_escaped(D.NameAsWritten); 390322f633cSDouglas Gregor OS << "\"\n"; 391de3ef502SDouglas Gregor } 392de3ef502SDouglas Gregor 39335b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 39435b13eceSDouglas Gregor OS.indent(Indent + 2); 39535b13eceSDouglas Gregor OS << "config_macros "; 39635b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 3978d932427SDouglas Gregor OS << "[exhaustive]"; 39835b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 39935b13eceSDouglas Gregor if (I) 40035b13eceSDouglas Gregor OS << ", "; 40135b13eceSDouglas Gregor OS << ConfigMacros[I]; 40235b13eceSDouglas Gregor } 4038d932427SDouglas Gregor OS << "\n"; 40435b13eceSDouglas Gregor } 40535b13eceSDouglas Gregor 4063c1a41adSRichard Smith struct { 407306d8920SRichard Smith StringRef Prefix; 4083c1a41adSRichard Smith HeaderKind Kind; 4093c1a41adSRichard Smith } Kinds[] = {{"", HK_Normal}, 4103c1a41adSRichard Smith {"textual ", HK_Textual}, 4113c1a41adSRichard Smith {"private ", HK_Private}, 4123c1a41adSRichard Smith {"private textual ", HK_PrivateTextual}, 4133c1a41adSRichard Smith {"exclude ", HK_Excluded}}; 414306d8920SRichard Smith 415306d8920SRichard Smith for (auto &K : Kinds) { 416040e1266SRichard Smith assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 4173c1a41adSRichard Smith for (auto &H : Headers[K.Kind]) { 418de3ef502SDouglas Gregor OS.indent(Indent + 2); 419306d8920SRichard Smith OS << K.Prefix << "header \""; 4203c1a41adSRichard Smith OS.write_escaped(H.NameAsWritten); 421040e1266SRichard Smith OS << "\" { size " << H.Entry->getSize() 422040e1266SRichard Smith << " mtime " << H.Entry->getModificationTime() << " }\n"; 423040e1266SRichard Smith } 424040e1266SRichard Smith } 425040e1266SRichard Smith for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 426040e1266SRichard Smith for (auto &U : *Unresolved) { 427040e1266SRichard Smith OS.indent(Indent + 2); 428040e1266SRichard Smith OS << Kinds[U.Kind].Prefix << "header \""; 429040e1266SRichard Smith OS.write_escaped(U.FileName); 430040e1266SRichard Smith OS << "\""; 431040e1266SRichard Smith if (U.Size || U.ModTime) { 432040e1266SRichard Smith OS << " {"; 433040e1266SRichard Smith if (U.Size) 434040e1266SRichard Smith OS << " size " << *U.Size; 435040e1266SRichard Smith if (U.ModTime) 436040e1266SRichard Smith OS << " mtime " << *U.ModTime; 437040e1266SRichard Smith OS << " }"; 438040e1266SRichard Smith } 439040e1266SRichard Smith OS << "\n"; 440de3ef502SDouglas Gregor } 441b53e5483SLawrence Crowl } 442b53e5483SLawrence Crowl 443*f0b11de2SDouglas Gregor if (!ExportAsModule.empty()) { 444*f0b11de2SDouglas Gregor OS.indent(Indent + 2); 445*f0b11de2SDouglas Gregor OS << "export_as" << ExportAsModule << "\n"; 446*f0b11de2SDouglas Gregor } 447*f0b11de2SDouglas Gregor 448eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 449de3ef502SDouglas Gregor MI != MIEnd; ++MI) 4509d6448b1SBen Langmuir // Print inferred subframework modules so that we don't need to re-infer 4519d6448b1SBen Langmuir // them (requires expensive directory iteration + stat calls) when we build 4529d6448b1SBen Langmuir // the module. Regular inferred submodules are OK, as we need to look at all 4539d6448b1SBen Langmuir // those header files anyway. 4549d6448b1SBen Langmuir if (!(*MI)->IsInferred || (*MI)->IsFramework) 455eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 456de3ef502SDouglas Gregor 45724bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 45824bb923aSDouglas Gregor OS.indent(Indent + 2); 4598c7c8352SDouglas Gregor OS << "export "; 4608c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 4619565c75bSRichard Smith OS << Restriction->getFullModuleName(true); 46224bb923aSDouglas Gregor if (Exports[I].getInt()) 46324bb923aSDouglas Gregor OS << ".*"; 4648c7c8352SDouglas Gregor } else { 4658c7c8352SDouglas Gregor OS << "*"; 4668c7c8352SDouglas Gregor } 46724bb923aSDouglas Gregor OS << "\n"; 46824bb923aSDouglas Gregor } 46924bb923aSDouglas Gregor 47024bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 47124bb923aSDouglas Gregor OS.indent(Indent + 2); 47224bb923aSDouglas Gregor OS << "export "; 47324bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 4747f96b391SDavide Italiano if (UnresolvedExports[I].Wildcard) 4757f96b391SDavide Italiano OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 47624bb923aSDouglas Gregor OS << "\n"; 47724bb923aSDouglas Gregor } 47824bb923aSDouglas Gregor 479ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 480ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 481ba7f2f71SDaniel Jasper OS << "use "; 4829565c75bSRichard Smith OS << DirectUses[I]->getFullModuleName(true); 483ba7f2f71SDaniel Jasper OS << "\n"; 484ba7f2f71SDaniel Jasper } 485ba7f2f71SDaniel Jasper 486ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 487ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 488ba7f2f71SDaniel Jasper OS << "use "; 489ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 490ba7f2f71SDaniel Jasper OS << "\n"; 491ba7f2f71SDaniel Jasper } 492ba7f2f71SDaniel Jasper 4936ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 4946ddfca91SDouglas Gregor OS.indent(Indent + 2); 4956ddfca91SDouglas Gregor OS << "link "; 4966ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 4976ddfca91SDouglas Gregor OS << "framework "; 4986ddfca91SDouglas Gregor OS << "\""; 4996ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 5006ddfca91SDouglas Gregor OS << "\""; 5016ddfca91SDouglas Gregor } 5026ddfca91SDouglas Gregor 503fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 504fb912657SDouglas Gregor OS.indent(Indent + 2); 505fb912657SDouglas Gregor OS << "conflict "; 506fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 507fb912657SDouglas Gregor OS << ", \""; 508fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 509fb912657SDouglas Gregor OS << "\"\n"; 510fb912657SDouglas Gregor } 511fb912657SDouglas Gregor 512fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 513fb912657SDouglas Gregor OS.indent(Indent + 2); 514fb912657SDouglas Gregor OS << "conflict "; 5159565c75bSRichard Smith OS << Conflicts[I].Other->getFullModuleName(true); 516fb912657SDouglas Gregor OS << ", \""; 517fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 518fb912657SDouglas Gregor OS << "\"\n"; 519fb912657SDouglas Gregor } 520fb912657SDouglas Gregor 52173441091SDouglas Gregor if (InferSubmodules) { 52273441091SDouglas Gregor OS.indent(Indent + 2); 52373441091SDouglas Gregor if (InferExplicitSubmodules) 52473441091SDouglas Gregor OS << "explicit "; 52573441091SDouglas Gregor OS << "module * {\n"; 52673441091SDouglas Gregor if (InferExportWildcard) { 52773441091SDouglas Gregor OS.indent(Indent + 4); 52873441091SDouglas Gregor OS << "export *\n"; 52973441091SDouglas Gregor } 53073441091SDouglas Gregor OS.indent(Indent + 2); 53173441091SDouglas Gregor OS << "}\n"; 53273441091SDouglas Gregor } 53373441091SDouglas Gregor 534de3ef502SDouglas Gregor OS.indent(Indent); 535de3ef502SDouglas Gregor OS << "}\n"; 536de3ef502SDouglas Gregor } 537de3ef502SDouglas Gregor 538cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const { 539de3ef502SDouglas Gregor print(llvm::errs()); 540de3ef502SDouglas Gregor } 541de3ef502SDouglas Gregor 542a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 543a7e2cc68SRichard Smith VisibleCallback Vis, ConflictCallback Cb) { 5446d25fdc4SBen Langmuir assert(Loc.isValid() && "setVisible expects a valid import location"); 545a7e2cc68SRichard Smith if (isVisible(M)) 546a7e2cc68SRichard Smith return; 547de3ef502SDouglas Gregor 548a7e2cc68SRichard Smith ++Generation; 549a7e2cc68SRichard Smith 550a7e2cc68SRichard Smith struct Visiting { 551a7e2cc68SRichard Smith Module *M; 552a7e2cc68SRichard Smith Visiting *ExportedBy; 553a7e2cc68SRichard Smith }; 554a7e2cc68SRichard Smith 555a7e2cc68SRichard Smith std::function<void(Visiting)> VisitModule = [&](Visiting V) { 556a7e2cc68SRichard Smith // Modules that aren't available cannot be made visible. 557a7e2cc68SRichard Smith if (!V.M->isAvailable()) 558a7e2cc68SRichard Smith return; 559a7e2cc68SRichard Smith 560a7e2cc68SRichard Smith // Nothing to do for a module that's already visible. 561a7e2cc68SRichard Smith unsigned ID = V.M->getVisibilityID(); 562a7e2cc68SRichard Smith if (ImportLocs.size() <= ID) 563a7e2cc68SRichard Smith ImportLocs.resize(ID + 1); 564a7e2cc68SRichard Smith else if (ImportLocs[ID].isValid()) 565a7e2cc68SRichard Smith return; 566a7e2cc68SRichard Smith 567a7e2cc68SRichard Smith ImportLocs[ID] = Loc; 568a7e2cc68SRichard Smith Vis(M); 569a7e2cc68SRichard Smith 570a7e2cc68SRichard Smith // Make any exported modules visible. 571a7e2cc68SRichard Smith SmallVector<Module *, 16> Exports; 572a7e2cc68SRichard Smith V.M->getExportedModules(Exports); 573a7e2cc68SRichard Smith for (Module *E : Exports) 574a7e2cc68SRichard Smith VisitModule({E, &V}); 575a7e2cc68SRichard Smith 576a7e2cc68SRichard Smith for (auto &C : V.M->Conflicts) { 577a7e2cc68SRichard Smith if (isVisible(C.Other)) { 578a7e2cc68SRichard Smith llvm::SmallVector<Module*, 8> Path; 579a7e2cc68SRichard Smith for (Visiting *I = &V; I; I = I->ExportedBy) 580a7e2cc68SRichard Smith Path.push_back(I->M); 581a7e2cc68SRichard Smith Cb(Path, C.Other, C.Message); 582a7e2cc68SRichard Smith } 583a7e2cc68SRichard Smith } 584a7e2cc68SRichard Smith }; 585a7e2cc68SRichard Smith VisitModule({M, nullptr}); 586a7e2cc68SRichard Smith } 587