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 //===----------------------------------------------------------------------===// 14*a3feee2aSRichard Smith 15de3ef502SDouglas Gregor #include "clang/Basic/Module.h" 16de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h" 171fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h" 180070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 193c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h" 201fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 211fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 223a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 233a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 24*a3feee2aSRichard Smith 25de3ef502SDouglas Gregor using namespace clang; 26de3ef502SDouglas Gregor 27eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 28eb90e830SDouglas Gregor bool IsFramework, bool IsExplicit) 29eb90e830SDouglas Gregor : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 3043af5132SArgyrios Kyrtzidis Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false), 31a686e1b0SDouglas Gregor IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), 32a686e1b0SDouglas Gregor InferSubmodules(false), InferExplicitSubmodules(false), 338d932427SDouglas Gregor InferExportWildcard(false), ConfigMacrosExhaustive(false), 348d932427SDouglas Gregor NameVisibility(Hidden) 35eb90e830SDouglas Gregor { 36eb90e830SDouglas Gregor if (Parent) { 37eb90e830SDouglas Gregor if (!Parent->isAvailable()) 38eb90e830SDouglas Gregor IsAvailable = false; 393ec6663bSDouglas Gregor if (Parent->IsSystem) 403ec6663bSDouglas Gregor IsSystem = true; 41eb90e830SDouglas Gregor 42eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 43eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 44eb90e830SDouglas Gregor } 45eb90e830SDouglas Gregor } 46eb90e830SDouglas Gregor 47de3ef502SDouglas Gregor Module::~Module() { 48eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 49de3ef502SDouglas Gregor I != IEnd; ++I) { 50eb90e830SDouglas Gregor delete *I; 51de3ef502SDouglas Gregor } 52de3ef502SDouglas Gregor } 53de3ef502SDouglas Gregor 541fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 551fb5c3a6SDouglas Gregor /// language options has the given feature. 5689929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 5789929282SDouglas Gregor const TargetInfo &Target) { 581fb5c3a6SDouglas Gregor return llvm::StringSwitch<bool>(Feature) 590070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 601fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 611fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 622bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 631fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 641fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 650070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 660070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 670070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 681fb5c3a6SDouglas Gregor } 691fb5c3a6SDouglas Gregor 701fb5c3a6SDouglas Gregor bool 7189929282SDouglas Gregor Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 72*a3feee2aSRichard Smith Requirement &Req) const { 731fb5c3a6SDouglas Gregor if (IsAvailable) 741fb5c3a6SDouglas Gregor return true; 751fb5c3a6SDouglas Gregor 761fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 77*a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 78*a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 79*a3feee2aSRichard Smith Current->Requirements[I].second) { 80*a3feee2aSRichard Smith Req = Current->Requirements[I]; 811fb5c3a6SDouglas Gregor return false; 821fb5c3a6SDouglas Gregor } 831fb5c3a6SDouglas Gregor } 841fb5c3a6SDouglas Gregor } 851fb5c3a6SDouglas Gregor 861fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 871fb5c3a6SDouglas Gregor } 881fb5c3a6SDouglas Gregor 89f5eedd05SDouglas Gregor bool Module::isSubModuleOf(Module *Other) const { 90f5eedd05SDouglas Gregor const Module *This = this; 91f5eedd05SDouglas Gregor do { 92f5eedd05SDouglas Gregor if (This == Other) 93f5eedd05SDouglas Gregor return true; 94f5eedd05SDouglas Gregor 95f5eedd05SDouglas Gregor This = This->Parent; 96f5eedd05SDouglas Gregor } while (This); 97f5eedd05SDouglas Gregor 98f5eedd05SDouglas Gregor return false; 99f5eedd05SDouglas Gregor } 100f5eedd05SDouglas Gregor 10173441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 10273441091SDouglas Gregor const Module *Result = this; 10373441091SDouglas Gregor while (Result->Parent) 10473441091SDouglas Gregor Result = Result->Parent; 10573441091SDouglas Gregor 10673441091SDouglas Gregor return Result; 10773441091SDouglas Gregor } 10873441091SDouglas Gregor 109de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 110f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 111de3ef502SDouglas Gregor 112de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 113de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 114de3ef502SDouglas Gregor Names.push_back(M->Name); 115de3ef502SDouglas Gregor 116de3ef502SDouglas Gregor std::string Result; 11761ac906bSCraig Topper for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(), 118de3ef502SDouglas Gregor IEnd = Names.rend(); 119de3ef502SDouglas Gregor I != IEnd; ++I) { 120de3ef502SDouglas Gregor if (!Result.empty()) 121de3ef502SDouglas Gregor Result += '.'; 122de3ef502SDouglas Gregor 123de3ef502SDouglas Gregor Result += *I; 124de3ef502SDouglas Gregor } 125de3ef502SDouglas Gregor 126de3ef502SDouglas Gregor return Result; 127de3ef502SDouglas Gregor } 128de3ef502SDouglas Gregor 12973141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const { 13073141fa9SDouglas Gregor if (const FileEntry *Header = getUmbrellaHeader()) 13173141fa9SDouglas Gregor return Header->getDir(); 13273141fa9SDouglas Gregor 13373141fa9SDouglas Gregor return Umbrella.dyn_cast<const DirectoryEntry *>(); 13473141fa9SDouglas Gregor } 13573141fa9SDouglas Gregor 1363c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1373c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1383c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1393c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1403c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1413c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1423c5305c1SArgyrios Kyrtzidis } 1433c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1443c5305c1SArgyrios Kyrtzidis } 1453c5305c1SArgyrios Kyrtzidis 1463c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 1473c5305c1SArgyrios Kyrtzidis } 1483c5305c1SArgyrios Kyrtzidis 149*a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 150*a3feee2aSRichard Smith const LangOptions &LangOpts, 15189929282SDouglas Gregor const TargetInfo &Target) { 152*a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 1531fb5c3a6SDouglas Gregor 1541fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 155*a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 1561fb5c3a6SDouglas Gregor return; 1571fb5c3a6SDouglas Gregor 1581fb5c3a6SDouglas Gregor if (!IsAvailable) 1591fb5c3a6SDouglas Gregor return; 1601fb5c3a6SDouglas Gregor 161f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 1621fb5c3a6SDouglas Gregor Stack.push_back(this); 1631fb5c3a6SDouglas Gregor while (!Stack.empty()) { 1641fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 1651fb5c3a6SDouglas Gregor Stack.pop_back(); 1661fb5c3a6SDouglas Gregor 1671fb5c3a6SDouglas Gregor if (!Current->IsAvailable) 1681fb5c3a6SDouglas Gregor continue; 1691fb5c3a6SDouglas Gregor 1701fb5c3a6SDouglas Gregor Current->IsAvailable = false; 171eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 172eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 1731fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 174eb90e830SDouglas Gregor if ((*Sub)->IsAvailable) 175eb90e830SDouglas Gregor Stack.push_back(*Sub); 1761fb5c3a6SDouglas Gregor } 1771fb5c3a6SDouglas Gregor } 1781fb5c3a6SDouglas Gregor } 1791fb5c3a6SDouglas Gregor 180eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 181eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 182eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 183eb90e830SDouglas Gregor return 0; 184eb90e830SDouglas Gregor 185eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 186eb90e830SDouglas Gregor } 187eb90e830SDouglas Gregor 188f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 18924bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 19024bb923aSDouglas Gregor if (I) 19124bb923aSDouglas Gregor OS << "."; 19224bb923aSDouglas Gregor OS << Id[I].first; 19324bb923aSDouglas Gregor } 19424bb923aSDouglas Gregor } 19524bb923aSDouglas Gregor 1968739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 1978739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 1988739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 1998739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2008739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2018739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2028739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2038739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2048739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2058739f7b7SArgyrios Kyrtzidis 2068739f7b7SArgyrios Kyrtzidis continue; 2078739f7b7SArgyrios Kyrtzidis } 2088739f7b7SArgyrios Kyrtzidis 2098739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2108739f7b7SArgyrios Kyrtzidis // the given pattern. 2118739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2128739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2138739f7b7SArgyrios Kyrtzidis continue; 2148739f7b7SArgyrios Kyrtzidis 2158739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2168739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 2178739f7b7SArgyrios Kyrtzidis else { 2188739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 2198739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 2208739f7b7SArgyrios Kyrtzidis } 2218739f7b7SArgyrios Kyrtzidis } 2228739f7b7SArgyrios Kyrtzidis 2238739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 2248739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 2258739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 2268739f7b7SArgyrios Kyrtzidis return; 2278739f7b7SArgyrios Kyrtzidis 2288739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2298739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 2308739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 2318739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 2328739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 2338739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 2348739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 2358739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 2368739f7b7SArgyrios Kyrtzidis Acceptable = true; 2378739f7b7SArgyrios Kyrtzidis break; 2388739f7b7SArgyrios Kyrtzidis } 2398739f7b7SArgyrios Kyrtzidis } 2408739f7b7SArgyrios Kyrtzidis } 2418739f7b7SArgyrios Kyrtzidis 2428739f7b7SArgyrios Kyrtzidis if (!Acceptable) 2438739f7b7SArgyrios Kyrtzidis continue; 2448739f7b7SArgyrios Kyrtzidis 2458739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2468739f7b7SArgyrios Kyrtzidis } 2478739f7b7SArgyrios Kyrtzidis } 2488739f7b7SArgyrios Kyrtzidis 2490e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 2500e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 2510e5d7b8cSRichard Smith 2520e5d7b8cSRichard Smith // This module is visible to itself. 2530e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 2540e5d7b8cSRichard Smith 2550e5d7b8cSRichard Smith llvm::SmallVector<Module*, 4> Exported; 2560e5d7b8cSRichard Smith for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2570e5d7b8cSRichard Smith // Every imported module is visible. 2580e5d7b8cSRichard Smith VisibleModulesCache.insert(Imports[I]); 2590e5d7b8cSRichard Smith 2600e5d7b8cSRichard Smith // Every module exported by an imported module is visible. 2610e5d7b8cSRichard Smith Imports[I]->getExportedModules(Exported); 2620e5d7b8cSRichard Smith VisibleModulesCache.insert(Exported.begin(), Exported.end()); 2630e5d7b8cSRichard Smith Exported.clear(); 2640e5d7b8cSRichard Smith } 2650e5d7b8cSRichard Smith } 2660e5d7b8cSRichard Smith 267f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 268de3ef502SDouglas Gregor OS.indent(Indent); 269de3ef502SDouglas Gregor if (IsFramework) 270de3ef502SDouglas Gregor OS << "framework "; 271de3ef502SDouglas Gregor if (IsExplicit) 272de3ef502SDouglas Gregor OS << "explicit "; 273a686e1b0SDouglas Gregor OS << "module " << Name; 274a686e1b0SDouglas Gregor 275a686e1b0SDouglas Gregor if (IsSystem) { 276a686e1b0SDouglas Gregor OS.indent(Indent + 2); 277a686e1b0SDouglas Gregor OS << " [system]"; 278a686e1b0SDouglas Gregor } 279a686e1b0SDouglas Gregor 280a686e1b0SDouglas Gregor OS << " {\n"; 281de3ef502SDouglas Gregor 282*a3feee2aSRichard Smith if (!Requirements.empty()) { 2831fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 2841fb5c3a6SDouglas Gregor OS << "requires "; 285*a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 2861fb5c3a6SDouglas Gregor if (I) 2871fb5c3a6SDouglas Gregor OS << ", "; 288*a3feee2aSRichard Smith if (!Requirements[I].second) 289*a3feee2aSRichard Smith OS << "!"; 290*a3feee2aSRichard Smith OS << Requirements[I].first; 2911fb5c3a6SDouglas Gregor } 2921fb5c3a6SDouglas Gregor OS << "\n"; 2931fb5c3a6SDouglas Gregor } 2941fb5c3a6SDouglas Gregor 29573141fa9SDouglas Gregor if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 296de3ef502SDouglas Gregor OS.indent(Indent + 2); 297322f633cSDouglas Gregor OS << "umbrella header \""; 298de3ef502SDouglas Gregor OS.write_escaped(UmbrellaHeader->getName()); 299de3ef502SDouglas Gregor OS << "\"\n"; 300322f633cSDouglas Gregor } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 301322f633cSDouglas Gregor OS.indent(Indent + 2); 302322f633cSDouglas Gregor OS << "umbrella \""; 303322f633cSDouglas Gregor OS.write_escaped(UmbrellaDir->getName()); 304322f633cSDouglas Gregor OS << "\"\n"; 305de3ef502SDouglas Gregor } 306de3ef502SDouglas Gregor 30735b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 30835b13eceSDouglas Gregor OS.indent(Indent + 2); 30935b13eceSDouglas Gregor OS << "config_macros "; 31035b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 3118d932427SDouglas Gregor OS << "[exhaustive]"; 31235b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 31335b13eceSDouglas Gregor if (I) 31435b13eceSDouglas Gregor OS << ", "; 31535b13eceSDouglas Gregor OS << ConfigMacros[I]; 31635b13eceSDouglas Gregor } 3178d932427SDouglas Gregor OS << "\n"; 31835b13eceSDouglas Gregor } 31935b13eceSDouglas Gregor 320b53e5483SLawrence Crowl for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) { 321de3ef502SDouglas Gregor OS.indent(Indent + 2); 322de3ef502SDouglas Gregor OS << "header \""; 323b53e5483SLawrence Crowl OS.write_escaped(NormalHeaders[I]->getName()); 324de3ef502SDouglas Gregor OS << "\"\n"; 325de3ef502SDouglas Gregor } 32659527666SDouglas Gregor 32759527666SDouglas Gregor for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) { 32859527666SDouglas Gregor OS.indent(Indent + 2); 32959527666SDouglas Gregor OS << "exclude header \""; 33059527666SDouglas Gregor OS.write_escaped(ExcludedHeaders[I]->getName()); 33159527666SDouglas Gregor OS << "\"\n"; 33259527666SDouglas Gregor } 333de3ef502SDouglas Gregor 334b53e5483SLawrence Crowl for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) { 335b53e5483SLawrence Crowl OS.indent(Indent + 2); 336b53e5483SLawrence Crowl OS << "private header \""; 337b53e5483SLawrence Crowl OS.write_escaped(PrivateHeaders[I]->getName()); 338b53e5483SLawrence Crowl OS << "\"\n"; 339b53e5483SLawrence Crowl } 340b53e5483SLawrence Crowl 341eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 342de3ef502SDouglas Gregor MI != MIEnd; ++MI) 343eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 344de3ef502SDouglas Gregor 34524bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 34624bb923aSDouglas Gregor OS.indent(Indent + 2); 3478c7c8352SDouglas Gregor OS << "export "; 3488c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 3498c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 35024bb923aSDouglas Gregor if (Exports[I].getInt()) 35124bb923aSDouglas Gregor OS << ".*"; 3528c7c8352SDouglas Gregor } else { 3538c7c8352SDouglas Gregor OS << "*"; 3548c7c8352SDouglas Gregor } 35524bb923aSDouglas Gregor OS << "\n"; 35624bb923aSDouglas Gregor } 35724bb923aSDouglas Gregor 35824bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 35924bb923aSDouglas Gregor OS.indent(Indent + 2); 36024bb923aSDouglas Gregor OS << "export "; 36124bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 3628c7c8352SDouglas Gregor if (UnresolvedExports[I].Wildcard) { 3638c7c8352SDouglas Gregor if (UnresolvedExports[I].Id.empty()) 3648c7c8352SDouglas Gregor OS << "*"; 3658c7c8352SDouglas Gregor else 36624bb923aSDouglas Gregor OS << ".*"; 3678c7c8352SDouglas Gregor } 36824bb923aSDouglas Gregor OS << "\n"; 36924bb923aSDouglas Gregor } 37024bb923aSDouglas Gregor 371ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 372ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 373ba7f2f71SDaniel Jasper OS << "use "; 374ba7f2f71SDaniel Jasper OS << DirectUses[I]->getFullModuleName(); 375ba7f2f71SDaniel Jasper OS << "\n"; 376ba7f2f71SDaniel Jasper } 377ba7f2f71SDaniel Jasper 378ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 379ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 380ba7f2f71SDaniel Jasper OS << "use "; 381ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 382ba7f2f71SDaniel Jasper OS << "\n"; 383ba7f2f71SDaniel Jasper } 384ba7f2f71SDaniel Jasper 3856ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 3866ddfca91SDouglas Gregor OS.indent(Indent + 2); 3876ddfca91SDouglas Gregor OS << "link "; 3886ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 3896ddfca91SDouglas Gregor OS << "framework "; 3906ddfca91SDouglas Gregor OS << "\""; 3916ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 3926ddfca91SDouglas Gregor OS << "\""; 3936ddfca91SDouglas Gregor } 3946ddfca91SDouglas Gregor 395fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 396fb912657SDouglas Gregor OS.indent(Indent + 2); 397fb912657SDouglas Gregor OS << "conflict "; 398fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 399fb912657SDouglas Gregor OS << ", \""; 400fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 401fb912657SDouglas Gregor OS << "\"\n"; 402fb912657SDouglas Gregor } 403fb912657SDouglas Gregor 404fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 405fb912657SDouglas Gregor OS.indent(Indent + 2); 406fb912657SDouglas Gregor OS << "conflict "; 407fb912657SDouglas Gregor OS << Conflicts[I].Other->getFullModuleName(); 408fb912657SDouglas Gregor OS << ", \""; 409fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 410fb912657SDouglas Gregor OS << "\"\n"; 411fb912657SDouglas Gregor } 412fb912657SDouglas Gregor 41373441091SDouglas Gregor if (InferSubmodules) { 41473441091SDouglas Gregor OS.indent(Indent + 2); 41573441091SDouglas Gregor if (InferExplicitSubmodules) 41673441091SDouglas Gregor OS << "explicit "; 41773441091SDouglas Gregor OS << "module * {\n"; 41873441091SDouglas Gregor if (InferExportWildcard) { 41973441091SDouglas Gregor OS.indent(Indent + 4); 42073441091SDouglas Gregor OS << "export *\n"; 42173441091SDouglas Gregor } 42273441091SDouglas Gregor OS.indent(Indent + 2); 42373441091SDouglas Gregor OS << "}\n"; 42473441091SDouglas Gregor } 42573441091SDouglas Gregor 426de3ef502SDouglas Gregor OS.indent(Indent); 427de3ef502SDouglas Gregor OS << "}\n"; 428de3ef502SDouglas Gregor } 429de3ef502SDouglas Gregor 430de3ef502SDouglas Gregor void Module::dump() const { 431de3ef502SDouglas Gregor print(llvm::errs()); 432de3ef502SDouglas Gregor } 433de3ef502SDouglas Gregor 434de3ef502SDouglas Gregor 435