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),
4790b0a1fcSJordan Rose       NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
4890b0a1fcSJordan Rose       NameVisibility(Hidden) {
49eb90e830SDouglas Gregor   if (Parent) {
50eb90e830SDouglas Gregor     if (!Parent->isAvailable())
51eb90e830SDouglas Gregor       IsAvailable = false;
523ec6663bSDouglas Gregor     if (Parent->IsSystem)
533ec6663bSDouglas Gregor       IsSystem = true;
549bca298fSRichard Smith     if (Parent->IsExternC)
559bca298fSRichard Smith       IsExternC = true;
56ed84df00SBruno Cardoso Lopes     if (Parent->NoUndeclaredIncludes)
57ed84df00SBruno Cardoso Lopes       NoUndeclaredIncludes = true;
5890b0a1fcSJordan Rose     if (Parent->ModuleMapIsPrivate)
5990b0a1fcSJordan Rose       ModuleMapIsPrivate = true;
60993055f8SBen Langmuir     IsMissingRequirement = Parent->IsMissingRequirement;
61eb90e830SDouglas Gregor 
62eb90e830SDouglas Gregor     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
63eb90e830SDouglas Gregor     Parent->SubModules.push_back(this);
64eb90e830SDouglas Gregor   }
65eb90e830SDouglas Gregor }
66eb90e830SDouglas Gregor 
67de3ef502SDouglas Gregor Module::~Module() {
68eb90e830SDouglas Gregor   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
69de3ef502SDouglas Gregor        I != IEnd; ++I) {
70eb90e830SDouglas Gregor     delete *I;
71de3ef502SDouglas Gregor   }
72de3ef502SDouglas Gregor }
73de3ef502SDouglas Gregor 
74e7240f02SBruno Cardoso Lopes static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
75e7240f02SBruno Cardoso Lopes   StringRef Platform = Target.getPlatformName();
76e7240f02SBruno Cardoso Lopes   StringRef Env = Target.getTriple().getEnvironmentName();
77e7240f02SBruno Cardoso Lopes 
78e7240f02SBruno Cardoso Lopes   // Attempt to match platform and environment.
79e7240f02SBruno Cardoso Lopes   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
80e7240f02SBruno Cardoso Lopes       Env == Feature)
81e7240f02SBruno Cardoso Lopes     return true;
82e7240f02SBruno Cardoso Lopes 
83e7240f02SBruno Cardoso Lopes   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
84e7240f02SBruno Cardoso Lopes     auto Pos = LHS.find("-");
85e7240f02SBruno Cardoso Lopes     if (Pos == StringRef::npos)
86e7240f02SBruno Cardoso Lopes       return false;
87e7240f02SBruno Cardoso Lopes     SmallString<128> NewLHS = LHS.slice(0, Pos);
88e7240f02SBruno Cardoso Lopes     NewLHS += LHS.slice(Pos+1, LHS.size());
89e7240f02SBruno Cardoso Lopes     return NewLHS == RHS;
90e7240f02SBruno Cardoso Lopes   };
91e7240f02SBruno Cardoso Lopes 
92e7240f02SBruno Cardoso Lopes   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
93e7240f02SBruno Cardoso Lopes   // Darwin has different but equivalent variants for simulators, example:
94e7240f02SBruno Cardoso Lopes   //   1. x86_64-apple-ios-simulator
95e7240f02SBruno Cardoso Lopes   //   2. x86_64-apple-iossimulator
96e7240f02SBruno Cardoso Lopes   // where both are valid examples of the same platform+environment but in the
97e7240f02SBruno Cardoso Lopes   // variant (2) the simulator is hardcoded as part of the platform name. Both
98e7240f02SBruno Cardoso Lopes   // forms above should match for "iossimulator" requirement.
99e7240f02SBruno Cardoso Lopes   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
100e7240f02SBruno Cardoso Lopes     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
101e7240f02SBruno Cardoso Lopes 
102e7240f02SBruno Cardoso Lopes   return PlatformEnv == Feature;
103e7240f02SBruno Cardoso Lopes }
104e7240f02SBruno Cardoso Lopes 
1059fc8faf9SAdrian Prantl /// Determine whether a translation unit built using the current
1061fb5c3a6SDouglas Gregor /// language options has the given feature.
10789929282SDouglas Gregor static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
10889929282SDouglas Gregor                        const TargetInfo &Target) {
109532d2104SBen Langmuir   bool HasFeature = llvm::StringSwitch<bool>(Feature)
1100070c0bfSDouglas Gregor                         .Case("altivec", LangOpts.AltiVec)
1111fb5c3a6SDouglas Gregor                         .Case("blocks", LangOpts.Blocks)
112e38cea02SEric Fiselier                         .Case("coroutines", LangOpts.CoroutinesTS)
1131fb5c3a6SDouglas Gregor                         .Case("cplusplus", LangOpts.CPlusPlus)
1142bf7fdb7SRichard Smith                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1156d9cf8aaSBruno Cardoso Lopes                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1166d9cf8aaSBruno Cardoso Lopes                         .Case("cplusplus17", LangOpts.CPlusPlus17)
1176d9cf8aaSBruno Cardoso Lopes                         .Case("c99", LangOpts.C99)
1186d9cf8aaSBruno Cardoso Lopes                         .Case("c11", LangOpts.C11)
1196d9cf8aaSBruno Cardoso Lopes                         .Case("c17", LangOpts.C17)
120fb6358d2SElad Cohen                         .Case("freestanding", LangOpts.Freestanding)
1216736e199SBruno Cardoso Lopes                         .Case("gnuinlineasm", LangOpts.GNUAsm)
122*fa98390bSErik Pilkington                         .Case("objc", LangOpts.ObjC)
1231fb5c3a6SDouglas Gregor                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
1240070c0bfSDouglas Gregor                         .Case("opencl", LangOpts.OpenCL)
1250070c0bfSDouglas Gregor                         .Case("tls", Target.isTLSSupported())
1263c5038a5SUlrich Weigand                         .Case("zvector", LangOpts.ZVector)
127e7240f02SBruno Cardoso Lopes                         .Default(Target.hasFeature(Feature) ||
128e7240f02SBruno Cardoso Lopes                                  isPlatformEnvironment(Target, Feature));
129532d2104SBen Langmuir   if (!HasFeature)
130532d2104SBen Langmuir     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
131532d2104SBen Langmuir                            LangOpts.ModuleFeatures.end(),
132532d2104SBen Langmuir                            Feature) != LangOpts.ModuleFeatures.end();
133532d2104SBen Langmuir   return HasFeature;
1341fb5c3a6SDouglas Gregor }
1351fb5c3a6SDouglas Gregor 
1363c1a41adSRichard Smith bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
1373c1a41adSRichard Smith                          Requirement &Req,
1388587dfd9SBruno Cardoso Lopes                          UnresolvedHeaderDirective &MissingHeader,
1398587dfd9SBruno Cardoso Lopes                          Module *&ShadowingModule) const {
1401fb5c3a6SDouglas Gregor   if (IsAvailable)
1411fb5c3a6SDouglas Gregor     return true;
1421fb5c3a6SDouglas Gregor 
1431fb5c3a6SDouglas Gregor   for (const Module *Current = this; Current; Current = Current->Parent) {
1448587dfd9SBruno Cardoso Lopes     if (Current->ShadowingModule) {
1458587dfd9SBruno Cardoso Lopes       ShadowingModule = Current->ShadowingModule;
1468587dfd9SBruno Cardoso Lopes       return false;
1478587dfd9SBruno Cardoso Lopes     }
148a3feee2aSRichard Smith     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
149a3feee2aSRichard Smith       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
150a3feee2aSRichard Smith               Current->Requirements[I].second) {
151a3feee2aSRichard Smith         Req = Current->Requirements[I];
1521fb5c3a6SDouglas Gregor         return false;
1531fb5c3a6SDouglas Gregor       }
1541fb5c3a6SDouglas Gregor     }
15575a7e435SBen Langmuir     if (!Current->MissingHeaders.empty()) {
15675a7e435SBen Langmuir       MissingHeader = Current->MissingHeaders.front();
15775a7e435SBen Langmuir       return false;
15875a7e435SBen Langmuir     }
1591fb5c3a6SDouglas Gregor   }
1601fb5c3a6SDouglas Gregor 
1611fb5c3a6SDouglas Gregor   llvm_unreachable("could not find a reason why module is unavailable");
1621fb5c3a6SDouglas Gregor }
1631fb5c3a6SDouglas Gregor 
16462bcd925SDmitri Gribenko bool Module::isSubModuleOf(const Module *Other) const {
165f5eedd05SDouglas Gregor   const Module *This = this;
166f5eedd05SDouglas Gregor   do {
167f5eedd05SDouglas Gregor     if (This == Other)
168f5eedd05SDouglas Gregor       return true;
169f5eedd05SDouglas Gregor 
170f5eedd05SDouglas Gregor     This = This->Parent;
171f5eedd05SDouglas Gregor   } while (This);
172f5eedd05SDouglas Gregor 
173f5eedd05SDouglas Gregor   return false;
174f5eedd05SDouglas Gregor }
175f5eedd05SDouglas Gregor 
17673441091SDouglas Gregor const Module *Module::getTopLevelModule() const {
17773441091SDouglas Gregor   const Module *Result = this;
17873441091SDouglas Gregor   while (Result->Parent)
17973441091SDouglas Gregor     Result = Result->Parent;
18073441091SDouglas Gregor 
18173441091SDouglas Gregor   return Result;
18273441091SDouglas Gregor }
18373441091SDouglas Gregor 
1849565c75bSRichard Smith static StringRef getModuleNameFromComponent(
1859565c75bSRichard Smith     const std::pair<std::string, SourceLocation> &IdComponent) {
1869565c75bSRichard Smith   return IdComponent.first;
1879565c75bSRichard Smith }
188918e0ca7SEugene Zelenko 
1899565c75bSRichard Smith static StringRef getModuleNameFromComponent(StringRef R) { return R; }
1909565c75bSRichard Smith 
1919565c75bSRichard Smith template<typename InputIter>
1929565c75bSRichard Smith static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
1939565c75bSRichard Smith                           bool AllowStringLiterals = true) {
1949565c75bSRichard Smith   for (InputIter It = Begin; It != End; ++It) {
1959565c75bSRichard Smith     if (It != Begin)
1969565c75bSRichard Smith       OS << ".";
1979565c75bSRichard Smith 
1989565c75bSRichard Smith     StringRef Name = getModuleNameFromComponent(*It);
1999565c75bSRichard Smith     if (!AllowStringLiterals || isValidIdentifier(Name))
2009565c75bSRichard Smith       OS << Name;
2019565c75bSRichard Smith     else {
2029565c75bSRichard Smith       OS << '"';
2039565c75bSRichard Smith       OS.write_escaped(Name);
2049565c75bSRichard Smith       OS << '"';
2059565c75bSRichard Smith     }
2069565c75bSRichard Smith   }
2079565c75bSRichard Smith }
2089565c75bSRichard Smith 
2099565c75bSRichard Smith template<typename Container>
2109565c75bSRichard Smith static void printModuleId(raw_ostream &OS, const Container &C) {
2119565c75bSRichard Smith   return printModuleId(OS, C.begin(), C.end());
2129565c75bSRichard Smith }
2139565c75bSRichard Smith 
2149565c75bSRichard Smith std::string Module::getFullModuleName(bool AllowStringLiterals) const {
215f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Names;
216de3ef502SDouglas Gregor 
217de3ef502SDouglas Gregor   // Build up the set of module names (from innermost to outermost).
218de3ef502SDouglas Gregor   for (const Module *M = this; M; M = M->Parent)
219de3ef502SDouglas Gregor     Names.push_back(M->Name);
220de3ef502SDouglas Gregor 
221de3ef502SDouglas Gregor   std::string Result;
222de3ef502SDouglas Gregor 
2239565c75bSRichard Smith   llvm::raw_string_ostream Out(Result);
2249565c75bSRichard Smith   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
2259565c75bSRichard Smith   Out.flush();
226de3ef502SDouglas Gregor 
227de3ef502SDouglas Gregor   return Result;
228de3ef502SDouglas Gregor }
229de3ef502SDouglas Gregor 
2307ff29148SBen Langmuir bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2317ff29148SBen Langmuir   for (const Module *M = this; M; M = M->Parent) {
2327ff29148SBen Langmuir     if (nameParts.empty() || M->Name != nameParts.back())
2337ff29148SBen Langmuir       return false;
2347ff29148SBen Langmuir     nameParts = nameParts.drop_back();
2357ff29148SBen Langmuir   }
2367ff29148SBen Langmuir   return nameParts.empty();
2377ff29148SBen Langmuir }
2387ff29148SBen Langmuir 
2392b63d15fSRichard Smith Module::DirectoryName Module::getUmbrellaDir() const {
2402b63d15fSRichard Smith   if (Header U = getUmbrellaHeader())
2412b63d15fSRichard Smith     return {"", U.Entry->getDir()};
24273141fa9SDouglas Gregor 
2432b63d15fSRichard Smith   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
24473141fa9SDouglas Gregor }
24573141fa9SDouglas Gregor 
2463c5305c1SArgyrios Kyrtzidis ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
2473c5305c1SArgyrios Kyrtzidis   if (!TopHeaderNames.empty()) {
2483c5305c1SArgyrios Kyrtzidis     for (std::vector<std::string>::iterator
2493c5305c1SArgyrios Kyrtzidis            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
2503c5305c1SArgyrios Kyrtzidis       if (const FileEntry *FE = FileMgr.getFile(*I))
2513c5305c1SArgyrios Kyrtzidis         TopHeaders.insert(FE);
2523c5305c1SArgyrios Kyrtzidis     }
2533c5305c1SArgyrios Kyrtzidis     TopHeaderNames.clear();
2543c5305c1SArgyrios Kyrtzidis   }
2553c5305c1SArgyrios Kyrtzidis 
2563c5305c1SArgyrios Kyrtzidis   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
2573c5305c1SArgyrios Kyrtzidis }
2583c5305c1SArgyrios Kyrtzidis 
2598f4d3ff1SRichard Smith bool Module::directlyUses(const Module *Requested) const {
2608f4d3ff1SRichard Smith   auto *Top = getTopLevelModule();
2618f4d3ff1SRichard Smith 
2628f4d3ff1SRichard Smith   // A top-level module implicitly uses itself.
2638f4d3ff1SRichard Smith   if (Requested->isSubModuleOf(Top))
2648f4d3ff1SRichard Smith     return true;
2658f4d3ff1SRichard Smith 
2668f4d3ff1SRichard Smith   for (auto *Use : Top->DirectUses)
2678f4d3ff1SRichard Smith     if (Requested->isSubModuleOf(Use))
2688f4d3ff1SRichard Smith       return true;
269ed84df00SBruno Cardoso Lopes 
270ed84df00SBruno Cardoso Lopes   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
271ed84df00SBruno Cardoso Lopes   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
272ed84df00SBruno Cardoso Lopes     return true;
273ed84df00SBruno Cardoso Lopes 
2748f4d3ff1SRichard Smith   return false;
2758f4d3ff1SRichard Smith }
2768f4d3ff1SRichard Smith 
277a3feee2aSRichard Smith void Module::addRequirement(StringRef Feature, bool RequiredState,
278a3feee2aSRichard Smith                             const LangOptions &LangOpts,
27989929282SDouglas Gregor                             const TargetInfo &Target) {
280a3feee2aSRichard Smith   Requirements.push_back(Requirement(Feature, RequiredState));
2811fb5c3a6SDouglas Gregor 
2821fb5c3a6SDouglas Gregor   // If this feature is currently available, we're done.
283a3feee2aSRichard Smith   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
2841fb5c3a6SDouglas Gregor     return;
2851fb5c3a6SDouglas Gregor 
286993055f8SBen Langmuir   markUnavailable(/*MissingRequirement*/true);
287ec8c9752SBen Langmuir }
288ec8c9752SBen Langmuir 
289993055f8SBen Langmuir void Module::markUnavailable(bool MissingRequirement) {
29075a7e435SBen Langmuir   auto needUpdate = [MissingRequirement](Module *M) {
29175a7e435SBen Langmuir     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
29275a7e435SBen Langmuir   };
29375a7e435SBen Langmuir 
29475a7e435SBen Langmuir   if (!needUpdate(this))
2951fb5c3a6SDouglas Gregor     return;
2961fb5c3a6SDouglas Gregor 
297f857950dSDmitri Gribenko   SmallVector<Module *, 2> Stack;
2981fb5c3a6SDouglas Gregor   Stack.push_back(this);
2991fb5c3a6SDouglas Gregor   while (!Stack.empty()) {
3001fb5c3a6SDouglas Gregor     Module *Current = Stack.back();
3011fb5c3a6SDouglas Gregor     Stack.pop_back();
3021fb5c3a6SDouglas Gregor 
30375a7e435SBen Langmuir     if (!needUpdate(Current))
3041fb5c3a6SDouglas Gregor       continue;
3051fb5c3a6SDouglas Gregor 
3061fb5c3a6SDouglas Gregor     Current->IsAvailable = false;
307993055f8SBen Langmuir     Current->IsMissingRequirement |= MissingRequirement;
308eb90e830SDouglas Gregor     for (submodule_iterator Sub = Current->submodule_begin(),
309eb90e830SDouglas Gregor                          SubEnd = Current->submodule_end();
3101fb5c3a6SDouglas Gregor          Sub != SubEnd; ++Sub) {
31175a7e435SBen Langmuir       if (needUpdate(*Sub))
312eb90e830SDouglas Gregor         Stack.push_back(*Sub);
3131fb5c3a6SDouglas Gregor     }
3141fb5c3a6SDouglas Gregor   }
3151fb5c3a6SDouglas Gregor }
3161fb5c3a6SDouglas Gregor 
317eb90e830SDouglas Gregor Module *Module::findSubmodule(StringRef Name) const {
318eb90e830SDouglas Gregor   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
319eb90e830SDouglas Gregor   if (Pos == SubModuleIndex.end())
320f1186c5aSCraig Topper     return nullptr;
321eb90e830SDouglas Gregor 
322eb90e830SDouglas Gregor   return SubModules[Pos->getValue()];
323eb90e830SDouglas Gregor }
324eb90e830SDouglas Gregor 
3258739f7b7SArgyrios Kyrtzidis void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
326e9bcf5b7SDmitri Gribenko   // All non-explicit submodules are exported.
327e9bcf5b7SDmitri Gribenko   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
328e9bcf5b7SDmitri Gribenko                                              E = SubModules.end();
329e9bcf5b7SDmitri Gribenko        I != E; ++I) {
330e9bcf5b7SDmitri Gribenko     Module *Mod = *I;
331e9bcf5b7SDmitri Gribenko     if (!Mod->IsExplicit)
332e9bcf5b7SDmitri Gribenko       Exported.push_back(Mod);
333e9bcf5b7SDmitri Gribenko   }
334e9bcf5b7SDmitri Gribenko 
335e9bcf5b7SDmitri Gribenko   // Find re-exported modules by filtering the list of imported modules.
3368739f7b7SArgyrios Kyrtzidis   bool AnyWildcard = false;
3378739f7b7SArgyrios Kyrtzidis   bool UnrestrictedWildcard = false;
3388739f7b7SArgyrios Kyrtzidis   SmallVector<Module *, 4> WildcardRestrictions;
3398739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
3408739f7b7SArgyrios Kyrtzidis     Module *Mod = Exports[I].getPointer();
3418739f7b7SArgyrios Kyrtzidis     if (!Exports[I].getInt()) {
3428739f7b7SArgyrios Kyrtzidis       // Export a named module directly; no wildcards involved.
3438739f7b7SArgyrios Kyrtzidis       Exported.push_back(Mod);
3448739f7b7SArgyrios Kyrtzidis 
3458739f7b7SArgyrios Kyrtzidis       continue;
3468739f7b7SArgyrios Kyrtzidis     }
3478739f7b7SArgyrios Kyrtzidis 
3488739f7b7SArgyrios Kyrtzidis     // Wildcard export: export all of the imported modules that match
3498739f7b7SArgyrios Kyrtzidis     // the given pattern.
3508739f7b7SArgyrios Kyrtzidis     AnyWildcard = true;
3518739f7b7SArgyrios Kyrtzidis     if (UnrestrictedWildcard)
3528739f7b7SArgyrios Kyrtzidis       continue;
3538739f7b7SArgyrios Kyrtzidis 
3548739f7b7SArgyrios Kyrtzidis     if (Module *Restriction = Exports[I].getPointer())
3558739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.push_back(Restriction);
3568739f7b7SArgyrios Kyrtzidis     else {
3578739f7b7SArgyrios Kyrtzidis       WildcardRestrictions.clear();
3588739f7b7SArgyrios Kyrtzidis       UnrestrictedWildcard = true;
3598739f7b7SArgyrios Kyrtzidis     }
3608739f7b7SArgyrios Kyrtzidis   }
3618739f7b7SArgyrios Kyrtzidis 
3628739f7b7SArgyrios Kyrtzidis   // If there were any wildcards, push any imported modules that were
3638739f7b7SArgyrios Kyrtzidis   // re-exported by the wildcard restriction.
3648739f7b7SArgyrios Kyrtzidis   if (!AnyWildcard)
3658739f7b7SArgyrios Kyrtzidis     return;
3668739f7b7SArgyrios Kyrtzidis 
3678739f7b7SArgyrios Kyrtzidis   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
3688739f7b7SArgyrios Kyrtzidis     Module *Mod = Imports[I];
3698739f7b7SArgyrios Kyrtzidis     bool Acceptable = UnrestrictedWildcard;
3708739f7b7SArgyrios Kyrtzidis     if (!Acceptable) {
3718739f7b7SArgyrios Kyrtzidis       // Check whether this module meets one of the restrictions.
3728739f7b7SArgyrios Kyrtzidis       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
3738739f7b7SArgyrios Kyrtzidis         Module *Restriction = WildcardRestrictions[R];
3748739f7b7SArgyrios Kyrtzidis         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
3758739f7b7SArgyrios Kyrtzidis           Acceptable = true;
3768739f7b7SArgyrios Kyrtzidis           break;
3778739f7b7SArgyrios Kyrtzidis         }
3788739f7b7SArgyrios Kyrtzidis       }
3798739f7b7SArgyrios Kyrtzidis     }
3808739f7b7SArgyrios Kyrtzidis 
3818739f7b7SArgyrios Kyrtzidis     if (!Acceptable)
3828739f7b7SArgyrios Kyrtzidis       continue;
3838739f7b7SArgyrios Kyrtzidis 
3848739f7b7SArgyrios Kyrtzidis     Exported.push_back(Mod);
3858739f7b7SArgyrios Kyrtzidis   }
3868739f7b7SArgyrios Kyrtzidis }
3878739f7b7SArgyrios Kyrtzidis 
3880e5d7b8cSRichard Smith void Module::buildVisibleModulesCache() const {
3890e5d7b8cSRichard Smith   assert(VisibleModulesCache.empty() && "cache does not need building");
3900e5d7b8cSRichard Smith 
3910e5d7b8cSRichard Smith   // This module is visible to itself.
3920e5d7b8cSRichard Smith   VisibleModulesCache.insert(this);
3930e5d7b8cSRichard Smith 
3940e5d7b8cSRichard Smith   // Every imported module is visible.
395dde17e74SRichard Smith   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
396dc360d57SDmitri Gribenko   while (!Stack.empty()) {
397dc360d57SDmitri Gribenko     Module *CurrModule = Stack.pop_back_val();
398dc360d57SDmitri Gribenko 
399dde17e74SRichard Smith     // Every module transitively exported by an imported module is visible.
400dde17e74SRichard Smith     if (VisibleModulesCache.insert(CurrModule).second)
401dde17e74SRichard Smith       CurrModule->getExportedModules(Stack);
4020e5d7b8cSRichard Smith   }
4030e5d7b8cSRichard Smith }
4040e5d7b8cSRichard Smith 
405f857950dSDmitri Gribenko void Module::print(raw_ostream &OS, unsigned Indent) const {
406de3ef502SDouglas Gregor   OS.indent(Indent);
407de3ef502SDouglas Gregor   if (IsFramework)
408de3ef502SDouglas Gregor     OS << "framework ";
409de3ef502SDouglas Gregor   if (IsExplicit)
410de3ef502SDouglas Gregor     OS << "explicit ";
4119565c75bSRichard Smith   OS << "module ";
4129565c75bSRichard Smith   printModuleId(OS, &Name, &Name + 1);
413a686e1b0SDouglas Gregor 
4147615f00eSBen Langmuir   if (IsSystem || IsExternC) {
415a686e1b0SDouglas Gregor     OS.indent(Indent + 2);
4167615f00eSBen Langmuir     if (IsSystem)
417a686e1b0SDouglas Gregor       OS << " [system]";
4187615f00eSBen Langmuir     if (IsExternC)
4197615f00eSBen Langmuir       OS << " [extern_c]";
420a686e1b0SDouglas Gregor   }
421a686e1b0SDouglas Gregor 
422a686e1b0SDouglas Gregor   OS << " {\n";
423de3ef502SDouglas Gregor 
424a3feee2aSRichard Smith   if (!Requirements.empty()) {
4251fb5c3a6SDouglas Gregor     OS.indent(Indent + 2);
4261fb5c3a6SDouglas Gregor     OS << "requires ";
427a3feee2aSRichard Smith     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
4281fb5c3a6SDouglas Gregor       if (I)
4291fb5c3a6SDouglas Gregor         OS << ", ";
430a3feee2aSRichard Smith       if (!Requirements[I].second)
431a3feee2aSRichard Smith         OS << "!";
432a3feee2aSRichard Smith       OS << Requirements[I].first;
4331fb5c3a6SDouglas Gregor     }
4341fb5c3a6SDouglas Gregor     OS << "\n";
4351fb5c3a6SDouglas Gregor   }
4361fb5c3a6SDouglas Gregor 
4372b63d15fSRichard Smith   if (Header H = getUmbrellaHeader()) {
438de3ef502SDouglas Gregor     OS.indent(Indent + 2);
439322f633cSDouglas Gregor     OS << "umbrella header \"";
4402b63d15fSRichard Smith     OS.write_escaped(H.NameAsWritten);
441de3ef502SDouglas Gregor     OS << "\"\n";
4422b63d15fSRichard Smith   } else if (DirectoryName D = getUmbrellaDir()) {
443322f633cSDouglas Gregor     OS.indent(Indent + 2);
444322f633cSDouglas Gregor     OS << "umbrella \"";
4452b63d15fSRichard Smith     OS.write_escaped(D.NameAsWritten);
446322f633cSDouglas Gregor     OS << "\"\n";
447de3ef502SDouglas Gregor   }
448de3ef502SDouglas Gregor 
44935b13eceSDouglas Gregor   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
45035b13eceSDouglas Gregor     OS.indent(Indent + 2);
45135b13eceSDouglas Gregor     OS << "config_macros ";
45235b13eceSDouglas Gregor     if (ConfigMacrosExhaustive)
4538d932427SDouglas Gregor       OS << "[exhaustive]";
45435b13eceSDouglas Gregor     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
45535b13eceSDouglas Gregor       if (I)
45635b13eceSDouglas Gregor         OS << ", ";
45735b13eceSDouglas Gregor       OS << ConfigMacros[I];
45835b13eceSDouglas Gregor     }
4598d932427SDouglas Gregor     OS << "\n";
46035b13eceSDouglas Gregor   }
46135b13eceSDouglas Gregor 
4623c1a41adSRichard Smith   struct {
463306d8920SRichard Smith     StringRef Prefix;
4643c1a41adSRichard Smith     HeaderKind Kind;
4653c1a41adSRichard Smith   } Kinds[] = {{"", HK_Normal},
4663c1a41adSRichard Smith                {"textual ", HK_Textual},
4673c1a41adSRichard Smith                {"private ", HK_Private},
4683c1a41adSRichard Smith                {"private textual ", HK_PrivateTextual},
4693c1a41adSRichard Smith                {"exclude ", HK_Excluded}};
470306d8920SRichard Smith 
471306d8920SRichard Smith   for (auto &K : Kinds) {
472040e1266SRichard Smith     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
4733c1a41adSRichard Smith     for (auto &H : Headers[K.Kind]) {
474de3ef502SDouglas Gregor       OS.indent(Indent + 2);
475306d8920SRichard Smith       OS << K.Prefix << "header \"";
4763c1a41adSRichard Smith       OS.write_escaped(H.NameAsWritten);
477040e1266SRichard Smith       OS << "\" { size " << H.Entry->getSize()
478040e1266SRichard Smith          << " mtime " << H.Entry->getModificationTime() << " }\n";
479040e1266SRichard Smith     }
480040e1266SRichard Smith   }
481040e1266SRichard Smith   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
482040e1266SRichard Smith     for (auto &U : *Unresolved) {
483040e1266SRichard Smith       OS.indent(Indent + 2);
484040e1266SRichard Smith       OS << Kinds[U.Kind].Prefix << "header \"";
485040e1266SRichard Smith       OS.write_escaped(U.FileName);
486040e1266SRichard Smith       OS << "\"";
487040e1266SRichard Smith       if (U.Size || U.ModTime) {
488040e1266SRichard Smith         OS << " {";
489040e1266SRichard Smith         if (U.Size)
490040e1266SRichard Smith           OS << " size " << *U.Size;
491040e1266SRichard Smith         if (U.ModTime)
492040e1266SRichard Smith           OS << " mtime " << *U.ModTime;
493040e1266SRichard Smith         OS << " }";
494040e1266SRichard Smith       }
495040e1266SRichard Smith       OS << "\n";
496de3ef502SDouglas Gregor     }
497b53e5483SLawrence Crowl   }
498b53e5483SLawrence Crowl 
499f0b11de2SDouglas Gregor   if (!ExportAsModule.empty()) {
500f0b11de2SDouglas Gregor     OS.indent(Indent + 2);
501f0b11de2SDouglas Gregor     OS << "export_as" << ExportAsModule << "\n";
502f0b11de2SDouglas Gregor   }
503f0b11de2SDouglas Gregor 
504eb90e830SDouglas Gregor   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
505de3ef502SDouglas Gregor        MI != MIEnd; ++MI)
5069d6448b1SBen Langmuir     // Print inferred subframework modules so that we don't need to re-infer
5079d6448b1SBen Langmuir     // them (requires expensive directory iteration + stat calls) when we build
5089d6448b1SBen Langmuir     // the module. Regular inferred submodules are OK, as we need to look at all
5099d6448b1SBen Langmuir     // those header files anyway.
5109d6448b1SBen Langmuir     if (!(*MI)->IsInferred || (*MI)->IsFramework)
511eb90e830SDouglas Gregor       (*MI)->print(OS, Indent + 2);
512de3ef502SDouglas Gregor 
51324bb923aSDouglas Gregor   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
51424bb923aSDouglas Gregor     OS.indent(Indent + 2);
5158c7c8352SDouglas Gregor     OS << "export ";
5168c7c8352SDouglas Gregor     if (Module *Restriction = Exports[I].getPointer()) {
5179565c75bSRichard Smith       OS << Restriction->getFullModuleName(true);
51824bb923aSDouglas Gregor       if (Exports[I].getInt())
51924bb923aSDouglas Gregor         OS << ".*";
5208c7c8352SDouglas Gregor     } else {
5218c7c8352SDouglas Gregor       OS << "*";
5228c7c8352SDouglas Gregor     }
52324bb923aSDouglas Gregor     OS << "\n";
52424bb923aSDouglas Gregor   }
52524bb923aSDouglas Gregor 
52624bb923aSDouglas Gregor   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
52724bb923aSDouglas Gregor     OS.indent(Indent + 2);
52824bb923aSDouglas Gregor     OS << "export ";
52924bb923aSDouglas Gregor     printModuleId(OS, UnresolvedExports[I].Id);
5307f96b391SDavide Italiano     if (UnresolvedExports[I].Wildcard)
5317f96b391SDavide Italiano       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
53224bb923aSDouglas Gregor     OS << "\n";
53324bb923aSDouglas Gregor   }
53424bb923aSDouglas Gregor 
535ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
536ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
537ba7f2f71SDaniel Jasper     OS << "use ";
5389565c75bSRichard Smith     OS << DirectUses[I]->getFullModuleName(true);
539ba7f2f71SDaniel Jasper     OS << "\n";
540ba7f2f71SDaniel Jasper   }
541ba7f2f71SDaniel Jasper 
542ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
543ba7f2f71SDaniel Jasper     OS.indent(Indent + 2);
544ba7f2f71SDaniel Jasper     OS << "use ";
545ba7f2f71SDaniel Jasper     printModuleId(OS, UnresolvedDirectUses[I]);
546ba7f2f71SDaniel Jasper     OS << "\n";
547ba7f2f71SDaniel Jasper   }
548ba7f2f71SDaniel Jasper 
5496ddfca91SDouglas Gregor   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
5506ddfca91SDouglas Gregor     OS.indent(Indent + 2);
5516ddfca91SDouglas Gregor     OS << "link ";
5526ddfca91SDouglas Gregor     if (LinkLibraries[I].IsFramework)
5536ddfca91SDouglas Gregor       OS << "framework ";
5546ddfca91SDouglas Gregor     OS << "\"";
5556ddfca91SDouglas Gregor     OS.write_escaped(LinkLibraries[I].Library);
5566ddfca91SDouglas Gregor     OS << "\"";
5576ddfca91SDouglas Gregor   }
5586ddfca91SDouglas Gregor 
559fb912657SDouglas Gregor   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
560fb912657SDouglas Gregor     OS.indent(Indent + 2);
561fb912657SDouglas Gregor     OS << "conflict ";
562fb912657SDouglas Gregor     printModuleId(OS, UnresolvedConflicts[I].Id);
563fb912657SDouglas Gregor     OS << ", \"";
564fb912657SDouglas Gregor     OS.write_escaped(UnresolvedConflicts[I].Message);
565fb912657SDouglas Gregor     OS << "\"\n";
566fb912657SDouglas Gregor   }
567fb912657SDouglas Gregor 
568fb912657SDouglas Gregor   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
569fb912657SDouglas Gregor     OS.indent(Indent + 2);
570fb912657SDouglas Gregor     OS << "conflict ";
5719565c75bSRichard Smith     OS << Conflicts[I].Other->getFullModuleName(true);
572fb912657SDouglas Gregor     OS << ", \"";
573fb912657SDouglas Gregor     OS.write_escaped(Conflicts[I].Message);
574fb912657SDouglas Gregor     OS << "\"\n";
575fb912657SDouglas Gregor   }
576fb912657SDouglas Gregor 
57773441091SDouglas Gregor   if (InferSubmodules) {
57873441091SDouglas Gregor     OS.indent(Indent + 2);
57973441091SDouglas Gregor     if (InferExplicitSubmodules)
58073441091SDouglas Gregor       OS << "explicit ";
58173441091SDouglas Gregor     OS << "module * {\n";
58273441091SDouglas Gregor     if (InferExportWildcard) {
58373441091SDouglas Gregor       OS.indent(Indent + 4);
58473441091SDouglas Gregor       OS << "export *\n";
58573441091SDouglas Gregor     }
58673441091SDouglas Gregor     OS.indent(Indent + 2);
58773441091SDouglas Gregor     OS << "}\n";
58873441091SDouglas Gregor   }
58973441091SDouglas Gregor 
590de3ef502SDouglas Gregor   OS.indent(Indent);
591de3ef502SDouglas Gregor   OS << "}\n";
592de3ef502SDouglas Gregor }
593de3ef502SDouglas Gregor 
594cdae941eSYaron Keren LLVM_DUMP_METHOD void Module::dump() const {
595de3ef502SDouglas Gregor   print(llvm::errs());
596de3ef502SDouglas Gregor }
597de3ef502SDouglas Gregor 
598a7e2cc68SRichard Smith void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
599a7e2cc68SRichard Smith                                   VisibleCallback Vis, ConflictCallback Cb) {
6006d25fdc4SBen Langmuir   assert(Loc.isValid() && "setVisible expects a valid import location");
601a7e2cc68SRichard Smith   if (isVisible(M))
602a7e2cc68SRichard Smith     return;
603de3ef502SDouglas Gregor 
604a7e2cc68SRichard Smith   ++Generation;
605a7e2cc68SRichard Smith 
606a7e2cc68SRichard Smith   struct Visiting {
607a7e2cc68SRichard Smith     Module *M;
608a7e2cc68SRichard Smith     Visiting *ExportedBy;
609a7e2cc68SRichard Smith   };
610a7e2cc68SRichard Smith 
611a7e2cc68SRichard Smith   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
612a7e2cc68SRichard Smith     // Nothing to do for a module that's already visible.
613a7e2cc68SRichard Smith     unsigned ID = V.M->getVisibilityID();
614a7e2cc68SRichard Smith     if (ImportLocs.size() <= ID)
615a7e2cc68SRichard Smith       ImportLocs.resize(ID + 1);
616a7e2cc68SRichard Smith     else if (ImportLocs[ID].isValid())
617a7e2cc68SRichard Smith       return;
618a7e2cc68SRichard Smith 
619a7e2cc68SRichard Smith     ImportLocs[ID] = Loc;
620a7e2cc68SRichard Smith     Vis(M);
621a7e2cc68SRichard Smith 
622a7e2cc68SRichard Smith     // Make any exported modules visible.
623a7e2cc68SRichard Smith     SmallVector<Module *, 16> Exports;
624a7e2cc68SRichard Smith     V.M->getExportedModules(Exports);
625841dbda3SRichard Smith     for (Module *E : Exports) {
626841dbda3SRichard Smith       // Don't recurse to unavailable submodules.
627841dbda3SRichard Smith       if (E->isAvailable())
628a7e2cc68SRichard Smith         VisitModule({E, &V});
629841dbda3SRichard Smith     }
630a7e2cc68SRichard Smith 
631a7e2cc68SRichard Smith     for (auto &C : V.M->Conflicts) {
632a7e2cc68SRichard Smith       if (isVisible(C.Other)) {
633a7e2cc68SRichard Smith         llvm::SmallVector<Module*, 8> Path;
634a7e2cc68SRichard Smith         for (Visiting *I = &V; I; I = I->ExportedBy)
635a7e2cc68SRichard Smith           Path.push_back(I->M);
636a7e2cc68SRichard Smith         Cb(Path, C.Other, C.Message);
637a7e2cc68SRichard Smith       }
638a7e2cc68SRichard Smith     }
639a7e2cc68SRichard Smith   };
640a7e2cc68SRichard Smith   VisitModule({M, nullptr});
641a7e2cc68SRichard Smith }
642