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(),
3060fa2888SDuncan P. N. Exon Smith       Umbrella(), 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),
36e6b7c28dSDavid Blaikie       NoUndeclaredIncludes(false), 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;
44ed84df00SBruno Cardoso Lopes     if (Parent->NoUndeclaredIncludes)
45ed84df00SBruno Cardoso Lopes       NoUndeclaredIncludes = true;
46993055f8SBen Langmuir     IsMissingRequirement = Parent->IsMissingRequirement;
47eb90e830SDouglas Gregor 
48eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
49eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
50eb90e830SDouglas Gregor   }
51eb90e830SDouglas Gregor }
52eb90e830SDouglas Gregor 
53de3ef502SDouglas Gregor Module::~Module() {
54eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
55de3ef502SDouglas Gregor        I != IEnd; ++I) {
56eb90e830SDouglas Gregor     delete *I;
57de3ef502SDouglas Gregor   }
58de3ef502SDouglas Gregor }
59de3ef502SDouglas Gregor 
601fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current
611fb5c3a6SDouglas Gregor /// language options has the given feature.
6289929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
6389929282SDouglas Gregor                        const TargetInfo &Target) {
64532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
650070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
661fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
67e38cea02SEric Fiselier                         .Case("coroutines", LangOpts.CoroutinesTS)
681fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
692bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
70fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
716736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
721fb5c3a6SDouglas Gregor                         .Case("objc", LangOpts.ObjC1)
731fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
740070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
750070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
763c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
770070c0bfSDouglas Gregor                         .Default(Target.hasFeature(Feature));
78532d2104SBen Langmuir   if (!HasFeature)
79532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
80532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
81532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
82532d2104SBen Langmuir   return HasFeature;
831fb5c3a6SDouglas Gregor }
841fb5c3a6SDouglas Gregor 
853c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
863c1a41adSRichard Smith                          Requirement &Req,
873c1a41adSRichard Smith                          UnresolvedHeaderDirective &MissingHeader) const {
881fb5c3a6SDouglas Gregor   if (IsAvailable)
891fb5c3a6SDouglas Gregor     return true;
901fb5c3a6SDouglas Gregor 
911fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
92a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
93a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
94a3feee2aSRichard Smith               Current->Requirements[I].second) {
95a3feee2aSRichard Smith         Req = Current->Requirements[I];
961fb5c3a6SDouglas Gregor         return false;
971fb5c3a6SDouglas Gregor       }
981fb5c3a6SDouglas Gregor     }
9975a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
10075a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
10175a7e435SBen Langmuir       return false;
10275a7e435SBen Langmuir     }
1031fb5c3a6SDouglas Gregor   }
1041fb5c3a6SDouglas Gregor 
1051fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1061fb5c3a6SDouglas Gregor }
1071fb5c3a6SDouglas Gregor 
10862bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
109f5eedd05SDouglas Gregor   const Module *This = this;
110f5eedd05SDouglas Gregor   do {
111f5eedd05SDouglas Gregor     if (This == Other)
112f5eedd05SDouglas Gregor       return true;
113f5eedd05SDouglas Gregor 
114f5eedd05SDouglas Gregor     This = This->Parent;
115f5eedd05SDouglas Gregor   } while (This);
116f5eedd05SDouglas Gregor 
117f5eedd05SDouglas Gregor   return false;
118f5eedd05SDouglas Gregor }
119f5eedd05SDouglas Gregor 
12073441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
12173441091SDouglas Gregor   const Module *Result = this;
12273441091SDouglas Gregor   while (Result->Parent)
12373441091SDouglas Gregor     Result = Result->Parent;
12473441091SDouglas Gregor 
12573441091SDouglas Gregor   return Result;
12673441091SDouglas Gregor }
12773441091SDouglas Gregor 
128de3ef502SDouglas Gregor std::string Module::getFullModuleName() const {
129f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
130de3ef502SDouglas Gregor 
131de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
132de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
133de3ef502SDouglas Gregor     Names.push_back(M->Name);
134de3ef502SDouglas Gregor 
135de3ef502SDouglas Gregor   std::string Result;
13661ac906bSCraig Topper   for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
137de3ef502SDouglas Gregor                                                  IEnd = Names.rend();
138de3ef502SDouglas Gregor        I != IEnd; ++I) {
139de3ef502SDouglas Gregor     if (!Result.empty())
140de3ef502SDouglas Gregor       Result += '.';
141de3ef502SDouglas Gregor 
142de3ef502SDouglas Gregor     Result += *I;
143de3ef502SDouglas Gregor   }
144de3ef502SDouglas Gregor 
145de3ef502SDouglas Gregor   return Result;
146de3ef502SDouglas Gregor }
147de3ef502SDouglas Gregor 
1487ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
1497ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
1507ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
1517ff29148SBen Langmuir       return false;
1527ff29148SBen Langmuir     nameParts = nameParts.drop_back();
1537ff29148SBen Langmuir   }
1547ff29148SBen Langmuir   return nameParts.empty();
1557ff29148SBen Langmuir }
1567ff29148SBen Langmuir 
1572b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
1582b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
1592b63d15fSRichard Smith     return {"", U.Entry->getDir()};
16073141fa9SDouglas Gregor 
1612b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
16273141fa9SDouglas Gregor }
16373141fa9SDouglas Gregor 
1643c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
1653c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
1663c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
1673c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
1683c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
1693c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
1703c5305c1SArgyrios Kyrtzidis     }
1713c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
1723c5305c1SArgyrios Kyrtzidis   }
1733c5305c1SArgyrios Kyrtzidis 
1743c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
1753c5305c1SArgyrios Kyrtzidis }
1763c5305c1SArgyrios Kyrtzidis 
1778f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
1788f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
1798f4d3ff1SRichard Smith 
1808f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
1818f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
1828f4d3ff1SRichard Smith     return true;
1838f4d3ff1SRichard Smith 
1848f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
1858f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
1868f4d3ff1SRichard Smith       return true;
187ed84df00SBruno Cardoso Lopes 
188ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
189ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
190ed84df00SBruno Cardoso Lopes     return true;
191ed84df00SBruno Cardoso Lopes 
1928f4d3ff1SRichard Smith   return false;
1938f4d3ff1SRichard Smith }
1948f4d3ff1SRichard Smith 
195a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
196a3feee2aSRichard Smith                             const LangOptions &LangOpts,
19789929282SDouglas Gregor                             const TargetInfo &Target) {
198a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
1991fb5c3a6SDouglas Gregor 
2001fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
201a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2021fb5c3a6SDouglas Gregor     return;
2031fb5c3a6SDouglas Gregor 
204993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
205ec8c9752SBen Langmuir }
206ec8c9752SBen Langmuir 
207993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
20875a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
20975a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
21075a7e435SBen Langmuir   };
21175a7e435SBen Langmuir 
21275a7e435SBen Langmuir   if (!needUpdate(this))
2131fb5c3a6SDouglas Gregor     return;
2141fb5c3a6SDouglas Gregor 
215f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2161fb5c3a6SDouglas Gregor   Stack.push_back(this);
2171fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
2181fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
2191fb5c3a6SDouglas Gregor     Stack.pop_back();
2201fb5c3a6SDouglas Gregor 
22175a7e435SBen Langmuir     if (!needUpdate(Current))
2221fb5c3a6SDouglas Gregor       continue;
2231fb5c3a6SDouglas Gregor 
2241fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
225993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
226eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
227eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
2281fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
22975a7e435SBen Langmuir       if (needUpdate(*Sub))
230eb90e830SDouglas Gregor         Stack.push_back(*Sub);
2311fb5c3a6SDouglas Gregor     }
2321fb5c3a6SDouglas Gregor   }
2331fb5c3a6SDouglas Gregor }
2341fb5c3a6SDouglas Gregor 
235eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
236eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
237eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
238f1186c5aSCraig Topper     return nullptr;
239eb90e830SDouglas Gregor 
240eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
241eb90e830SDouglas Gregor }
242eb90e830SDouglas Gregor 
243f857950dSDmitri Gribenko static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
24424bb923aSDouglas Gregor   for (unsigned I = 0, N = Id.size(); I != N; ++I) {
24524bb923aSDouglas Gregor     if (I)
24624bb923aSDouglas Gregor       OS << ".";
24724bb923aSDouglas Gregor     OS << Id[I].first;
24824bb923aSDouglas Gregor   }
24924bb923aSDouglas Gregor }
25024bb923aSDouglas Gregor 
2518739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
252e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
253e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
254e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
255e9bcf5b7SDmitri Gribenko        I != E; ++I) {
256e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
257e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
258e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
259e9bcf5b7SDmitri Gribenko   }
260e9bcf5b7SDmitri Gribenko 
261e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2628739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2638739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2648739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2658739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2668739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2678739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2688739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2698739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2708739f7b7SArgyrios Kyrtzidis 
2718739f7b7SArgyrios Kyrtzidis       continue;
2728739f7b7SArgyrios Kyrtzidis     }
2738739f7b7SArgyrios Kyrtzidis 
2748739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
2758739f7b7SArgyrios Kyrtzidis     // the given pattern.
2768739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
2778739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
2788739f7b7SArgyrios Kyrtzidis       continue;
2798739f7b7SArgyrios Kyrtzidis 
2808739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
2818739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
2828739f7b7SArgyrios Kyrtzidis     else {
2838739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
2848739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
2858739f7b7SArgyrios Kyrtzidis     }
2868739f7b7SArgyrios Kyrtzidis   }
2878739f7b7SArgyrios Kyrtzidis 
2888739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
2898739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
2908739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
2918739f7b7SArgyrios Kyrtzidis     return;
2928739f7b7SArgyrios Kyrtzidis 
2938739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
2948739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
2958739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
2968739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
2978739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
2988739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
2998739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
3008739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
3018739f7b7SArgyrios Kyrtzidis           Acceptable = true;
3028739f7b7SArgyrios Kyrtzidis           break;
3038739f7b7SArgyrios Kyrtzidis         }
3048739f7b7SArgyrios Kyrtzidis       }
3058739f7b7SArgyrios Kyrtzidis     }
3068739f7b7SArgyrios Kyrtzidis 
3078739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
3088739f7b7SArgyrios Kyrtzidis       continue;
3098739f7b7SArgyrios Kyrtzidis 
3108739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3118739f7b7SArgyrios Kyrtzidis   }
3128739f7b7SArgyrios Kyrtzidis }
3138739f7b7SArgyrios Kyrtzidis 
3140e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3150e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3160e5d7b8cSRichard Smith 
3170e5d7b8cSRichard Smith   // This module is visible to itself.
3180e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3190e5d7b8cSRichard Smith 
3200e5d7b8cSRichard Smith   // Every imported module is visible.
321dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
322dc360d57SDmitri Gribenko   while (!Stack.empty()) {
323dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
324dc360d57SDmitri Gribenko 
325dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
326dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
327dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
3280e5d7b8cSRichard Smith   }
3290e5d7b8cSRichard Smith }
3300e5d7b8cSRichard Smith 
331f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
332de3ef502SDouglas Gregor   OS.indent(Indent);
333de3ef502SDouglas Gregor   if (IsFramework)
334de3ef502SDouglas Gregor     OS << "framework ";
335de3ef502SDouglas Gregor   if (IsExplicit)
336de3ef502SDouglas Gregor     OS << "explicit ";
337a686e1b0SDouglas Gregor   OS << "module " << Name;
338a686e1b0SDouglas Gregor 
3397615f00eSBen Langmuir   if (IsSystem || IsExternC) {
340a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3417615f00eSBen Langmuir     if (IsSystem)
342a686e1b0SDouglas Gregor       OS << " [system]";
3437615f00eSBen Langmuir     if (IsExternC)
3447615f00eSBen Langmuir       OS << " [extern_c]";
345a686e1b0SDouglas Gregor   }
346a686e1b0SDouglas Gregor 
347a686e1b0SDouglas Gregor   OS << " {\n";
348de3ef502SDouglas Gregor 
349a3feee2aSRichard Smith   if (!Requirements.empty()) {
3501fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3511fb5c3a6SDouglas Gregor     OS << "requires ";
352a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3531fb5c3a6SDouglas Gregor       if (I)
3541fb5c3a6SDouglas Gregor         OS << ", ";
355a3feee2aSRichard Smith       if (!Requirements[I].second)
356a3feee2aSRichard Smith         OS << "!";
357a3feee2aSRichard Smith       OS << Requirements[I].first;
3581fb5c3a6SDouglas Gregor     }
3591fb5c3a6SDouglas Gregor     OS << "\n";
3601fb5c3a6SDouglas Gregor   }
3611fb5c3a6SDouglas Gregor 
3622b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
363de3ef502SDouglas Gregor     OS.indent(Indent + 2);
364322f633cSDouglas Gregor     OS << "umbrella header \"";
3652b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
366de3ef502SDouglas Gregor     OS << "\"\n";
3672b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
368322f633cSDouglas Gregor     OS.indent(Indent + 2);
369322f633cSDouglas Gregor     OS << "umbrella \"";
3702b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
371322f633cSDouglas Gregor     OS << "\"\n";
372de3ef502SDouglas Gregor   }
373de3ef502SDouglas Gregor 
37435b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
37535b13eceSDouglas Gregor     OS.indent(Indent + 2);
37635b13eceSDouglas Gregor     OS << "config_macros ";
37735b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
3788d932427SDouglas Gregor       OS << "[exhaustive]";
37935b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
38035b13eceSDouglas Gregor       if (I)
38135b13eceSDouglas Gregor         OS << ", ";
38235b13eceSDouglas Gregor       OS << ConfigMacros[I];
38335b13eceSDouglas Gregor     }
3848d932427SDouglas Gregor     OS << "\n";
38535b13eceSDouglas Gregor   }
38635b13eceSDouglas Gregor 
3873c1a41adSRichard Smith   struct {
388306d8920SRichard Smith     StringRef Prefix;
3893c1a41adSRichard Smith     HeaderKind Kind;
3903c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
3913c1a41adSRichard Smith                {"textual ", HK_Textual},
3923c1a41adSRichard Smith                {"private ", HK_Private},
3933c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
3943c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
395306d8920SRichard Smith 
396306d8920SRichard Smith   for (auto &K : Kinds) {
397*040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
3983c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
399de3ef502SDouglas Gregor       OS.indent(Indent + 2);
400306d8920SRichard Smith       OS << K.Prefix << "header \"";
4013c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
402*040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
403*040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
404*040e1266SRichard Smith     }
405*040e1266SRichard Smith   }
406*040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
407*040e1266SRichard Smith     for (auto &U : *Unresolved) {
408*040e1266SRichard Smith       OS.indent(Indent + 2);
409*040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
410*040e1266SRichard Smith       OS.write_escaped(U.FileName);
411*040e1266SRichard Smith       OS << "\"";
412*040e1266SRichard Smith       if (U.Size || U.ModTime) {
413*040e1266SRichard Smith         OS << " {";
414*040e1266SRichard Smith         if (U.Size)
415*040e1266SRichard Smith           OS << " size " << *U.Size;
416*040e1266SRichard Smith         if (U.ModTime)
417*040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
418*040e1266SRichard Smith         OS << " }";
419*040e1266SRichard Smith       }
420*040e1266SRichard Smith       OS << "\n";
421de3ef502SDouglas Gregor     }
422b53e5483SLawrence Crowl   }
423b53e5483SLawrence Crowl 
424eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
425de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
4269d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
4279d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
4289d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4299d6448b1SBen Langmuir     // those header files anyway.
4309d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
431eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
432de3ef502SDouglas Gregor 
43324bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
43424bb923aSDouglas Gregor     OS.indent(Indent + 2);
4358c7c8352SDouglas Gregor     OS << "export ";
4368c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4378c7c8352SDouglas Gregor       OS << Restriction->getFullModuleName();
43824bb923aSDouglas Gregor       if (Exports[I].getInt())
43924bb923aSDouglas Gregor         OS << ".*";
4408c7c8352SDouglas Gregor     } else {
4418c7c8352SDouglas Gregor       OS << "*";
4428c7c8352SDouglas Gregor     }
44324bb923aSDouglas Gregor     OS << "\n";
44424bb923aSDouglas Gregor   }
44524bb923aSDouglas Gregor 
44624bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
44724bb923aSDouglas Gregor     OS.indent(Indent + 2);
44824bb923aSDouglas Gregor     OS << "export ";
44924bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4507f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
4517f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
45224bb923aSDouglas Gregor     OS << "\n";
45324bb923aSDouglas Gregor   }
45424bb923aSDouglas Gregor 
455ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
456ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
457ba7f2f71SDaniel Jasper     OS << "use ";
458ba7f2f71SDaniel Jasper     OS << DirectUses[I]->getFullModuleName();
459ba7f2f71SDaniel Jasper     OS << "\n";
460ba7f2f71SDaniel Jasper   }
461ba7f2f71SDaniel Jasper 
462ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
463ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
464ba7f2f71SDaniel Jasper     OS << "use ";
465ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
466ba7f2f71SDaniel Jasper     OS << "\n";
467ba7f2f71SDaniel Jasper   }
468ba7f2f71SDaniel Jasper 
4696ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4706ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4716ddfca91SDouglas Gregor     OS << "link ";
4726ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4736ddfca91SDouglas Gregor       OS << "framework ";
4746ddfca91SDouglas Gregor     OS << "\"";
4756ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
4766ddfca91SDouglas Gregor     OS << "\"";
4776ddfca91SDouglas Gregor   }
4786ddfca91SDouglas Gregor 
479fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
480fb912657SDouglas Gregor     OS.indent(Indent + 2);
481fb912657SDouglas Gregor     OS << "conflict ";
482fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
483fb912657SDouglas Gregor     OS << ", \"";
484fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
485fb912657SDouglas Gregor     OS << "\"\n";
486fb912657SDouglas Gregor   }
487fb912657SDouglas Gregor 
488fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
489fb912657SDouglas Gregor     OS.indent(Indent + 2);
490fb912657SDouglas Gregor     OS << "conflict ";
491fb912657SDouglas Gregor     OS << Conflicts[I].Other->getFullModuleName();
492fb912657SDouglas Gregor     OS << ", \"";
493fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
494fb912657SDouglas Gregor     OS << "\"\n";
495fb912657SDouglas Gregor   }
496fb912657SDouglas Gregor 
49773441091SDouglas Gregor   if (InferSubmodules) {
49873441091SDouglas Gregor     OS.indent(Indent + 2);
49973441091SDouglas Gregor     if (InferExplicitSubmodules)
50073441091SDouglas Gregor       OS << "explicit ";
50173441091SDouglas Gregor     OS << "module * {\n";
50273441091SDouglas Gregor     if (InferExportWildcard) {
50373441091SDouglas Gregor       OS.indent(Indent + 4);
50473441091SDouglas Gregor       OS << "export *\n";
50573441091SDouglas Gregor     }
50673441091SDouglas Gregor     OS.indent(Indent + 2);
50773441091SDouglas Gregor     OS << "}\n";
50873441091SDouglas Gregor   }
50973441091SDouglas Gregor 
510de3ef502SDouglas Gregor   OS.indent(Indent);
511de3ef502SDouglas Gregor   OS << "}\n";
512de3ef502SDouglas Gregor }
513de3ef502SDouglas Gregor 
514cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
515de3ef502SDouglas Gregor   print(llvm::errs());
516de3ef502SDouglas Gregor }
517de3ef502SDouglas Gregor 
518a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
519a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
5206d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
521a7e2cc68SRichard Smith   if (isVisible(M))
522a7e2cc68SRichard Smith     return;
523de3ef502SDouglas Gregor 
524a7e2cc68SRichard Smith   ++Generation;
525a7e2cc68SRichard Smith 
526a7e2cc68SRichard Smith   struct Visiting {
527a7e2cc68SRichard Smith     Module *M;
528a7e2cc68SRichard Smith     Visiting *ExportedBy;
529a7e2cc68SRichard Smith   };
530a7e2cc68SRichard Smith 
531a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
532a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
533a7e2cc68SRichard Smith     if (!V.M->isAvailable())
534a7e2cc68SRichard Smith       return;
535a7e2cc68SRichard Smith 
536a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
537a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
538a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
539a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
540a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
541a7e2cc68SRichard Smith       return;
542a7e2cc68SRichard Smith 
543a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
544a7e2cc68SRichard Smith     Vis(M);
545a7e2cc68SRichard Smith 
546a7e2cc68SRichard Smith     // Make any exported modules visible.
547a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
548a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
549a7e2cc68SRichard Smith     for (Module *E : Exports)
550a7e2cc68SRichard Smith       VisitModule({E, &V});
551a7e2cc68SRichard Smith 
552a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
553a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
554a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
555a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
556a7e2cc68SRichard Smith           Path.push_back(I->M);
557a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
558a7e2cc68SRichard Smith       }
559a7e2cc68SRichard Smith     }
560a7e2cc68SRichard Smith   };
561a7e2cc68SRichard Smith   VisitModule({M, nullptr});
562a7e2cc68SRichard Smith }
563