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)
67*e38cea02SEric 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) {
3973c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
398de3ef502SDouglas Gregor       OS.indent(Indent + 2);
399306d8920SRichard Smith       OS << K.Prefix << "header \"";
4003c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
401de3ef502SDouglas Gregor       OS << "\"\n";
402de3ef502SDouglas Gregor     }
403b53e5483SLawrence Crowl   }
404b53e5483SLawrence Crowl 
405eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
406de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
4079d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
4089d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
4099d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4109d6448b1SBen Langmuir     // those header files anyway.
4119d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
412eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
413de3ef502SDouglas Gregor 
41424bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
41524bb923aSDouglas Gregor     OS.indent(Indent + 2);
4168c7c8352SDouglas Gregor     OS << "export ";
4178c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4188c7c8352SDouglas Gregor       OS << Restriction->getFullModuleName();
41924bb923aSDouglas Gregor       if (Exports[I].getInt())
42024bb923aSDouglas Gregor         OS << ".*";
4218c7c8352SDouglas Gregor     } else {
4228c7c8352SDouglas Gregor       OS << "*";
4238c7c8352SDouglas Gregor     }
42424bb923aSDouglas Gregor     OS << "\n";
42524bb923aSDouglas Gregor   }
42624bb923aSDouglas Gregor 
42724bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
42824bb923aSDouglas Gregor     OS.indent(Indent + 2);
42924bb923aSDouglas Gregor     OS << "export ";
43024bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4317f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
4327f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
43324bb923aSDouglas Gregor     OS << "\n";
43424bb923aSDouglas Gregor   }
43524bb923aSDouglas Gregor 
436ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
437ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
438ba7f2f71SDaniel Jasper     OS << "use ";
439ba7f2f71SDaniel Jasper     OS << DirectUses[I]->getFullModuleName();
440ba7f2f71SDaniel Jasper     OS << "\n";
441ba7f2f71SDaniel Jasper   }
442ba7f2f71SDaniel Jasper 
443ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
444ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
445ba7f2f71SDaniel Jasper     OS << "use ";
446ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
447ba7f2f71SDaniel Jasper     OS << "\n";
448ba7f2f71SDaniel Jasper   }
449ba7f2f71SDaniel Jasper 
4506ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4516ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4526ddfca91SDouglas Gregor     OS << "link ";
4536ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4546ddfca91SDouglas Gregor       OS << "framework ";
4556ddfca91SDouglas Gregor     OS << "\"";
4566ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
4576ddfca91SDouglas Gregor     OS << "\"";
4586ddfca91SDouglas Gregor   }
4596ddfca91SDouglas Gregor 
460fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
461fb912657SDouglas Gregor     OS.indent(Indent + 2);
462fb912657SDouglas Gregor     OS << "conflict ";
463fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
464fb912657SDouglas Gregor     OS << ", \"";
465fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
466fb912657SDouglas Gregor     OS << "\"\n";
467fb912657SDouglas Gregor   }
468fb912657SDouglas Gregor 
469fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
470fb912657SDouglas Gregor     OS.indent(Indent + 2);
471fb912657SDouglas Gregor     OS << "conflict ";
472fb912657SDouglas Gregor     OS << Conflicts[I].Other->getFullModuleName();
473fb912657SDouglas Gregor     OS << ", \"";
474fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
475fb912657SDouglas Gregor     OS << "\"\n";
476fb912657SDouglas Gregor   }
477fb912657SDouglas Gregor 
47873441091SDouglas Gregor   if (InferSubmodules) {
47973441091SDouglas Gregor     OS.indent(Indent + 2);
48073441091SDouglas Gregor     if (InferExplicitSubmodules)
48173441091SDouglas Gregor       OS << "explicit ";
48273441091SDouglas Gregor     OS << "module * {\n";
48373441091SDouglas Gregor     if (InferExportWildcard) {
48473441091SDouglas Gregor       OS.indent(Indent + 4);
48573441091SDouglas Gregor       OS << "export *\n";
48673441091SDouglas Gregor     }
48773441091SDouglas Gregor     OS.indent(Indent + 2);
48873441091SDouglas Gregor     OS << "}\n";
48973441091SDouglas Gregor   }
49073441091SDouglas Gregor 
491de3ef502SDouglas Gregor   OS.indent(Indent);
492de3ef502SDouglas Gregor   OS << "}\n";
493de3ef502SDouglas Gregor }
494de3ef502SDouglas Gregor 
495cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
496de3ef502SDouglas Gregor   print(llvm::errs());
497de3ef502SDouglas Gregor }
498de3ef502SDouglas Gregor 
499a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
500a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
5016d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
502a7e2cc68SRichard Smith   if (isVisible(M))
503a7e2cc68SRichard Smith     return;
504de3ef502SDouglas Gregor 
505a7e2cc68SRichard Smith   ++Generation;
506a7e2cc68SRichard Smith 
507a7e2cc68SRichard Smith   struct Visiting {
508a7e2cc68SRichard Smith     Module *M;
509a7e2cc68SRichard Smith     Visiting *ExportedBy;
510a7e2cc68SRichard Smith   };
511a7e2cc68SRichard Smith 
512a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
513a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
514a7e2cc68SRichard Smith     if (!V.M->isAvailable())
515a7e2cc68SRichard Smith       return;
516a7e2cc68SRichard Smith 
517a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
518a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
519a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
520a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
521a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
522a7e2cc68SRichard Smith       return;
523a7e2cc68SRichard Smith 
524a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
525a7e2cc68SRichard Smith     Vis(M);
526a7e2cc68SRichard Smith 
527a7e2cc68SRichard Smith     // Make any exported modules visible.
528a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
529a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
530a7e2cc68SRichard Smith     for (Module *E : Exports)
531a7e2cc68SRichard Smith       VisitModule({E, &V});
532a7e2cc68SRichard Smith 
533a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
534a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
535a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
536a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
537a7e2cc68SRichard Smith           Path.push_back(I->M);
538a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
539a7e2cc68SRichard Smith       }
540a7e2cc68SRichard Smith     }
541a7e2cc68SRichard Smith   };
542a7e2cc68SRichard Smith   VisitModule({M, nullptr});
543a7e2cc68SRichard Smith }
544