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,
28a7e2cc68SRichard Smith                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
293c1a41adSRichard Smith     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
3015bcf70cSAdrian Prantl       Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID),
318a308ec2SRichard Smith       IsMissingRequirement(false), HasIncompatibleModuleFile(false),
328a308ec2SRichard Smith       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
338a308ec2SRichard Smith       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
348a308ec2SRichard Smith       IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
358a308ec2SRichard Smith       InferExportWildcard(false), ConfigMacrosExhaustive(false),
368a308ec2SRichard Smith       NameVisibility(Hidden) {
37eb90e830SDouglas Gregor   if (Parent) {
38eb90e830SDouglas Gregor     if (!Parent->isAvailable())
39eb90e830SDouglas Gregor       IsAvailable = false;
403ec6663bSDouglas Gregor     if (Parent->IsSystem)
413ec6663bSDouglas Gregor       IsSystem = true;
429bca298fSRichard Smith     if (Parent->IsExternC)
439bca298fSRichard Smith       IsExternC = true;
44993055f8SBen Langmuir     IsMissingRequirement = Parent->IsMissingRequirement;
45eb90e830SDouglas Gregor 
46eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
47eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
48eb90e830SDouglas Gregor   }
49eb90e830SDouglas Gregor }
50eb90e830SDouglas Gregor 
51de3ef502SDouglas Gregor Module::~Module() {
52eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
53de3ef502SDouglas Gregor        I != IEnd; ++I) {
54eb90e830SDouglas Gregor     delete *I;
55de3ef502SDouglas Gregor   }
56de3ef502SDouglas Gregor }
57de3ef502SDouglas Gregor 
581fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current
591fb5c3a6SDouglas Gregor /// language options has the given feature.
6089929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
6189929282SDouglas Gregor                        const TargetInfo &Target) {
62532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
630070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
641fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
651fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
662bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
67*fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
686736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
691fb5c3a6SDouglas Gregor                         .Case("objc", LangOpts.ObjC1)
701fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
710070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
720070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
733c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
740070c0bfSDouglas Gregor                         .Default(Target.hasFeature(Feature));
75532d2104SBen Langmuir   if (!HasFeature)
76532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
77532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
78532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
79532d2104SBen Langmuir   return HasFeature;
801fb5c3a6SDouglas Gregor }
811fb5c3a6SDouglas Gregor 
823c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
833c1a41adSRichard Smith                          Requirement &Req,
843c1a41adSRichard Smith                          UnresolvedHeaderDirective &MissingHeader) const {
851fb5c3a6SDouglas Gregor   if (IsAvailable)
861fb5c3a6SDouglas Gregor     return true;
871fb5c3a6SDouglas Gregor 
881fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
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     }
9675a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
9775a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
9875a7e435SBen Langmuir       return false;
9975a7e435SBen Langmuir     }
1001fb5c3a6SDouglas Gregor   }
1011fb5c3a6SDouglas Gregor 
1021fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1031fb5c3a6SDouglas Gregor }
1041fb5c3a6SDouglas Gregor 
10562bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
106f5eedd05SDouglas Gregor   const Module *This = this;
107f5eedd05SDouglas Gregor   do {
108f5eedd05SDouglas Gregor     if (This == Other)
109f5eedd05SDouglas Gregor       return true;
110f5eedd05SDouglas Gregor 
111f5eedd05SDouglas Gregor     This = This->Parent;
112f5eedd05SDouglas Gregor   } while (This);
113f5eedd05SDouglas Gregor 
114f5eedd05SDouglas Gregor   return false;
115f5eedd05SDouglas Gregor }
116f5eedd05SDouglas Gregor 
11773441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
11873441091SDouglas Gregor   const Module *Result = this;
11973441091SDouglas Gregor   while (Result->Parent)
12073441091SDouglas Gregor     Result = Result->Parent;
12173441091SDouglas Gregor 
12273441091SDouglas Gregor   return Result;
12373441091SDouglas Gregor }
12473441091SDouglas Gregor 
125de3ef502SDouglas Gregor std::string Module::getFullModuleName() const {
126f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
127de3ef502SDouglas Gregor 
128de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
129de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
130de3ef502SDouglas Gregor     Names.push_back(M->Name);
131de3ef502SDouglas Gregor 
132de3ef502SDouglas Gregor   std::string Result;
13361ac906bSCraig Topper   for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
134de3ef502SDouglas Gregor                                                  IEnd = Names.rend();
135de3ef502SDouglas Gregor        I != IEnd; ++I) {
136de3ef502SDouglas Gregor     if (!Result.empty())
137de3ef502SDouglas Gregor       Result += '.';
138de3ef502SDouglas Gregor 
139de3ef502SDouglas Gregor     Result += *I;
140de3ef502SDouglas Gregor   }
141de3ef502SDouglas Gregor 
142de3ef502SDouglas Gregor   return Result;
143de3ef502SDouglas Gregor }
144de3ef502SDouglas Gregor 
1457ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
1467ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
1477ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
1487ff29148SBen Langmuir       return false;
1497ff29148SBen Langmuir     nameParts = nameParts.drop_back();
1507ff29148SBen Langmuir   }
1517ff29148SBen Langmuir   return nameParts.empty();
1527ff29148SBen Langmuir }
1537ff29148SBen Langmuir 
1542b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
1552b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
1562b63d15fSRichard Smith     return {"", U.Entry->getDir()};
15773141fa9SDouglas Gregor 
1582b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
15973141fa9SDouglas Gregor }
16073141fa9SDouglas Gregor 
1613c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
1623c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
1633c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
1643c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
1653c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
1663c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
1673c5305c1SArgyrios Kyrtzidis     }
1683c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
1693c5305c1SArgyrios Kyrtzidis   }
1703c5305c1SArgyrios Kyrtzidis 
1713c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
1723c5305c1SArgyrios Kyrtzidis }
1733c5305c1SArgyrios Kyrtzidis 
1748f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
1758f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
1768f4d3ff1SRichard Smith 
1778f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
1788f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
1798f4d3ff1SRichard Smith     return true;
1808f4d3ff1SRichard Smith 
1818f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
1828f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
1838f4d3ff1SRichard Smith       return true;
1848f4d3ff1SRichard Smith   return false;
1858f4d3ff1SRichard Smith }
1868f4d3ff1SRichard Smith 
187a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
188a3feee2aSRichard Smith                             const LangOptions &LangOpts,
18989929282SDouglas Gregor                             const TargetInfo &Target) {
190a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
1911fb5c3a6SDouglas Gregor 
1921fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
193a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
1941fb5c3a6SDouglas Gregor     return;
1951fb5c3a6SDouglas Gregor 
196993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
197ec8c9752SBen Langmuir }
198ec8c9752SBen Langmuir 
199993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
20075a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
20175a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
20275a7e435SBen Langmuir   };
20375a7e435SBen Langmuir 
20475a7e435SBen Langmuir   if (!needUpdate(this))
2051fb5c3a6SDouglas Gregor     return;
2061fb5c3a6SDouglas Gregor 
207f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2081fb5c3a6SDouglas Gregor   Stack.push_back(this);
2091fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
2101fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
2111fb5c3a6SDouglas Gregor     Stack.pop_back();
2121fb5c3a6SDouglas Gregor 
21375a7e435SBen Langmuir     if (!needUpdate(Current))
2141fb5c3a6SDouglas Gregor       continue;
2151fb5c3a6SDouglas Gregor 
2161fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
217993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
218eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
219eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
2201fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
22175a7e435SBen Langmuir       if (needUpdate(*Sub))
222eb90e830SDouglas Gregor         Stack.push_back(*Sub);
2231fb5c3a6SDouglas Gregor     }
2241fb5c3a6SDouglas Gregor   }
2251fb5c3a6SDouglas Gregor }
2261fb5c3a6SDouglas Gregor 
227eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
228eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
229eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
230f1186c5aSCraig Topper     return nullptr;
231eb90e830SDouglas Gregor 
232eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
233eb90e830SDouglas Gregor }
234eb90e830SDouglas Gregor 
235f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
23624bb923aSDouglas Gregor   for (unsigned I = 0, N = Id.size(); I != N; ++I) {
23724bb923aSDouglas Gregor     if (I)
23824bb923aSDouglas Gregor       OS << ".";
23924bb923aSDouglas Gregor     OS << Id[I].first;
24024bb923aSDouglas Gregor   }
24124bb923aSDouglas Gregor }
24224bb923aSDouglas Gregor 
2438739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
244e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
245e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
246e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
247e9bcf5b7SDmitri Gribenko        I != E; ++I) {
248e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
249e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
250e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
251e9bcf5b7SDmitri Gribenko   }
252e9bcf5b7SDmitri Gribenko 
253e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2548739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2558739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2568739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2578739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2588739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2598739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2608739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2618739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2628739f7b7SArgyrios Kyrtzidis 
2638739f7b7SArgyrios Kyrtzidis       continue;
2648739f7b7SArgyrios Kyrtzidis     }
2658739f7b7SArgyrios Kyrtzidis 
2668739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
2678739f7b7SArgyrios Kyrtzidis     // the given pattern.
2688739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
2698739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
2708739f7b7SArgyrios Kyrtzidis       continue;
2718739f7b7SArgyrios Kyrtzidis 
2728739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
2738739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
2748739f7b7SArgyrios Kyrtzidis     else {
2758739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
2768739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
2778739f7b7SArgyrios Kyrtzidis     }
2788739f7b7SArgyrios Kyrtzidis   }
2798739f7b7SArgyrios Kyrtzidis 
2808739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
2818739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
2828739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
2838739f7b7SArgyrios Kyrtzidis     return;
2848739f7b7SArgyrios Kyrtzidis 
2858739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
2868739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
2878739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
2888739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
2898739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
2908739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
2918739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
2928739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
2938739f7b7SArgyrios Kyrtzidis           Acceptable = true;
2948739f7b7SArgyrios Kyrtzidis           break;
2958739f7b7SArgyrios Kyrtzidis         }
2968739f7b7SArgyrios Kyrtzidis       }
2978739f7b7SArgyrios Kyrtzidis     }
2988739f7b7SArgyrios Kyrtzidis 
2998739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
3008739f7b7SArgyrios Kyrtzidis       continue;
3018739f7b7SArgyrios Kyrtzidis 
3028739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3038739f7b7SArgyrios Kyrtzidis   }
3048739f7b7SArgyrios Kyrtzidis }
3058739f7b7SArgyrios Kyrtzidis 
3060e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3070e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3080e5d7b8cSRichard Smith 
3090e5d7b8cSRichard Smith   // This module is visible to itself.
3100e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3110e5d7b8cSRichard Smith 
3120e5d7b8cSRichard Smith   // Every imported module is visible.
313dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
314dc360d57SDmitri Gribenko   while (!Stack.empty()) {
315dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
316dc360d57SDmitri Gribenko 
317dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
318dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
319dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
3200e5d7b8cSRichard Smith   }
3210e5d7b8cSRichard Smith }
3220e5d7b8cSRichard Smith 
323f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
324de3ef502SDouglas Gregor   OS.indent(Indent);
325de3ef502SDouglas Gregor   if (IsFramework)
326de3ef502SDouglas Gregor     OS << "framework ";
327de3ef502SDouglas Gregor   if (IsExplicit)
328de3ef502SDouglas Gregor     OS << "explicit ";
329a686e1b0SDouglas Gregor   OS << "module " << Name;
330a686e1b0SDouglas Gregor 
3317615f00eSBen Langmuir   if (IsSystem || IsExternC) {
332a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3337615f00eSBen Langmuir     if (IsSystem)
334a686e1b0SDouglas Gregor       OS << " [system]";
3357615f00eSBen Langmuir     if (IsExternC)
3367615f00eSBen Langmuir       OS << " [extern_c]";
337a686e1b0SDouglas Gregor   }
338a686e1b0SDouglas Gregor 
339a686e1b0SDouglas Gregor   OS << " {\n";
340de3ef502SDouglas Gregor 
341a3feee2aSRichard Smith   if (!Requirements.empty()) {
3421fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3431fb5c3a6SDouglas Gregor     OS << "requires ";
344a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3451fb5c3a6SDouglas Gregor       if (I)
3461fb5c3a6SDouglas Gregor         OS << ", ";
347a3feee2aSRichard Smith       if (!Requirements[I].second)
348a3feee2aSRichard Smith         OS << "!";
349a3feee2aSRichard Smith       OS << Requirements[I].first;
3501fb5c3a6SDouglas Gregor     }
3511fb5c3a6SDouglas Gregor     OS << "\n";
3521fb5c3a6SDouglas Gregor   }
3531fb5c3a6SDouglas Gregor 
3542b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
355de3ef502SDouglas Gregor     OS.indent(Indent + 2);
356322f633cSDouglas Gregor     OS << "umbrella header \"";
3572b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
358de3ef502SDouglas Gregor     OS << "\"\n";
3592b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
360322f633cSDouglas Gregor     OS.indent(Indent + 2);
361322f633cSDouglas Gregor     OS << "umbrella \"";
3622b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
363322f633cSDouglas Gregor     OS << "\"\n";
364de3ef502SDouglas Gregor   }
365de3ef502SDouglas Gregor 
36635b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
36735b13eceSDouglas Gregor     OS.indent(Indent + 2);
36835b13eceSDouglas Gregor     OS << "config_macros ";
36935b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
3708d932427SDouglas Gregor       OS << "[exhaustive]";
37135b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
37235b13eceSDouglas Gregor       if (I)
37335b13eceSDouglas Gregor         OS << ", ";
37435b13eceSDouglas Gregor       OS << ConfigMacros[I];
37535b13eceSDouglas Gregor     }
3768d932427SDouglas Gregor     OS << "\n";
37735b13eceSDouglas Gregor   }
37835b13eceSDouglas Gregor 
3793c1a41adSRichard Smith   struct {
380306d8920SRichard Smith     StringRef Prefix;
3813c1a41adSRichard Smith     HeaderKind Kind;
3823c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
3833c1a41adSRichard Smith                {"textual ", HK_Textual},
3843c1a41adSRichard Smith                {"private ", HK_Private},
3853c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
3863c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
387306d8920SRichard Smith 
388306d8920SRichard Smith   for (auto &K : Kinds) {
3893c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
390de3ef502SDouglas Gregor       OS.indent(Indent + 2);
391306d8920SRichard Smith       OS << K.Prefix << "header \"";
3923c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
393de3ef502SDouglas Gregor       OS << "\"\n";
394de3ef502SDouglas Gregor     }
395b53e5483SLawrence Crowl   }
396b53e5483SLawrence Crowl 
397eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
398de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
3999d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
4009d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
4019d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4029d6448b1SBen Langmuir     // those header files anyway.
4039d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
404eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
405de3ef502SDouglas Gregor 
40624bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
40724bb923aSDouglas Gregor     OS.indent(Indent + 2);
4088c7c8352SDouglas Gregor     OS << "export ";
4098c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4108c7c8352SDouglas Gregor       OS << Restriction->getFullModuleName();
41124bb923aSDouglas Gregor       if (Exports[I].getInt())
41224bb923aSDouglas Gregor         OS << ".*";
4138c7c8352SDouglas Gregor     } else {
4148c7c8352SDouglas Gregor       OS << "*";
4158c7c8352SDouglas Gregor     }
41624bb923aSDouglas Gregor     OS << "\n";
41724bb923aSDouglas Gregor   }
41824bb923aSDouglas Gregor 
41924bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
42024bb923aSDouglas Gregor     OS.indent(Indent + 2);
42124bb923aSDouglas Gregor     OS << "export ";
42224bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4237f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
4247f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
42524bb923aSDouglas Gregor     OS << "\n";
42624bb923aSDouglas Gregor   }
42724bb923aSDouglas Gregor 
428ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
429ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
430ba7f2f71SDaniel Jasper     OS << "use ";
431ba7f2f71SDaniel Jasper     OS << DirectUses[I]->getFullModuleName();
432ba7f2f71SDaniel Jasper     OS << "\n";
433ba7f2f71SDaniel Jasper   }
434ba7f2f71SDaniel Jasper 
435ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
436ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
437ba7f2f71SDaniel Jasper     OS << "use ";
438ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
439ba7f2f71SDaniel Jasper     OS << "\n";
440ba7f2f71SDaniel Jasper   }
441ba7f2f71SDaniel Jasper 
4426ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4436ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4446ddfca91SDouglas Gregor     OS << "link ";
4456ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4466ddfca91SDouglas Gregor       OS << "framework ";
4476ddfca91SDouglas Gregor     OS << "\"";
4486ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
4496ddfca91SDouglas Gregor     OS << "\"";
4506ddfca91SDouglas Gregor   }
4516ddfca91SDouglas Gregor 
452fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
453fb912657SDouglas Gregor     OS.indent(Indent + 2);
454fb912657SDouglas Gregor     OS << "conflict ";
455fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
456fb912657SDouglas Gregor     OS << ", \"";
457fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
458fb912657SDouglas Gregor     OS << "\"\n";
459fb912657SDouglas Gregor   }
460fb912657SDouglas Gregor 
461fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
462fb912657SDouglas Gregor     OS.indent(Indent + 2);
463fb912657SDouglas Gregor     OS << "conflict ";
464fb912657SDouglas Gregor     OS << Conflicts[I].Other->getFullModuleName();
465fb912657SDouglas Gregor     OS << ", \"";
466fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
467fb912657SDouglas Gregor     OS << "\"\n";
468fb912657SDouglas Gregor   }
469fb912657SDouglas Gregor 
47073441091SDouglas Gregor   if (InferSubmodules) {
47173441091SDouglas Gregor     OS.indent(Indent + 2);
47273441091SDouglas Gregor     if (InferExplicitSubmodules)
47373441091SDouglas Gregor       OS << "explicit ";
47473441091SDouglas Gregor     OS << "module * {\n";
47573441091SDouglas Gregor     if (InferExportWildcard) {
47673441091SDouglas Gregor       OS.indent(Indent + 4);
47773441091SDouglas Gregor       OS << "export *\n";
47873441091SDouglas Gregor     }
47973441091SDouglas Gregor     OS.indent(Indent + 2);
48073441091SDouglas Gregor     OS << "}\n";
48173441091SDouglas Gregor   }
48273441091SDouglas Gregor 
483de3ef502SDouglas Gregor   OS.indent(Indent);
484de3ef502SDouglas Gregor   OS << "}\n";
485de3ef502SDouglas Gregor }
486de3ef502SDouglas Gregor 
487cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
488de3ef502SDouglas Gregor   print(llvm::errs());
489de3ef502SDouglas Gregor }
490de3ef502SDouglas Gregor 
491a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
492a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
4936d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
494a7e2cc68SRichard Smith   if (isVisible(M))
495a7e2cc68SRichard Smith     return;
496de3ef502SDouglas Gregor 
497a7e2cc68SRichard Smith   ++Generation;
498a7e2cc68SRichard Smith 
499a7e2cc68SRichard Smith   struct Visiting {
500a7e2cc68SRichard Smith     Module *M;
501a7e2cc68SRichard Smith     Visiting *ExportedBy;
502a7e2cc68SRichard Smith   };
503a7e2cc68SRichard Smith 
504a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
505a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
506a7e2cc68SRichard Smith     if (!V.M->isAvailable())
507a7e2cc68SRichard Smith       return;
508a7e2cc68SRichard Smith 
509a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
510a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
511a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
512a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
513a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
514a7e2cc68SRichard Smith       return;
515a7e2cc68SRichard Smith 
516a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
517a7e2cc68SRichard Smith     Vis(M);
518a7e2cc68SRichard Smith 
519a7e2cc68SRichard Smith     // Make any exported modules visible.
520a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
521a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
522a7e2cc68SRichard Smith     for (Module *E : Exports)
523a7e2cc68SRichard Smith       VisitModule({E, &V});
524a7e2cc68SRichard Smith 
525a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
526a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
527a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
528a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
529a7e2cc68SRichard Smith           Path.push_back(I->M);
530a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
531a7e2cc68SRichard Smith       }
532a7e2cc68SRichard Smith     }
533a7e2cc68SRichard Smith   };
534a7e2cc68SRichard Smith   VisitModule({M, nullptr});
535a7e2cc68SRichard Smith }
536