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