19a199699SDimitry Andric //===- Module.cpp - Describe a module -------------------------------------===//
2dff0c46cSDimitry Andric //
3dff0c46cSDimitry Andric //                     The LLVM Compiler Infrastructure
4dff0c46cSDimitry Andric //
5dff0c46cSDimitry Andric // This file is distributed under the University of Illinois Open Source
6dff0c46cSDimitry Andric // License. See LICENSE.TXT for details.
7dff0c46cSDimitry Andric //
8dff0c46cSDimitry Andric //===----------------------------------------------------------------------===//
9dff0c46cSDimitry Andric //
10dff0c46cSDimitry Andric // This file defines the Module class, which describes a module in the source
11dff0c46cSDimitry Andric // code.
12dff0c46cSDimitry Andric //
13dff0c46cSDimitry Andric //===----------------------------------------------------------------------===//
14f785676fSDimitry Andric 
15dff0c46cSDimitry Andric #include "clang/Basic/Module.h"
16edd7eaddSDimitry Andric #include "clang/Basic/CharInfo.h"
17dff0c46cSDimitry Andric #include "clang/Basic/FileManager.h"
18dff0c46cSDimitry Andric #include "clang/Basic/LangOptions.h"
199a199699SDimitry Andric #include "clang/Basic/SourceLocation.h"
20dff0c46cSDimitry Andric #include "clang/Basic/TargetInfo.h"
21139f7f9bSDimitry Andric #include "llvm/ADT/ArrayRef.h"
22dff0c46cSDimitry Andric #include "llvm/ADT/SmallVector.h"
239a199699SDimitry Andric #include "llvm/ADT/StringMap.h"
249a199699SDimitry Andric #include "llvm/ADT/StringRef.h"
25dff0c46cSDimitry Andric #include "llvm/ADT/StringSwitch.h"
269a199699SDimitry Andric #include "llvm/Support/Compiler.h"
27139f7f9bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
28139f7f9bSDimitry Andric #include "llvm/Support/raw_ostream.h"
299a199699SDimitry Andric #include <algorithm>
309a199699SDimitry Andric #include <cassert>
319a199699SDimitry Andric #include <functional>
329a199699SDimitry Andric #include <string>
339a199699SDimitry Andric #include <utility>
349a199699SDimitry Andric #include <vector>
35f785676fSDimitry Andric 
36dff0c46cSDimitry Andric using namespace clang;
37dff0c46cSDimitry Andric 
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)38dff0c46cSDimitry Andric Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
3933956c43SDimitry Andric                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
409a199699SDimitry Andric     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
419a199699SDimitry Andric       VisibilityID(VisibilityID), IsMissingRequirement(false),
429a199699SDimitry Andric       HasIncompatibleModuleFile(false), IsAvailable(true),
439a199699SDimitry Andric       IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
449a199699SDimitry Andric       IsSystem(false), IsExternC(false), IsInferred(false),
459a199699SDimitry Andric       InferSubmodules(false), InferExplicitSubmodules(false),
460623d748SDimitry Andric       InferExportWildcard(false), ConfigMacrosExhaustive(false),
474ba319b5SDimitry Andric       NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
484ba319b5SDimitry Andric       NameVisibility(Hidden) {
49dff0c46cSDimitry Andric   if (Parent) {
50dff0c46cSDimitry Andric     if (!Parent->isAvailable())
51dff0c46cSDimitry Andric       IsAvailable = false;
52dff0c46cSDimitry Andric     if (Parent->IsSystem)
53dff0c46cSDimitry Andric       IsSystem = true;
5459d1ed5bSDimitry Andric     if (Parent->IsExternC)
5559d1ed5bSDimitry Andric       IsExternC = true;
5644290647SDimitry Andric     if (Parent->NoUndeclaredIncludes)
5744290647SDimitry Andric       NoUndeclaredIncludes = true;
584ba319b5SDimitry Andric     if (Parent->ModuleMapIsPrivate)
594ba319b5SDimitry Andric       ModuleMapIsPrivate = true;
6059d1ed5bSDimitry Andric     IsMissingRequirement = Parent->IsMissingRequirement;
61dff0c46cSDimitry Andric 
62dff0c46cSDimitry Andric     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
63dff0c46cSDimitry Andric     Parent->SubModules.push_back(this);
64dff0c46cSDimitry Andric   }
65dff0c46cSDimitry Andric }
66dff0c46cSDimitry Andric 
~Module()67dff0c46cSDimitry Andric Module::~Module() {
68dff0c46cSDimitry Andric   for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
69dff0c46cSDimitry Andric        I != IEnd; ++I) {
70dff0c46cSDimitry Andric     delete *I;
71dff0c46cSDimitry Andric   }
72dff0c46cSDimitry Andric }
73dff0c46cSDimitry Andric 
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)74*b5893f02SDimitry Andric static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
75*b5893f02SDimitry Andric   StringRef Platform = Target.getPlatformName();
76*b5893f02SDimitry Andric   StringRef Env = Target.getTriple().getEnvironmentName();
77*b5893f02SDimitry Andric 
78*b5893f02SDimitry Andric   // Attempt to match platform and environment.
79*b5893f02SDimitry Andric   if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
80*b5893f02SDimitry Andric       Env == Feature)
81*b5893f02SDimitry Andric     return true;
82*b5893f02SDimitry Andric 
83*b5893f02SDimitry Andric   auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
84*b5893f02SDimitry Andric     auto Pos = LHS.find("-");
85*b5893f02SDimitry Andric     if (Pos == StringRef::npos)
86*b5893f02SDimitry Andric       return false;
87*b5893f02SDimitry Andric     SmallString<128> NewLHS = LHS.slice(0, Pos);
88*b5893f02SDimitry Andric     NewLHS += LHS.slice(Pos+1, LHS.size());
89*b5893f02SDimitry Andric     return NewLHS == RHS;
90*b5893f02SDimitry Andric   };
91*b5893f02SDimitry Andric 
92*b5893f02SDimitry Andric   SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
93*b5893f02SDimitry Andric   // Darwin has different but equivalent variants for simulators, example:
94*b5893f02SDimitry Andric   //   1. x86_64-apple-ios-simulator
95*b5893f02SDimitry Andric   //   2. x86_64-apple-iossimulator
96*b5893f02SDimitry Andric   // where both are valid examples of the same platform+environment but in the
97*b5893f02SDimitry Andric   // variant (2) the simulator is hardcoded as part of the platform name. Both
98*b5893f02SDimitry Andric   // forms above should match for "iossimulator" requirement.
99*b5893f02SDimitry Andric   if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
100*b5893f02SDimitry Andric     return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
101*b5893f02SDimitry Andric 
102*b5893f02SDimitry Andric   return PlatformEnv == Feature;
103*b5893f02SDimitry Andric }
104*b5893f02SDimitry Andric 
1054ba319b5SDimitry Andric /// Determine whether a translation unit built using the current
106dff0c46cSDimitry Andric /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)107dff0c46cSDimitry Andric static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
108dff0c46cSDimitry Andric                        const TargetInfo &Target) {
10933956c43SDimitry Andric   bool HasFeature = llvm::StringSwitch<bool>(Feature)
110dff0c46cSDimitry Andric                         .Case("altivec", LangOpts.AltiVec)
111dff0c46cSDimitry Andric                         .Case("blocks", LangOpts.Blocks)
112302affcbSDimitry Andric                         .Case("coroutines", LangOpts.CoroutinesTS)
113dff0c46cSDimitry Andric                         .Case("cplusplus", LangOpts.CPlusPlus)
114139f7f9bSDimitry Andric                         .Case("cplusplus11", LangOpts.CPlusPlus11)
1154ba319b5SDimitry Andric                         .Case("cplusplus14", LangOpts.CPlusPlus14)
1164ba319b5SDimitry Andric                         .Case("cplusplus17", LangOpts.CPlusPlus17)
1174ba319b5SDimitry Andric                         .Case("c99", LangOpts.C99)
1184ba319b5SDimitry Andric                         .Case("c11", LangOpts.C11)
1194ba319b5SDimitry Andric                         .Case("c17", LangOpts.C17)
12044290647SDimitry Andric                         .Case("freestanding", LangOpts.Freestanding)
12144290647SDimitry Andric                         .Case("gnuinlineasm", LangOpts.GNUAsm)
122*b5893f02SDimitry Andric                         .Case("objc", LangOpts.ObjC)
123dff0c46cSDimitry Andric                         .Case("objc_arc", LangOpts.ObjCAutoRefCount)
124dff0c46cSDimitry Andric                         .Case("opencl", LangOpts.OpenCL)
125dff0c46cSDimitry Andric                         .Case("tls", Target.isTLSSupported())
126b6c25e0eSDimitry Andric                         .Case("zvector", LangOpts.ZVector)
127*b5893f02SDimitry Andric                         .Default(Target.hasFeature(Feature) ||
128*b5893f02SDimitry Andric                                  isPlatformEnvironment(Target, Feature));
12933956c43SDimitry Andric   if (!HasFeature)
13033956c43SDimitry Andric     HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
13133956c43SDimitry Andric                            LangOpts.ModuleFeatures.end(),
13233956c43SDimitry Andric                            Feature) != LangOpts.ModuleFeatures.end();
13333956c43SDimitry Andric   return HasFeature;
134dff0c46cSDimitry Andric }
135dff0c46cSDimitry Andric 
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const13639d628a0SDimitry Andric bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
13739d628a0SDimitry Andric                          Requirement &Req,
1384ba319b5SDimitry Andric                          UnresolvedHeaderDirective &MissingHeader,
1394ba319b5SDimitry Andric                          Module *&ShadowingModule) const {
140dff0c46cSDimitry Andric   if (IsAvailable)
141dff0c46cSDimitry Andric     return true;
142dff0c46cSDimitry Andric 
143dff0c46cSDimitry Andric   for (const Module *Current = this; Current; Current = Current->Parent) {
1444ba319b5SDimitry Andric     if (Current->ShadowingModule) {
1454ba319b5SDimitry Andric       ShadowingModule = Current->ShadowingModule;
1464ba319b5SDimitry Andric       return false;
1474ba319b5SDimitry Andric     }
148f785676fSDimitry Andric     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
149f785676fSDimitry Andric       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
150f785676fSDimitry Andric               Current->Requirements[I].second) {
151f785676fSDimitry Andric         Req = Current->Requirements[I];
152dff0c46cSDimitry Andric         return false;
153dff0c46cSDimitry Andric       }
154dff0c46cSDimitry Andric     }
155875ed548SDimitry Andric     if (!Current->MissingHeaders.empty()) {
156875ed548SDimitry Andric       MissingHeader = Current->MissingHeaders.front();
157875ed548SDimitry Andric       return false;
158875ed548SDimitry Andric     }
159dff0c46cSDimitry Andric   }
160dff0c46cSDimitry Andric 
161dff0c46cSDimitry Andric   llvm_unreachable("could not find a reason why module is unavailable");
162dff0c46cSDimitry Andric }
163dff0c46cSDimitry Andric 
isSubModuleOf(const Module * Other) const16459d1ed5bSDimitry Andric bool Module::isSubModuleOf(const Module *Other) const {
165dff0c46cSDimitry Andric   const Module *This = this;
166dff0c46cSDimitry Andric   do {
167dff0c46cSDimitry Andric     if (This == Other)
168dff0c46cSDimitry Andric       return true;
169dff0c46cSDimitry Andric 
170dff0c46cSDimitry Andric     This = This->Parent;
171dff0c46cSDimitry Andric   } while (This);
172dff0c46cSDimitry Andric 
173dff0c46cSDimitry Andric   return false;
174dff0c46cSDimitry Andric }
175dff0c46cSDimitry Andric 
getTopLevelModule() const176dff0c46cSDimitry Andric const Module *Module::getTopLevelModule() const {
177dff0c46cSDimitry Andric   const Module *Result = this;
178dff0c46cSDimitry Andric   while (Result->Parent)
179dff0c46cSDimitry Andric     Result = Result->Parent;
180dff0c46cSDimitry Andric 
181dff0c46cSDimitry Andric   return Result;
182dff0c46cSDimitry Andric }
183dff0c46cSDimitry Andric 
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)184edd7eaddSDimitry Andric static StringRef getModuleNameFromComponent(
185edd7eaddSDimitry Andric     const std::pair<std::string, SourceLocation> &IdComponent) {
186edd7eaddSDimitry Andric   return IdComponent.first;
187edd7eaddSDimitry Andric }
1889a199699SDimitry Andric 
getModuleNameFromComponent(StringRef R)189edd7eaddSDimitry Andric static StringRef getModuleNameFromComponent(StringRef R) { return R; }
190edd7eaddSDimitry Andric 
191edd7eaddSDimitry Andric template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)192edd7eaddSDimitry Andric static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
193edd7eaddSDimitry Andric                           bool AllowStringLiterals = true) {
194edd7eaddSDimitry Andric   for (InputIter It = Begin; It != End; ++It) {
195edd7eaddSDimitry Andric     if (It != Begin)
196edd7eaddSDimitry Andric       OS << ".";
197edd7eaddSDimitry Andric 
198edd7eaddSDimitry Andric     StringRef Name = getModuleNameFromComponent(*It);
199edd7eaddSDimitry Andric     if (!AllowStringLiterals || isValidIdentifier(Name))
200edd7eaddSDimitry Andric       OS << Name;
201edd7eaddSDimitry Andric     else {
202edd7eaddSDimitry Andric       OS << '"';
203edd7eaddSDimitry Andric       OS.write_escaped(Name);
204edd7eaddSDimitry Andric       OS << '"';
205edd7eaddSDimitry Andric     }
206edd7eaddSDimitry Andric   }
207edd7eaddSDimitry Andric }
208edd7eaddSDimitry Andric 
209edd7eaddSDimitry Andric template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)210edd7eaddSDimitry Andric static void printModuleId(raw_ostream &OS, const Container &C) {
211edd7eaddSDimitry Andric   return printModuleId(OS, C.begin(), C.end());
212edd7eaddSDimitry Andric }
213edd7eaddSDimitry Andric 
getFullModuleName(bool AllowStringLiterals) const214edd7eaddSDimitry Andric std::string Module::getFullModuleName(bool AllowStringLiterals) const {
215139f7f9bSDimitry Andric   SmallVector<StringRef, 2> Names;
216dff0c46cSDimitry Andric 
217dff0c46cSDimitry Andric   // Build up the set of module names (from innermost to outermost).
218dff0c46cSDimitry Andric   for (const Module *M = this; M; M = M->Parent)
219dff0c46cSDimitry Andric     Names.push_back(M->Name);
220dff0c46cSDimitry Andric 
221dff0c46cSDimitry Andric   std::string Result;
222dff0c46cSDimitry Andric 
223edd7eaddSDimitry Andric   llvm::raw_string_ostream Out(Result);
224edd7eaddSDimitry Andric   printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
225edd7eaddSDimitry Andric   Out.flush();
226dff0c46cSDimitry Andric 
227dff0c46cSDimitry Andric   return Result;
228dff0c46cSDimitry Andric }
229dff0c46cSDimitry Andric 
fullModuleNameIs(ArrayRef<StringRef> nameParts) const2300623d748SDimitry Andric bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
2310623d748SDimitry Andric   for (const Module *M = this; M; M = M->Parent) {
2320623d748SDimitry Andric     if (nameParts.empty() || M->Name != nameParts.back())
2330623d748SDimitry Andric       return false;
2340623d748SDimitry Andric     nameParts = nameParts.drop_back();
2350623d748SDimitry Andric   }
2360623d748SDimitry Andric   return nameParts.empty();
2370623d748SDimitry Andric }
2380623d748SDimitry Andric 
getUmbrellaDir() const23933956c43SDimitry Andric Module::DirectoryName Module::getUmbrellaDir() const {
24033956c43SDimitry Andric   if (Header U = getUmbrellaHeader())
24133956c43SDimitry Andric     return {"", U.Entry->getDir()};
242dff0c46cSDimitry Andric 
24333956c43SDimitry Andric   return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
244dff0c46cSDimitry Andric }
245dff0c46cSDimitry Andric 
getTopHeaders(FileManager & FileMgr)246139f7f9bSDimitry Andric ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
247139f7f9bSDimitry Andric   if (!TopHeaderNames.empty()) {
248139f7f9bSDimitry Andric     for (std::vector<std::string>::iterator
249139f7f9bSDimitry Andric            I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
250139f7f9bSDimitry Andric       if (const FileEntry *FE = FileMgr.getFile(*I))
251139f7f9bSDimitry Andric         TopHeaders.insert(FE);
252139f7f9bSDimitry Andric     }
253139f7f9bSDimitry Andric     TopHeaderNames.clear();
254139f7f9bSDimitry Andric   }
255139f7f9bSDimitry Andric 
256139f7f9bSDimitry Andric   return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
257139f7f9bSDimitry Andric }
258139f7f9bSDimitry Andric 
directlyUses(const Module * Requested) const25933956c43SDimitry Andric bool Module::directlyUses(const Module *Requested) const {
26033956c43SDimitry Andric   auto *Top = getTopLevelModule();
26133956c43SDimitry Andric 
26233956c43SDimitry Andric   // A top-level module implicitly uses itself.
26333956c43SDimitry Andric   if (Requested->isSubModuleOf(Top))
26433956c43SDimitry Andric     return true;
26533956c43SDimitry Andric 
26633956c43SDimitry Andric   for (auto *Use : Top->DirectUses)
26733956c43SDimitry Andric     if (Requested->isSubModuleOf(Use))
26833956c43SDimitry Andric       return true;
26944290647SDimitry Andric 
27044290647SDimitry Andric   // Anyone is allowed to use our builtin stddef.h and its accompanying module.
27144290647SDimitry Andric   if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
27244290647SDimitry Andric     return true;
27344290647SDimitry Andric 
27433956c43SDimitry Andric   return false;
27533956c43SDimitry Andric }
27633956c43SDimitry Andric 
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)277f785676fSDimitry Andric void Module::addRequirement(StringRef Feature, bool RequiredState,
278f785676fSDimitry Andric                             const LangOptions &LangOpts,
279dff0c46cSDimitry Andric                             const TargetInfo &Target) {
280f785676fSDimitry Andric   Requirements.push_back(Requirement(Feature, RequiredState));
281dff0c46cSDimitry Andric 
282dff0c46cSDimitry Andric   // If this feature is currently available, we're done.
283f785676fSDimitry Andric   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
284dff0c46cSDimitry Andric     return;
285dff0c46cSDimitry Andric 
28659d1ed5bSDimitry Andric   markUnavailable(/*MissingRequirement*/true);
28759d1ed5bSDimitry Andric }
28859d1ed5bSDimitry Andric 
markUnavailable(bool MissingRequirement)28959d1ed5bSDimitry Andric void Module::markUnavailable(bool MissingRequirement) {
290875ed548SDimitry Andric   auto needUpdate = [MissingRequirement](Module *M) {
291875ed548SDimitry Andric     return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
292875ed548SDimitry Andric   };
293875ed548SDimitry Andric 
294875ed548SDimitry Andric   if (!needUpdate(this))
295dff0c46cSDimitry Andric     return;
296dff0c46cSDimitry Andric 
297139f7f9bSDimitry Andric   SmallVector<Module *, 2> Stack;
298dff0c46cSDimitry Andric   Stack.push_back(this);
299dff0c46cSDimitry Andric   while (!Stack.empty()) {
300dff0c46cSDimitry Andric     Module *Current = Stack.back();
301dff0c46cSDimitry Andric     Stack.pop_back();
302dff0c46cSDimitry Andric 
303875ed548SDimitry Andric     if (!needUpdate(Current))
304dff0c46cSDimitry Andric       continue;
305dff0c46cSDimitry Andric 
306dff0c46cSDimitry Andric     Current->IsAvailable = false;
30759d1ed5bSDimitry Andric     Current->IsMissingRequirement |= MissingRequirement;
308dff0c46cSDimitry Andric     for (submodule_iterator Sub = Current->submodule_begin(),
309dff0c46cSDimitry Andric                          SubEnd = Current->submodule_end();
310dff0c46cSDimitry Andric          Sub != SubEnd; ++Sub) {
311875ed548SDimitry Andric       if (needUpdate(*Sub))
312dff0c46cSDimitry Andric         Stack.push_back(*Sub);
313dff0c46cSDimitry Andric     }
314dff0c46cSDimitry Andric   }
315dff0c46cSDimitry Andric }
316dff0c46cSDimitry Andric 
findSubmodule(StringRef Name) const317dff0c46cSDimitry Andric Module *Module::findSubmodule(StringRef Name) const {
318dff0c46cSDimitry Andric   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
319dff0c46cSDimitry Andric   if (Pos == SubModuleIndex.end())
32059d1ed5bSDimitry Andric     return nullptr;
321dff0c46cSDimitry Andric 
322dff0c46cSDimitry Andric   return SubModules[Pos->getValue()];
323dff0c46cSDimitry Andric }
324dff0c46cSDimitry Andric 
getExportedModules(SmallVectorImpl<Module * > & Exported) const325139f7f9bSDimitry Andric void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
326f785676fSDimitry Andric   // All non-explicit submodules are exported.
327f785676fSDimitry Andric   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
328f785676fSDimitry Andric                                              E = SubModules.end();
329f785676fSDimitry Andric        I != E; ++I) {
330f785676fSDimitry Andric     Module *Mod = *I;
331f785676fSDimitry Andric     if (!Mod->IsExplicit)
332f785676fSDimitry Andric       Exported.push_back(Mod);
333f785676fSDimitry Andric   }
334f785676fSDimitry Andric 
335f785676fSDimitry Andric   // Find re-exported modules by filtering the list of imported modules.
336139f7f9bSDimitry Andric   bool AnyWildcard = false;
337139f7f9bSDimitry Andric   bool UnrestrictedWildcard = false;
338139f7f9bSDimitry Andric   SmallVector<Module *, 4> WildcardRestrictions;
339139f7f9bSDimitry Andric   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
340139f7f9bSDimitry Andric     Module *Mod = Exports[I].getPointer();
341139f7f9bSDimitry Andric     if (!Exports[I].getInt()) {
342139f7f9bSDimitry Andric       // Export a named module directly; no wildcards involved.
343139f7f9bSDimitry Andric       Exported.push_back(Mod);
344139f7f9bSDimitry Andric 
345139f7f9bSDimitry Andric       continue;
346139f7f9bSDimitry Andric     }
347139f7f9bSDimitry Andric 
348139f7f9bSDimitry Andric     // Wildcard export: export all of the imported modules that match
349139f7f9bSDimitry Andric     // the given pattern.
350139f7f9bSDimitry Andric     AnyWildcard = true;
351139f7f9bSDimitry Andric     if (UnrestrictedWildcard)
352139f7f9bSDimitry Andric       continue;
353139f7f9bSDimitry Andric 
354139f7f9bSDimitry Andric     if (Module *Restriction = Exports[I].getPointer())
355139f7f9bSDimitry Andric       WildcardRestrictions.push_back(Restriction);
356139f7f9bSDimitry Andric     else {
357139f7f9bSDimitry Andric       WildcardRestrictions.clear();
358139f7f9bSDimitry Andric       UnrestrictedWildcard = true;
359139f7f9bSDimitry Andric     }
360139f7f9bSDimitry Andric   }
361139f7f9bSDimitry Andric 
362139f7f9bSDimitry Andric   // If there were any wildcards, push any imported modules that were
363139f7f9bSDimitry Andric   // re-exported by the wildcard restriction.
364139f7f9bSDimitry Andric   if (!AnyWildcard)
365139f7f9bSDimitry Andric     return;
366139f7f9bSDimitry Andric 
367139f7f9bSDimitry Andric   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
368139f7f9bSDimitry Andric     Module *Mod = Imports[I];
369139f7f9bSDimitry Andric     bool Acceptable = UnrestrictedWildcard;
370139f7f9bSDimitry Andric     if (!Acceptable) {
371139f7f9bSDimitry Andric       // Check whether this module meets one of the restrictions.
372139f7f9bSDimitry Andric       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
373139f7f9bSDimitry Andric         Module *Restriction = WildcardRestrictions[R];
374139f7f9bSDimitry Andric         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
375139f7f9bSDimitry Andric           Acceptable = true;
376139f7f9bSDimitry Andric           break;
377139f7f9bSDimitry Andric         }
378139f7f9bSDimitry Andric       }
379139f7f9bSDimitry Andric     }
380139f7f9bSDimitry Andric 
381139f7f9bSDimitry Andric     if (!Acceptable)
382139f7f9bSDimitry Andric       continue;
383139f7f9bSDimitry Andric 
384139f7f9bSDimitry Andric     Exported.push_back(Mod);
385139f7f9bSDimitry Andric   }
386139f7f9bSDimitry Andric }
387139f7f9bSDimitry Andric 
buildVisibleModulesCache() const388f785676fSDimitry Andric void Module::buildVisibleModulesCache() const {
389f785676fSDimitry Andric   assert(VisibleModulesCache.empty() && "cache does not need building");
390f785676fSDimitry Andric 
391f785676fSDimitry Andric   // This module is visible to itself.
392f785676fSDimitry Andric   VisibleModulesCache.insert(this);
393f785676fSDimitry Andric 
394f785676fSDimitry Andric   // Every imported module is visible.
395f785676fSDimitry Andric   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
396f785676fSDimitry Andric   while (!Stack.empty()) {
397f785676fSDimitry Andric     Module *CurrModule = Stack.pop_back_val();
398f785676fSDimitry Andric 
399f785676fSDimitry Andric     // Every module transitively exported by an imported module is visible.
400f785676fSDimitry Andric     if (VisibleModulesCache.insert(CurrModule).second)
401f785676fSDimitry Andric       CurrModule->getExportedModules(Stack);
402f785676fSDimitry Andric   }
403f785676fSDimitry Andric }
404f785676fSDimitry Andric 
print(raw_ostream & OS,unsigned Indent) const405139f7f9bSDimitry Andric void Module::print(raw_ostream &OS, unsigned Indent) const {
406dff0c46cSDimitry Andric   OS.indent(Indent);
407dff0c46cSDimitry Andric   if (IsFramework)
408dff0c46cSDimitry Andric     OS << "framework ";
409dff0c46cSDimitry Andric   if (IsExplicit)
410dff0c46cSDimitry Andric     OS << "explicit ";
411edd7eaddSDimitry Andric   OS << "module ";
412edd7eaddSDimitry Andric   printModuleId(OS, &Name, &Name + 1);
413dff0c46cSDimitry Andric 
41439d628a0SDimitry Andric   if (IsSystem || IsExternC) {
415dff0c46cSDimitry Andric     OS.indent(Indent + 2);
41639d628a0SDimitry Andric     if (IsSystem)
417dff0c46cSDimitry Andric       OS << " [system]";
41839d628a0SDimitry Andric     if (IsExternC)
41939d628a0SDimitry Andric       OS << " [extern_c]";
420dff0c46cSDimitry Andric   }
421dff0c46cSDimitry Andric 
422dff0c46cSDimitry Andric   OS << " {\n";
423dff0c46cSDimitry Andric 
424f785676fSDimitry Andric   if (!Requirements.empty()) {
425dff0c46cSDimitry Andric     OS.indent(Indent + 2);
426dff0c46cSDimitry Andric     OS << "requires ";
427f785676fSDimitry Andric     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
428dff0c46cSDimitry Andric       if (I)
429dff0c46cSDimitry Andric         OS << ", ";
430f785676fSDimitry Andric       if (!Requirements[I].second)
431f785676fSDimitry Andric         OS << "!";
432f785676fSDimitry Andric       OS << Requirements[I].first;
433dff0c46cSDimitry Andric     }
434dff0c46cSDimitry Andric     OS << "\n";
435dff0c46cSDimitry Andric   }
436dff0c46cSDimitry Andric 
43733956c43SDimitry Andric   if (Header H = getUmbrellaHeader()) {
438dff0c46cSDimitry Andric     OS.indent(Indent + 2);
439dff0c46cSDimitry Andric     OS << "umbrella header \"";
44033956c43SDimitry Andric     OS.write_escaped(H.NameAsWritten);
441dff0c46cSDimitry Andric     OS << "\"\n";
44233956c43SDimitry Andric   } else if (DirectoryName D = getUmbrellaDir()) {
443dff0c46cSDimitry Andric     OS.indent(Indent + 2);
444dff0c46cSDimitry Andric     OS << "umbrella \"";
44533956c43SDimitry Andric     OS.write_escaped(D.NameAsWritten);
446dff0c46cSDimitry Andric     OS << "\"\n";
447dff0c46cSDimitry Andric   }
448dff0c46cSDimitry Andric 
449139f7f9bSDimitry Andric   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
450139f7f9bSDimitry Andric     OS.indent(Indent + 2);
451139f7f9bSDimitry Andric     OS << "config_macros ";
452139f7f9bSDimitry Andric     if (ConfigMacrosExhaustive)
453139f7f9bSDimitry Andric       OS << "[exhaustive]";
454139f7f9bSDimitry Andric     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
455139f7f9bSDimitry Andric       if (I)
456139f7f9bSDimitry Andric         OS << ", ";
457139f7f9bSDimitry Andric       OS << ConfigMacros[I];
458139f7f9bSDimitry Andric     }
459139f7f9bSDimitry Andric     OS << "\n";
460139f7f9bSDimitry Andric   }
461139f7f9bSDimitry Andric 
46239d628a0SDimitry Andric   struct {
46339d628a0SDimitry Andric     StringRef Prefix;
46439d628a0SDimitry Andric     HeaderKind Kind;
46539d628a0SDimitry Andric   } Kinds[] = {{"", HK_Normal},
46639d628a0SDimitry Andric                {"textual ", HK_Textual},
46739d628a0SDimitry Andric                {"private ", HK_Private},
46839d628a0SDimitry Andric                {"private textual ", HK_PrivateTextual},
46939d628a0SDimitry Andric                {"exclude ", HK_Excluded}};
47039d628a0SDimitry Andric 
47139d628a0SDimitry Andric   for (auto &K : Kinds) {
4726d97bb29SDimitry Andric     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
47339d628a0SDimitry Andric     for (auto &H : Headers[K.Kind]) {
474dff0c46cSDimitry Andric       OS.indent(Indent + 2);
47539d628a0SDimitry Andric       OS << K.Prefix << "header \"";
47639d628a0SDimitry Andric       OS.write_escaped(H.NameAsWritten);
4776d97bb29SDimitry Andric       OS << "\" { size " << H.Entry->getSize()
4786d97bb29SDimitry Andric          << " mtime " << H.Entry->getModificationTime() << " }\n";
4796d97bb29SDimitry Andric     }
4806d97bb29SDimitry Andric   }
4816d97bb29SDimitry Andric   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
4826d97bb29SDimitry Andric     for (auto &U : *Unresolved) {
4836d97bb29SDimitry Andric       OS.indent(Indent + 2);
4846d97bb29SDimitry Andric       OS << Kinds[U.Kind].Prefix << "header \"";
4856d97bb29SDimitry Andric       OS.write_escaped(U.FileName);
4866d97bb29SDimitry Andric       OS << "\"";
4876d97bb29SDimitry Andric       if (U.Size || U.ModTime) {
4886d97bb29SDimitry Andric         OS << " {";
4896d97bb29SDimitry Andric         if (U.Size)
4906d97bb29SDimitry Andric           OS << " size " << *U.Size;
4916d97bb29SDimitry Andric         if (U.ModTime)
4926d97bb29SDimitry Andric           OS << " mtime " << *U.ModTime;
4936d97bb29SDimitry Andric         OS << " }";
4946d97bb29SDimitry Andric       }
4956d97bb29SDimitry Andric       OS << "\n";
496dff0c46cSDimitry Andric     }
497f785676fSDimitry Andric   }
498f785676fSDimitry Andric 
4999a199699SDimitry Andric   if (!ExportAsModule.empty()) {
5009a199699SDimitry Andric     OS.indent(Indent + 2);
5019a199699SDimitry Andric     OS << "export_as" << ExportAsModule << "\n";
5029a199699SDimitry Andric   }
5039a199699SDimitry Andric 
504dff0c46cSDimitry Andric   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
505dff0c46cSDimitry Andric        MI != MIEnd; ++MI)
50639d628a0SDimitry Andric     // Print inferred subframework modules so that we don't need to re-infer
50739d628a0SDimitry Andric     // them (requires expensive directory iteration + stat calls) when we build
50839d628a0SDimitry Andric     // the module. Regular inferred submodules are OK, as we need to look at all
50939d628a0SDimitry Andric     // those header files anyway.
51039d628a0SDimitry Andric     if (!(*MI)->IsInferred || (*MI)->IsFramework)
511dff0c46cSDimitry Andric       (*MI)->print(OS, Indent + 2);
512dff0c46cSDimitry Andric 
513dff0c46cSDimitry Andric   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
514dff0c46cSDimitry Andric     OS.indent(Indent + 2);
515dff0c46cSDimitry Andric     OS << "export ";
516dff0c46cSDimitry Andric     if (Module *Restriction = Exports[I].getPointer()) {
517edd7eaddSDimitry Andric       OS << Restriction->getFullModuleName(true);
518dff0c46cSDimitry Andric       if (Exports[I].getInt())
519dff0c46cSDimitry Andric         OS << ".*";
520dff0c46cSDimitry Andric     } else {
521dff0c46cSDimitry Andric       OS << "*";
522dff0c46cSDimitry Andric     }
523dff0c46cSDimitry Andric     OS << "\n";
524dff0c46cSDimitry Andric   }
525dff0c46cSDimitry Andric 
526dff0c46cSDimitry Andric   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
527dff0c46cSDimitry Andric     OS.indent(Indent + 2);
528dff0c46cSDimitry Andric     OS << "export ";
529dff0c46cSDimitry Andric     printModuleId(OS, UnresolvedExports[I].Id);
530e7145dcbSDimitry Andric     if (UnresolvedExports[I].Wildcard)
531e7145dcbSDimitry Andric       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
532dff0c46cSDimitry Andric     OS << "\n";
533dff0c46cSDimitry Andric   }
534dff0c46cSDimitry Andric 
535f785676fSDimitry Andric   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
536f785676fSDimitry Andric     OS.indent(Indent + 2);
537f785676fSDimitry Andric     OS << "use ";
538edd7eaddSDimitry Andric     OS << DirectUses[I]->getFullModuleName(true);
539f785676fSDimitry Andric     OS << "\n";
540f785676fSDimitry Andric   }
541f785676fSDimitry Andric 
542f785676fSDimitry Andric   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
543f785676fSDimitry Andric     OS.indent(Indent + 2);
544f785676fSDimitry Andric     OS << "use ";
545f785676fSDimitry Andric     printModuleId(OS, UnresolvedDirectUses[I]);
546f785676fSDimitry Andric     OS << "\n";
547f785676fSDimitry Andric   }
548f785676fSDimitry Andric 
549139f7f9bSDimitry Andric   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
550139f7f9bSDimitry Andric     OS.indent(Indent + 2);
551139f7f9bSDimitry Andric     OS << "link ";
552139f7f9bSDimitry Andric     if (LinkLibraries[I].IsFramework)
553139f7f9bSDimitry Andric       OS << "framework ";
554139f7f9bSDimitry Andric     OS << "\"";
555139f7f9bSDimitry Andric     OS.write_escaped(LinkLibraries[I].Library);
556139f7f9bSDimitry Andric     OS << "\"";
557139f7f9bSDimitry Andric   }
558139f7f9bSDimitry Andric 
559139f7f9bSDimitry Andric   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
560139f7f9bSDimitry Andric     OS.indent(Indent + 2);
561139f7f9bSDimitry Andric     OS << "conflict ";
562139f7f9bSDimitry Andric     printModuleId(OS, UnresolvedConflicts[I].Id);
563139f7f9bSDimitry Andric     OS << ", \"";
564139f7f9bSDimitry Andric     OS.write_escaped(UnresolvedConflicts[I].Message);
565139f7f9bSDimitry Andric     OS << "\"\n";
566139f7f9bSDimitry Andric   }
567139f7f9bSDimitry Andric 
568139f7f9bSDimitry Andric   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
569139f7f9bSDimitry Andric     OS.indent(Indent + 2);
570139f7f9bSDimitry Andric     OS << "conflict ";
571edd7eaddSDimitry Andric     OS << Conflicts[I].Other->getFullModuleName(true);
572139f7f9bSDimitry Andric     OS << ", \"";
573139f7f9bSDimitry Andric     OS.write_escaped(Conflicts[I].Message);
574139f7f9bSDimitry Andric     OS << "\"\n";
575139f7f9bSDimitry Andric   }
576139f7f9bSDimitry Andric 
577dff0c46cSDimitry Andric   if (InferSubmodules) {
578dff0c46cSDimitry Andric     OS.indent(Indent + 2);
579dff0c46cSDimitry Andric     if (InferExplicitSubmodules)
580dff0c46cSDimitry Andric       OS << "explicit ";
581dff0c46cSDimitry Andric     OS << "module * {\n";
582dff0c46cSDimitry Andric     if (InferExportWildcard) {
583dff0c46cSDimitry Andric       OS.indent(Indent + 4);
584dff0c46cSDimitry Andric       OS << "export *\n";
585dff0c46cSDimitry Andric     }
586dff0c46cSDimitry Andric     OS.indent(Indent + 2);
587dff0c46cSDimitry Andric     OS << "}\n";
588dff0c46cSDimitry Andric   }
589dff0c46cSDimitry Andric 
590dff0c46cSDimitry Andric   OS.indent(Indent);
591dff0c46cSDimitry Andric   OS << "}\n";
592dff0c46cSDimitry Andric }
593dff0c46cSDimitry Andric 
dump() const594e7145dcbSDimitry Andric LLVM_DUMP_METHOD void Module::dump() const {
595dff0c46cSDimitry Andric   print(llvm::errs());
596dff0c46cSDimitry Andric }
597dff0c46cSDimitry Andric 
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)59833956c43SDimitry Andric void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
59933956c43SDimitry Andric                                   VisibleCallback Vis, ConflictCallback Cb) {
600e7145dcbSDimitry Andric   assert(Loc.isValid() && "setVisible expects a valid import location");
60133956c43SDimitry Andric   if (isVisible(M))
60233956c43SDimitry Andric     return;
603dff0c46cSDimitry Andric 
60433956c43SDimitry Andric   ++Generation;
60533956c43SDimitry Andric 
60633956c43SDimitry Andric   struct Visiting {
60733956c43SDimitry Andric     Module *M;
60833956c43SDimitry Andric     Visiting *ExportedBy;
60933956c43SDimitry Andric   };
61033956c43SDimitry Andric 
61133956c43SDimitry Andric   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
61233956c43SDimitry Andric     // Nothing to do for a module that's already visible.
61333956c43SDimitry Andric     unsigned ID = V.M->getVisibilityID();
61433956c43SDimitry Andric     if (ImportLocs.size() <= ID)
61533956c43SDimitry Andric       ImportLocs.resize(ID + 1);
61633956c43SDimitry Andric     else if (ImportLocs[ID].isValid())
61733956c43SDimitry Andric       return;
61833956c43SDimitry Andric 
61933956c43SDimitry Andric     ImportLocs[ID] = Loc;
62033956c43SDimitry Andric     Vis(M);
62133956c43SDimitry Andric 
62233956c43SDimitry Andric     // Make any exported modules visible.
62333956c43SDimitry Andric     SmallVector<Module *, 16> Exports;
62433956c43SDimitry Andric     V.M->getExportedModules(Exports);
625*b5893f02SDimitry Andric     for (Module *E : Exports) {
626*b5893f02SDimitry Andric       // Don't recurse to unavailable submodules.
627*b5893f02SDimitry Andric       if (E->isAvailable())
62833956c43SDimitry Andric         VisitModule({E, &V});
629*b5893f02SDimitry Andric     }
63033956c43SDimitry Andric 
63133956c43SDimitry Andric     for (auto &C : V.M->Conflicts) {
63233956c43SDimitry Andric       if (isVisible(C.Other)) {
63333956c43SDimitry Andric         llvm::SmallVector<Module*, 8> Path;
63433956c43SDimitry Andric         for (Visiting *I = &V; I; I = I->ExportedBy)
63533956c43SDimitry Andric           Path.push_back(I->M);
63633956c43SDimitry Andric         Cb(Path, C.Other, C.Message);
63733956c43SDimitry Andric       }
63833956c43SDimitry Andric     }
63933956c43SDimitry Andric   };
64033956c43SDimitry Andric   VisitModule({M, nullptr});
64133956c43SDimitry Andric }
642