1*918e0ca7SEugene 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"
19*918e0ca7SEugene 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"
23*918e0ca7SEugene Zelenko #include "llvm/ADT/StringMap.h"
24*918e0ca7SEugene Zelenko #include "llvm/ADT/StringRef.h"
251fb5c3a6SDouglas Gregor #include "llvm/ADT/StringSwitch.h"
26*918e0ca7SEugene Zelenko #include "llvm/Support/Compiler.h"
273a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h"
283a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h"
29*918e0ca7SEugene Zelenko #include <algorithm>
30*918e0ca7SEugene Zelenko #include <cassert>
31*918e0ca7SEugene Zelenko #include <functional>
32*918e0ca7SEugene Zelenko #include <string>
33*918e0ca7SEugene Zelenko #include <utility>
34*918e0ca7SEugene 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)
40*918e0ca7SEugene Zelenko     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
41*918e0ca7SEugene Zelenko       VisibilityID(VisibilityID), IsMissingRequirement(false),
42*918e0ca7SEugene Zelenko       HasIncompatibleModuleFile(false), IsAvailable(true),
43*918e0ca7SEugene Zelenko       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
44*918e0ca7SEugene Zelenko       IsSystem(false), IsExternC(false), IsInferred(false),
45*918e0ca7SEugene 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,
983c1a41adSRichard Smith                          UnresolvedHeaderDirective &MissingHeader) const {
991fb5c3a6SDouglas Gregor   if (IsAvailable)
1001fb5c3a6SDouglas Gregor     return true;
1011fb5c3a6SDouglas Gregor 
1021fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
103a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
104a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
105a3feee2aSRichard Smith               Current->Requirements[I].second) {
106a3feee2aSRichard Smith         Req = Current->Requirements[I];
1071fb5c3a6SDouglas Gregor         return false;
1081fb5c3a6SDouglas Gregor       }
1091fb5c3a6SDouglas Gregor     }
11075a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
11175a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
11275a7e435SBen Langmuir       return false;
11375a7e435SBen Langmuir     }
1141fb5c3a6SDouglas Gregor   }
1151fb5c3a6SDouglas Gregor 
1161fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1171fb5c3a6SDouglas Gregor }
1181fb5c3a6SDouglas Gregor 
11962bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
120f5eedd05SDouglas Gregor   const Module *This = this;
121f5eedd05SDouglas Gregor   do {
122f5eedd05SDouglas Gregor     if (This == Other)
123f5eedd05SDouglas Gregor       return true;
124f5eedd05SDouglas Gregor 
125f5eedd05SDouglas Gregor     This = This->Parent;
126f5eedd05SDouglas Gregor   } while (This);
127f5eedd05SDouglas Gregor 
128f5eedd05SDouglas Gregor   return false;
129f5eedd05SDouglas Gregor }
130f5eedd05SDouglas Gregor 
13173441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
13273441091SDouglas Gregor   const Module *Result = this;
13373441091SDouglas Gregor   while (Result->Parent)
13473441091SDouglas Gregor     Result = Result->Parent;
13573441091SDouglas Gregor 
13673441091SDouglas Gregor   return Result;
13773441091SDouglas Gregor }
13873441091SDouglas Gregor 
1399565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1409565c75bSRichard Smith     const std::pair<std::string, SourceLocation> &IdComponent) {
1419565c75bSRichard Smith   return IdComponent.first;
1429565c75bSRichard Smith }
143*918e0ca7SEugene Zelenko 
1449565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1459565c75bSRichard Smith 
1469565c75bSRichard Smith template<typename InputIter>
1479565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
1489565c75bSRichard Smith                           bool AllowStringLiterals = true) {
1499565c75bSRichard Smith   for (InputIter It = Begin; It != End; ++It) {
1509565c75bSRichard Smith     if (It != Begin)
1519565c75bSRichard Smith       OS << ".";
1529565c75bSRichard Smith 
1539565c75bSRichard Smith     StringRef Name = getModuleNameFromComponent(*It);
1549565c75bSRichard Smith     if (!AllowStringLiterals || isValidIdentifier(Name))
1559565c75bSRichard Smith       OS << Name;
1569565c75bSRichard Smith     else {
1579565c75bSRichard Smith       OS << '"';
1589565c75bSRichard Smith       OS.write_escaped(Name);
1599565c75bSRichard Smith       OS << '"';
1609565c75bSRichard Smith     }
1619565c75bSRichard Smith   }
1629565c75bSRichard Smith }
1639565c75bSRichard Smith 
1649565c75bSRichard Smith template<typename Container>
1659565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
1669565c75bSRichard Smith   return printModuleId(OS, C.begin(), C.end());
1679565c75bSRichard Smith }
1689565c75bSRichard Smith 
1699565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
170f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
171de3ef502SDouglas Gregor 
172de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
173de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
174de3ef502SDouglas Gregor     Names.push_back(M->Name);
175de3ef502SDouglas Gregor 
176de3ef502SDouglas Gregor   std::string Result;
177de3ef502SDouglas Gregor 
1789565c75bSRichard Smith   llvm::raw_string_ostream Out(Result);
1799565c75bSRichard Smith   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
1809565c75bSRichard Smith   Out.flush();
181de3ef502SDouglas Gregor 
182de3ef502SDouglas Gregor   return Result;
183de3ef502SDouglas Gregor }
184de3ef502SDouglas Gregor 
1857ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
1867ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
1877ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
1887ff29148SBen Langmuir       return false;
1897ff29148SBen Langmuir     nameParts = nameParts.drop_back();
1907ff29148SBen Langmuir   }
1917ff29148SBen Langmuir   return nameParts.empty();
1927ff29148SBen Langmuir }
1937ff29148SBen Langmuir 
1942b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
1952b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
1962b63d15fSRichard Smith     return {"", U.Entry->getDir()};
19773141fa9SDouglas Gregor 
1982b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
19973141fa9SDouglas Gregor }
20073141fa9SDouglas Gregor 
2013c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2023c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
2033c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
2043c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2053c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
2063c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
2073c5305c1SArgyrios Kyrtzidis     }
2083c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
2093c5305c1SArgyrios Kyrtzidis   }
2103c5305c1SArgyrios Kyrtzidis 
2113c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2123c5305c1SArgyrios Kyrtzidis }
2133c5305c1SArgyrios Kyrtzidis 
2148f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
2158f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
2168f4d3ff1SRichard Smith 
2178f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
2188f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
2198f4d3ff1SRichard Smith     return true;
2208f4d3ff1SRichard Smith 
2218f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
2228f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
2238f4d3ff1SRichard Smith       return true;
224ed84df00SBruno Cardoso Lopes 
225ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
226ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
227ed84df00SBruno Cardoso Lopes     return true;
228ed84df00SBruno Cardoso Lopes 
2298f4d3ff1SRichard Smith   return false;
2308f4d3ff1SRichard Smith }
2318f4d3ff1SRichard Smith 
232a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
233a3feee2aSRichard Smith                             const LangOptions &LangOpts,
23489929282SDouglas Gregor                             const TargetInfo &Target) {
235a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
2361fb5c3a6SDouglas Gregor 
2371fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
238a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2391fb5c3a6SDouglas Gregor     return;
2401fb5c3a6SDouglas Gregor 
241993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
242ec8c9752SBen Langmuir }
243ec8c9752SBen Langmuir 
244993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
24575a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
24675a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
24775a7e435SBen Langmuir   };
24875a7e435SBen Langmuir 
24975a7e435SBen Langmuir   if (!needUpdate(this))
2501fb5c3a6SDouglas Gregor     return;
2511fb5c3a6SDouglas Gregor 
252f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2531fb5c3a6SDouglas Gregor   Stack.push_back(this);
2541fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
2551fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
2561fb5c3a6SDouglas Gregor     Stack.pop_back();
2571fb5c3a6SDouglas Gregor 
25875a7e435SBen Langmuir     if (!needUpdate(Current))
2591fb5c3a6SDouglas Gregor       continue;
2601fb5c3a6SDouglas Gregor 
2611fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
262993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
263eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
264eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
2651fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
26675a7e435SBen Langmuir       if (needUpdate(*Sub))
267eb90e830SDouglas Gregor         Stack.push_back(*Sub);
2681fb5c3a6SDouglas Gregor     }
2691fb5c3a6SDouglas Gregor   }
2701fb5c3a6SDouglas Gregor }
2711fb5c3a6SDouglas Gregor 
272eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
273eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
274eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
275f1186c5aSCraig Topper     return nullptr;
276eb90e830SDouglas Gregor 
277eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
278eb90e830SDouglas Gregor }
279eb90e830SDouglas Gregor 
2808739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
281e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
282e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
283e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
284e9bcf5b7SDmitri Gribenko        I != E; ++I) {
285e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
286e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
287e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
288e9bcf5b7SDmitri Gribenko   }
289e9bcf5b7SDmitri Gribenko 
290e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
2918739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
2928739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
2938739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
2948739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
2958739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
2968739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
2978739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
2988739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
2998739f7b7SArgyrios Kyrtzidis 
3008739f7b7SArgyrios Kyrtzidis       continue;
3018739f7b7SArgyrios Kyrtzidis     }
3028739f7b7SArgyrios Kyrtzidis 
3038739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
3048739f7b7SArgyrios Kyrtzidis     // the given pattern.
3058739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
3068739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
3078739f7b7SArgyrios Kyrtzidis       continue;
3088739f7b7SArgyrios Kyrtzidis 
3098739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
3108739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
3118739f7b7SArgyrios Kyrtzidis     else {
3128739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
3138739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
3148739f7b7SArgyrios Kyrtzidis     }
3158739f7b7SArgyrios Kyrtzidis   }
3168739f7b7SArgyrios Kyrtzidis 
3178739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
3188739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
3198739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
3208739f7b7SArgyrios Kyrtzidis     return;
3218739f7b7SArgyrios Kyrtzidis 
3228739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3238739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
3248739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
3258739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
3268739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
3278739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
3288739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
3298739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
3308739f7b7SArgyrios Kyrtzidis           Acceptable = true;
3318739f7b7SArgyrios Kyrtzidis           break;
3328739f7b7SArgyrios Kyrtzidis         }
3338739f7b7SArgyrios Kyrtzidis       }
3348739f7b7SArgyrios Kyrtzidis     }
3358739f7b7SArgyrios Kyrtzidis 
3368739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
3378739f7b7SArgyrios Kyrtzidis       continue;
3388739f7b7SArgyrios Kyrtzidis 
3398739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3408739f7b7SArgyrios Kyrtzidis   }
3418739f7b7SArgyrios Kyrtzidis }
3428739f7b7SArgyrios Kyrtzidis 
3430e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3440e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3450e5d7b8cSRichard Smith 
3460e5d7b8cSRichard Smith   // This module is visible to itself.
3470e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3480e5d7b8cSRichard Smith 
3490e5d7b8cSRichard Smith   // Every imported module is visible.
350dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
351dc360d57SDmitri Gribenko   while (!Stack.empty()) {
352dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
353dc360d57SDmitri Gribenko 
354dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
355dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
356dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
3570e5d7b8cSRichard Smith   }
3580e5d7b8cSRichard Smith }
3590e5d7b8cSRichard Smith 
360f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
361de3ef502SDouglas Gregor   OS.indent(Indent);
362de3ef502SDouglas Gregor   if (IsFramework)
363de3ef502SDouglas Gregor     OS << "framework ";
364de3ef502SDouglas Gregor   if (IsExplicit)
365de3ef502SDouglas Gregor     OS << "explicit ";
3669565c75bSRichard Smith   OS << "module ";
3679565c75bSRichard Smith   printModuleId(OS, &Name, &Name + 1);
368a686e1b0SDouglas Gregor 
3697615f00eSBen Langmuir   if (IsSystem || IsExternC) {
370a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
3717615f00eSBen Langmuir     if (IsSystem)
372a686e1b0SDouglas Gregor       OS << " [system]";
3737615f00eSBen Langmuir     if (IsExternC)
3747615f00eSBen Langmuir       OS << " [extern_c]";
375a686e1b0SDouglas Gregor   }
376a686e1b0SDouglas Gregor 
377a686e1b0SDouglas Gregor   OS << " {\n";
378de3ef502SDouglas Gregor 
379a3feee2aSRichard Smith   if (!Requirements.empty()) {
3801fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
3811fb5c3a6SDouglas Gregor     OS << "requires ";
382a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
3831fb5c3a6SDouglas Gregor       if (I)
3841fb5c3a6SDouglas Gregor         OS << ", ";
385a3feee2aSRichard Smith       if (!Requirements[I].second)
386a3feee2aSRichard Smith         OS << "!";
387a3feee2aSRichard Smith       OS << Requirements[I].first;
3881fb5c3a6SDouglas Gregor     }
3891fb5c3a6SDouglas Gregor     OS << "\n";
3901fb5c3a6SDouglas Gregor   }
3911fb5c3a6SDouglas Gregor 
3922b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
393de3ef502SDouglas Gregor     OS.indent(Indent + 2);
394322f633cSDouglas Gregor     OS << "umbrella header \"";
3952b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
396de3ef502SDouglas Gregor     OS << "\"\n";
3972b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
398322f633cSDouglas Gregor     OS.indent(Indent + 2);
399322f633cSDouglas Gregor     OS << "umbrella \"";
4002b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
401322f633cSDouglas Gregor     OS << "\"\n";
402de3ef502SDouglas Gregor   }
403de3ef502SDouglas Gregor 
40435b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
40535b13eceSDouglas Gregor     OS.indent(Indent + 2);
40635b13eceSDouglas Gregor     OS << "config_macros ";
40735b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
4088d932427SDouglas Gregor       OS << "[exhaustive]";
40935b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
41035b13eceSDouglas Gregor       if (I)
41135b13eceSDouglas Gregor         OS << ", ";
41235b13eceSDouglas Gregor       OS << ConfigMacros[I];
41335b13eceSDouglas Gregor     }
4148d932427SDouglas Gregor     OS << "\n";
41535b13eceSDouglas Gregor   }
41635b13eceSDouglas Gregor 
4173c1a41adSRichard Smith   struct {
418306d8920SRichard Smith     StringRef Prefix;
4193c1a41adSRichard Smith     HeaderKind Kind;
4203c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
4213c1a41adSRichard Smith                {"textual ", HK_Textual},
4223c1a41adSRichard Smith                {"private ", HK_Private},
4233c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
4243c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
425306d8920SRichard Smith 
426306d8920SRichard Smith   for (auto &K : Kinds) {
427040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
4283c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
429de3ef502SDouglas Gregor       OS.indent(Indent + 2);
430306d8920SRichard Smith       OS << K.Prefix << "header \"";
4313c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
432040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
433040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
434040e1266SRichard Smith     }
435040e1266SRichard Smith   }
436040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
437040e1266SRichard Smith     for (auto &U : *Unresolved) {
438040e1266SRichard Smith       OS.indent(Indent + 2);
439040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
440040e1266SRichard Smith       OS.write_escaped(U.FileName);
441040e1266SRichard Smith       OS << "\"";
442040e1266SRichard Smith       if (U.Size || U.ModTime) {
443040e1266SRichard Smith         OS << " {";
444040e1266SRichard Smith         if (U.Size)
445040e1266SRichard Smith           OS << " size " << *U.Size;
446040e1266SRichard Smith         if (U.ModTime)
447040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
448040e1266SRichard Smith         OS << " }";
449040e1266SRichard Smith       }
450040e1266SRichard Smith       OS << "\n";
451de3ef502SDouglas Gregor     }
452b53e5483SLawrence Crowl   }
453b53e5483SLawrence Crowl 
454f0b11de2SDouglas Gregor   if (!ExportAsModule.empty()) {
455f0b11de2SDouglas Gregor     OS.indent(Indent + 2);
456f0b11de2SDouglas Gregor     OS << "export_as" << ExportAsModule << "\n";
457f0b11de2SDouglas Gregor   }
458f0b11de2SDouglas Gregor 
459eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
460de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
4619d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
4629d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
4639d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
4649d6448b1SBen Langmuir     // those header files anyway.
4659d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
466eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
467de3ef502SDouglas Gregor 
46824bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
46924bb923aSDouglas Gregor     OS.indent(Indent + 2);
4708c7c8352SDouglas Gregor     OS << "export ";
4718c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
4729565c75bSRichard Smith       OS << Restriction->getFullModuleName(true);
47324bb923aSDouglas Gregor       if (Exports[I].getInt())
47424bb923aSDouglas Gregor         OS << ".*";
4758c7c8352SDouglas Gregor     } else {
4768c7c8352SDouglas Gregor       OS << "*";
4778c7c8352SDouglas Gregor     }
47824bb923aSDouglas Gregor     OS << "\n";
47924bb923aSDouglas Gregor   }
48024bb923aSDouglas Gregor 
48124bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
48224bb923aSDouglas Gregor     OS.indent(Indent + 2);
48324bb923aSDouglas Gregor     OS << "export ";
48424bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
4857f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
4867f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
48724bb923aSDouglas Gregor     OS << "\n";
48824bb923aSDouglas Gregor   }
48924bb923aSDouglas Gregor 
490ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
491ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
492ba7f2f71SDaniel Jasper     OS << "use ";
4939565c75bSRichard Smith     OS << DirectUses[I]->getFullModuleName(true);
494ba7f2f71SDaniel Jasper     OS << "\n";
495ba7f2f71SDaniel Jasper   }
496ba7f2f71SDaniel Jasper 
497ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
498ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
499ba7f2f71SDaniel Jasper     OS << "use ";
500ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
501ba7f2f71SDaniel Jasper     OS << "\n";
502ba7f2f71SDaniel Jasper   }
503ba7f2f71SDaniel Jasper 
5046ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5056ddfca91SDouglas Gregor     OS.indent(Indent + 2);
5066ddfca91SDouglas Gregor     OS << "link ";
5076ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
5086ddfca91SDouglas Gregor       OS << "framework ";
5096ddfca91SDouglas Gregor     OS << "\"";
5106ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
5116ddfca91SDouglas Gregor     OS << "\"";
5126ddfca91SDouglas Gregor   }
5136ddfca91SDouglas Gregor 
514fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
515fb912657SDouglas Gregor     OS.indent(Indent + 2);
516fb912657SDouglas Gregor     OS << "conflict ";
517fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
518fb912657SDouglas Gregor     OS << ", \"";
519fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
520fb912657SDouglas Gregor     OS << "\"\n";
521fb912657SDouglas Gregor   }
522fb912657SDouglas Gregor 
523fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
524fb912657SDouglas Gregor     OS.indent(Indent + 2);
525fb912657SDouglas Gregor     OS << "conflict ";
5269565c75bSRichard Smith     OS << Conflicts[I].Other->getFullModuleName(true);
527fb912657SDouglas Gregor     OS << ", \"";
528fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
529fb912657SDouglas Gregor     OS << "\"\n";
530fb912657SDouglas Gregor   }
531fb912657SDouglas Gregor 
53273441091SDouglas Gregor   if (InferSubmodules) {
53373441091SDouglas Gregor     OS.indent(Indent + 2);
53473441091SDouglas Gregor     if (InferExplicitSubmodules)
53573441091SDouglas Gregor       OS << "explicit ";
53673441091SDouglas Gregor     OS << "module * {\n";
53773441091SDouglas Gregor     if (InferExportWildcard) {
53873441091SDouglas Gregor       OS.indent(Indent + 4);
53973441091SDouglas Gregor       OS << "export *\n";
54073441091SDouglas Gregor     }
54173441091SDouglas Gregor     OS.indent(Indent + 2);
54273441091SDouglas Gregor     OS << "}\n";
54373441091SDouglas Gregor   }
54473441091SDouglas Gregor 
545de3ef502SDouglas Gregor   OS.indent(Indent);
546de3ef502SDouglas Gregor   OS << "}\n";
547de3ef502SDouglas Gregor }
548de3ef502SDouglas Gregor 
549cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
550de3ef502SDouglas Gregor   print(llvm::errs());
551de3ef502SDouglas Gregor }
552de3ef502SDouglas Gregor 
553a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
554a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
5556d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
556a7e2cc68SRichard Smith   if (isVisible(M))
557a7e2cc68SRichard Smith     return;
558de3ef502SDouglas Gregor 
559a7e2cc68SRichard Smith   ++Generation;
560a7e2cc68SRichard Smith 
561a7e2cc68SRichard Smith   struct Visiting {
562a7e2cc68SRichard Smith     Module *M;
563a7e2cc68SRichard Smith     Visiting *ExportedBy;
564a7e2cc68SRichard Smith   };
565a7e2cc68SRichard Smith 
566a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
567a7e2cc68SRichard Smith     // Modules that aren't available cannot be made visible.
568a7e2cc68SRichard Smith     if (!V.M->isAvailable())
569a7e2cc68SRichard Smith       return;
570a7e2cc68SRichard Smith 
571a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
572a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
573a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
574a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
575a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
576a7e2cc68SRichard Smith       return;
577a7e2cc68SRichard Smith 
578a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
579a7e2cc68SRichard Smith     Vis(M);
580a7e2cc68SRichard Smith 
581a7e2cc68SRichard Smith     // Make any exported modules visible.
582a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
583a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
584a7e2cc68SRichard Smith     for (Module *E : Exports)
585a7e2cc68SRichard Smith       VisitModule({E, &V});
586a7e2cc68SRichard Smith 
587a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
588a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
589a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
590a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
591a7e2cc68SRichard Smith           Path.push_back(I->M);
592a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
593a7e2cc68SRichard Smith       }
594a7e2cc68SRichard Smith     }
595a7e2cc68SRichard Smith   };
596a7e2cc68SRichard Smith   VisitModule({M, nullptr});
597a7e2cc68SRichard Smith }
598