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)
671fb5c3a6SDouglas Gregor                         .Case("objc", LangOpts.ObjC1)
681fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
690070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
700070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
713c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
720070c0bfSDouglas Gregor                         .Default(Target.hasFeature(Feature));
73532d2104SBen Langmuir   if (!HasFeature)
74532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
75532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
76532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
77532d2104SBen Langmuir   return HasFeature;
781fb5c3a6SDouglas Gregor }
791fb5c3a6SDouglas Gregor 
803c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
813c1a41adSRichard Smith                          Requirement &Req,
823c1a41adSRichard Smith                          UnresolvedHeaderDirective &MissingHeader) const {
831fb5c3a6SDouglas Gregor   if (IsAvailable)
841fb5c3a6SDouglas Gregor     return true;
851fb5c3a6SDouglas Gregor 
861fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
87a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
88a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
89a3feee2aSRichard Smith               Current->Requirements[I].second) {
90a3feee2aSRichard Smith         Req = Current->Requirements[I];
911fb5c3a6SDouglas Gregor         return false;
921fb5c3a6SDouglas Gregor       }
931fb5c3a6SDouglas Gregor     }
9475a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
9575a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
9675a7e435SBen Langmuir       return false;
9775a7e435SBen Langmuir     }
981fb5c3a6SDouglas Gregor   }
991fb5c3a6SDouglas Gregor 
1001fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1011fb5c3a6SDouglas Gregor }
1021fb5c3a6SDouglas Gregor 
10362bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
104f5eedd05SDouglas Gregor   const Module *This = this;
105f5eedd05SDouglas Gregor   do {
106f5eedd05SDouglas Gregor     if (This == Other)
107f5eedd05SDouglas Gregor       return true;
108f5eedd05SDouglas Gregor 
109f5eedd05SDouglas Gregor     This = This->Parent;
110f5eedd05SDouglas Gregor   } while (This);
111f5eedd05SDouglas Gregor 
112f5eedd05SDouglas Gregor   return false;
113f5eedd05SDouglas Gregor }
114f5eedd05SDouglas Gregor 
11573441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
11673441091SDouglas Gregor   const Module *Result = this;
11773441091SDouglas Gregor   while (Result->Parent)
11873441091SDouglas Gregor     Result = Result->Parent;
11973441091SDouglas Gregor 
12073441091SDouglas Gregor   return Result;
12173441091SDouglas Gregor }
12273441091SDouglas Gregor 
123de3ef502SDouglas Gregor std::string Module::getFullModuleName() const {
124f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
125de3ef502SDouglas Gregor 
126de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
127de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
128de3ef502SDouglas Gregor     Names.push_back(M->Name);
129de3ef502SDouglas Gregor 
130de3ef502SDouglas Gregor   std::string Result;
13161ac906bSCraig Topper   for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
132de3ef502SDouglas Gregor                                                  IEnd = Names.rend();
133de3ef502SDouglas Gregor        I != IEnd; ++I) {
134de3ef502SDouglas Gregor     if (!Result.empty())
135de3ef502SDouglas Gregor       Result += '.';
136de3ef502SDouglas Gregor 
137de3ef502SDouglas Gregor     Result += *I;
138de3ef502SDouglas Gregor   }
139de3ef502SDouglas Gregor 
140de3ef502SDouglas Gregor   return Result;
141de3ef502SDouglas Gregor }
142de3ef502SDouglas Gregor 
1437ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
1447ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
1457ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
1467ff29148SBen Langmuir       return false;
1477ff29148SBen Langmuir     nameParts = nameParts.drop_back();
1487ff29148SBen Langmuir   }
1497ff29148SBen Langmuir   return nameParts.empty();
1507ff29148SBen Langmuir }
1517ff29148SBen Langmuir 
1522b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
1532b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
1542b63d15fSRichard Smith     return {"", U.Entry->getDir()};
15573141fa9SDouglas Gregor 
1562b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
15773141fa9SDouglas Gregor }
15873141fa9SDouglas Gregor 
1593c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
1603c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
1613c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
1623c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
1633c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
1643c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
1653c5305c1SArgyrios Kyrtzidis     }
1663c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
1673c5305c1SArgyrios Kyrtzidis   }
1683c5305c1SArgyrios Kyrtzidis 
1693c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
1703c5305c1SArgyrios Kyrtzidis }
1713c5305c1SArgyrios Kyrtzidis 
1728f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
1738f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
1748f4d3ff1SRichard Smith 
1758f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
1768f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
1778f4d3ff1SRichard Smith     return true;
1788f4d3ff1SRichard Smith 
1798f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
1808f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
1818f4d3ff1SRichard Smith       return true;
1828f4d3ff1SRichard Smith   return false;
1838f4d3ff1SRichard Smith }
1848f4d3ff1SRichard Smith 
185a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
186a3feee2aSRichard Smith                             const LangOptions &LangOpts,
18789929282SDouglas Gregor                             const TargetInfo &Target) {
188a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
1891fb5c3a6SDouglas Gregor 
1901fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
191a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
1921fb5c3a6SDouglas Gregor     return;
1931fb5c3a6SDouglas Gregor 
194993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
195ec8c9752SBen Langmuir }
196ec8c9752SBen Langmuir 
197993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
19875a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
19975a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
20075a7e435SBen Langmuir   };
20175a7e435SBen Langmuir 
20275a7e435SBen Langmuir   if (!needUpdate(this))
2031fb5c3a6SDouglas Gregor     return;
2041fb5c3a6SDouglas Gregor 
205f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2061fb5c3a6SDouglas Gregor   Stack.push_back(this);
2071fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
2081fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
2091fb5c3a6SDouglas Gregor     Stack.pop_back();
2101fb5c3a6SDouglas Gregor 
21175a7e435SBen Langmuir     if (!needUpdate(Current))
2121fb5c3a6SDouglas Gregor       continue;
2131fb5c3a6SDouglas Gregor 
2141fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
215993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
216eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
217eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
2181fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
21975a7e435SBen Langmuir       if (needUpdate(*Sub))
220eb90e830SDouglas Gregor         Stack.push_back(*Sub);
2211fb5c3a6SDouglas Gregor     }
2221fb5c3a6SDouglas Gregor   }
2231fb5c3a6SDouglas Gregor }
2241fb5c3a6SDouglas Gregor 
225eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
226eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
227eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
228f1186c5aSCraig Topper     return nullptr;
229eb90e830SDouglas Gregor 
230eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
231eb90e830SDouglas Gregor }
232eb90e830SDouglas Gregor 
233f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
23424bb923aSDouglas Gregor   for (unsigned I = 0, N = Id.size(); I != N; ++I) {
23524bb923aSDouglas Gregor     if (I)
23624bb923aSDouglas Gregor       OS << ".";
23724bb923aSDouglas Gregor     OS << Id[I].first;
23824bb923aSDouglas Gregor   }
23924bb923aSDouglas Gregor }
24024bb923aSDouglas Gregor 
2418739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
242e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
243e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
244e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
245e9bcf5b7SDmitri Gribenko        I != E; ++I) {
246e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
247e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
248e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
249e9bcf5b7SDmitri Gribenko   }
250e9bcf5b7SDmitri Gribenko 
251e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2528739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2538739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2548739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2558739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2568739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2578739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2588739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2598739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2608739f7b7SArgyrios Kyrtzidis 
2618739f7b7SArgyrios Kyrtzidis       continue;
2628739f7b7SArgyrios Kyrtzidis     }
2638739f7b7SArgyrios Kyrtzidis 
2648739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
2658739f7b7SArgyrios Kyrtzidis     // the given pattern.
2668739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
2678739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
2688739f7b7SArgyrios Kyrtzidis       continue;
2698739f7b7SArgyrios Kyrtzidis 
2708739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
2718739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
2728739f7b7SArgyrios Kyrtzidis     else {
2738739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
2748739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
2758739f7b7SArgyrios Kyrtzidis     }
2768739f7b7SArgyrios Kyrtzidis   }
2778739f7b7SArgyrios Kyrtzidis 
2788739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
2798739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
2808739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
2818739f7b7SArgyrios Kyrtzidis     return;
2828739f7b7SArgyrios Kyrtzidis 
2838739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
2848739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
2858739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
2868739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
2878739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
2888739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
2898739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
2908739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
2918739f7b7SArgyrios Kyrtzidis           Acceptable = true;
2928739f7b7SArgyrios Kyrtzidis           break;
2938739f7b7SArgyrios Kyrtzidis         }
2948739f7b7SArgyrios Kyrtzidis       }
2958739f7b7SArgyrios Kyrtzidis     }
2968739f7b7SArgyrios Kyrtzidis 
2978739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
2988739f7b7SArgyrios Kyrtzidis       continue;
2998739f7b7SArgyrios Kyrtzidis 
3008739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3018739f7b7SArgyrios Kyrtzidis   }
3028739f7b7SArgyrios Kyrtzidis }
3038739f7b7SArgyrios Kyrtzidis 
3040e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3050e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3060e5d7b8cSRichard Smith 
3070e5d7b8cSRichard Smith   // This module is visible to itself.
3080e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3090e5d7b8cSRichard Smith 
3100e5d7b8cSRichard Smith   // Every imported module is visible.
311dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
312dc360d57SDmitri Gribenko   while (!Stack.empty()) {
313dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
314dc360d57SDmitri Gribenko 
315dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
316dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
317dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
3180e5d7b8cSRichard Smith   }
3190e5d7b8cSRichard Smith }
3200e5d7b8cSRichard Smith 
321f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
322de3ef502SDouglas Gregor   OS.indent(Indent);
323de3ef502SDouglas Gregor   if (IsFramework)
324de3ef502SDouglas Gregor     OS << "framework ";
325de3ef502SDouglas Gregor   if (IsExplicit)
326de3ef502SDouglas Gregor     OS << "explicit ";
327a686e1b0SDouglas Gregor   OS << "module " << Name;
328a686e1b0SDouglas Gregor 
3297615f00eSBen Langmuir   if (IsSystem || IsExternC) {
330a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3317615f00eSBen Langmuir     if (IsSystem)
332a686e1b0SDouglas Gregor       OS << " [system]";
3337615f00eSBen Langmuir     if (IsExternC)
3347615f00eSBen Langmuir       OS << " [extern_c]";
335a686e1b0SDouglas Gregor   }
336a686e1b0SDouglas Gregor 
337a686e1b0SDouglas Gregor   OS << " {\n";
338de3ef502SDouglas Gregor 
339a3feee2aSRichard Smith   if (!Requirements.empty()) {
3401fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3411fb5c3a6SDouglas Gregor     OS << "requires ";
342a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3431fb5c3a6SDouglas Gregor       if (I)
3441fb5c3a6SDouglas Gregor         OS << ", ";
345a3feee2aSRichard Smith       if (!Requirements[I].second)
346a3feee2aSRichard Smith         OS << "!";
347a3feee2aSRichard Smith       OS << Requirements[I].first;
3481fb5c3a6SDouglas Gregor     }
3491fb5c3a6SDouglas Gregor     OS << "\n";
3501fb5c3a6SDouglas Gregor   }
3511fb5c3a6SDouglas Gregor 
3522b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
353de3ef502SDouglas Gregor     OS.indent(Indent + 2);
354322f633cSDouglas Gregor     OS << "umbrella header \"";
3552b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
356de3ef502SDouglas Gregor     OS << "\"\n";
3572b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
358322f633cSDouglas Gregor     OS.indent(Indent + 2);
359322f633cSDouglas Gregor     OS << "umbrella \"";
3602b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
361322f633cSDouglas Gregor     OS << "\"\n";
362de3ef502SDouglas Gregor   }
363de3ef502SDouglas Gregor 
36435b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
36535b13eceSDouglas Gregor     OS.indent(Indent + 2);
36635b13eceSDouglas Gregor     OS << "config_macros ";
36735b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
3688d932427SDouglas Gregor       OS << "[exhaustive]";
36935b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
37035b13eceSDouglas Gregor       if (I)
37135b13eceSDouglas Gregor         OS << ", ";
37235b13eceSDouglas Gregor       OS << ConfigMacros[I];
37335b13eceSDouglas Gregor     }
3748d932427SDouglas Gregor     OS << "\n";
37535b13eceSDouglas Gregor   }
37635b13eceSDouglas Gregor 
3773c1a41adSRichard Smith   struct {
378306d8920SRichard Smith     StringRef Prefix;
3793c1a41adSRichard Smith     HeaderKind Kind;
3803c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
3813c1a41adSRichard Smith                {"textual ", HK_Textual},
3823c1a41adSRichard Smith                {"private ", HK_Private},
3833c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
3843c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
385306d8920SRichard Smith 
386306d8920SRichard Smith   for (auto &K : Kinds) {
3873c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
388de3ef502SDouglas Gregor       OS.indent(Indent + 2);
389306d8920SRichard Smith       OS << K.Prefix << "header \"";
3903c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
391de3ef502SDouglas Gregor       OS << "\"\n";
392de3ef502SDouglas Gregor     }
393b53e5483SLawrence Crowl   }
394b53e5483SLawrence Crowl 
395eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
396de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
3979d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
3989d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
3999d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4009d6448b1SBen Langmuir     // those header files anyway.
4019d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
402eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
403de3ef502SDouglas Gregor 
40424bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
40524bb923aSDouglas Gregor     OS.indent(Indent + 2);
4068c7c8352SDouglas Gregor     OS << "export ";
4078c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4088c7c8352SDouglas Gregor       OS << Restriction->getFullModuleName();
40924bb923aSDouglas Gregor       if (Exports[I].getInt())
41024bb923aSDouglas Gregor         OS << ".*";
4118c7c8352SDouglas Gregor     } else {
4128c7c8352SDouglas Gregor       OS << "*";
4138c7c8352SDouglas Gregor     }
41424bb923aSDouglas Gregor     OS << "\n";
41524bb923aSDouglas Gregor   }
41624bb923aSDouglas Gregor 
41724bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
41824bb923aSDouglas Gregor     OS.indent(Indent + 2);
41924bb923aSDouglas Gregor     OS << "export ";
42024bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4218c7c8352SDouglas Gregor     if (UnresolvedExports[I].Wildcard) {
4228c7c8352SDouglas Gregor       if (UnresolvedExports[I].Id.empty())
4238c7c8352SDouglas Gregor         OS << "*";
4248c7c8352SDouglas Gregor       else
42524bb923aSDouglas Gregor         OS << ".*";
4268c7c8352SDouglas Gregor     }
42724bb923aSDouglas Gregor     OS << "\n";
42824bb923aSDouglas Gregor   }
42924bb923aSDouglas Gregor 
430ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
431ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
432ba7f2f71SDaniel Jasper     OS << "use ";
433ba7f2f71SDaniel Jasper     OS << DirectUses[I]->getFullModuleName();
434ba7f2f71SDaniel Jasper     OS << "\n";
435ba7f2f71SDaniel Jasper   }
436ba7f2f71SDaniel Jasper 
437ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
438ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
439ba7f2f71SDaniel Jasper     OS << "use ";
440ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
441ba7f2f71SDaniel Jasper     OS << "\n";
442ba7f2f71SDaniel Jasper   }
443ba7f2f71SDaniel Jasper 
4446ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4456ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4466ddfca91SDouglas Gregor     OS << "link ";
4476ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4486ddfca91SDouglas Gregor       OS << "framework ";
4496ddfca91SDouglas Gregor     OS << "\"";
4506ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
4516ddfca91SDouglas Gregor     OS << "\"";
4526ddfca91SDouglas Gregor   }
4536ddfca91SDouglas Gregor 
454fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
455fb912657SDouglas Gregor     OS.indent(Indent + 2);
456fb912657SDouglas Gregor     OS << "conflict ";
457fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
458fb912657SDouglas Gregor     OS << ", \"";
459fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
460fb912657SDouglas Gregor     OS << "\"\n";
461fb912657SDouglas Gregor   }
462fb912657SDouglas Gregor 
463fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
464fb912657SDouglas Gregor     OS.indent(Indent + 2);
465fb912657SDouglas Gregor     OS << "conflict ";
466fb912657SDouglas Gregor     OS << Conflicts[I].Other->getFullModuleName();
467fb912657SDouglas Gregor     OS << ", \"";
468fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
469fb912657SDouglas Gregor     OS << "\"\n";
470fb912657SDouglas Gregor   }
471fb912657SDouglas Gregor 
47273441091SDouglas Gregor   if (InferSubmodules) {
47373441091SDouglas Gregor     OS.indent(Indent + 2);
47473441091SDouglas Gregor     if (InferExplicitSubmodules)
47573441091SDouglas Gregor       OS << "explicit ";
47673441091SDouglas Gregor     OS << "module * {\n";
47773441091SDouglas Gregor     if (InferExportWildcard) {
47873441091SDouglas Gregor       OS.indent(Indent + 4);
47973441091SDouglas Gregor       OS << "export *\n";
48073441091SDouglas Gregor     }
48173441091SDouglas Gregor     OS.indent(Indent + 2);
48273441091SDouglas Gregor     OS << "}\n";
48373441091SDouglas Gregor   }
48473441091SDouglas Gregor 
485de3ef502SDouglas Gregor   OS.indent(Indent);
486de3ef502SDouglas Gregor   OS << "}\n";
487de3ef502SDouglas Gregor }
488de3ef502SDouglas Gregor 
489*cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
490de3ef502SDouglas Gregor   print(llvm::errs());
491de3ef502SDouglas Gregor }
492de3ef502SDouglas Gregor 
493a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
494a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
495a7e2cc68SRichard Smith   if (isVisible(M))
496a7e2cc68SRichard Smith     return;
497de3ef502SDouglas Gregor 
498a7e2cc68SRichard Smith   ++Generation;
499a7e2cc68SRichard Smith 
500a7e2cc68SRichard Smith   struct Visiting {
501a7e2cc68SRichard Smith     Module *M;
502a7e2cc68SRichard Smith     Visiting *ExportedBy;
503a7e2cc68SRichard Smith   };
504a7e2cc68SRichard Smith 
505a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
506a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
507a7e2cc68SRichard Smith     if (!V.M->isAvailable())
508a7e2cc68SRichard Smith       return;
509a7e2cc68SRichard Smith 
510a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
511a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
512a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
513a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
514a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
515a7e2cc68SRichard Smith       return;
516a7e2cc68SRichard Smith 
517a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
518a7e2cc68SRichard Smith     Vis(M);
519a7e2cc68SRichard Smith 
520a7e2cc68SRichard Smith     // Make any exported modules visible.
521a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
522a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
523a7e2cc68SRichard Smith     for (Module *E : Exports)
524a7e2cc68SRichard Smith       VisitModule({E, &V});
525a7e2cc68SRichard Smith 
526a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
527a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
528a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
529a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
530a7e2cc68SRichard Smith           Path.push_back(I->M);
531a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
532a7e2cc68SRichard Smith       }
533a7e2cc68SRichard Smith     }
534a7e2cc68SRichard Smith   };
535a7e2cc68SRichard Smith   VisitModule({M, nullptr});
536a7e2cc68SRichard Smith }
537