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"
169565c75bSRichard Smith #include "clang/Basic/CharInfo.h"
17de3ef502SDouglas Gregor #include "clang/Basic/FileManager.h"
181fb5c3a6SDouglas Gregor #include "clang/Basic/LangOptions.h"
190070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h"
203c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h"
211fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h"
221fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h"
233a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h"
243a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
25a3feee2aSRichard Smith 
26de3ef502SDouglas Gregor using namespace clang;
27de3ef502SDouglas Gregor 
28eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
29a7e2cc68SRichard Smith                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
303c1a41adSRichard Smith     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
3160fa2888SDuncan P. N. Exon Smith       Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID),
328a308ec2SRichard Smith       IsMissingRequirement(false), HasIncompatibleModuleFile(false),
338a308ec2SRichard Smith       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
348a308ec2SRichard Smith       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
358a308ec2SRichard Smith       IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
368a308ec2SRichard Smith       InferExportWildcard(false), ConfigMacrosExhaustive(false),
37e6b7c28dSDavid Blaikie       NoUndeclaredIncludes(false), NameVisibility(Hidden) {
38eb90e830SDouglas Gregor   if (Parent) {
39eb90e830SDouglas Gregor     if (!Parent->isAvailable())
40eb90e830SDouglas Gregor       IsAvailable = false;
413ec6663bSDouglas Gregor     if (Parent->IsSystem)
423ec6663bSDouglas Gregor       IsSystem = true;
439bca298fSRichard Smith     if (Parent->IsExternC)
449bca298fSRichard Smith       IsExternC = true;
45ed84df00SBruno Cardoso Lopes     if (Parent->NoUndeclaredIncludes)
46ed84df00SBruno Cardoso Lopes       NoUndeclaredIncludes = true;
47993055f8SBen Langmuir     IsMissingRequirement = Parent->IsMissingRequirement;
48eb90e830SDouglas Gregor 
49eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
50eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
51eb90e830SDouglas Gregor   }
52eb90e830SDouglas Gregor }
53eb90e830SDouglas Gregor 
54de3ef502SDouglas Gregor Module::~Module() {
55eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
56de3ef502SDouglas Gregor        I != IEnd; ++I) {
57eb90e830SDouglas Gregor     delete *I;
58de3ef502SDouglas Gregor   }
59de3ef502SDouglas Gregor }
60de3ef502SDouglas Gregor 
611fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current
621fb5c3a6SDouglas Gregor /// language options has the given feature.
6389929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
6489929282SDouglas Gregor                        const TargetInfo &Target) {
65532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
660070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
671fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
68e38cea02SEric Fiselier                         .Case("coroutines", LangOpts.CoroutinesTS)
691fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
702bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
71fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
726736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
731fb5c3a6SDouglas Gregor                         .Case("objc", LangOpts.ObjC1)
741fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
750070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
760070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
773c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
780070c0bfSDouglas Gregor                         .Default(Target.hasFeature(Feature));
79532d2104SBen Langmuir   if (!HasFeature)
80532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
81532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
82532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
83532d2104SBen Langmuir   return HasFeature;
841fb5c3a6SDouglas Gregor }
851fb5c3a6SDouglas Gregor 
863c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
873c1a41adSRichard Smith                          Requirement &Req,
883c1a41adSRichard Smith                          UnresolvedHeaderDirective &MissingHeader) const {
891fb5c3a6SDouglas Gregor   if (IsAvailable)
901fb5c3a6SDouglas Gregor     return true;
911fb5c3a6SDouglas Gregor 
921fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
93a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
94a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
95a3feee2aSRichard Smith               Current->Requirements[I].second) {
96a3feee2aSRichard Smith         Req = Current->Requirements[I];
971fb5c3a6SDouglas Gregor         return false;
981fb5c3a6SDouglas Gregor       }
991fb5c3a6SDouglas Gregor     }
10075a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
10175a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
10275a7e435SBen Langmuir       return false;
10375a7e435SBen Langmuir     }
1041fb5c3a6SDouglas Gregor   }
1051fb5c3a6SDouglas Gregor 
1061fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1071fb5c3a6SDouglas Gregor }
1081fb5c3a6SDouglas Gregor 
10962bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
110f5eedd05SDouglas Gregor   const Module *This = this;
111f5eedd05SDouglas Gregor   do {
112f5eedd05SDouglas Gregor     if (This == Other)
113f5eedd05SDouglas Gregor       return true;
114f5eedd05SDouglas Gregor 
115f5eedd05SDouglas Gregor     This = This->Parent;
116f5eedd05SDouglas Gregor   } while (This);
117f5eedd05SDouglas Gregor 
118f5eedd05SDouglas Gregor   return false;
119f5eedd05SDouglas Gregor }
120f5eedd05SDouglas Gregor 
12173441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
12273441091SDouglas Gregor   const Module *Result = this;
12373441091SDouglas Gregor   while (Result->Parent)
12473441091SDouglas Gregor     Result = Result->Parent;
12573441091SDouglas Gregor 
12673441091SDouglas Gregor   return Result;
12773441091SDouglas Gregor }
12873441091SDouglas Gregor 
1299565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1309565c75bSRichard Smith     const std::pair<std::string, SourceLocation> &IdComponent) {
1319565c75bSRichard Smith   return IdComponent.first;
1329565c75bSRichard Smith }
1339565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1349565c75bSRichard Smith 
1359565c75bSRichard Smith template<typename InputIter>
1369565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
1379565c75bSRichard Smith                           bool AllowStringLiterals = true) {
1389565c75bSRichard Smith   for (InputIter It = Begin; It != End; ++It) {
1399565c75bSRichard Smith     if (It != Begin)
1409565c75bSRichard Smith       OS << ".";
1419565c75bSRichard Smith 
1429565c75bSRichard Smith     StringRef Name = getModuleNameFromComponent(*It);
1439565c75bSRichard Smith     if (!AllowStringLiterals || isValidIdentifier(Name))
1449565c75bSRichard Smith       OS << Name;
1459565c75bSRichard Smith     else {
1469565c75bSRichard Smith       OS << '"';
1479565c75bSRichard Smith       OS.write_escaped(Name);
1489565c75bSRichard Smith       OS << '"';
1499565c75bSRichard Smith     }
1509565c75bSRichard Smith   }
1519565c75bSRichard Smith }
1529565c75bSRichard Smith 
1539565c75bSRichard Smith template<typename Container>
1549565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
1559565c75bSRichard Smith   return printModuleId(OS, C.begin(), C.end());
1569565c75bSRichard Smith }
1579565c75bSRichard Smith 
1589565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
159f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
160de3ef502SDouglas Gregor 
161de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
162de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
163de3ef502SDouglas Gregor     Names.push_back(M->Name);
164de3ef502SDouglas Gregor 
165de3ef502SDouglas Gregor   std::string Result;
166de3ef502SDouglas Gregor 
1679565c75bSRichard Smith   llvm::raw_string_ostream Out(Result);
1689565c75bSRichard Smith   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
1699565c75bSRichard Smith   Out.flush();
170de3ef502SDouglas Gregor 
171de3ef502SDouglas Gregor   return Result;
172de3ef502SDouglas Gregor }
173de3ef502SDouglas Gregor 
1747ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
1757ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
1767ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
1777ff29148SBen Langmuir       return false;
1787ff29148SBen Langmuir     nameParts = nameParts.drop_back();
1797ff29148SBen Langmuir   }
1807ff29148SBen Langmuir   return nameParts.empty();
1817ff29148SBen Langmuir }
1827ff29148SBen Langmuir 
1832b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
1842b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
1852b63d15fSRichard Smith     return {"", U.Entry->getDir()};
18673141fa9SDouglas Gregor 
1872b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
18873141fa9SDouglas Gregor }
18973141fa9SDouglas Gregor 
1903c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
1913c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
1923c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
1933c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
1943c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
1953c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
1963c5305c1SArgyrios Kyrtzidis     }
1973c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
1983c5305c1SArgyrios Kyrtzidis   }
1993c5305c1SArgyrios Kyrtzidis 
2003c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2013c5305c1SArgyrios Kyrtzidis }
2023c5305c1SArgyrios Kyrtzidis 
2038f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
2048f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
2058f4d3ff1SRichard Smith 
2068f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
2078f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
2088f4d3ff1SRichard Smith     return true;
2098f4d3ff1SRichard Smith 
2108f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
2118f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
2128f4d3ff1SRichard Smith       return true;
213ed84df00SBruno Cardoso Lopes 
214ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
215ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
216ed84df00SBruno Cardoso Lopes     return true;
217ed84df00SBruno Cardoso Lopes 
2188f4d3ff1SRichard Smith   return false;
2198f4d3ff1SRichard Smith }
2208f4d3ff1SRichard Smith 
221a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
222a3feee2aSRichard Smith                             const LangOptions &LangOpts,
22389929282SDouglas Gregor                             const TargetInfo &Target) {
224a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
2251fb5c3a6SDouglas Gregor 
2261fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
227a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2281fb5c3a6SDouglas Gregor     return;
2291fb5c3a6SDouglas Gregor 
230993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
231ec8c9752SBen Langmuir }
232ec8c9752SBen Langmuir 
233993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
23475a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
23575a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
23675a7e435SBen Langmuir   };
23775a7e435SBen Langmuir 
23875a7e435SBen Langmuir   if (!needUpdate(this))
2391fb5c3a6SDouglas Gregor     return;
2401fb5c3a6SDouglas Gregor 
241f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2421fb5c3a6SDouglas Gregor   Stack.push_back(this);
2431fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
2441fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
2451fb5c3a6SDouglas Gregor     Stack.pop_back();
2461fb5c3a6SDouglas Gregor 
24775a7e435SBen Langmuir     if (!needUpdate(Current))
2481fb5c3a6SDouglas Gregor       continue;
2491fb5c3a6SDouglas Gregor 
2501fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
251993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
252eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
253eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
2541fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
25575a7e435SBen Langmuir       if (needUpdate(*Sub))
256eb90e830SDouglas Gregor         Stack.push_back(*Sub);
2571fb5c3a6SDouglas Gregor     }
2581fb5c3a6SDouglas Gregor   }
2591fb5c3a6SDouglas Gregor }
2601fb5c3a6SDouglas Gregor 
261eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
262eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
263eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
264f1186c5aSCraig Topper     return nullptr;
265eb90e830SDouglas Gregor 
266eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
267eb90e830SDouglas Gregor }
268eb90e830SDouglas Gregor 
2698739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
270e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
271e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
272e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
273e9bcf5b7SDmitri Gribenko        I != E; ++I) {
274e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
275e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
276e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
277e9bcf5b7SDmitri Gribenko   }
278e9bcf5b7SDmitri Gribenko 
279e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2808739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2818739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2828739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2838739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2848739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2858739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2868739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2878739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2888739f7b7SArgyrios Kyrtzidis 
2898739f7b7SArgyrios Kyrtzidis       continue;
2908739f7b7SArgyrios Kyrtzidis     }
2918739f7b7SArgyrios Kyrtzidis 
2928739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
2938739f7b7SArgyrios Kyrtzidis     // the given pattern.
2948739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
2958739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
2968739f7b7SArgyrios Kyrtzidis       continue;
2978739f7b7SArgyrios Kyrtzidis 
2988739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
2998739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
3008739f7b7SArgyrios Kyrtzidis     else {
3018739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
3028739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
3038739f7b7SArgyrios Kyrtzidis     }
3048739f7b7SArgyrios Kyrtzidis   }
3058739f7b7SArgyrios Kyrtzidis 
3068739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
3078739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
3088739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
3098739f7b7SArgyrios Kyrtzidis     return;
3108739f7b7SArgyrios Kyrtzidis 
3118739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3128739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
3138739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
3148739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
3158739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
3168739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
3178739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
3188739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
3198739f7b7SArgyrios Kyrtzidis           Acceptable = true;
3208739f7b7SArgyrios Kyrtzidis           break;
3218739f7b7SArgyrios Kyrtzidis         }
3228739f7b7SArgyrios Kyrtzidis       }
3238739f7b7SArgyrios Kyrtzidis     }
3248739f7b7SArgyrios Kyrtzidis 
3258739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
3268739f7b7SArgyrios Kyrtzidis       continue;
3278739f7b7SArgyrios Kyrtzidis 
3288739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3298739f7b7SArgyrios Kyrtzidis   }
3308739f7b7SArgyrios Kyrtzidis }
3318739f7b7SArgyrios Kyrtzidis 
3320e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3330e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3340e5d7b8cSRichard Smith 
3350e5d7b8cSRichard Smith   // This module is visible to itself.
3360e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3370e5d7b8cSRichard Smith 
3380e5d7b8cSRichard Smith   // Every imported module is visible.
339dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
340dc360d57SDmitri Gribenko   while (!Stack.empty()) {
341dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
342dc360d57SDmitri Gribenko 
343dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
344dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
345dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
3460e5d7b8cSRichard Smith   }
3470e5d7b8cSRichard Smith }
3480e5d7b8cSRichard Smith 
349f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
350de3ef502SDouglas Gregor   OS.indent(Indent);
351de3ef502SDouglas Gregor   if (IsFramework)
352de3ef502SDouglas Gregor     OS << "framework ";
353de3ef502SDouglas Gregor   if (IsExplicit)
354de3ef502SDouglas Gregor     OS << "explicit ";
3559565c75bSRichard Smith   OS << "module ";
3569565c75bSRichard Smith   printModuleId(OS, &Name, &Name + 1);
357a686e1b0SDouglas Gregor 
3587615f00eSBen Langmuir   if (IsSystem || IsExternC) {
359a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3607615f00eSBen Langmuir     if (IsSystem)
361a686e1b0SDouglas Gregor       OS << " [system]";
3627615f00eSBen Langmuir     if (IsExternC)
3637615f00eSBen Langmuir       OS << " [extern_c]";
364a686e1b0SDouglas Gregor   }
365a686e1b0SDouglas Gregor 
366a686e1b0SDouglas Gregor   OS << " {\n";
367de3ef502SDouglas Gregor 
368a3feee2aSRichard Smith   if (!Requirements.empty()) {
3691fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3701fb5c3a6SDouglas Gregor     OS << "requires ";
371a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3721fb5c3a6SDouglas Gregor       if (I)
3731fb5c3a6SDouglas Gregor         OS << ", ";
374a3feee2aSRichard Smith       if (!Requirements[I].second)
375a3feee2aSRichard Smith         OS << "!";
376a3feee2aSRichard Smith       OS << Requirements[I].first;
3771fb5c3a6SDouglas Gregor     }
3781fb5c3a6SDouglas Gregor     OS << "\n";
3791fb5c3a6SDouglas Gregor   }
3801fb5c3a6SDouglas Gregor 
3812b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
382de3ef502SDouglas Gregor     OS.indent(Indent + 2);
383322f633cSDouglas Gregor     OS << "umbrella header \"";
3842b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
385de3ef502SDouglas Gregor     OS << "\"\n";
3862b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
387322f633cSDouglas Gregor     OS.indent(Indent + 2);
388322f633cSDouglas Gregor     OS << "umbrella \"";
3892b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
390322f633cSDouglas Gregor     OS << "\"\n";
391de3ef502SDouglas Gregor   }
392de3ef502SDouglas Gregor 
39335b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
39435b13eceSDouglas Gregor     OS.indent(Indent + 2);
39535b13eceSDouglas Gregor     OS << "config_macros ";
39635b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
3978d932427SDouglas Gregor       OS << "[exhaustive]";
39835b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
39935b13eceSDouglas Gregor       if (I)
40035b13eceSDouglas Gregor         OS << ", ";
40135b13eceSDouglas Gregor       OS << ConfigMacros[I];
40235b13eceSDouglas Gregor     }
4038d932427SDouglas Gregor     OS << "\n";
40435b13eceSDouglas Gregor   }
40535b13eceSDouglas Gregor 
4063c1a41adSRichard Smith   struct {
407306d8920SRichard Smith     StringRef Prefix;
4083c1a41adSRichard Smith     HeaderKind Kind;
4093c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
4103c1a41adSRichard Smith                {"textual ", HK_Textual},
4113c1a41adSRichard Smith                {"private ", HK_Private},
4123c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
4133c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
414306d8920SRichard Smith 
415306d8920SRichard Smith   for (auto &K : Kinds) {
416040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
4173c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
418de3ef502SDouglas Gregor       OS.indent(Indent + 2);
419306d8920SRichard Smith       OS << K.Prefix << "header \"";
4203c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
421040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
422040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
423040e1266SRichard Smith     }
424040e1266SRichard Smith   }
425040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
426040e1266SRichard Smith     for (auto &U : *Unresolved) {
427040e1266SRichard Smith       OS.indent(Indent + 2);
428040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
429040e1266SRichard Smith       OS.write_escaped(U.FileName);
430040e1266SRichard Smith       OS << "\"";
431040e1266SRichard Smith       if (U.Size || U.ModTime) {
432040e1266SRichard Smith         OS << " {";
433040e1266SRichard Smith         if (U.Size)
434040e1266SRichard Smith           OS << " size " << *U.Size;
435040e1266SRichard Smith         if (U.ModTime)
436040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
437040e1266SRichard Smith         OS << " }";
438040e1266SRichard Smith       }
439040e1266SRichard Smith       OS << "\n";
440de3ef502SDouglas Gregor     }
441b53e5483SLawrence Crowl   }
442b53e5483SLawrence Crowl 
443*f0b11de2SDouglas Gregor   if (!ExportAsModule.empty()) {
444*f0b11de2SDouglas Gregor     OS.indent(Indent + 2);
445*f0b11de2SDouglas Gregor     OS << "export_as" << ExportAsModule << "\n";
446*f0b11de2SDouglas Gregor   }
447*f0b11de2SDouglas Gregor 
448eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
449de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
4509d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
4519d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
4529d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4539d6448b1SBen Langmuir     // those header files anyway.
4549d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
455eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
456de3ef502SDouglas Gregor 
45724bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
45824bb923aSDouglas Gregor     OS.indent(Indent + 2);
4598c7c8352SDouglas Gregor     OS << "export ";
4608c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4619565c75bSRichard Smith       OS << Restriction->getFullModuleName(true);
46224bb923aSDouglas Gregor       if (Exports[I].getInt())
46324bb923aSDouglas Gregor         OS << ".*";
4648c7c8352SDouglas Gregor     } else {
4658c7c8352SDouglas Gregor       OS << "*";
4668c7c8352SDouglas Gregor     }
46724bb923aSDouglas Gregor     OS << "\n";
46824bb923aSDouglas Gregor   }
46924bb923aSDouglas Gregor 
47024bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
47124bb923aSDouglas Gregor     OS.indent(Indent + 2);
47224bb923aSDouglas Gregor     OS << "export ";
47324bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4747f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
4757f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
47624bb923aSDouglas Gregor     OS << "\n";
47724bb923aSDouglas Gregor   }
47824bb923aSDouglas Gregor 
479ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
480ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
481ba7f2f71SDaniel Jasper     OS << "use ";
4829565c75bSRichard Smith     OS << DirectUses[I]->getFullModuleName(true);
483ba7f2f71SDaniel Jasper     OS << "\n";
484ba7f2f71SDaniel Jasper   }
485ba7f2f71SDaniel Jasper 
486ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
487ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
488ba7f2f71SDaniel Jasper     OS << "use ";
489ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
490ba7f2f71SDaniel Jasper     OS << "\n";
491ba7f2f71SDaniel Jasper   }
492ba7f2f71SDaniel Jasper 
4936ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
4946ddfca91SDouglas Gregor     OS.indent(Indent + 2);
4956ddfca91SDouglas Gregor     OS << "link ";
4966ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
4976ddfca91SDouglas Gregor       OS << "framework ";
4986ddfca91SDouglas Gregor     OS << "\"";
4996ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
5006ddfca91SDouglas Gregor     OS << "\"";
5016ddfca91SDouglas Gregor   }
5026ddfca91SDouglas Gregor 
503fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
504fb912657SDouglas Gregor     OS.indent(Indent + 2);
505fb912657SDouglas Gregor     OS << "conflict ";
506fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
507fb912657SDouglas Gregor     OS << ", \"";
508fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
509fb912657SDouglas Gregor     OS << "\"\n";
510fb912657SDouglas Gregor   }
511fb912657SDouglas Gregor 
512fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
513fb912657SDouglas Gregor     OS.indent(Indent + 2);
514fb912657SDouglas Gregor     OS << "conflict ";
5159565c75bSRichard Smith     OS << Conflicts[I].Other->getFullModuleName(true);
516fb912657SDouglas Gregor     OS << ", \"";
517fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
518fb912657SDouglas Gregor     OS << "\"\n";
519fb912657SDouglas Gregor   }
520fb912657SDouglas Gregor 
52173441091SDouglas Gregor   if (InferSubmodules) {
52273441091SDouglas Gregor     OS.indent(Indent + 2);
52373441091SDouglas Gregor     if (InferExplicitSubmodules)
52473441091SDouglas Gregor       OS << "explicit ";
52573441091SDouglas Gregor     OS << "module * {\n";
52673441091SDouglas Gregor     if (InferExportWildcard) {
52773441091SDouglas Gregor       OS.indent(Indent + 4);
52873441091SDouglas Gregor       OS << "export *\n";
52973441091SDouglas Gregor     }
53073441091SDouglas Gregor     OS.indent(Indent + 2);
53173441091SDouglas Gregor     OS << "}\n";
53273441091SDouglas Gregor   }
53373441091SDouglas Gregor 
534de3ef502SDouglas Gregor   OS.indent(Indent);
535de3ef502SDouglas Gregor   OS << "}\n";
536de3ef502SDouglas Gregor }
537de3ef502SDouglas Gregor 
538cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
539de3ef502SDouglas Gregor   print(llvm::errs());
540de3ef502SDouglas Gregor }
541de3ef502SDouglas Gregor 
542a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
543a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
5446d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
545a7e2cc68SRichard Smith   if (isVisible(M))
546a7e2cc68SRichard Smith     return;
547de3ef502SDouglas Gregor 
548a7e2cc68SRichard Smith   ++Generation;
549a7e2cc68SRichard Smith 
550a7e2cc68SRichard Smith   struct Visiting {
551a7e2cc68SRichard Smith     Module *M;
552a7e2cc68SRichard Smith     Visiting *ExportedBy;
553a7e2cc68SRichard Smith   };
554a7e2cc68SRichard Smith 
555a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
556a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
557a7e2cc68SRichard Smith     if (!V.M->isAvailable())
558a7e2cc68SRichard Smith       return;
559a7e2cc68SRichard Smith 
560a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
561a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
562a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
563a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
564a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
565a7e2cc68SRichard Smith       return;
566a7e2cc68SRichard Smith 
567a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
568a7e2cc68SRichard Smith     Vis(M);
569a7e2cc68SRichard Smith 
570a7e2cc68SRichard Smith     // Make any exported modules visible.
571a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
572a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
573a7e2cc68SRichard Smith     for (Module *E : Exports)
574a7e2cc68SRichard Smith       VisitModule({E, &V});
575a7e2cc68SRichard Smith 
576a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
577a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
578a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
579a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
580a7e2cc68SRichard Smith           Path.push_back(I->M);
581a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
582a7e2cc68SRichard Smith       }
583a7e2cc68SRichard Smith     }
584a7e2cc68SRichard Smith   };
585a7e2cc68SRichard Smith   VisitModule({M, nullptr});
586a7e2cc68SRichard Smith }
587