1918e0ca7SEugene Zelenko //===- 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"
19918e0ca7SEugene Zelenko #include "clang/Basic/SourceLocation.h"
200070c0bfSDouglas Gregor #include "clang/Basic/TargetInfo.h"
213c5305c1SArgyrios Kyrtzidis #include "llvm/ADT/ArrayRef.h"
221fb5c3a6SDouglas Gregor #include "llvm/ADT/SmallVector.h"
23918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h"
24918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h"
251fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h"
26918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h"
273a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h"
283a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
29918e0ca7SEugene Zelenko #include <algorithm>
30918e0ca7SEugene Zelenko #include <cassert>
31918e0ca7SEugene Zelenko #include <functional>
32918e0ca7SEugene Zelenko #include <string>
33918e0ca7SEugene Zelenko #include <utility>
34918e0ca7SEugene Zelenko #include <vector>
35a3feee2aSRichard Smith 
36de3ef502SDouglas Gregor using namespace clang;
37de3ef502SDouglas Gregor 
38eb90e830SDouglas Gregor Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
39a7e2cc68SRichard Smith                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
40918e0ca7SEugene Zelenko     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
41918e0ca7SEugene Zelenko       VisibilityID(VisibilityID), IsMissingRequirement(false),
42918e0ca7SEugene Zelenko       HasIncompatibleModuleFile(false), IsAvailable(true),
43918e0ca7SEugene Zelenko       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
44918e0ca7SEugene Zelenko       IsSystem(false), IsExternC(false), IsInferred(false),
45918e0ca7SEugene Zelenko       InferSubmodules(false), InferExplicitSubmodules(false),
468a308ec2SRichard Smith       InferExportWildcard(false), ConfigMacrosExhaustive(false),
47e6b7c28dSDavid Blaikie       NoUndeclaredIncludes(false), NameVisibility(Hidden) {
48eb90e830SDouglas Gregor   if (Parent) {
49eb90e830SDouglas Gregor     if (!Parent->isAvailable())
50eb90e830SDouglas Gregor       IsAvailable = false;
513ec6663bSDouglas Gregor     if (Parent->IsSystem)
523ec6663bSDouglas Gregor       IsSystem = true;
539bca298fSRichard Smith     if (Parent->IsExternC)
549bca298fSRichard Smith       IsExternC = true;
55ed84df00SBruno Cardoso Lopes     if (Parent->NoUndeclaredIncludes)
56ed84df00SBruno Cardoso Lopes       NoUndeclaredIncludes = true;
57993055f8SBen Langmuir     IsMissingRequirement = Parent->IsMissingRequirement;
58eb90e830SDouglas Gregor 
59eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
60eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
61eb90e830SDouglas Gregor   }
62eb90e830SDouglas Gregor }
63eb90e830SDouglas Gregor 
64de3ef502SDouglas Gregor Module::~Module() {
65eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
66de3ef502SDouglas Gregor        I != IEnd; ++I) {
67eb90e830SDouglas Gregor     delete *I;
68de3ef502SDouglas Gregor   }
69de3ef502SDouglas Gregor }
70de3ef502SDouglas Gregor 
711fb5c3a6SDouglas Gregor /// \brief Determine whether a translation unit built using the current
721fb5c3a6SDouglas Gregor /// language options has the given feature.
7389929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
7489929282SDouglas Gregor                        const TargetInfo &Target) {
75532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
760070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
771fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
78e38cea02SEric Fiselier                         .Case("coroutines", LangOpts.CoroutinesTS)
791fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
802bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
81fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
826736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
831fb5c3a6SDouglas Gregor                         .Case("objc", LangOpts.ObjC1)
841fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
850070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
860070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
873c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
880070c0bfSDouglas Gregor                         .Default(Target.hasFeature(Feature));
89532d2104SBen Langmuir   if (!HasFeature)
90532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
91532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
92532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
93532d2104SBen Langmuir   return HasFeature;
941fb5c3a6SDouglas Gregor }
951fb5c3a6SDouglas Gregor 
963c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
973c1a41adSRichard Smith                          Requirement &Req,
98*8587dfd9SBruno Cardoso Lopes                          UnresolvedHeaderDirective &MissingHeader,
99*8587dfd9SBruno Cardoso Lopes                          Module *&ShadowingModule) const {
1001fb5c3a6SDouglas Gregor   if (IsAvailable)
1011fb5c3a6SDouglas Gregor     return true;
1021fb5c3a6SDouglas Gregor 
1031fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
104*8587dfd9SBruno Cardoso Lopes     if (Current->ShadowingModule) {
105*8587dfd9SBruno Cardoso Lopes       ShadowingModule = Current->ShadowingModule;
106*8587dfd9SBruno Cardoso Lopes       return false;
107*8587dfd9SBruno Cardoso Lopes     }
108a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
109a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
110a3feee2aSRichard Smith               Current->Requirements[I].second) {
111a3feee2aSRichard Smith         Req = Current->Requirements[I];
1121fb5c3a6SDouglas Gregor         return false;
1131fb5c3a6SDouglas Gregor       }
1141fb5c3a6SDouglas Gregor     }
11575a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
11675a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
11775a7e435SBen Langmuir       return false;
11875a7e435SBen Langmuir     }
1191fb5c3a6SDouglas Gregor   }
1201fb5c3a6SDouglas Gregor 
1211fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1221fb5c3a6SDouglas Gregor }
1231fb5c3a6SDouglas Gregor 
12462bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
125f5eedd05SDouglas Gregor   const Module *This = this;
126f5eedd05SDouglas Gregor   do {
127f5eedd05SDouglas Gregor     if (This == Other)
128f5eedd05SDouglas Gregor       return true;
129f5eedd05SDouglas Gregor 
130f5eedd05SDouglas Gregor     This = This->Parent;
131f5eedd05SDouglas Gregor   } while (This);
132f5eedd05SDouglas Gregor 
133f5eedd05SDouglas Gregor   return false;
134f5eedd05SDouglas Gregor }
135f5eedd05SDouglas Gregor 
13673441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
13773441091SDouglas Gregor   const Module *Result = this;
13873441091SDouglas Gregor   while (Result->Parent)
13973441091SDouglas Gregor     Result = Result->Parent;
14073441091SDouglas Gregor 
14173441091SDouglas Gregor   return Result;
14273441091SDouglas Gregor }
14373441091SDouglas Gregor 
1449565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1459565c75bSRichard Smith     const std::pair<std::string, SourceLocation> &IdComponent) {
1469565c75bSRichard Smith   return IdComponent.first;
1479565c75bSRichard Smith }
148918e0ca7SEugene Zelenko 
1499565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1509565c75bSRichard Smith 
1519565c75bSRichard Smith template<typename InputIter>
1529565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
1539565c75bSRichard Smith                           bool AllowStringLiterals = true) {
1549565c75bSRichard Smith   for (InputIter It = Begin; It != End; ++It) {
1559565c75bSRichard Smith     if (It != Begin)
1569565c75bSRichard Smith       OS << ".";
1579565c75bSRichard Smith 
1589565c75bSRichard Smith     StringRef Name = getModuleNameFromComponent(*It);
1599565c75bSRichard Smith     if (!AllowStringLiterals || isValidIdentifier(Name))
1609565c75bSRichard Smith       OS << Name;
1619565c75bSRichard Smith     else {
1629565c75bSRichard Smith       OS << '"';
1639565c75bSRichard Smith       OS.write_escaped(Name);
1649565c75bSRichard Smith       OS << '"';
1659565c75bSRichard Smith     }
1669565c75bSRichard Smith   }
1679565c75bSRichard Smith }
1689565c75bSRichard Smith 
1699565c75bSRichard Smith template<typename Container>
1709565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
1719565c75bSRichard Smith   return printModuleId(OS, C.begin(), C.end());
1729565c75bSRichard Smith }
1739565c75bSRichard Smith 
1749565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
175f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
176de3ef502SDouglas Gregor 
177de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
178de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
179de3ef502SDouglas Gregor     Names.push_back(M->Name);
180de3ef502SDouglas Gregor 
181de3ef502SDouglas Gregor   std::string Result;
182de3ef502SDouglas Gregor 
1839565c75bSRichard Smith   llvm::raw_string_ostream Out(Result);
1849565c75bSRichard Smith   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
1859565c75bSRichard Smith   Out.flush();
186de3ef502SDouglas Gregor 
187de3ef502SDouglas Gregor   return Result;
188de3ef502SDouglas Gregor }
189de3ef502SDouglas Gregor 
1907ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
1917ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
1927ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
1937ff29148SBen Langmuir       return false;
1947ff29148SBen Langmuir     nameParts = nameParts.drop_back();
1957ff29148SBen Langmuir   }
1967ff29148SBen Langmuir   return nameParts.empty();
1977ff29148SBen Langmuir }
1987ff29148SBen Langmuir 
1992b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
2002b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
2012b63d15fSRichard Smith     return {"", U.Entry->getDir()};
20273141fa9SDouglas Gregor 
2032b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
20473141fa9SDouglas Gregor }
20573141fa9SDouglas Gregor 
2063c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2073c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
2083c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
2093c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2103c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
2113c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
2123c5305c1SArgyrios Kyrtzidis     }
2133c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
2143c5305c1SArgyrios Kyrtzidis   }
2153c5305c1SArgyrios Kyrtzidis 
2163c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2173c5305c1SArgyrios Kyrtzidis }
2183c5305c1SArgyrios Kyrtzidis 
2198f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
2208f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
2218f4d3ff1SRichard Smith 
2228f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
2238f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
2248f4d3ff1SRichard Smith     return true;
2258f4d3ff1SRichard Smith 
2268f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
2278f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
2288f4d3ff1SRichard Smith       return true;
229ed84df00SBruno Cardoso Lopes 
230ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
231ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
232ed84df00SBruno Cardoso Lopes     return true;
233ed84df00SBruno Cardoso Lopes 
2348f4d3ff1SRichard Smith   return false;
2358f4d3ff1SRichard Smith }
2368f4d3ff1SRichard Smith 
237a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
238a3feee2aSRichard Smith                             const LangOptions &LangOpts,
23989929282SDouglas Gregor                             const TargetInfo &Target) {
240a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
2411fb5c3a6SDouglas Gregor 
2421fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
243a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2441fb5c3a6SDouglas Gregor     return;
2451fb5c3a6SDouglas Gregor 
246993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
247ec8c9752SBen Langmuir }
248ec8c9752SBen Langmuir 
249993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
25075a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
25175a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
25275a7e435SBen Langmuir   };
25375a7e435SBen Langmuir 
25475a7e435SBen Langmuir   if (!needUpdate(this))
2551fb5c3a6SDouglas Gregor     return;
2561fb5c3a6SDouglas Gregor 
257f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2581fb5c3a6SDouglas Gregor   Stack.push_back(this);
2591fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
2601fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
2611fb5c3a6SDouglas Gregor     Stack.pop_back();
2621fb5c3a6SDouglas Gregor 
26375a7e435SBen Langmuir     if (!needUpdate(Current))
2641fb5c3a6SDouglas Gregor       continue;
2651fb5c3a6SDouglas Gregor 
2661fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
267993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
268eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
269eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
2701fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
27175a7e435SBen Langmuir       if (needUpdate(*Sub))
272eb90e830SDouglas Gregor         Stack.push_back(*Sub);
2731fb5c3a6SDouglas Gregor     }
2741fb5c3a6SDouglas Gregor   }
2751fb5c3a6SDouglas Gregor }
2761fb5c3a6SDouglas Gregor 
277eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
278eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
279eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
280f1186c5aSCraig Topper     return nullptr;
281eb90e830SDouglas Gregor 
282eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
283eb90e830SDouglas Gregor }
284eb90e830SDouglas Gregor 
2858739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
286e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
287e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
288e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
289e9bcf5b7SDmitri Gribenko        I != E; ++I) {
290e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
291e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
292e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
293e9bcf5b7SDmitri Gribenko   }
294e9bcf5b7SDmitri Gribenko 
295e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2968739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2978739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2988739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2998739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3008739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
3018739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
3028739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
3038739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
3048739f7b7SArgyrios Kyrtzidis 
3058739f7b7SArgyrios Kyrtzidis       continue;
3068739f7b7SArgyrios Kyrtzidis     }
3078739f7b7SArgyrios Kyrtzidis 
3088739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
3098739f7b7SArgyrios Kyrtzidis     // the given pattern.
3108739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
3118739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
3128739f7b7SArgyrios Kyrtzidis       continue;
3138739f7b7SArgyrios Kyrtzidis 
3148739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
3158739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
3168739f7b7SArgyrios Kyrtzidis     else {
3178739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
3188739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
3198739f7b7SArgyrios Kyrtzidis     }
3208739f7b7SArgyrios Kyrtzidis   }
3218739f7b7SArgyrios Kyrtzidis 
3228739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
3238739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
3248739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
3258739f7b7SArgyrios Kyrtzidis     return;
3268739f7b7SArgyrios Kyrtzidis 
3278739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3288739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
3298739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
3308739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
3318739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
3328739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
3338739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
3348739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
3358739f7b7SArgyrios Kyrtzidis           Acceptable = true;
3368739f7b7SArgyrios Kyrtzidis           break;
3378739f7b7SArgyrios Kyrtzidis         }
3388739f7b7SArgyrios Kyrtzidis       }
3398739f7b7SArgyrios Kyrtzidis     }
3408739f7b7SArgyrios Kyrtzidis 
3418739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
3428739f7b7SArgyrios Kyrtzidis       continue;
3438739f7b7SArgyrios Kyrtzidis 
3448739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3458739f7b7SArgyrios Kyrtzidis   }
3468739f7b7SArgyrios Kyrtzidis }
3478739f7b7SArgyrios Kyrtzidis 
3480e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3490e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3500e5d7b8cSRichard Smith 
3510e5d7b8cSRichard Smith   // This module is visible to itself.
3520e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3530e5d7b8cSRichard Smith 
3540e5d7b8cSRichard Smith   // Every imported module is visible.
355dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
356dc360d57SDmitri Gribenko   while (!Stack.empty()) {
357dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
358dc360d57SDmitri Gribenko 
359dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
360dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
361dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
3620e5d7b8cSRichard Smith   }
3630e5d7b8cSRichard Smith }
3640e5d7b8cSRichard Smith 
365f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
366de3ef502SDouglas Gregor   OS.indent(Indent);
367de3ef502SDouglas Gregor   if (IsFramework)
368de3ef502SDouglas Gregor     OS << "framework ";
369de3ef502SDouglas Gregor   if (IsExplicit)
370de3ef502SDouglas Gregor     OS << "explicit ";
3719565c75bSRichard Smith   OS << "module ";
3729565c75bSRichard Smith   printModuleId(OS, &Name, &Name + 1);
373a686e1b0SDouglas Gregor 
3747615f00eSBen Langmuir   if (IsSystem || IsExternC) {
375a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3767615f00eSBen Langmuir     if (IsSystem)
377a686e1b0SDouglas Gregor       OS << " [system]";
3787615f00eSBen Langmuir     if (IsExternC)
3797615f00eSBen Langmuir       OS << " [extern_c]";
380a686e1b0SDouglas Gregor   }
381a686e1b0SDouglas Gregor 
382a686e1b0SDouglas Gregor   OS << " {\n";
383de3ef502SDouglas Gregor 
384a3feee2aSRichard Smith   if (!Requirements.empty()) {
3851fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3861fb5c3a6SDouglas Gregor     OS << "requires ";
387a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3881fb5c3a6SDouglas Gregor       if (I)
3891fb5c3a6SDouglas Gregor         OS << ", ";
390a3feee2aSRichard Smith       if (!Requirements[I].second)
391a3feee2aSRichard Smith         OS << "!";
392a3feee2aSRichard Smith       OS << Requirements[I].first;
3931fb5c3a6SDouglas Gregor     }
3941fb5c3a6SDouglas Gregor     OS << "\n";
3951fb5c3a6SDouglas Gregor   }
3961fb5c3a6SDouglas Gregor 
3972b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
398de3ef502SDouglas Gregor     OS.indent(Indent + 2);
399322f633cSDouglas Gregor     OS << "umbrella header \"";
4002b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
401de3ef502SDouglas Gregor     OS << "\"\n";
4022b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
403322f633cSDouglas Gregor     OS.indent(Indent + 2);
404322f633cSDouglas Gregor     OS << "umbrella \"";
4052b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
406322f633cSDouglas Gregor     OS << "\"\n";
407de3ef502SDouglas Gregor   }
408de3ef502SDouglas Gregor 
40935b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
41035b13eceSDouglas Gregor     OS.indent(Indent + 2);
41135b13eceSDouglas Gregor     OS << "config_macros ";
41235b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
4138d932427SDouglas Gregor       OS << "[exhaustive]";
41435b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
41535b13eceSDouglas Gregor       if (I)
41635b13eceSDouglas Gregor         OS << ", ";
41735b13eceSDouglas Gregor       OS << ConfigMacros[I];
41835b13eceSDouglas Gregor     }
4198d932427SDouglas Gregor     OS << "\n";
42035b13eceSDouglas Gregor   }
42135b13eceSDouglas Gregor 
4223c1a41adSRichard Smith   struct {
423306d8920SRichard Smith     StringRef Prefix;
4243c1a41adSRichard Smith     HeaderKind Kind;
4253c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
4263c1a41adSRichard Smith                {"textual ", HK_Textual},
4273c1a41adSRichard Smith                {"private ", HK_Private},
4283c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
4293c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
430306d8920SRichard Smith 
431306d8920SRichard Smith   for (auto &K : Kinds) {
432040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
4333c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
434de3ef502SDouglas Gregor       OS.indent(Indent + 2);
435306d8920SRichard Smith       OS << K.Prefix << "header \"";
4363c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
437040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
438040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
439040e1266SRichard Smith     }
440040e1266SRichard Smith   }
441040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
442040e1266SRichard Smith     for (auto &U : *Unresolved) {
443040e1266SRichard Smith       OS.indent(Indent + 2);
444040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
445040e1266SRichard Smith       OS.write_escaped(U.FileName);
446040e1266SRichard Smith       OS << "\"";
447040e1266SRichard Smith       if (U.Size || U.ModTime) {
448040e1266SRichard Smith         OS << " {";
449040e1266SRichard Smith         if (U.Size)
450040e1266SRichard Smith           OS << " size " << *U.Size;
451040e1266SRichard Smith         if (U.ModTime)
452040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
453040e1266SRichard Smith         OS << " }";
454040e1266SRichard Smith       }
455040e1266SRichard Smith       OS << "\n";
456de3ef502SDouglas Gregor     }
457b53e5483SLawrence Crowl   }
458b53e5483SLawrence Crowl 
459f0b11de2SDouglas Gregor   if (!ExportAsModule.empty()) {
460f0b11de2SDouglas Gregor     OS.indent(Indent + 2);
461f0b11de2SDouglas Gregor     OS << "export_as" << ExportAsModule << "\n";
462f0b11de2SDouglas Gregor   }
463f0b11de2SDouglas Gregor 
464eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
465de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
4669d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
4679d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
4689d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4699d6448b1SBen Langmuir     // those header files anyway.
4709d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
471eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
472de3ef502SDouglas Gregor 
47324bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
47424bb923aSDouglas Gregor     OS.indent(Indent + 2);
4758c7c8352SDouglas Gregor     OS << "export ";
4768c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4779565c75bSRichard Smith       OS << Restriction->getFullModuleName(true);
47824bb923aSDouglas Gregor       if (Exports[I].getInt())
47924bb923aSDouglas Gregor         OS << ".*";
4808c7c8352SDouglas Gregor     } else {
4818c7c8352SDouglas Gregor       OS << "*";
4828c7c8352SDouglas Gregor     }
48324bb923aSDouglas Gregor     OS << "\n";
48424bb923aSDouglas Gregor   }
48524bb923aSDouglas Gregor 
48624bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
48724bb923aSDouglas Gregor     OS.indent(Indent + 2);
48824bb923aSDouglas Gregor     OS << "export ";
48924bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4907f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
4917f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
49224bb923aSDouglas Gregor     OS << "\n";
49324bb923aSDouglas Gregor   }
49424bb923aSDouglas Gregor 
495ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
496ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
497ba7f2f71SDaniel Jasper     OS << "use ";
4989565c75bSRichard Smith     OS << DirectUses[I]->getFullModuleName(true);
499ba7f2f71SDaniel Jasper     OS << "\n";
500ba7f2f71SDaniel Jasper   }
501ba7f2f71SDaniel Jasper 
502ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
503ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
504ba7f2f71SDaniel Jasper     OS << "use ";
505ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
506ba7f2f71SDaniel Jasper     OS << "\n";
507ba7f2f71SDaniel Jasper   }
508ba7f2f71SDaniel Jasper 
5096ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5106ddfca91SDouglas Gregor     OS.indent(Indent + 2);
5116ddfca91SDouglas Gregor     OS << "link ";
5126ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
5136ddfca91SDouglas Gregor       OS << "framework ";
5146ddfca91SDouglas Gregor     OS << "\"";
5156ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
5166ddfca91SDouglas Gregor     OS << "\"";
5176ddfca91SDouglas Gregor   }
5186ddfca91SDouglas Gregor 
519fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
520fb912657SDouglas Gregor     OS.indent(Indent + 2);
521fb912657SDouglas Gregor     OS << "conflict ";
522fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
523fb912657SDouglas Gregor     OS << ", \"";
524fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
525fb912657SDouglas Gregor     OS << "\"\n";
526fb912657SDouglas Gregor   }
527fb912657SDouglas Gregor 
528fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
529fb912657SDouglas Gregor     OS.indent(Indent + 2);
530fb912657SDouglas Gregor     OS << "conflict ";
5319565c75bSRichard Smith     OS << Conflicts[I].Other->getFullModuleName(true);
532fb912657SDouglas Gregor     OS << ", \"";
533fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
534fb912657SDouglas Gregor     OS << "\"\n";
535fb912657SDouglas Gregor   }
536fb912657SDouglas Gregor 
53773441091SDouglas Gregor   if (InferSubmodules) {
53873441091SDouglas Gregor     OS.indent(Indent + 2);
53973441091SDouglas Gregor     if (InferExplicitSubmodules)
54073441091SDouglas Gregor       OS << "explicit ";
54173441091SDouglas Gregor     OS << "module * {\n";
54273441091SDouglas Gregor     if (InferExportWildcard) {
54373441091SDouglas Gregor       OS.indent(Indent + 4);
54473441091SDouglas Gregor       OS << "export *\n";
54573441091SDouglas Gregor     }
54673441091SDouglas Gregor     OS.indent(Indent + 2);
54773441091SDouglas Gregor     OS << "}\n";
54873441091SDouglas Gregor   }
54973441091SDouglas Gregor 
550de3ef502SDouglas Gregor   OS.indent(Indent);
551de3ef502SDouglas Gregor   OS << "}\n";
552de3ef502SDouglas Gregor }
553de3ef502SDouglas Gregor 
554cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
555de3ef502SDouglas Gregor   print(llvm::errs());
556de3ef502SDouglas Gregor }
557de3ef502SDouglas Gregor 
558a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
559a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
5606d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
561a7e2cc68SRichard Smith   if (isVisible(M))
562a7e2cc68SRichard Smith     return;
563de3ef502SDouglas Gregor 
564a7e2cc68SRichard Smith   ++Generation;
565a7e2cc68SRichard Smith 
566a7e2cc68SRichard Smith   struct Visiting {
567a7e2cc68SRichard Smith     Module *M;
568a7e2cc68SRichard Smith     Visiting *ExportedBy;
569a7e2cc68SRichard Smith   };
570a7e2cc68SRichard Smith 
571a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
572a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
573a7e2cc68SRichard Smith     if (!V.M->isAvailable())
574a7e2cc68SRichard Smith       return;
575a7e2cc68SRichard Smith 
576a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
577a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
578a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
579a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
580a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
581a7e2cc68SRichard Smith       return;
582a7e2cc68SRichard Smith 
583a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
584a7e2cc68SRichard Smith     Vis(M);
585a7e2cc68SRichard Smith 
586a7e2cc68SRichard Smith     // Make any exported modules visible.
587a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
588a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
589a7e2cc68SRichard Smith     for (Module *E : Exports)
590a7e2cc68SRichard Smith       VisitModule({E, &V});
591a7e2cc68SRichard Smith 
592a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
593a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
594a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
595a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
596a7e2cc68SRichard Smith           Path.push_back(I->M);
597a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
598a7e2cc68SRichard Smith       }
599a7e2cc68SRichard Smith     }
600a7e2cc68SRichard Smith   };
601a7e2cc68SRichard Smith   VisitModule({M, nullptr});
602a7e2cc68SRichard Smith }
603