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,
289d6448b1SBen Langmuir                bool IsFramework, bool IsExplicit)
293c1a41adSRichard Smith     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
30f1186c5aSCraig Topper       Umbrella(), ASTFile(nullptr), IsMissingRequirement(false),
31f1186c5aSCraig Topper       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
32f1186c5aSCraig Topper       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
33f1186c5aSCraig Topper       IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
34ffbafa2aSBen Langmuir       InferExportWildcard(false), ConfigMacrosExhaustive(false),
35ffbafa2aSBen 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) {
61*532d2104SBen Langmuir   bool HasFeature = 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));
71*532d2104SBen Langmuir   if (!HasFeature)
72*532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
73*532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
74*532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
75*532d2104SBen Langmuir   return HasFeature;
761fb5c3a6SDouglas Gregor }
771fb5c3a6SDouglas Gregor 
783c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
793c1a41adSRichard Smith                          Requirement &Req,
803c1a41adSRichard Smith                          UnresolvedHeaderDirective &MissingHeader) const {
811fb5c3a6SDouglas Gregor   if (IsAvailable)
821fb5c3a6SDouglas Gregor     return true;
831fb5c3a6SDouglas Gregor 
841fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
850761a8a0SDaniel Jasper     if (!Current->MissingHeaders.empty()) {
860761a8a0SDaniel Jasper       MissingHeader = Current->MissingHeaders.front();
870761a8a0SDaniel Jasper       return false;
880761a8a0SDaniel Jasper     }
89a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
90a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
91a3feee2aSRichard Smith               Current->Requirements[I].second) {
92a3feee2aSRichard Smith         Req = Current->Requirements[I];
931fb5c3a6SDouglas Gregor         return false;
941fb5c3a6SDouglas Gregor       }
951fb5c3a6SDouglas Gregor     }
961fb5c3a6SDouglas Gregor   }
971fb5c3a6SDouglas Gregor 
981fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
991fb5c3a6SDouglas Gregor }
1001fb5c3a6SDouglas Gregor 
10162bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
102f5eedd05SDouglas Gregor   const Module *This = this;
103f5eedd05SDouglas Gregor   do {
104f5eedd05SDouglas Gregor     if (This == Other)
105f5eedd05SDouglas Gregor       return true;
106f5eedd05SDouglas Gregor 
107f5eedd05SDouglas Gregor     This = This->Parent;
108f5eedd05SDouglas Gregor   } while (This);
109f5eedd05SDouglas Gregor 
110f5eedd05SDouglas Gregor   return false;
111f5eedd05SDouglas Gregor }
112f5eedd05SDouglas Gregor 
11373441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
11473441091SDouglas Gregor   const Module *Result = this;
11573441091SDouglas Gregor   while (Result->Parent)
11673441091SDouglas Gregor     Result = Result->Parent;
11773441091SDouglas Gregor 
11873441091SDouglas Gregor   return Result;
11973441091SDouglas Gregor }
12073441091SDouglas Gregor 
121de3ef502SDouglas Gregor std::string Module::getFullModuleName() const {
122f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
123de3ef502SDouglas Gregor 
124de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
125de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
126de3ef502SDouglas Gregor     Names.push_back(M->Name);
127de3ef502SDouglas Gregor 
128de3ef502SDouglas Gregor   std::string Result;
12961ac906bSCraig Topper   for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
130de3ef502SDouglas Gregor                                                  IEnd = Names.rend();
131de3ef502SDouglas Gregor        I != IEnd; ++I) {
132de3ef502SDouglas Gregor     if (!Result.empty())
133de3ef502SDouglas Gregor       Result += '.';
134de3ef502SDouglas Gregor 
135de3ef502SDouglas Gregor     Result += *I;
136de3ef502SDouglas Gregor   }
137de3ef502SDouglas Gregor 
138de3ef502SDouglas Gregor   return Result;
139de3ef502SDouglas Gregor }
140de3ef502SDouglas Gregor 
14173141fa9SDouglas Gregor const DirectoryEntry *Module::getUmbrellaDir() const {
14273141fa9SDouglas Gregor   if (const FileEntry *Header = getUmbrellaHeader())
14373141fa9SDouglas Gregor     return Header->getDir();
14473141fa9SDouglas Gregor 
14573141fa9SDouglas Gregor   return Umbrella.dyn_cast<const DirectoryEntry *>();
14673141fa9SDouglas Gregor }
14773141fa9SDouglas Gregor 
1483c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
1493c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
1503c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
1513c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
1523c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
1533c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
1543c5305c1SArgyrios Kyrtzidis     }
1553c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
1563c5305c1SArgyrios Kyrtzidis   }
1573c5305c1SArgyrios Kyrtzidis 
1583c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
1593c5305c1SArgyrios Kyrtzidis }
1603c5305c1SArgyrios Kyrtzidis 
161a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
162a3feee2aSRichard Smith                             const LangOptions &LangOpts,
16389929282SDouglas Gregor                             const TargetInfo &Target) {
164a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
1651fb5c3a6SDouglas Gregor 
1661fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
167a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
1681fb5c3a6SDouglas Gregor     return;
1691fb5c3a6SDouglas Gregor 
170993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
171ec8c9752SBen Langmuir }
172ec8c9752SBen Langmuir 
173993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
1741fb5c3a6SDouglas Gregor   if (!IsAvailable)
1751fb5c3a6SDouglas Gregor     return;
1761fb5c3a6SDouglas Gregor 
177f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
1781fb5c3a6SDouglas Gregor   Stack.push_back(this);
1791fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
1801fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
1811fb5c3a6SDouglas Gregor     Stack.pop_back();
1821fb5c3a6SDouglas Gregor 
1831fb5c3a6SDouglas Gregor     if (!Current->IsAvailable)
1841fb5c3a6SDouglas Gregor       continue;
1851fb5c3a6SDouglas Gregor 
1861fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
187993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
188eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
189eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
1901fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
191eb90e830SDouglas Gregor       if ((*Sub)->IsAvailable)
192eb90e830SDouglas Gregor         Stack.push_back(*Sub);
1931fb5c3a6SDouglas Gregor     }
1941fb5c3a6SDouglas Gregor   }
1951fb5c3a6SDouglas Gregor }
1961fb5c3a6SDouglas Gregor 
197eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
198eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
199eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
200f1186c5aSCraig Topper     return nullptr;
201eb90e830SDouglas Gregor 
202eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
203eb90e830SDouglas Gregor }
204eb90e830SDouglas Gregor 
205f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
20624bb923aSDouglas Gregor   for (unsigned I = 0, N = Id.size(); I != N; ++I) {
20724bb923aSDouglas Gregor     if (I)
20824bb923aSDouglas Gregor       OS << ".";
20924bb923aSDouglas Gregor     OS << Id[I].first;
21024bb923aSDouglas Gregor   }
21124bb923aSDouglas Gregor }
21224bb923aSDouglas Gregor 
2138739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
214e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
215e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
216e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
217e9bcf5b7SDmitri Gribenko        I != E; ++I) {
218e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
219e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
220e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
221e9bcf5b7SDmitri Gribenko   }
222e9bcf5b7SDmitri Gribenko 
223e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2248739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2258739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2268739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2278739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2288739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2298739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2308739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2318739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2328739f7b7SArgyrios Kyrtzidis 
2338739f7b7SArgyrios Kyrtzidis       continue;
2348739f7b7SArgyrios Kyrtzidis     }
2358739f7b7SArgyrios Kyrtzidis 
2368739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
2378739f7b7SArgyrios Kyrtzidis     // the given pattern.
2388739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
2398739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
2408739f7b7SArgyrios Kyrtzidis       continue;
2418739f7b7SArgyrios Kyrtzidis 
2428739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
2438739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
2448739f7b7SArgyrios Kyrtzidis     else {
2458739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
2468739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
2478739f7b7SArgyrios Kyrtzidis     }
2488739f7b7SArgyrios Kyrtzidis   }
2498739f7b7SArgyrios Kyrtzidis 
2508739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
2518739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
2528739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
2538739f7b7SArgyrios Kyrtzidis     return;
2548739f7b7SArgyrios Kyrtzidis 
2558739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
2568739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
2578739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
2588739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
2598739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
2608739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
2618739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
2628739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
2638739f7b7SArgyrios Kyrtzidis           Acceptable = true;
2648739f7b7SArgyrios Kyrtzidis           break;
2658739f7b7SArgyrios Kyrtzidis         }
2668739f7b7SArgyrios Kyrtzidis       }
2678739f7b7SArgyrios Kyrtzidis     }
2688739f7b7SArgyrios Kyrtzidis 
2698739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
2708739f7b7SArgyrios Kyrtzidis       continue;
2718739f7b7SArgyrios Kyrtzidis 
2728739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
2738739f7b7SArgyrios Kyrtzidis   }
2748739f7b7SArgyrios Kyrtzidis }
2758739f7b7SArgyrios Kyrtzidis 
2760e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
2770e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
2780e5d7b8cSRichard Smith 
2790e5d7b8cSRichard Smith   // This module is visible to itself.
2800e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
2810e5d7b8cSRichard Smith 
2820e5d7b8cSRichard Smith   // Every imported module is visible.
283dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
284dc360d57SDmitri Gribenko   while (!Stack.empty()) {
285dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
286dc360d57SDmitri Gribenko 
287dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
288dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
289dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
2900e5d7b8cSRichard Smith   }
2910e5d7b8cSRichard Smith }
2920e5d7b8cSRichard Smith 
293f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
294de3ef502SDouglas Gregor   OS.indent(Indent);
295de3ef502SDouglas Gregor   if (IsFramework)
296de3ef502SDouglas Gregor     OS << "framework ";
297de3ef502SDouglas Gregor   if (IsExplicit)
298de3ef502SDouglas Gregor     OS << "explicit ";
299a686e1b0SDouglas Gregor   OS << "module " << Name;
300a686e1b0SDouglas Gregor 
3017615f00eSBen Langmuir   if (IsSystem || IsExternC) {
302a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3037615f00eSBen Langmuir     if (IsSystem)
304a686e1b0SDouglas Gregor       OS << " [system]";
3057615f00eSBen Langmuir     if (IsExternC)
3067615f00eSBen Langmuir       OS << " [extern_c]";
307a686e1b0SDouglas Gregor   }
308a686e1b0SDouglas Gregor 
309a686e1b0SDouglas Gregor   OS << " {\n";
310de3ef502SDouglas Gregor 
311a3feee2aSRichard Smith   if (!Requirements.empty()) {
3121fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3131fb5c3a6SDouglas Gregor     OS << "requires ";
314a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3151fb5c3a6SDouglas Gregor       if (I)
3161fb5c3a6SDouglas Gregor         OS << ", ";
317a3feee2aSRichard Smith       if (!Requirements[I].second)
318a3feee2aSRichard Smith         OS << "!";
319a3feee2aSRichard Smith       OS << Requirements[I].first;
3201fb5c3a6SDouglas Gregor     }
3211fb5c3a6SDouglas Gregor     OS << "\n";
3221fb5c3a6SDouglas Gregor   }
3231fb5c3a6SDouglas Gregor 
32473141fa9SDouglas Gregor   if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
325de3ef502SDouglas Gregor     OS.indent(Indent + 2);
326322f633cSDouglas Gregor     OS << "umbrella header \"";
327de3ef502SDouglas Gregor     OS.write_escaped(UmbrellaHeader->getName());
328de3ef502SDouglas Gregor     OS << "\"\n";
329322f633cSDouglas Gregor   } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) {
330322f633cSDouglas Gregor     OS.indent(Indent + 2);
331322f633cSDouglas Gregor     OS << "umbrella \"";
332322f633cSDouglas Gregor     OS.write_escaped(UmbrellaDir->getName());
333322f633cSDouglas Gregor     OS << "\"\n";
334de3ef502SDouglas Gregor   }
335de3ef502SDouglas Gregor 
33635b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
33735b13eceSDouglas Gregor     OS.indent(Indent + 2);
33835b13eceSDouglas Gregor     OS << "config_macros ";
33935b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
3408d932427SDouglas Gregor       OS << "[exhaustive]";
34135b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
34235b13eceSDouglas Gregor       if (I)
34335b13eceSDouglas Gregor         OS << ", ";
34435b13eceSDouglas Gregor       OS << ConfigMacros[I];
34535b13eceSDouglas Gregor     }
3468d932427SDouglas Gregor     OS << "\n";
34735b13eceSDouglas Gregor   }
34835b13eceSDouglas Gregor 
3493c1a41adSRichard Smith   struct {
350306d8920SRichard Smith     StringRef Prefix;
3513c1a41adSRichard Smith     HeaderKind Kind;
3523c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
3533c1a41adSRichard Smith                {"textual ", HK_Textual},
3543c1a41adSRichard Smith                {"private ", HK_Private},
3553c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
3563c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
357306d8920SRichard Smith 
358306d8920SRichard Smith   for (auto &K : Kinds) {
3593c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
360de3ef502SDouglas Gregor       OS.indent(Indent + 2);
361306d8920SRichard Smith       OS << K.Prefix << "header \"";
3623c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
363de3ef502SDouglas Gregor       OS << "\"\n";
364de3ef502SDouglas Gregor     }
365b53e5483SLawrence Crowl   }
366b53e5483SLawrence Crowl 
367eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
368de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
3699d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
3709d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
3719d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
3729d6448b1SBen Langmuir     // those header files anyway.
3739d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
374eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
375de3ef502SDouglas Gregor 
37624bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
37724bb923aSDouglas Gregor     OS.indent(Indent + 2);
3788c7c8352SDouglas Gregor     OS << "export ";
3798c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
3808c7c8352SDouglas Gregor       OS << Restriction->getFullModuleName();
38124bb923aSDouglas Gregor       if (Exports[I].getInt())
38224bb923aSDouglas Gregor         OS << ".*";
3838c7c8352SDouglas Gregor     } else {
3848c7c8352SDouglas Gregor       OS << "*";
3858c7c8352SDouglas Gregor     }
38624bb923aSDouglas Gregor     OS << "\n";
38724bb923aSDouglas Gregor   }
38824bb923aSDouglas Gregor 
38924bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
39024bb923aSDouglas Gregor     OS.indent(Indent + 2);
39124bb923aSDouglas Gregor     OS << "export ";
39224bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
3938c7c8352SDouglas Gregor     if (UnresolvedExports[I].Wildcard) {
3948c7c8352SDouglas Gregor       if (UnresolvedExports[I].Id.empty())
3958c7c8352SDouglas Gregor         OS << "*";
3968c7c8352SDouglas Gregor       else
39724bb923aSDouglas Gregor         OS << ".*";
3988c7c8352SDouglas Gregor     }
39924bb923aSDouglas Gregor     OS << "\n";
40024bb923aSDouglas Gregor   }
40124bb923aSDouglas Gregor 
402ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
403ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
404ba7f2f71SDaniel Jasper     OS << "use ";
405ba7f2f71SDaniel Jasper     OS << DirectUses[I]->getFullModuleName();
406ba7f2f71SDaniel Jasper     OS << "\n";
407ba7f2f71SDaniel Jasper   }
408ba7f2f71SDaniel Jasper 
409ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
410ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
411ba7f2f71SDaniel Jasper     OS << "use ";
412ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
413ba7f2f71SDaniel Jasper     OS << "\n";
414ba7f2f71SDaniel Jasper   }
415ba7f2f71SDaniel Jasper 
4166ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4176ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4186ddfca91SDouglas Gregor     OS << "link ";
4196ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4206ddfca91SDouglas Gregor       OS << "framework ";
4216ddfca91SDouglas Gregor     OS << "\"";
4226ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
4236ddfca91SDouglas Gregor     OS << "\"";
4246ddfca91SDouglas Gregor   }
4256ddfca91SDouglas Gregor 
426fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
427fb912657SDouglas Gregor     OS.indent(Indent + 2);
428fb912657SDouglas Gregor     OS << "conflict ";
429fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
430fb912657SDouglas Gregor     OS << ", \"";
431fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
432fb912657SDouglas Gregor     OS << "\"\n";
433fb912657SDouglas Gregor   }
434fb912657SDouglas Gregor 
435fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
436fb912657SDouglas Gregor     OS.indent(Indent + 2);
437fb912657SDouglas Gregor     OS << "conflict ";
438fb912657SDouglas Gregor     OS << Conflicts[I].Other->getFullModuleName();
439fb912657SDouglas Gregor     OS << ", \"";
440fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
441fb912657SDouglas Gregor     OS << "\"\n";
442fb912657SDouglas Gregor   }
443fb912657SDouglas Gregor 
44473441091SDouglas Gregor   if (InferSubmodules) {
44573441091SDouglas Gregor     OS.indent(Indent + 2);
44673441091SDouglas Gregor     if (InferExplicitSubmodules)
44773441091SDouglas Gregor       OS << "explicit ";
44873441091SDouglas Gregor     OS << "module * {\n";
44973441091SDouglas Gregor     if (InferExportWildcard) {
45073441091SDouglas Gregor       OS.indent(Indent + 4);
45173441091SDouglas Gregor       OS << "export *\n";
45273441091SDouglas Gregor     }
45373441091SDouglas Gregor     OS.indent(Indent + 2);
45473441091SDouglas Gregor     OS << "}\n";
45573441091SDouglas Gregor   }
45673441091SDouglas Gregor 
457de3ef502SDouglas Gregor   OS.indent(Indent);
458de3ef502SDouglas Gregor   OS << "}\n";
459de3ef502SDouglas Gregor }
460de3ef502SDouglas Gregor 
461de3ef502SDouglas Gregor void Module::dump() const {
462de3ef502SDouglas Gregor   print(llvm::errs());
463de3ef502SDouglas Gregor }
464de3ef502SDouglas Gregor 
465de3ef502SDouglas Gregor 
466