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,
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),
3277944868SRichard Smith     IsExternC(false), InferSubmodules(false), InferExplicitSubmodules(false),
338d932427SDouglas Gregor     InferExportWildcard(false), ConfigMacrosExhaustive(false),
3477944868SRichard Smith     NameVisibility(Hidden) {
35eb90e830SDouglas Gregor   if (Parent) {
36eb90e830SDouglas Gregor     if (!Parent->isAvailable())
37eb90e830SDouglas Gregor       IsAvailable = false;
383ec6663bSDouglas Gregor     if (Parent->IsSystem)
393ec6663bSDouglas Gregor       IsSystem = true;
40*9bca298fSRichard Smith     if (Parent->IsExternC)
41*9bca298fSRichard Smith       IsExternC = true;
42eb90e830SDouglas Gregor 
43eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
44eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
45eb90e830SDouglas Gregor   }
46eb90e830SDouglas Gregor }
47eb90e830SDouglas Gregor 
48de3ef502SDouglas Gregor Module::~Module() {
49eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
50de3ef502SDouglas Gregor        I != IEnd; ++I) {
51eb90e830SDouglas Gregor     delete *I;
52de3ef502SDouglas Gregor   }
53de3ef502SDouglas Gregor }
54de3ef502SDouglas Gregor 
551fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current
561fb5c3a6SDouglas Gregor /// language options has the given feature.
5789929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
5889929282SDouglas Gregor                        const TargetInfo &Target) {
591fb5c3a6SDouglas Gregor   return llvm::StringSwitch<bool>(Feature)
600070c0bfSDouglas Gregor            .Case("altivec", LangOpts.AltiVec)
611fb5c3a6SDouglas Gregor            .Case("blocks", LangOpts.Blocks)
621fb5c3a6SDouglas Gregor            .Case("cplusplus", LangOpts.CPlusPlus)
632bf7fdb7SRichard Smith            .Case("cplusplus11", LangOpts.CPlusPlus11)
641fb5c3a6SDouglas Gregor            .Case("objc", LangOpts.ObjC1)
651fb5c3a6SDouglas Gregor            .Case("objc_arc", LangOpts.ObjCAutoRefCount)
660070c0bfSDouglas Gregor            .Case("opencl", LangOpts.OpenCL)
670070c0bfSDouglas Gregor            .Case("tls", Target.isTLSSupported())
680070c0bfSDouglas Gregor            .Default(Target.hasFeature(Feature));
691fb5c3a6SDouglas Gregor }
701fb5c3a6SDouglas Gregor 
711fb5c3a6SDouglas Gregor bool
7289929282SDouglas Gregor Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
730761a8a0SDaniel Jasper                     Requirement &Req, HeaderDirective &MissingHeader) const {
741fb5c3a6SDouglas Gregor   if (IsAvailable)
751fb5c3a6SDouglas Gregor     return true;
761fb5c3a6SDouglas Gregor 
771fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
780761a8a0SDaniel Jasper     if (!Current->MissingHeaders.empty()) {
790761a8a0SDaniel Jasper       MissingHeader = Current->MissingHeaders.front();
800761a8a0SDaniel Jasper       return false;
810761a8a0SDaniel Jasper     }
82a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
83a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
84a3feee2aSRichard Smith               Current->Requirements[I].second) {
85a3feee2aSRichard Smith         Req = Current->Requirements[I];
861fb5c3a6SDouglas Gregor         return false;
871fb5c3a6SDouglas Gregor       }
881fb5c3a6SDouglas Gregor     }
891fb5c3a6SDouglas Gregor   }
901fb5c3a6SDouglas Gregor 
911fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
921fb5c3a6SDouglas Gregor }
931fb5c3a6SDouglas Gregor 
94f5eedd05SDouglas Gregor bool Module::isSubModuleOf(Module *Other) const {
95f5eedd05SDouglas Gregor   const Module *This = this;
96f5eedd05SDouglas Gregor   do {
97f5eedd05SDouglas Gregor     if (This == Other)
98f5eedd05SDouglas Gregor       return true;
99f5eedd05SDouglas Gregor 
100f5eedd05SDouglas Gregor     This = This->Parent;
101f5eedd05SDouglas Gregor   } while (This);
102f5eedd05SDouglas Gregor 
103f5eedd05SDouglas Gregor   return false;
104f5eedd05SDouglas Gregor }
105f5eedd05SDouglas Gregor 
10673441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
10773441091SDouglas Gregor   const Module *Result = this;
10873441091SDouglas Gregor   while (Result->Parent)
10973441091SDouglas Gregor     Result = Result->Parent;
11073441091SDouglas Gregor 
11173441091SDouglas Gregor   return Result;
11273441091SDouglas Gregor }
11373441091SDouglas Gregor 
114de3ef502SDouglas Gregor std::string Module::getFullModuleName() const {
115f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
116de3ef502SDouglas Gregor 
117de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
118de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
119de3ef502SDouglas Gregor     Names.push_back(M->Name);
120de3ef502SDouglas Gregor 
121de3ef502SDouglas Gregor   std::string Result;
12261ac906bSCraig Topper   for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
123de3ef502SDouglas Gregor                                                  IEnd = Names.rend();
124de3ef502SDouglas Gregor        I != IEnd; ++I) {
125de3ef502SDouglas Gregor     if (!Result.empty())
126de3ef502SDouglas Gregor       Result += '.';
127de3ef502SDouglas Gregor 
128de3ef502SDouglas Gregor     Result += *I;
129de3ef502SDouglas Gregor   }
130de3ef502SDouglas Gregor 
131de3ef502SDouglas Gregor   return Result;
132de3ef502SDouglas Gregor }
133de3ef502SDouglas Gregor 
13473141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const {
13573141fa9SDouglas Gregor   if (const FileEntry *Header = getUmbrellaHeader())
13673141fa9SDouglas Gregor     return Header->getDir();
13773141fa9SDouglas Gregor 
13873141fa9SDouglas Gregor   return Umbrella.dyn_cast<const DirectoryEntry *>();
13973141fa9SDouglas Gregor }
14073141fa9SDouglas Gregor 
1413c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
1423c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
1433c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
1443c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
1453c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
1463c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
1473c5305c1SArgyrios Kyrtzidis     }
1483c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
1493c5305c1SArgyrios Kyrtzidis   }
1503c5305c1SArgyrios Kyrtzidis 
1513c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
1523c5305c1SArgyrios Kyrtzidis }
1533c5305c1SArgyrios Kyrtzidis 
154a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
155a3feee2aSRichard Smith                             const LangOptions &LangOpts,
15689929282SDouglas Gregor                             const TargetInfo &Target) {
157a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
1581fb5c3a6SDouglas Gregor 
1591fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
160a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
1611fb5c3a6SDouglas Gregor     return;
1621fb5c3a6SDouglas Gregor 
1631fb5c3a6SDouglas Gregor   if (!IsAvailable)
1641fb5c3a6SDouglas Gregor     return;
1651fb5c3a6SDouglas Gregor 
166f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
1671fb5c3a6SDouglas Gregor   Stack.push_back(this);
1681fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
1691fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
1701fb5c3a6SDouglas Gregor     Stack.pop_back();
1711fb5c3a6SDouglas Gregor 
1721fb5c3a6SDouglas Gregor     if (!Current->IsAvailable)
1731fb5c3a6SDouglas Gregor       continue;
1741fb5c3a6SDouglas Gregor 
1751fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
176eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
177eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
1781fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
179eb90e830SDouglas Gregor       if ((*Sub)->IsAvailable)
180eb90e830SDouglas Gregor         Stack.push_back(*Sub);
1811fb5c3a6SDouglas Gregor     }
1821fb5c3a6SDouglas Gregor   }
1831fb5c3a6SDouglas Gregor }
1841fb5c3a6SDouglas Gregor 
185eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
186eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
187eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
188eb90e830SDouglas Gregor     return 0;
189eb90e830SDouglas Gregor 
190eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
191eb90e830SDouglas Gregor }
192eb90e830SDouglas Gregor 
193f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
19424bb923aSDouglas Gregor   for (unsigned I = 0, N = Id.size(); I != N; ++I) {
19524bb923aSDouglas Gregor     if (I)
19624bb923aSDouglas Gregor       OS << ".";
19724bb923aSDouglas Gregor     OS << Id[I].first;
19824bb923aSDouglas Gregor   }
19924bb923aSDouglas Gregor }
20024bb923aSDouglas Gregor 
2018739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
202e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
203e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
204e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
205e9bcf5b7SDmitri Gribenko        I != E; ++I) {
206e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
207e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
208e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
209e9bcf5b7SDmitri Gribenko   }
210e9bcf5b7SDmitri Gribenko 
211e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2128739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2138739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2148739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2158739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2168739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2178739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2188739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2198739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2208739f7b7SArgyrios Kyrtzidis 
2218739f7b7SArgyrios Kyrtzidis       continue;
2228739f7b7SArgyrios Kyrtzidis     }
2238739f7b7SArgyrios Kyrtzidis 
2248739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
2258739f7b7SArgyrios Kyrtzidis     // the given pattern.
2268739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
2278739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
2288739f7b7SArgyrios Kyrtzidis       continue;
2298739f7b7SArgyrios Kyrtzidis 
2308739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
2318739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
2328739f7b7SArgyrios Kyrtzidis     else {
2338739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
2348739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
2358739f7b7SArgyrios Kyrtzidis     }
2368739f7b7SArgyrios Kyrtzidis   }
2378739f7b7SArgyrios Kyrtzidis 
2388739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
2398739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
2408739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
2418739f7b7SArgyrios Kyrtzidis     return;
2428739f7b7SArgyrios Kyrtzidis 
2438739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
2448739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
2458739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
2468739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
2478739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
2488739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
2498739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
2508739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
2518739f7b7SArgyrios Kyrtzidis           Acceptable = true;
2528739f7b7SArgyrios Kyrtzidis           break;
2538739f7b7SArgyrios Kyrtzidis         }
2548739f7b7SArgyrios Kyrtzidis       }
2558739f7b7SArgyrios Kyrtzidis     }
2568739f7b7SArgyrios Kyrtzidis 
2578739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
2588739f7b7SArgyrios Kyrtzidis       continue;
2598739f7b7SArgyrios Kyrtzidis 
2608739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
2618739f7b7SArgyrios Kyrtzidis   }
2628739f7b7SArgyrios Kyrtzidis }
2638739f7b7SArgyrios Kyrtzidis 
2640e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
2650e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
2660e5d7b8cSRichard Smith 
2670e5d7b8cSRichard Smith   // This module is visible to itself.
2680e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
2690e5d7b8cSRichard Smith 
2700e5d7b8cSRichard Smith   // Every imported module is visible.
271dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
272dc360d57SDmitri Gribenko   while (!Stack.empty()) {
273dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
274dc360d57SDmitri Gribenko 
275dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
276dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
277dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
2780e5d7b8cSRichard Smith   }
2790e5d7b8cSRichard Smith }
2800e5d7b8cSRichard Smith 
281f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
282de3ef502SDouglas Gregor   OS.indent(Indent);
283de3ef502SDouglas Gregor   if (IsFramework)
284de3ef502SDouglas Gregor     OS << "framework ";
285de3ef502SDouglas Gregor   if (IsExplicit)
286de3ef502SDouglas Gregor     OS << "explicit ";
287a686e1b0SDouglas Gregor   OS << "module " << Name;
288a686e1b0SDouglas Gregor 
289a686e1b0SDouglas Gregor   if (IsSystem) {
290a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
291a686e1b0SDouglas Gregor     OS << " [system]";
292a686e1b0SDouglas Gregor   }
293a686e1b0SDouglas Gregor 
294a686e1b0SDouglas Gregor   OS << " {\n";
295de3ef502SDouglas Gregor 
296a3feee2aSRichard Smith   if (!Requirements.empty()) {
2971fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
2981fb5c3a6SDouglas Gregor     OS << "requires ";
299a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3001fb5c3a6SDouglas Gregor       if (I)
3011fb5c3a6SDouglas Gregor         OS << ", ";
302a3feee2aSRichard Smith       if (!Requirements[I].second)
303a3feee2aSRichard Smith         OS << "!";
304a3feee2aSRichard Smith       OS << Requirements[I].first;
3051fb5c3a6SDouglas Gregor     }
3061fb5c3a6SDouglas Gregor     OS << "\n";
3071fb5c3a6SDouglas Gregor   }
3081fb5c3a6SDouglas Gregor 
30973141fa9SDouglas Gregor   if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
310de3ef502SDouglas Gregor     OS.indent(Indent + 2);
311322f633cSDouglas Gregor     OS << "umbrella header \"";
312de3ef502SDouglas Gregor     OS.write_escaped(UmbrellaHeader->getName());
313de3ef502SDouglas Gregor     OS << "\"\n";
314322f633cSDouglas Gregor   } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
315322f633cSDouglas Gregor     OS.indent(Indent + 2);
316322f633cSDouglas Gregor     OS << "umbrella \"";
317322f633cSDouglas Gregor     OS.write_escaped(UmbrellaDir->getName());
318322f633cSDouglas Gregor     OS << "\"\n";
319de3ef502SDouglas Gregor   }
320de3ef502SDouglas Gregor 
32135b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
32235b13eceSDouglas Gregor     OS.indent(Indent + 2);
32335b13eceSDouglas Gregor     OS << "config_macros ";
32435b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
3258d932427SDouglas Gregor       OS << "[exhaustive]";
32635b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
32735b13eceSDouglas Gregor       if (I)
32835b13eceSDouglas Gregor         OS << ", ";
32935b13eceSDouglas Gregor       OS << ConfigMacros[I];
33035b13eceSDouglas Gregor     }
3318d932427SDouglas Gregor     OS << "\n";
33235b13eceSDouglas Gregor   }
33335b13eceSDouglas Gregor 
334b53e5483SLawrence Crowl   for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) {
335de3ef502SDouglas Gregor     OS.indent(Indent + 2);
336de3ef502SDouglas Gregor     OS << "header \"";
337b53e5483SLawrence Crowl     OS.write_escaped(NormalHeaders[I]->getName());
338de3ef502SDouglas Gregor     OS << "\"\n";
339de3ef502SDouglas Gregor   }
34059527666SDouglas Gregor 
34159527666SDouglas Gregor   for (unsigned I = 0, N = ExcludedHeaders.size(); I != N; ++I) {
34259527666SDouglas Gregor     OS.indent(Indent + 2);
34359527666SDouglas Gregor     OS << "exclude header \"";
34459527666SDouglas Gregor     OS.write_escaped(ExcludedHeaders[I]->getName());
34559527666SDouglas Gregor     OS << "\"\n";
34659527666SDouglas Gregor   }
347de3ef502SDouglas Gregor 
348b53e5483SLawrence Crowl   for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) {
349b53e5483SLawrence Crowl     OS.indent(Indent + 2);
350b53e5483SLawrence Crowl     OS << "private header \"";
351b53e5483SLawrence Crowl     OS.write_escaped(PrivateHeaders[I]->getName());
352b53e5483SLawrence Crowl     OS << "\"\n";
353b53e5483SLawrence Crowl   }
354b53e5483SLawrence Crowl 
355eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
356de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
357eb90e830SDouglas Gregor     (*MI)->print(OS, Indent + 2);
358de3ef502SDouglas Gregor 
35924bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
36024bb923aSDouglas Gregor     OS.indent(Indent + 2);
3618c7c8352SDouglas Gregor     OS << "export ";
3628c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
3638c7c8352SDouglas Gregor       OS << Restriction->getFullModuleName();
36424bb923aSDouglas Gregor       if (Exports[I].getInt())
36524bb923aSDouglas Gregor         OS << ".*";
3668c7c8352SDouglas Gregor     } else {
3678c7c8352SDouglas Gregor       OS << "*";
3688c7c8352SDouglas Gregor     }
36924bb923aSDouglas Gregor     OS << "\n";
37024bb923aSDouglas Gregor   }
37124bb923aSDouglas Gregor 
37224bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
37324bb923aSDouglas Gregor     OS.indent(Indent + 2);
37424bb923aSDouglas Gregor     OS << "export ";
37524bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
3768c7c8352SDouglas Gregor     if (UnresolvedExports[I].Wildcard) {
3778c7c8352SDouglas Gregor       if (UnresolvedExports[I].Id.empty())
3788c7c8352SDouglas Gregor         OS << "*";
3798c7c8352SDouglas Gregor       else
38024bb923aSDouglas Gregor         OS << ".*";
3818c7c8352SDouglas Gregor     }
38224bb923aSDouglas Gregor     OS << "\n";
38324bb923aSDouglas Gregor   }
38424bb923aSDouglas Gregor 
385ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
386ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
387ba7f2f71SDaniel Jasper     OS << "use ";
388ba7f2f71SDaniel Jasper     OS << DirectUses[I]->getFullModuleName();
389ba7f2f71SDaniel Jasper     OS << "\n";
390ba7f2f71SDaniel Jasper   }
391ba7f2f71SDaniel Jasper 
392ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
393ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
394ba7f2f71SDaniel Jasper     OS << "use ";
395ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
396ba7f2f71SDaniel Jasper     OS << "\n";
397ba7f2f71SDaniel Jasper   }
398ba7f2f71SDaniel Jasper 
3996ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4006ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4016ddfca91SDouglas Gregor     OS << "link ";
4026ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4036ddfca91SDouglas Gregor       OS << "framework ";
4046ddfca91SDouglas Gregor     OS << "\"";
4056ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
4066ddfca91SDouglas Gregor     OS << "\"";
4076ddfca91SDouglas Gregor   }
4086ddfca91SDouglas Gregor 
409fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
410fb912657SDouglas Gregor     OS.indent(Indent + 2);
411fb912657SDouglas Gregor     OS << "conflict ";
412fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
413fb912657SDouglas Gregor     OS << ", \"";
414fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
415fb912657SDouglas Gregor     OS << "\"\n";
416fb912657SDouglas Gregor   }
417fb912657SDouglas Gregor 
418fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
419fb912657SDouglas Gregor     OS.indent(Indent + 2);
420fb912657SDouglas Gregor     OS << "conflict ";
421fb912657SDouglas Gregor     OS << Conflicts[I].Other->getFullModuleName();
422fb912657SDouglas Gregor     OS << ", \"";
423fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
424fb912657SDouglas Gregor     OS << "\"\n";
425fb912657SDouglas Gregor   }
426fb912657SDouglas Gregor 
42773441091SDouglas Gregor   if (InferSubmodules) {
42873441091SDouglas Gregor     OS.indent(Indent + 2);
42973441091SDouglas Gregor     if (InferExplicitSubmodules)
43073441091SDouglas Gregor       OS << "explicit ";
43173441091SDouglas Gregor     OS << "module * {\n";
43273441091SDouglas Gregor     if (InferExportWildcard) {
43373441091SDouglas Gregor       OS.indent(Indent + 4);
43473441091SDouglas Gregor       OS << "export *\n";
43573441091SDouglas Gregor     }
43673441091SDouglas Gregor     OS.indent(Indent + 2);
43773441091SDouglas Gregor     OS << "}\n";
43873441091SDouglas Gregor   }
43973441091SDouglas Gregor 
440de3ef502SDouglas Gregor   OS.indent(Indent);
441de3ef502SDouglas Gregor   OS << "}\n";
442de3ef502SDouglas Gregor }
443de3ef502SDouglas Gregor 
444de3ef502SDouglas Gregor void Module::dump() const {
445de3ef502SDouglas Gregor   print(llvm::errs());
446de3ef502SDouglas Gregor }
447de3ef502SDouglas Gregor 
448de3ef502SDouglas Gregor 
449