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" 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" 24a3feee2aSRichard Smith 25de3ef502SDouglas Gregor using namespace clang; 26de3ef502SDouglas Gregor 27eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 28beee15e7SBen Langmuir const FileEntry *File, bool IsFramework, bool IsExplicit) 29beee15e7SBen Langmuir : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), ModuleMap(File), 3086dbed75SRichard Smith Umbrella(), ASTFile(0), IsMissingRequirement(false), IsAvailable(true), 3186dbed75SRichard Smith IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), 32*ffbafa2aSBen Langmuir IsSystem(false), IsExternC(false), IsInferred(false), 33*ffbafa2aSBen Langmuir InferSubmodules(false), InferExplicitSubmodules(false), 34*ffbafa2aSBen Langmuir InferExportWildcard(false), ConfigMacrosExhaustive(false), 35*ffbafa2aSBen Langmuir NameVisibility(Hidden) { 36eb90e830SDouglas Gregor if (Parent) { 37eb90e830SDouglas Gregor if (!Parent->isAvailable()) 38eb90e830SDouglas Gregor IsAvailable = false; 393ec6663bSDouglas Gregor if (Parent->IsSystem) 403ec6663bSDouglas Gregor IsSystem = true; 419bca298fSRichard Smith if (Parent->IsExternC) 429bca298fSRichard Smith IsExternC = true; 43993055f8SBen Langmuir IsMissingRequirement = Parent->IsMissingRequirement; 44eb90e830SDouglas Gregor 45eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 46eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 47eb90e830SDouglas Gregor } 48eb90e830SDouglas Gregor } 49eb90e830SDouglas Gregor 50de3ef502SDouglas Gregor Module::~Module() { 51eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 52de3ef502SDouglas Gregor I != IEnd; ++I) { 53eb90e830SDouglas Gregor delete *I; 54de3ef502SDouglas Gregor } 55de3ef502SDouglas Gregor } 56de3ef502SDouglas Gregor 571fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 581fb5c3a6SDouglas Gregor /// language options has the given feature. 5989929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 6089929282SDouglas Gregor const TargetInfo &Target) { 611fb5c3a6SDouglas Gregor return llvm::StringSwitch<bool>(Feature) 620070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 631fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 641fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 652bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 661fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 671fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 680070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 690070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 700070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 711fb5c3a6SDouglas Gregor } 721fb5c3a6SDouglas Gregor 731fb5c3a6SDouglas Gregor bool 7489929282SDouglas Gregor Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 750761a8a0SDaniel Jasper Requirement &Req, HeaderDirective &MissingHeader) const { 761fb5c3a6SDouglas Gregor if (IsAvailable) 771fb5c3a6SDouglas Gregor return true; 781fb5c3a6SDouglas Gregor 791fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 800761a8a0SDaniel Jasper if (!Current->MissingHeaders.empty()) { 810761a8a0SDaniel Jasper MissingHeader = Current->MissingHeaders.front(); 820761a8a0SDaniel Jasper return false; 830761a8a0SDaniel Jasper } 84a3feee2aSRichard Smith for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 85a3feee2aSRichard Smith if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 86a3feee2aSRichard Smith Current->Requirements[I].second) { 87a3feee2aSRichard Smith Req = Current->Requirements[I]; 881fb5c3a6SDouglas Gregor return false; 891fb5c3a6SDouglas Gregor } 901fb5c3a6SDouglas Gregor } 911fb5c3a6SDouglas Gregor } 921fb5c3a6SDouglas Gregor 931fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 941fb5c3a6SDouglas Gregor } 951fb5c3a6SDouglas Gregor 9662bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const { 97f5eedd05SDouglas Gregor const Module *This = this; 98f5eedd05SDouglas Gregor do { 99f5eedd05SDouglas Gregor if (This == Other) 100f5eedd05SDouglas Gregor return true; 101f5eedd05SDouglas Gregor 102f5eedd05SDouglas Gregor This = This->Parent; 103f5eedd05SDouglas Gregor } while (This); 104f5eedd05SDouglas Gregor 105f5eedd05SDouglas Gregor return false; 106f5eedd05SDouglas Gregor } 107f5eedd05SDouglas Gregor 10873441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 10973441091SDouglas Gregor const Module *Result = this; 11073441091SDouglas Gregor while (Result->Parent) 11173441091SDouglas Gregor Result = Result->Parent; 11273441091SDouglas Gregor 11373441091SDouglas Gregor return Result; 11473441091SDouglas Gregor } 11573441091SDouglas Gregor 116de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 117f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 118de3ef502SDouglas Gregor 119de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 120de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 121de3ef502SDouglas Gregor Names.push_back(M->Name); 122de3ef502SDouglas Gregor 123de3ef502SDouglas Gregor std::string Result; 12461ac906bSCraig Topper for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(), 125de3ef502SDouglas Gregor IEnd = Names.rend(); 126de3ef502SDouglas Gregor I != IEnd; ++I) { 127de3ef502SDouglas Gregor if (!Result.empty()) 128de3ef502SDouglas Gregor Result += '.'; 129de3ef502SDouglas Gregor 130de3ef502SDouglas Gregor Result += *I; 131de3ef502SDouglas Gregor } 132de3ef502SDouglas Gregor 133de3ef502SDouglas Gregor return Result; 134de3ef502SDouglas Gregor } 135de3ef502SDouglas Gregor 13673141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const { 13773141fa9SDouglas Gregor if (const FileEntry *Header = getUmbrellaHeader()) 13873141fa9SDouglas Gregor return Header->getDir(); 13973141fa9SDouglas Gregor 14073141fa9SDouglas Gregor return Umbrella.dyn_cast<const DirectoryEntry *>(); 14173141fa9SDouglas Gregor } 14273141fa9SDouglas Gregor 1433c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1443c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1453c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1463c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1473c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1483c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1493c5305c1SArgyrios Kyrtzidis } 1503c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1513c5305c1SArgyrios Kyrtzidis } 1523c5305c1SArgyrios Kyrtzidis 1533c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 1543c5305c1SArgyrios Kyrtzidis } 1553c5305c1SArgyrios Kyrtzidis 156a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState, 157a3feee2aSRichard Smith const LangOptions &LangOpts, 15889929282SDouglas Gregor const TargetInfo &Target) { 159a3feee2aSRichard Smith Requirements.push_back(Requirement(Feature, RequiredState)); 1601fb5c3a6SDouglas Gregor 1611fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 162a3feee2aSRichard Smith if (hasFeature(Feature, LangOpts, Target) == RequiredState) 1631fb5c3a6SDouglas Gregor return; 1641fb5c3a6SDouglas Gregor 165993055f8SBen Langmuir markUnavailable(/*MissingRequirement*/true); 166ec8c9752SBen Langmuir } 167ec8c9752SBen Langmuir 168993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) { 1691fb5c3a6SDouglas Gregor if (!IsAvailable) 1701fb5c3a6SDouglas Gregor return; 1711fb5c3a6SDouglas Gregor 172f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 1731fb5c3a6SDouglas Gregor Stack.push_back(this); 1741fb5c3a6SDouglas Gregor while (!Stack.empty()) { 1751fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 1761fb5c3a6SDouglas Gregor Stack.pop_back(); 1771fb5c3a6SDouglas Gregor 1781fb5c3a6SDouglas Gregor if (!Current->IsAvailable) 1791fb5c3a6SDouglas Gregor continue; 1801fb5c3a6SDouglas Gregor 1811fb5c3a6SDouglas Gregor Current->IsAvailable = false; 182993055f8SBen Langmuir Current->IsMissingRequirement |= MissingRequirement; 183eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 184eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 1851fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 186eb90e830SDouglas Gregor if ((*Sub)->IsAvailable) 187eb90e830SDouglas Gregor Stack.push_back(*Sub); 1881fb5c3a6SDouglas Gregor } 1891fb5c3a6SDouglas Gregor } 1901fb5c3a6SDouglas Gregor } 1911fb5c3a6SDouglas Gregor 192eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 193eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 194eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 195eb90e830SDouglas Gregor return 0; 196eb90e830SDouglas Gregor 197eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 198eb90e830SDouglas Gregor } 199eb90e830SDouglas Gregor 200f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 20124bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 20224bb923aSDouglas Gregor if (I) 20324bb923aSDouglas Gregor OS << "."; 20424bb923aSDouglas Gregor OS << Id[I].first; 20524bb923aSDouglas Gregor } 20624bb923aSDouglas Gregor } 20724bb923aSDouglas Gregor 2088739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 209e9bcf5b7SDmitri Gribenko // All non-explicit submodules are exported. 210e9bcf5b7SDmitri Gribenko for (std::vector<Module *>::const_iterator I = SubModules.begin(), 211e9bcf5b7SDmitri Gribenko E = SubModules.end(); 212e9bcf5b7SDmitri Gribenko I != E; ++I) { 213e9bcf5b7SDmitri Gribenko Module *Mod = *I; 214e9bcf5b7SDmitri Gribenko if (!Mod->IsExplicit) 215e9bcf5b7SDmitri Gribenko Exported.push_back(Mod); 216e9bcf5b7SDmitri Gribenko } 217e9bcf5b7SDmitri Gribenko 218e9bcf5b7SDmitri Gribenko // Find re-exported modules by filtering the list of imported modules. 2198739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 2208739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 2218739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 2228739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 2238739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 2248739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 2258739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2268739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2278739f7b7SArgyrios Kyrtzidis 2288739f7b7SArgyrios Kyrtzidis continue; 2298739f7b7SArgyrios Kyrtzidis } 2308739f7b7SArgyrios Kyrtzidis 2318739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2328739f7b7SArgyrios Kyrtzidis // the given pattern. 2338739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2348739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2358739f7b7SArgyrios Kyrtzidis continue; 2368739f7b7SArgyrios Kyrtzidis 2378739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2388739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 2398739f7b7SArgyrios Kyrtzidis else { 2408739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 2418739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 2428739f7b7SArgyrios Kyrtzidis } 2438739f7b7SArgyrios Kyrtzidis } 2448739f7b7SArgyrios Kyrtzidis 2458739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 2468739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 2478739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 2488739f7b7SArgyrios Kyrtzidis return; 2498739f7b7SArgyrios Kyrtzidis 2508739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2518739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 2528739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 2538739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 2548739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 2558739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 2568739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 2578739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 2588739f7b7SArgyrios Kyrtzidis Acceptable = true; 2598739f7b7SArgyrios Kyrtzidis break; 2608739f7b7SArgyrios Kyrtzidis } 2618739f7b7SArgyrios Kyrtzidis } 2628739f7b7SArgyrios Kyrtzidis } 2638739f7b7SArgyrios Kyrtzidis 2648739f7b7SArgyrios Kyrtzidis if (!Acceptable) 2658739f7b7SArgyrios Kyrtzidis continue; 2668739f7b7SArgyrios Kyrtzidis 2678739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2688739f7b7SArgyrios Kyrtzidis } 2698739f7b7SArgyrios Kyrtzidis } 2708739f7b7SArgyrios Kyrtzidis 2710e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const { 2720e5d7b8cSRichard Smith assert(VisibleModulesCache.empty() && "cache does not need building"); 2730e5d7b8cSRichard Smith 2740e5d7b8cSRichard Smith // This module is visible to itself. 2750e5d7b8cSRichard Smith VisibleModulesCache.insert(this); 2760e5d7b8cSRichard Smith 2770e5d7b8cSRichard Smith // Every imported module is visible. 278dde17e74SRichard Smith SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 279dc360d57SDmitri Gribenko while (!Stack.empty()) { 280dc360d57SDmitri Gribenko Module *CurrModule = Stack.pop_back_val(); 281dc360d57SDmitri Gribenko 282dde17e74SRichard Smith // Every module transitively exported by an imported module is visible. 283dde17e74SRichard Smith if (VisibleModulesCache.insert(CurrModule).second) 284dde17e74SRichard Smith CurrModule->getExportedModules(Stack); 2850e5d7b8cSRichard Smith } 2860e5d7b8cSRichard Smith } 2870e5d7b8cSRichard Smith 288f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 289de3ef502SDouglas Gregor OS.indent(Indent); 290de3ef502SDouglas Gregor if (IsFramework) 291de3ef502SDouglas Gregor OS << "framework "; 292de3ef502SDouglas Gregor if (IsExplicit) 293de3ef502SDouglas Gregor OS << "explicit "; 294a686e1b0SDouglas Gregor OS << "module " << Name; 295a686e1b0SDouglas Gregor 296a686e1b0SDouglas Gregor if (IsSystem) { 297a686e1b0SDouglas Gregor OS.indent(Indent + 2); 298a686e1b0SDouglas Gregor OS << " [system]"; 299a686e1b0SDouglas Gregor } 300a686e1b0SDouglas Gregor 301a686e1b0SDouglas Gregor OS << " {\n"; 302de3ef502SDouglas Gregor 303a3feee2aSRichard Smith if (!Requirements.empty()) { 3041fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 3051fb5c3a6SDouglas Gregor OS << "requires "; 306a3feee2aSRichard Smith for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 3071fb5c3a6SDouglas Gregor if (I) 3081fb5c3a6SDouglas Gregor OS << ", "; 309a3feee2aSRichard Smith if (!Requirements[I].second) 310a3feee2aSRichard Smith OS << "!"; 311a3feee2aSRichard Smith OS << Requirements[I].first; 3121fb5c3a6SDouglas Gregor } 3131fb5c3a6SDouglas Gregor OS << "\n"; 3141fb5c3a6SDouglas Gregor } 3151fb5c3a6SDouglas Gregor 31673141fa9SDouglas Gregor if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 317de3ef502SDouglas Gregor OS.indent(Indent + 2); 318322f633cSDouglas Gregor OS << "umbrella header \""; 319de3ef502SDouglas Gregor OS.write_escaped(UmbrellaHeader->getName()); 320de3ef502SDouglas Gregor OS << "\"\n"; 321322f633cSDouglas Gregor } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 322322f633cSDouglas Gregor OS.indent(Indent + 2); 323322f633cSDouglas Gregor OS << "umbrella \""; 324322f633cSDouglas Gregor OS.write_escaped(UmbrellaDir->getName()); 325322f633cSDouglas Gregor OS << "\"\n"; 326de3ef502SDouglas Gregor } 327de3ef502SDouglas Gregor 32835b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 32935b13eceSDouglas Gregor OS.indent(Indent + 2); 33035b13eceSDouglas Gregor OS << "config_macros "; 33135b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 3328d932427SDouglas Gregor OS << "[exhaustive]"; 33335b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 33435b13eceSDouglas Gregor if (I) 33535b13eceSDouglas Gregor OS << ", "; 33635b13eceSDouglas Gregor OS << ConfigMacros[I]; 33735b13eceSDouglas Gregor } 3388d932427SDouglas Gregor OS << "\n"; 33935b13eceSDouglas Gregor } 34035b13eceSDouglas Gregor 341b53e5483SLawrence Crowl for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) { 342de3ef502SDouglas Gregor OS.indent(Indent + 2); 343de3ef502SDouglas Gregor OS << "header \""; 344b53e5483SLawrence Crowl OS.write_escaped(NormalHeaders[I]->getName()); 345de3ef502SDouglas Gregor OS << "\"\n"; 346de3ef502SDouglas Gregor } 34759527666SDouglas Gregor 34859527666SDouglas Gregor for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) { 34959527666SDouglas Gregor OS.indent(Indent + 2); 35059527666SDouglas Gregor OS << "exclude header \""; 35159527666SDouglas Gregor OS.write_escaped(ExcludedHeaders[I]->getName()); 35259527666SDouglas Gregor OS << "\"\n"; 35359527666SDouglas Gregor } 354de3ef502SDouglas Gregor 355b53e5483SLawrence Crowl for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) { 356b53e5483SLawrence Crowl OS.indent(Indent + 2); 357b53e5483SLawrence Crowl OS << "private header \""; 358b53e5483SLawrence Crowl OS.write_escaped(PrivateHeaders[I]->getName()); 359b53e5483SLawrence Crowl OS << "\"\n"; 360b53e5483SLawrence Crowl } 361b53e5483SLawrence Crowl 362eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 363de3ef502SDouglas Gregor MI != MIEnd; ++MI) 364*ffbafa2aSBen Langmuir if (!(*MI)->IsInferred) 365eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 366de3ef502SDouglas Gregor 36724bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 36824bb923aSDouglas Gregor OS.indent(Indent + 2); 3698c7c8352SDouglas Gregor OS << "export "; 3708c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 3718c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 37224bb923aSDouglas Gregor if (Exports[I].getInt()) 37324bb923aSDouglas Gregor OS << ".*"; 3748c7c8352SDouglas Gregor } else { 3758c7c8352SDouglas Gregor OS << "*"; 3768c7c8352SDouglas Gregor } 37724bb923aSDouglas Gregor OS << "\n"; 37824bb923aSDouglas Gregor } 37924bb923aSDouglas Gregor 38024bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 38124bb923aSDouglas Gregor OS.indent(Indent + 2); 38224bb923aSDouglas Gregor OS << "export "; 38324bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 3848c7c8352SDouglas Gregor if (UnresolvedExports[I].Wildcard) { 3858c7c8352SDouglas Gregor if (UnresolvedExports[I].Id.empty()) 3868c7c8352SDouglas Gregor OS << "*"; 3878c7c8352SDouglas Gregor else 38824bb923aSDouglas Gregor OS << ".*"; 3898c7c8352SDouglas Gregor } 39024bb923aSDouglas Gregor OS << "\n"; 39124bb923aSDouglas Gregor } 39224bb923aSDouglas Gregor 393ba7f2f71SDaniel Jasper for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 394ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 395ba7f2f71SDaniel Jasper OS << "use "; 396ba7f2f71SDaniel Jasper OS << DirectUses[I]->getFullModuleName(); 397ba7f2f71SDaniel Jasper OS << "\n"; 398ba7f2f71SDaniel Jasper } 399ba7f2f71SDaniel Jasper 400ba7f2f71SDaniel Jasper for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 401ba7f2f71SDaniel Jasper OS.indent(Indent + 2); 402ba7f2f71SDaniel Jasper OS << "use "; 403ba7f2f71SDaniel Jasper printModuleId(OS, UnresolvedDirectUses[I]); 404ba7f2f71SDaniel Jasper OS << "\n"; 405ba7f2f71SDaniel Jasper } 406ba7f2f71SDaniel Jasper 4076ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 4086ddfca91SDouglas Gregor OS.indent(Indent + 2); 4096ddfca91SDouglas Gregor OS << "link "; 4106ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 4116ddfca91SDouglas Gregor OS << "framework "; 4126ddfca91SDouglas Gregor OS << "\""; 4136ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 4146ddfca91SDouglas Gregor OS << "\""; 4156ddfca91SDouglas Gregor } 4166ddfca91SDouglas Gregor 417fb912657SDouglas Gregor for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 418fb912657SDouglas Gregor OS.indent(Indent + 2); 419fb912657SDouglas Gregor OS << "conflict "; 420fb912657SDouglas Gregor printModuleId(OS, UnresolvedConflicts[I].Id); 421fb912657SDouglas Gregor OS << ", \""; 422fb912657SDouglas Gregor OS.write_escaped(UnresolvedConflicts[I].Message); 423fb912657SDouglas Gregor OS << "\"\n"; 424fb912657SDouglas Gregor } 425fb912657SDouglas Gregor 426fb912657SDouglas Gregor for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 427fb912657SDouglas Gregor OS.indent(Indent + 2); 428fb912657SDouglas Gregor OS << "conflict "; 429fb912657SDouglas Gregor OS << Conflicts[I].Other->getFullModuleName(); 430fb912657SDouglas Gregor OS << ", \""; 431fb912657SDouglas Gregor OS.write_escaped(Conflicts[I].Message); 432fb912657SDouglas Gregor OS << "\"\n"; 433fb912657SDouglas Gregor } 434fb912657SDouglas Gregor 43573441091SDouglas Gregor if (InferSubmodules) { 43673441091SDouglas Gregor OS.indent(Indent + 2); 43773441091SDouglas Gregor if (InferExplicitSubmodules) 43873441091SDouglas Gregor OS << "explicit "; 43973441091SDouglas Gregor OS << "module * {\n"; 44073441091SDouglas Gregor if (InferExportWildcard) { 44173441091SDouglas Gregor OS.indent(Indent + 4); 44273441091SDouglas Gregor OS << "export *\n"; 44373441091SDouglas Gregor } 44473441091SDouglas Gregor OS.indent(Indent + 2); 44573441091SDouglas Gregor OS << "}\n"; 44673441091SDouglas Gregor } 44773441091SDouglas Gregor 448de3ef502SDouglas Gregor OS.indent(Indent); 449de3ef502SDouglas Gregor OS << "}\n"; 450de3ef502SDouglas Gregor } 451de3ef502SDouglas Gregor 452de3ef502SDouglas Gregor void Module::dump() const { 453de3ef502SDouglas Gregor print(llvm::errs()); 454de3ef502SDouglas Gregor } 455de3ef502SDouglas Gregor 456de3ef502SDouglas Gregor 457