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 //===----------------------------------------------------------------------===// 14de3ef502SDouglas Gregor #include "clang/Basic/Module.h" 15de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h" 161fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h" 170070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h" 183c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h" 191fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h" 201fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h" 213a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 223a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 23de3ef502SDouglas Gregor using namespace clang; 24de3ef502SDouglas Gregor 25eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 26eb90e830SDouglas Gregor bool IsFramework, bool IsExplicit) 27eb90e830SDouglas Gregor : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 2843af5132SArgyrios Kyrtzidis Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false), 29a686e1b0SDouglas Gregor IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), 30a686e1b0SDouglas Gregor InferSubmodules(false), InferExplicitSubmodules(false), 31a686e1b0SDouglas Gregor InferExportWildcard(false), NameVisibility(Hidden) 32eb90e830SDouglas Gregor { 33eb90e830SDouglas Gregor if (Parent) { 34eb90e830SDouglas Gregor if (!Parent->isAvailable()) 35eb90e830SDouglas Gregor IsAvailable = false; 363ec6663bSDouglas Gregor if (Parent->IsSystem) 373ec6663bSDouglas Gregor IsSystem = true; 38eb90e830SDouglas Gregor 39eb90e830SDouglas Gregor Parent->SubModuleIndex[Name] = Parent->SubModules.size(); 40eb90e830SDouglas Gregor Parent->SubModules.push_back(this); 41eb90e830SDouglas Gregor } 42eb90e830SDouglas Gregor } 43eb90e830SDouglas Gregor 44de3ef502SDouglas Gregor Module::~Module() { 45eb90e830SDouglas Gregor for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); 46de3ef502SDouglas Gregor I != IEnd; ++I) { 47eb90e830SDouglas Gregor delete *I; 48de3ef502SDouglas Gregor } 49de3ef502SDouglas Gregor 50de3ef502SDouglas Gregor } 51de3ef502SDouglas Gregor 521fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current 531fb5c3a6SDouglas Gregor /// language options has the given feature. 5489929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 5589929282SDouglas Gregor const TargetInfo &Target) { 561fb5c3a6SDouglas Gregor return llvm::StringSwitch<bool>(Feature) 570070c0bfSDouglas Gregor .Case("altivec", LangOpts.AltiVec) 581fb5c3a6SDouglas Gregor .Case("blocks", LangOpts.Blocks) 591fb5c3a6SDouglas Gregor .Case("cplusplus", LangOpts.CPlusPlus) 602bf7fdb7SRichard Smith .Case("cplusplus11", LangOpts.CPlusPlus11) 611fb5c3a6SDouglas Gregor .Case("objc", LangOpts.ObjC1) 621fb5c3a6SDouglas Gregor .Case("objc_arc", LangOpts.ObjCAutoRefCount) 630070c0bfSDouglas Gregor .Case("opencl", LangOpts.OpenCL) 640070c0bfSDouglas Gregor .Case("tls", Target.isTLSSupported()) 650070c0bfSDouglas Gregor .Default(Target.hasFeature(Feature)); 661fb5c3a6SDouglas Gregor } 671fb5c3a6SDouglas Gregor 681fb5c3a6SDouglas Gregor bool 6989929282SDouglas Gregor Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 7089929282SDouglas Gregor StringRef &Feature) const { 711fb5c3a6SDouglas Gregor if (IsAvailable) 721fb5c3a6SDouglas Gregor return true; 731fb5c3a6SDouglas Gregor 741fb5c3a6SDouglas Gregor for (const Module *Current = this; Current; Current = Current->Parent) { 751fb5c3a6SDouglas Gregor for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { 7689929282SDouglas Gregor if (!hasFeature(Current->Requires[I], LangOpts, Target)) { 771fb5c3a6SDouglas Gregor Feature = Current->Requires[I]; 781fb5c3a6SDouglas Gregor return false; 791fb5c3a6SDouglas Gregor } 801fb5c3a6SDouglas Gregor } 811fb5c3a6SDouglas Gregor } 821fb5c3a6SDouglas Gregor 831fb5c3a6SDouglas Gregor llvm_unreachable("could not find a reason why module is unavailable"); 841fb5c3a6SDouglas Gregor } 851fb5c3a6SDouglas Gregor 86f5eedd05SDouglas Gregor bool Module::isSubModuleOf(Module *Other) const { 87f5eedd05SDouglas Gregor const Module *This = this; 88f5eedd05SDouglas Gregor do { 89f5eedd05SDouglas Gregor if (This == Other) 90f5eedd05SDouglas Gregor return true; 91f5eedd05SDouglas Gregor 92f5eedd05SDouglas Gregor This = This->Parent; 93f5eedd05SDouglas Gregor } while (This); 94f5eedd05SDouglas Gregor 95f5eedd05SDouglas Gregor return false; 96f5eedd05SDouglas Gregor } 97f5eedd05SDouglas Gregor 9873441091SDouglas Gregor const Module *Module::getTopLevelModule() const { 9973441091SDouglas Gregor const Module *Result = this; 10073441091SDouglas Gregor while (Result->Parent) 10173441091SDouglas Gregor Result = Result->Parent; 10273441091SDouglas Gregor 10373441091SDouglas Gregor return Result; 10473441091SDouglas Gregor } 10573441091SDouglas Gregor 106de3ef502SDouglas Gregor std::string Module::getFullModuleName() const { 107f857950dSDmitri Gribenko SmallVector<StringRef, 2> Names; 108de3ef502SDouglas Gregor 109de3ef502SDouglas Gregor // Build up the set of module names (from innermost to outermost). 110de3ef502SDouglas Gregor for (const Module *M = this; M; M = M->Parent) 111de3ef502SDouglas Gregor Names.push_back(M->Name); 112de3ef502SDouglas Gregor 113de3ef502SDouglas Gregor std::string Result; 114f857950dSDmitri Gribenko for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), 115de3ef502SDouglas Gregor IEnd = Names.rend(); 116de3ef502SDouglas Gregor I != IEnd; ++I) { 117de3ef502SDouglas Gregor if (!Result.empty()) 118de3ef502SDouglas Gregor Result += '.'; 119de3ef502SDouglas Gregor 120de3ef502SDouglas Gregor Result += *I; 121de3ef502SDouglas Gregor } 122de3ef502SDouglas Gregor 123de3ef502SDouglas Gregor return Result; 124de3ef502SDouglas Gregor } 125de3ef502SDouglas Gregor 12673141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const { 12773141fa9SDouglas Gregor if (const FileEntry *Header = getUmbrellaHeader()) 12873141fa9SDouglas Gregor return Header->getDir(); 12973141fa9SDouglas Gregor 13073141fa9SDouglas Gregor return Umbrella.dyn_cast<const DirectoryEntry *>(); 13173141fa9SDouglas Gregor } 13273141fa9SDouglas Gregor 1333c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { 1343c5305c1SArgyrios Kyrtzidis if (!TopHeaderNames.empty()) { 1353c5305c1SArgyrios Kyrtzidis for (std::vector<std::string>::iterator 1363c5305c1SArgyrios Kyrtzidis I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { 1373c5305c1SArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(*I)) 1383c5305c1SArgyrios Kyrtzidis TopHeaders.insert(FE); 1393c5305c1SArgyrios Kyrtzidis } 1403c5305c1SArgyrios Kyrtzidis TopHeaderNames.clear(); 1413c5305c1SArgyrios Kyrtzidis } 1423c5305c1SArgyrios Kyrtzidis 1433c5305c1SArgyrios Kyrtzidis return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); 1443c5305c1SArgyrios Kyrtzidis } 1453c5305c1SArgyrios Kyrtzidis 14689929282SDouglas Gregor void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, 14789929282SDouglas Gregor const TargetInfo &Target) { 1481fb5c3a6SDouglas Gregor Requires.push_back(Feature); 1491fb5c3a6SDouglas Gregor 1501fb5c3a6SDouglas Gregor // If this feature is currently available, we're done. 15189929282SDouglas Gregor if (hasFeature(Feature, LangOpts, Target)) 1521fb5c3a6SDouglas Gregor return; 1531fb5c3a6SDouglas Gregor 1541fb5c3a6SDouglas Gregor if (!IsAvailable) 1551fb5c3a6SDouglas Gregor return; 1561fb5c3a6SDouglas Gregor 157f857950dSDmitri Gribenko SmallVector<Module *, 2> Stack; 1581fb5c3a6SDouglas Gregor Stack.push_back(this); 1591fb5c3a6SDouglas Gregor while (!Stack.empty()) { 1601fb5c3a6SDouglas Gregor Module *Current = Stack.back(); 1611fb5c3a6SDouglas Gregor Stack.pop_back(); 1621fb5c3a6SDouglas Gregor 1631fb5c3a6SDouglas Gregor if (!Current->IsAvailable) 1641fb5c3a6SDouglas Gregor continue; 1651fb5c3a6SDouglas Gregor 1661fb5c3a6SDouglas Gregor Current->IsAvailable = false; 167eb90e830SDouglas Gregor for (submodule_iterator Sub = Current->submodule_begin(), 168eb90e830SDouglas Gregor SubEnd = Current->submodule_end(); 1691fb5c3a6SDouglas Gregor Sub != SubEnd; ++Sub) { 170eb90e830SDouglas Gregor if ((*Sub)->IsAvailable) 171eb90e830SDouglas Gregor Stack.push_back(*Sub); 1721fb5c3a6SDouglas Gregor } 1731fb5c3a6SDouglas Gregor } 1741fb5c3a6SDouglas Gregor } 1751fb5c3a6SDouglas Gregor 176eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const { 177eb90e830SDouglas Gregor llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 178eb90e830SDouglas Gregor if (Pos == SubModuleIndex.end()) 179eb90e830SDouglas Gregor return 0; 180eb90e830SDouglas Gregor 181eb90e830SDouglas Gregor return SubModules[Pos->getValue()]; 182eb90e830SDouglas Gregor } 183eb90e830SDouglas Gregor 184f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) { 18524bb923aSDouglas Gregor for (unsigned I = 0, N = Id.size(); I != N; ++I) { 18624bb923aSDouglas Gregor if (I) 18724bb923aSDouglas Gregor OS << "."; 18824bb923aSDouglas Gregor OS << Id[I].first; 18924bb923aSDouglas Gregor } 19024bb923aSDouglas Gregor } 19124bb923aSDouglas Gregor 1928739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 1938739f7b7SArgyrios Kyrtzidis bool AnyWildcard = false; 1948739f7b7SArgyrios Kyrtzidis bool UnrestrictedWildcard = false; 1958739f7b7SArgyrios Kyrtzidis SmallVector<Module *, 4> WildcardRestrictions; 1968739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 1978739f7b7SArgyrios Kyrtzidis Module *Mod = Exports[I].getPointer(); 1988739f7b7SArgyrios Kyrtzidis if (!Exports[I].getInt()) { 1998739f7b7SArgyrios Kyrtzidis // Export a named module directly; no wildcards involved. 2008739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2018739f7b7SArgyrios Kyrtzidis 2028739f7b7SArgyrios Kyrtzidis continue; 2038739f7b7SArgyrios Kyrtzidis } 2048739f7b7SArgyrios Kyrtzidis 2058739f7b7SArgyrios Kyrtzidis // Wildcard export: export all of the imported modules that match 2068739f7b7SArgyrios Kyrtzidis // the given pattern. 2078739f7b7SArgyrios Kyrtzidis AnyWildcard = true; 2088739f7b7SArgyrios Kyrtzidis if (UnrestrictedWildcard) 2098739f7b7SArgyrios Kyrtzidis continue; 2108739f7b7SArgyrios Kyrtzidis 2118739f7b7SArgyrios Kyrtzidis if (Module *Restriction = Exports[I].getPointer()) 2128739f7b7SArgyrios Kyrtzidis WildcardRestrictions.push_back(Restriction); 2138739f7b7SArgyrios Kyrtzidis else { 2148739f7b7SArgyrios Kyrtzidis WildcardRestrictions.clear(); 2158739f7b7SArgyrios Kyrtzidis UnrestrictedWildcard = true; 2168739f7b7SArgyrios Kyrtzidis } 2178739f7b7SArgyrios Kyrtzidis } 2188739f7b7SArgyrios Kyrtzidis 2198739f7b7SArgyrios Kyrtzidis // If there were any wildcards, push any imported modules that were 2208739f7b7SArgyrios Kyrtzidis // re-exported by the wildcard restriction. 2218739f7b7SArgyrios Kyrtzidis if (!AnyWildcard) 2228739f7b7SArgyrios Kyrtzidis return; 2238739f7b7SArgyrios Kyrtzidis 2248739f7b7SArgyrios Kyrtzidis for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 2258739f7b7SArgyrios Kyrtzidis Module *Mod = Imports[I]; 2268739f7b7SArgyrios Kyrtzidis bool Acceptable = UnrestrictedWildcard; 2278739f7b7SArgyrios Kyrtzidis if (!Acceptable) { 2288739f7b7SArgyrios Kyrtzidis // Check whether this module meets one of the restrictions. 2298739f7b7SArgyrios Kyrtzidis for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 2308739f7b7SArgyrios Kyrtzidis Module *Restriction = WildcardRestrictions[R]; 2318739f7b7SArgyrios Kyrtzidis if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 2328739f7b7SArgyrios Kyrtzidis Acceptable = true; 2338739f7b7SArgyrios Kyrtzidis break; 2348739f7b7SArgyrios Kyrtzidis } 2358739f7b7SArgyrios Kyrtzidis } 2368739f7b7SArgyrios Kyrtzidis } 2378739f7b7SArgyrios Kyrtzidis 2388739f7b7SArgyrios Kyrtzidis if (!Acceptable) 2398739f7b7SArgyrios Kyrtzidis continue; 2408739f7b7SArgyrios Kyrtzidis 2418739f7b7SArgyrios Kyrtzidis Exported.push_back(Mod); 2428739f7b7SArgyrios Kyrtzidis } 2438739f7b7SArgyrios Kyrtzidis } 2448739f7b7SArgyrios Kyrtzidis 245f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const { 246de3ef502SDouglas Gregor OS.indent(Indent); 247de3ef502SDouglas Gregor if (IsFramework) 248de3ef502SDouglas Gregor OS << "framework "; 249de3ef502SDouglas Gregor if (IsExplicit) 250de3ef502SDouglas Gregor OS << "explicit "; 251a686e1b0SDouglas Gregor OS << "module " << Name; 252a686e1b0SDouglas Gregor 253a686e1b0SDouglas Gregor if (IsSystem) { 254a686e1b0SDouglas Gregor OS.indent(Indent + 2); 255a686e1b0SDouglas Gregor OS << " [system]"; 256a686e1b0SDouglas Gregor } 257a686e1b0SDouglas Gregor 258a686e1b0SDouglas Gregor OS << " {\n"; 259de3ef502SDouglas Gregor 2601fb5c3a6SDouglas Gregor if (!Requires.empty()) { 2611fb5c3a6SDouglas Gregor OS.indent(Indent + 2); 2621fb5c3a6SDouglas Gregor OS << "requires "; 2631fb5c3a6SDouglas Gregor for (unsigned I = 0, N = Requires.size(); I != N; ++I) { 2641fb5c3a6SDouglas Gregor if (I) 2651fb5c3a6SDouglas Gregor OS << ", "; 2661fb5c3a6SDouglas Gregor OS << Requires[I]; 2671fb5c3a6SDouglas Gregor } 2681fb5c3a6SDouglas Gregor OS << "\n"; 2691fb5c3a6SDouglas Gregor } 2701fb5c3a6SDouglas Gregor 27173141fa9SDouglas Gregor if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { 272de3ef502SDouglas Gregor OS.indent(Indent + 2); 273322f633cSDouglas Gregor OS << "umbrella header \""; 274de3ef502SDouglas Gregor OS.write_escaped(UmbrellaHeader->getName()); 275de3ef502SDouglas Gregor OS << "\"\n"; 276322f633cSDouglas Gregor } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { 277322f633cSDouglas Gregor OS.indent(Indent + 2); 278322f633cSDouglas Gregor OS << "umbrella \""; 279322f633cSDouglas Gregor OS.write_escaped(UmbrellaDir->getName()); 280322f633cSDouglas Gregor OS << "\"\n"; 281de3ef502SDouglas Gregor } 282de3ef502SDouglas Gregor 283*35b13eceSDouglas Gregor if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 284*35b13eceSDouglas Gregor OS.indent(Indent + 2); 285*35b13eceSDouglas Gregor OS << "config_macros "; 286*35b13eceSDouglas Gregor if (ConfigMacrosExhaustive) 287*35b13eceSDouglas Gregor OS << "[exhausive]"; 288*35b13eceSDouglas Gregor for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 289*35b13eceSDouglas Gregor if (I) 290*35b13eceSDouglas Gregor OS << ", "; 291*35b13eceSDouglas Gregor OS << ConfigMacros[I]; 292*35b13eceSDouglas Gregor } 293*35b13eceSDouglas Gregor } 294*35b13eceSDouglas Gregor 295de3ef502SDouglas Gregor for (unsigned I = 0, N = Headers.size(); I != N; ++I) { 296de3ef502SDouglas Gregor OS.indent(Indent + 2); 297de3ef502SDouglas Gregor OS << "header \""; 298de3ef502SDouglas Gregor OS.write_escaped(Headers[I]->getName()); 299de3ef502SDouglas Gregor OS << "\"\n"; 300de3ef502SDouglas Gregor } 30159527666SDouglas Gregor 30259527666SDouglas Gregor for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) { 30359527666SDouglas Gregor OS.indent(Indent + 2); 30459527666SDouglas Gregor OS << "exclude header \""; 30559527666SDouglas Gregor OS.write_escaped(ExcludedHeaders[I]->getName()); 30659527666SDouglas Gregor OS << "\"\n"; 30759527666SDouglas Gregor } 308de3ef502SDouglas Gregor 309eb90e830SDouglas Gregor for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); 310de3ef502SDouglas Gregor MI != MIEnd; ++MI) 311eb90e830SDouglas Gregor (*MI)->print(OS, Indent + 2); 312de3ef502SDouglas Gregor 31324bb923aSDouglas Gregor for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 31424bb923aSDouglas Gregor OS.indent(Indent + 2); 3158c7c8352SDouglas Gregor OS << "export "; 3168c7c8352SDouglas Gregor if (Module *Restriction = Exports[I].getPointer()) { 3178c7c8352SDouglas Gregor OS << Restriction->getFullModuleName(); 31824bb923aSDouglas Gregor if (Exports[I].getInt()) 31924bb923aSDouglas Gregor OS << ".*"; 3208c7c8352SDouglas Gregor } else { 3218c7c8352SDouglas Gregor OS << "*"; 3228c7c8352SDouglas Gregor } 32324bb923aSDouglas Gregor OS << "\n"; 32424bb923aSDouglas Gregor } 32524bb923aSDouglas Gregor 32624bb923aSDouglas Gregor for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 32724bb923aSDouglas Gregor OS.indent(Indent + 2); 32824bb923aSDouglas Gregor OS << "export "; 32924bb923aSDouglas Gregor printModuleId(OS, UnresolvedExports[I].Id); 3308c7c8352SDouglas Gregor if (UnresolvedExports[I].Wildcard) { 3318c7c8352SDouglas Gregor if (UnresolvedExports[I].Id.empty()) 3328c7c8352SDouglas Gregor OS << "*"; 3338c7c8352SDouglas Gregor else 33424bb923aSDouglas Gregor OS << ".*"; 3358c7c8352SDouglas Gregor } 33624bb923aSDouglas Gregor OS << "\n"; 33724bb923aSDouglas Gregor } 33824bb923aSDouglas Gregor 3396ddfca91SDouglas Gregor for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 3406ddfca91SDouglas Gregor OS.indent(Indent + 2); 3416ddfca91SDouglas Gregor OS << "link "; 3426ddfca91SDouglas Gregor if (LinkLibraries[I].IsFramework) 3436ddfca91SDouglas Gregor OS << "framework "; 3446ddfca91SDouglas Gregor OS << "\""; 3456ddfca91SDouglas Gregor OS.write_escaped(LinkLibraries[I].Library); 3466ddfca91SDouglas Gregor OS << "\""; 3476ddfca91SDouglas Gregor } 3486ddfca91SDouglas Gregor 34973441091SDouglas Gregor if (InferSubmodules) { 35073441091SDouglas Gregor OS.indent(Indent + 2); 35173441091SDouglas Gregor if (InferExplicitSubmodules) 35273441091SDouglas Gregor OS << "explicit "; 35373441091SDouglas Gregor OS << "module * {\n"; 35473441091SDouglas Gregor if (InferExportWildcard) { 35573441091SDouglas Gregor OS.indent(Indent + 4); 35673441091SDouglas Gregor OS << "export *\n"; 35773441091SDouglas Gregor } 35873441091SDouglas Gregor OS.indent(Indent + 2); 35973441091SDouglas Gregor OS << "}\n"; 36073441091SDouglas Gregor } 36173441091SDouglas Gregor 362de3ef502SDouglas Gregor OS.indent(Indent); 363de3ef502SDouglas Gregor OS << "}\n"; 364de3ef502SDouglas Gregor } 365de3ef502SDouglas Gregor 366de3ef502SDouglas Gregor void Module::dump() const { 367de3ef502SDouglas Gregor print(llvm::errs()); 368de3ef502SDouglas Gregor } 369de3ef502SDouglas Gregor 370de3ef502SDouglas Gregor 371