1e5dd7070Spatrick //===- Module.cpp - Describe a module -------------------------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file defines the Module class, which describes a module in the source
10e5dd7070Spatrick // code.
11e5dd7070Spatrick //
12e5dd7070Spatrick //===----------------------------------------------------------------------===//
13e5dd7070Spatrick
14e5dd7070Spatrick #include "clang/Basic/Module.h"
15e5dd7070Spatrick #include "clang/Basic/CharInfo.h"
16e5dd7070Spatrick #include "clang/Basic/FileManager.h"
17e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
18e5dd7070Spatrick #include "clang/Basic/SourceLocation.h"
19e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
20e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
21e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
22e5dd7070Spatrick #include "llvm/ADT/StringMap.h"
23e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
24e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
25e5dd7070Spatrick #include "llvm/Support/Compiler.h"
26e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
27e5dd7070Spatrick #include "llvm/Support/raw_ostream.h"
28e5dd7070Spatrick #include <algorithm>
29e5dd7070Spatrick #include <cassert>
30e5dd7070Spatrick #include <functional>
31e5dd7070Spatrick #include <string>
32e5dd7070Spatrick #include <utility>
33e5dd7070Spatrick #include <vector>
34e5dd7070Spatrick
35e5dd7070Spatrick using namespace clang;
36e5dd7070Spatrick
Module(StringRef Name,SourceLocation DefinitionLoc,Module * Parent,bool IsFramework,bool IsExplicit,unsigned VisibilityID)37e5dd7070Spatrick Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
38e5dd7070Spatrick bool IsFramework, bool IsExplicit, unsigned VisibilityID)
39e5dd7070Spatrick : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40ec727ea7Spatrick VisibilityID(VisibilityID), IsUnimportable(false),
41e5dd7070Spatrick HasIncompatibleModuleFile(false), IsAvailable(true),
42e5dd7070Spatrick IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
43e5dd7070Spatrick IsSystem(false), IsExternC(false), IsInferred(false),
44e5dd7070Spatrick InferSubmodules(false), InferExplicitSubmodules(false),
45e5dd7070Spatrick InferExportWildcard(false), ConfigMacrosExhaustive(false),
46e5dd7070Spatrick NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
47a9ac8606Spatrick NameVisibility(Hidden) {
48e5dd7070Spatrick if (Parent) {
49ec727ea7Spatrick IsAvailable = Parent->isAvailable();
50ec727ea7Spatrick IsUnimportable = Parent->isUnimportable();
51ec727ea7Spatrick IsSystem = Parent->IsSystem;
52ec727ea7Spatrick IsExternC = Parent->IsExternC;
53ec727ea7Spatrick NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
54ec727ea7Spatrick ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
55e5dd7070Spatrick
56e5dd7070Spatrick Parent->SubModuleIndex[Name] = Parent->SubModules.size();
57e5dd7070Spatrick Parent->SubModules.push_back(this);
58e5dd7070Spatrick }
59e5dd7070Spatrick }
60e5dd7070Spatrick
~Module()61e5dd7070Spatrick Module::~Module() {
62e5dd7070Spatrick for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
63e5dd7070Spatrick I != IEnd; ++I) {
64e5dd7070Spatrick delete *I;
65e5dd7070Spatrick }
66e5dd7070Spatrick }
67e5dd7070Spatrick
isPlatformEnvironment(const TargetInfo & Target,StringRef Feature)68e5dd7070Spatrick static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
69e5dd7070Spatrick StringRef Platform = Target.getPlatformName();
70e5dd7070Spatrick StringRef Env = Target.getTriple().getEnvironmentName();
71e5dd7070Spatrick
72e5dd7070Spatrick // Attempt to match platform and environment.
73e5dd7070Spatrick if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
74e5dd7070Spatrick Env == Feature)
75e5dd7070Spatrick return true;
76e5dd7070Spatrick
77e5dd7070Spatrick auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
78a9ac8606Spatrick auto Pos = LHS.find('-');
79e5dd7070Spatrick if (Pos == StringRef::npos)
80e5dd7070Spatrick return false;
81e5dd7070Spatrick SmallString<128> NewLHS = LHS.slice(0, Pos);
82e5dd7070Spatrick NewLHS += LHS.slice(Pos+1, LHS.size());
83e5dd7070Spatrick return NewLHS == RHS;
84e5dd7070Spatrick };
85e5dd7070Spatrick
86e5dd7070Spatrick SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
87e5dd7070Spatrick // Darwin has different but equivalent variants for simulators, example:
88e5dd7070Spatrick // 1. x86_64-apple-ios-simulator
89e5dd7070Spatrick // 2. x86_64-apple-iossimulator
90e5dd7070Spatrick // where both are valid examples of the same platform+environment but in the
91e5dd7070Spatrick // variant (2) the simulator is hardcoded as part of the platform name. Both
92e5dd7070Spatrick // forms above should match for "iossimulator" requirement.
93e5dd7070Spatrick if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
94e5dd7070Spatrick return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
95e5dd7070Spatrick
96e5dd7070Spatrick return PlatformEnv == Feature;
97e5dd7070Spatrick }
98e5dd7070Spatrick
99e5dd7070Spatrick /// Determine whether a translation unit built using the current
100e5dd7070Spatrick /// language options has the given feature.
hasFeature(StringRef Feature,const LangOptions & LangOpts,const TargetInfo & Target)101e5dd7070Spatrick static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
102e5dd7070Spatrick const TargetInfo &Target) {
103e5dd7070Spatrick bool HasFeature = llvm::StringSwitch<bool>(Feature)
104e5dd7070Spatrick .Case("altivec", LangOpts.AltiVec)
105e5dd7070Spatrick .Case("blocks", LangOpts.Blocks)
106e5dd7070Spatrick .Case("coroutines", LangOpts.Coroutines)
107e5dd7070Spatrick .Case("cplusplus", LangOpts.CPlusPlus)
108e5dd7070Spatrick .Case("cplusplus11", LangOpts.CPlusPlus11)
109e5dd7070Spatrick .Case("cplusplus14", LangOpts.CPlusPlus14)
110e5dd7070Spatrick .Case("cplusplus17", LangOpts.CPlusPlus17)
111e5dd7070Spatrick .Case("c99", LangOpts.C99)
112e5dd7070Spatrick .Case("c11", LangOpts.C11)
113e5dd7070Spatrick .Case("c17", LangOpts.C17)
114e5dd7070Spatrick .Case("freestanding", LangOpts.Freestanding)
115e5dd7070Spatrick .Case("gnuinlineasm", LangOpts.GNUAsm)
116e5dd7070Spatrick .Case("objc", LangOpts.ObjC)
117e5dd7070Spatrick .Case("objc_arc", LangOpts.ObjCAutoRefCount)
118e5dd7070Spatrick .Case("opencl", LangOpts.OpenCL)
119e5dd7070Spatrick .Case("tls", Target.isTLSSupported())
120e5dd7070Spatrick .Case("zvector", LangOpts.ZVector)
121e5dd7070Spatrick .Default(Target.hasFeature(Feature) ||
122e5dd7070Spatrick isPlatformEnvironment(Target, Feature));
123e5dd7070Spatrick if (!HasFeature)
124*12c85518Srobert HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
125e5dd7070Spatrick return HasFeature;
126e5dd7070Spatrick }
127e5dd7070Spatrick
isUnimportable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,Module * & ShadowingModule) const128ec727ea7Spatrick bool Module::isUnimportable(const LangOptions &LangOpts,
129ec727ea7Spatrick const TargetInfo &Target, Requirement &Req,
130ec727ea7Spatrick Module *&ShadowingModule) const {
131ec727ea7Spatrick if (!IsUnimportable)
132ec727ea7Spatrick return false;
133ec727ea7Spatrick
134ec727ea7Spatrick for (const Module *Current = this; Current; Current = Current->Parent) {
135ec727ea7Spatrick if (Current->ShadowingModule) {
136ec727ea7Spatrick ShadowingModule = Current->ShadowingModule;
137ec727ea7Spatrick return true;
138ec727ea7Spatrick }
139ec727ea7Spatrick for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
140ec727ea7Spatrick if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
141ec727ea7Spatrick Current->Requirements[I].second) {
142ec727ea7Spatrick Req = Current->Requirements[I];
143ec727ea7Spatrick return true;
144ec727ea7Spatrick }
145ec727ea7Spatrick }
146ec727ea7Spatrick }
147ec727ea7Spatrick
148ec727ea7Spatrick llvm_unreachable("could not find a reason why module is unimportable");
149ec727ea7Spatrick }
150ec727ea7Spatrick
151*12c85518Srobert // The -fmodule-name option tells the compiler to textually include headers in
152*12c85518Srobert // the specified module, meaning Clang won't build the specified module. This
153*12c85518Srobert // is useful in a number of situations, for instance, when building a library
154*12c85518Srobert // that vends a module map, one might want to avoid hitting intermediate build
155*12c85518Srobert // products containing the module map or avoid finding the system installed
156*12c85518Srobert // modulemap for that library.
isForBuilding(const LangOptions & LangOpts) const157*12c85518Srobert bool Module::isForBuilding(const LangOptions &LangOpts) const {
158*12c85518Srobert StringRef TopLevelName = getTopLevelModuleName();
159*12c85518Srobert StringRef CurrentModule = LangOpts.CurrentModule;
160*12c85518Srobert
161*12c85518Srobert // When building framework Foo, we want to make sure that Foo *and*
162*12c85518Srobert // Foo_Private are textually included and no modules are built for both.
163*12c85518Srobert if (getTopLevelModule()->IsFramework &&
164*12c85518Srobert CurrentModule == LangOpts.ModuleName &&
165*12c85518Srobert !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
166*12c85518Srobert TopLevelName = TopLevelName.drop_back(8);
167*12c85518Srobert
168*12c85518Srobert return TopLevelName == CurrentModule;
169*12c85518Srobert }
170*12c85518Srobert
isAvailable(const LangOptions & LangOpts,const TargetInfo & Target,Requirement & Req,UnresolvedHeaderDirective & MissingHeader,Module * & ShadowingModule) const171e5dd7070Spatrick bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
172e5dd7070Spatrick Requirement &Req,
173e5dd7070Spatrick UnresolvedHeaderDirective &MissingHeader,
174e5dd7070Spatrick Module *&ShadowingModule) const {
175e5dd7070Spatrick if (IsAvailable)
176e5dd7070Spatrick return true;
177e5dd7070Spatrick
178ec727ea7Spatrick if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
179ec727ea7Spatrick return false;
180ec727ea7Spatrick
181ec727ea7Spatrick // FIXME: All missing headers are listed on the top-level module. Should we
182ec727ea7Spatrick // just look there?
183e5dd7070Spatrick for (const Module *Current = this; Current; Current = Current->Parent) {
184e5dd7070Spatrick if (!Current->MissingHeaders.empty()) {
185e5dd7070Spatrick MissingHeader = Current->MissingHeaders.front();
186e5dd7070Spatrick return false;
187e5dd7070Spatrick }
188e5dd7070Spatrick }
189e5dd7070Spatrick
190e5dd7070Spatrick llvm_unreachable("could not find a reason why module is unavailable");
191e5dd7070Spatrick }
192e5dd7070Spatrick
isSubModuleOf(const Module * Other) const193e5dd7070Spatrick bool Module::isSubModuleOf(const Module *Other) const {
194a9ac8606Spatrick for (auto *Parent = this; Parent; Parent = Parent->Parent) {
195a9ac8606Spatrick if (Parent == Other)
196e5dd7070Spatrick return true;
197a9ac8606Spatrick }
198e5dd7070Spatrick return false;
199e5dd7070Spatrick }
200e5dd7070Spatrick
getTopLevelModule() const201e5dd7070Spatrick const Module *Module::getTopLevelModule() const {
202e5dd7070Spatrick const Module *Result = this;
203e5dd7070Spatrick while (Result->Parent)
204e5dd7070Spatrick Result = Result->Parent;
205e5dd7070Spatrick
206e5dd7070Spatrick return Result;
207e5dd7070Spatrick }
208e5dd7070Spatrick
getModuleNameFromComponent(const std::pair<std::string,SourceLocation> & IdComponent)209e5dd7070Spatrick static StringRef getModuleNameFromComponent(
210e5dd7070Spatrick const std::pair<std::string, SourceLocation> &IdComponent) {
211e5dd7070Spatrick return IdComponent.first;
212e5dd7070Spatrick }
213e5dd7070Spatrick
getModuleNameFromComponent(StringRef R)214e5dd7070Spatrick static StringRef getModuleNameFromComponent(StringRef R) { return R; }
215e5dd7070Spatrick
216e5dd7070Spatrick template<typename InputIter>
printModuleId(raw_ostream & OS,InputIter Begin,InputIter End,bool AllowStringLiterals=true)217e5dd7070Spatrick static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
218e5dd7070Spatrick bool AllowStringLiterals = true) {
219e5dd7070Spatrick for (InputIter It = Begin; It != End; ++It) {
220e5dd7070Spatrick if (It != Begin)
221e5dd7070Spatrick OS << ".";
222e5dd7070Spatrick
223e5dd7070Spatrick StringRef Name = getModuleNameFromComponent(*It);
224*12c85518Srobert if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
225e5dd7070Spatrick OS << Name;
226e5dd7070Spatrick else {
227e5dd7070Spatrick OS << '"';
228e5dd7070Spatrick OS.write_escaped(Name);
229e5dd7070Spatrick OS << '"';
230e5dd7070Spatrick }
231e5dd7070Spatrick }
232e5dd7070Spatrick }
233e5dd7070Spatrick
234e5dd7070Spatrick template<typename Container>
printModuleId(raw_ostream & OS,const Container & C)235e5dd7070Spatrick static void printModuleId(raw_ostream &OS, const Container &C) {
236e5dd7070Spatrick return printModuleId(OS, C.begin(), C.end());
237e5dd7070Spatrick }
238e5dd7070Spatrick
getFullModuleName(bool AllowStringLiterals) const239e5dd7070Spatrick std::string Module::getFullModuleName(bool AllowStringLiterals) const {
240e5dd7070Spatrick SmallVector<StringRef, 2> Names;
241e5dd7070Spatrick
242e5dd7070Spatrick // Build up the set of module names (from innermost to outermost).
243e5dd7070Spatrick for (const Module *M = this; M; M = M->Parent)
244e5dd7070Spatrick Names.push_back(M->Name);
245e5dd7070Spatrick
246e5dd7070Spatrick std::string Result;
247e5dd7070Spatrick
248e5dd7070Spatrick llvm::raw_string_ostream Out(Result);
249e5dd7070Spatrick printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
250e5dd7070Spatrick Out.flush();
251e5dd7070Spatrick
252e5dd7070Spatrick return Result;
253e5dd7070Spatrick }
254e5dd7070Spatrick
fullModuleNameIs(ArrayRef<StringRef> nameParts) const255e5dd7070Spatrick bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
256e5dd7070Spatrick for (const Module *M = this; M; M = M->Parent) {
257e5dd7070Spatrick if (nameParts.empty() || M->Name != nameParts.back())
258e5dd7070Spatrick return false;
259e5dd7070Spatrick nameParts = nameParts.drop_back();
260e5dd7070Spatrick }
261e5dd7070Spatrick return nameParts.empty();
262e5dd7070Spatrick }
263e5dd7070Spatrick
getUmbrellaDir() const264e5dd7070Spatrick Module::DirectoryName Module::getUmbrellaDir() const {
265e5dd7070Spatrick if (Header U = getUmbrellaHeader())
266a9ac8606Spatrick return {"", "", U.Entry->getDir()};
267e5dd7070Spatrick
268a9ac8606Spatrick return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
269a9ac8606Spatrick Umbrella.dyn_cast<const DirectoryEntry *>()};
270ec727ea7Spatrick }
271ec727ea7Spatrick
addTopHeader(const FileEntry * File)272ec727ea7Spatrick void Module::addTopHeader(const FileEntry *File) {
273ec727ea7Spatrick assert(File);
274ec727ea7Spatrick TopHeaders.insert(File);
275e5dd7070Spatrick }
276e5dd7070Spatrick
getTopHeaders(FileManager & FileMgr)277e5dd7070Spatrick ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
278e5dd7070Spatrick if (!TopHeaderNames.empty()) {
279e5dd7070Spatrick for (std::vector<std::string>::iterator
280e5dd7070Spatrick I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
281e5dd7070Spatrick if (auto FE = FileMgr.getFile(*I))
282e5dd7070Spatrick TopHeaders.insert(*FE);
283e5dd7070Spatrick }
284e5dd7070Spatrick TopHeaderNames.clear();
285e5dd7070Spatrick }
286e5dd7070Spatrick
287*12c85518Srobert return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
288e5dd7070Spatrick }
289e5dd7070Spatrick
directlyUses(const Module * Requested)290*12c85518Srobert bool Module::directlyUses(const Module *Requested) {
291e5dd7070Spatrick auto *Top = getTopLevelModule();
292e5dd7070Spatrick
293e5dd7070Spatrick // A top-level module implicitly uses itself.
294e5dd7070Spatrick if (Requested->isSubModuleOf(Top))
295e5dd7070Spatrick return true;
296e5dd7070Spatrick
297e5dd7070Spatrick for (auto *Use : Top->DirectUses)
298e5dd7070Spatrick if (Requested->isSubModuleOf(Use))
299e5dd7070Spatrick return true;
300e5dd7070Spatrick
301e5dd7070Spatrick // Anyone is allowed to use our builtin stddef.h and its accompanying module.
302e5dd7070Spatrick if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
303e5dd7070Spatrick return true;
304e5dd7070Spatrick
305*12c85518Srobert if (NoUndeclaredIncludes)
306*12c85518Srobert UndeclaredUses.insert(Requested);
307*12c85518Srobert
308e5dd7070Spatrick return false;
309e5dd7070Spatrick }
310e5dd7070Spatrick
addRequirement(StringRef Feature,bool RequiredState,const LangOptions & LangOpts,const TargetInfo & Target)311e5dd7070Spatrick void Module::addRequirement(StringRef Feature, bool RequiredState,
312e5dd7070Spatrick const LangOptions &LangOpts,
313e5dd7070Spatrick const TargetInfo &Target) {
314ec727ea7Spatrick Requirements.push_back(Requirement(std::string(Feature), RequiredState));
315e5dd7070Spatrick
316e5dd7070Spatrick // If this feature is currently available, we're done.
317e5dd7070Spatrick if (hasFeature(Feature, LangOpts, Target) == RequiredState)
318e5dd7070Spatrick return;
319e5dd7070Spatrick
320ec727ea7Spatrick markUnavailable(/*Unimportable*/true);
321e5dd7070Spatrick }
322e5dd7070Spatrick
markUnavailable(bool Unimportable)323ec727ea7Spatrick void Module::markUnavailable(bool Unimportable) {
324ec727ea7Spatrick auto needUpdate = [Unimportable](Module *M) {
325ec727ea7Spatrick return M->IsAvailable || (!M->IsUnimportable && Unimportable);
326e5dd7070Spatrick };
327e5dd7070Spatrick
328e5dd7070Spatrick if (!needUpdate(this))
329e5dd7070Spatrick return;
330e5dd7070Spatrick
331e5dd7070Spatrick SmallVector<Module *, 2> Stack;
332e5dd7070Spatrick Stack.push_back(this);
333e5dd7070Spatrick while (!Stack.empty()) {
334e5dd7070Spatrick Module *Current = Stack.back();
335e5dd7070Spatrick Stack.pop_back();
336e5dd7070Spatrick
337e5dd7070Spatrick if (!needUpdate(Current))
338e5dd7070Spatrick continue;
339e5dd7070Spatrick
340e5dd7070Spatrick Current->IsAvailable = false;
341ec727ea7Spatrick Current->IsUnimportable |= Unimportable;
342e5dd7070Spatrick for (submodule_iterator Sub = Current->submodule_begin(),
343e5dd7070Spatrick SubEnd = Current->submodule_end();
344e5dd7070Spatrick Sub != SubEnd; ++Sub) {
345e5dd7070Spatrick if (needUpdate(*Sub))
346e5dd7070Spatrick Stack.push_back(*Sub);
347e5dd7070Spatrick }
348e5dd7070Spatrick }
349e5dd7070Spatrick }
350e5dd7070Spatrick
findSubmodule(StringRef Name) const351e5dd7070Spatrick Module *Module::findSubmodule(StringRef Name) const {
352e5dd7070Spatrick llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
353e5dd7070Spatrick if (Pos == SubModuleIndex.end())
354e5dd7070Spatrick return nullptr;
355e5dd7070Spatrick
356e5dd7070Spatrick return SubModules[Pos->getValue()];
357e5dd7070Spatrick }
358e5dd7070Spatrick
findOrInferSubmodule(StringRef Name)359e5dd7070Spatrick Module *Module::findOrInferSubmodule(StringRef Name) {
360e5dd7070Spatrick llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
361e5dd7070Spatrick if (Pos != SubModuleIndex.end())
362e5dd7070Spatrick return SubModules[Pos->getValue()];
363e5dd7070Spatrick if (!InferSubmodules)
364e5dd7070Spatrick return nullptr;
365e5dd7070Spatrick Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
366e5dd7070Spatrick Result->InferExplicitSubmodules = InferExplicitSubmodules;
367e5dd7070Spatrick Result->InferSubmodules = InferSubmodules;
368e5dd7070Spatrick Result->InferExportWildcard = InferExportWildcard;
369e5dd7070Spatrick if (Result->InferExportWildcard)
370e5dd7070Spatrick Result->Exports.push_back(Module::ExportDecl(nullptr, true));
371e5dd7070Spatrick return Result;
372e5dd7070Spatrick }
373e5dd7070Spatrick
getExportedModules(SmallVectorImpl<Module * > & Exported) const374e5dd7070Spatrick void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
375e5dd7070Spatrick // All non-explicit submodules are exported.
376e5dd7070Spatrick for (std::vector<Module *>::const_iterator I = SubModules.begin(),
377e5dd7070Spatrick E = SubModules.end();
378e5dd7070Spatrick I != E; ++I) {
379e5dd7070Spatrick Module *Mod = *I;
380e5dd7070Spatrick if (!Mod->IsExplicit)
381e5dd7070Spatrick Exported.push_back(Mod);
382e5dd7070Spatrick }
383e5dd7070Spatrick
384e5dd7070Spatrick // Find re-exported modules by filtering the list of imported modules.
385e5dd7070Spatrick bool AnyWildcard = false;
386e5dd7070Spatrick bool UnrestrictedWildcard = false;
387e5dd7070Spatrick SmallVector<Module *, 4> WildcardRestrictions;
388e5dd7070Spatrick for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
389e5dd7070Spatrick Module *Mod = Exports[I].getPointer();
390e5dd7070Spatrick if (!Exports[I].getInt()) {
391e5dd7070Spatrick // Export a named module directly; no wildcards involved.
392e5dd7070Spatrick Exported.push_back(Mod);
393e5dd7070Spatrick
394e5dd7070Spatrick continue;
395e5dd7070Spatrick }
396e5dd7070Spatrick
397e5dd7070Spatrick // Wildcard export: export all of the imported modules that match
398e5dd7070Spatrick // the given pattern.
399e5dd7070Spatrick AnyWildcard = true;
400e5dd7070Spatrick if (UnrestrictedWildcard)
401e5dd7070Spatrick continue;
402e5dd7070Spatrick
403e5dd7070Spatrick if (Module *Restriction = Exports[I].getPointer())
404e5dd7070Spatrick WildcardRestrictions.push_back(Restriction);
405e5dd7070Spatrick else {
406e5dd7070Spatrick WildcardRestrictions.clear();
407e5dd7070Spatrick UnrestrictedWildcard = true;
408e5dd7070Spatrick }
409e5dd7070Spatrick }
410e5dd7070Spatrick
411e5dd7070Spatrick // If there were any wildcards, push any imported modules that were
412e5dd7070Spatrick // re-exported by the wildcard restriction.
413e5dd7070Spatrick if (!AnyWildcard)
414e5dd7070Spatrick return;
415e5dd7070Spatrick
416e5dd7070Spatrick for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
417e5dd7070Spatrick Module *Mod = Imports[I];
418e5dd7070Spatrick bool Acceptable = UnrestrictedWildcard;
419e5dd7070Spatrick if (!Acceptable) {
420e5dd7070Spatrick // Check whether this module meets one of the restrictions.
421e5dd7070Spatrick for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
422e5dd7070Spatrick Module *Restriction = WildcardRestrictions[R];
423e5dd7070Spatrick if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
424e5dd7070Spatrick Acceptable = true;
425e5dd7070Spatrick break;
426e5dd7070Spatrick }
427e5dd7070Spatrick }
428e5dd7070Spatrick }
429e5dd7070Spatrick
430e5dd7070Spatrick if (!Acceptable)
431e5dd7070Spatrick continue;
432e5dd7070Spatrick
433e5dd7070Spatrick Exported.push_back(Mod);
434e5dd7070Spatrick }
435e5dd7070Spatrick }
436e5dd7070Spatrick
buildVisibleModulesCache() const437e5dd7070Spatrick void Module::buildVisibleModulesCache() const {
438e5dd7070Spatrick assert(VisibleModulesCache.empty() && "cache does not need building");
439e5dd7070Spatrick
440e5dd7070Spatrick // This module is visible to itself.
441e5dd7070Spatrick VisibleModulesCache.insert(this);
442e5dd7070Spatrick
443e5dd7070Spatrick // Every imported module is visible.
444e5dd7070Spatrick SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
445e5dd7070Spatrick while (!Stack.empty()) {
446e5dd7070Spatrick Module *CurrModule = Stack.pop_back_val();
447e5dd7070Spatrick
448e5dd7070Spatrick // Every module transitively exported by an imported module is visible.
449e5dd7070Spatrick if (VisibleModulesCache.insert(CurrModule).second)
450e5dd7070Spatrick CurrModule->getExportedModules(Stack);
451e5dd7070Spatrick }
452e5dd7070Spatrick }
453e5dd7070Spatrick
print(raw_ostream & OS,unsigned Indent,bool Dump) const454a9ac8606Spatrick void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
455e5dd7070Spatrick OS.indent(Indent);
456e5dd7070Spatrick if (IsFramework)
457e5dd7070Spatrick OS << "framework ";
458e5dd7070Spatrick if (IsExplicit)
459e5dd7070Spatrick OS << "explicit ";
460e5dd7070Spatrick OS << "module ";
461e5dd7070Spatrick printModuleId(OS, &Name, &Name + 1);
462e5dd7070Spatrick
463e5dd7070Spatrick if (IsSystem || IsExternC) {
464e5dd7070Spatrick OS.indent(Indent + 2);
465e5dd7070Spatrick if (IsSystem)
466e5dd7070Spatrick OS << " [system]";
467e5dd7070Spatrick if (IsExternC)
468e5dd7070Spatrick OS << " [extern_c]";
469e5dd7070Spatrick }
470e5dd7070Spatrick
471e5dd7070Spatrick OS << " {\n";
472e5dd7070Spatrick
473e5dd7070Spatrick if (!Requirements.empty()) {
474e5dd7070Spatrick OS.indent(Indent + 2);
475e5dd7070Spatrick OS << "requires ";
476e5dd7070Spatrick for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
477e5dd7070Spatrick if (I)
478e5dd7070Spatrick OS << ", ";
479e5dd7070Spatrick if (!Requirements[I].second)
480e5dd7070Spatrick OS << "!";
481e5dd7070Spatrick OS << Requirements[I].first;
482e5dd7070Spatrick }
483e5dd7070Spatrick OS << "\n";
484e5dd7070Spatrick }
485e5dd7070Spatrick
486e5dd7070Spatrick if (Header H = getUmbrellaHeader()) {
487e5dd7070Spatrick OS.indent(Indent + 2);
488e5dd7070Spatrick OS << "umbrella header \"";
489e5dd7070Spatrick OS.write_escaped(H.NameAsWritten);
490e5dd7070Spatrick OS << "\"\n";
491e5dd7070Spatrick } else if (DirectoryName D = getUmbrellaDir()) {
492e5dd7070Spatrick OS.indent(Indent + 2);
493e5dd7070Spatrick OS << "umbrella \"";
494e5dd7070Spatrick OS.write_escaped(D.NameAsWritten);
495e5dd7070Spatrick OS << "\"\n";
496e5dd7070Spatrick }
497e5dd7070Spatrick
498e5dd7070Spatrick if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
499e5dd7070Spatrick OS.indent(Indent + 2);
500e5dd7070Spatrick OS << "config_macros ";
501e5dd7070Spatrick if (ConfigMacrosExhaustive)
502e5dd7070Spatrick OS << "[exhaustive]";
503e5dd7070Spatrick for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
504e5dd7070Spatrick if (I)
505e5dd7070Spatrick OS << ", ";
506e5dd7070Spatrick OS << ConfigMacros[I];
507e5dd7070Spatrick }
508e5dd7070Spatrick OS << "\n";
509e5dd7070Spatrick }
510e5dd7070Spatrick
511e5dd7070Spatrick struct {
512e5dd7070Spatrick StringRef Prefix;
513e5dd7070Spatrick HeaderKind Kind;
514e5dd7070Spatrick } Kinds[] = {{"", HK_Normal},
515e5dd7070Spatrick {"textual ", HK_Textual},
516e5dd7070Spatrick {"private ", HK_Private},
517e5dd7070Spatrick {"private textual ", HK_PrivateTextual},
518e5dd7070Spatrick {"exclude ", HK_Excluded}};
519e5dd7070Spatrick
520e5dd7070Spatrick for (auto &K : Kinds) {
521e5dd7070Spatrick assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
522e5dd7070Spatrick for (auto &H : Headers[K.Kind]) {
523e5dd7070Spatrick OS.indent(Indent + 2);
524e5dd7070Spatrick OS << K.Prefix << "header \"";
525e5dd7070Spatrick OS.write_escaped(H.NameAsWritten);
526e5dd7070Spatrick OS << "\" { size " << H.Entry->getSize()
527e5dd7070Spatrick << " mtime " << H.Entry->getModificationTime() << " }\n";
528e5dd7070Spatrick }
529e5dd7070Spatrick }
530e5dd7070Spatrick for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
531e5dd7070Spatrick for (auto &U : *Unresolved) {
532e5dd7070Spatrick OS.indent(Indent + 2);
533e5dd7070Spatrick OS << Kinds[U.Kind].Prefix << "header \"";
534e5dd7070Spatrick OS.write_escaped(U.FileName);
535e5dd7070Spatrick OS << "\"";
536e5dd7070Spatrick if (U.Size || U.ModTime) {
537e5dd7070Spatrick OS << " {";
538e5dd7070Spatrick if (U.Size)
539e5dd7070Spatrick OS << " size " << *U.Size;
540e5dd7070Spatrick if (U.ModTime)
541e5dd7070Spatrick OS << " mtime " << *U.ModTime;
542e5dd7070Spatrick OS << " }";
543e5dd7070Spatrick }
544e5dd7070Spatrick OS << "\n";
545e5dd7070Spatrick }
546e5dd7070Spatrick }
547e5dd7070Spatrick
548e5dd7070Spatrick if (!ExportAsModule.empty()) {
549e5dd7070Spatrick OS.indent(Indent + 2);
550e5dd7070Spatrick OS << "export_as" << ExportAsModule << "\n";
551e5dd7070Spatrick }
552e5dd7070Spatrick
553e5dd7070Spatrick for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
554e5dd7070Spatrick MI != MIEnd; ++MI)
555e5dd7070Spatrick // Print inferred subframework modules so that we don't need to re-infer
556e5dd7070Spatrick // them (requires expensive directory iteration + stat calls) when we build
557e5dd7070Spatrick // the module. Regular inferred submodules are OK, as we need to look at all
558e5dd7070Spatrick // those header files anyway.
559e5dd7070Spatrick if (!(*MI)->IsInferred || (*MI)->IsFramework)
560a9ac8606Spatrick (*MI)->print(OS, Indent + 2, Dump);
561e5dd7070Spatrick
562e5dd7070Spatrick for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
563e5dd7070Spatrick OS.indent(Indent + 2);
564e5dd7070Spatrick OS << "export ";
565e5dd7070Spatrick if (Module *Restriction = Exports[I].getPointer()) {
566e5dd7070Spatrick OS << Restriction->getFullModuleName(true);
567e5dd7070Spatrick if (Exports[I].getInt())
568e5dd7070Spatrick OS << ".*";
569e5dd7070Spatrick } else {
570e5dd7070Spatrick OS << "*";
571e5dd7070Spatrick }
572e5dd7070Spatrick OS << "\n";
573e5dd7070Spatrick }
574e5dd7070Spatrick
575e5dd7070Spatrick for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
576e5dd7070Spatrick OS.indent(Indent + 2);
577e5dd7070Spatrick OS << "export ";
578e5dd7070Spatrick printModuleId(OS, UnresolvedExports[I].Id);
579e5dd7070Spatrick if (UnresolvedExports[I].Wildcard)
580e5dd7070Spatrick OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
581e5dd7070Spatrick OS << "\n";
582e5dd7070Spatrick }
583e5dd7070Spatrick
584a9ac8606Spatrick if (Dump) {
585a9ac8606Spatrick for (Module *M : Imports) {
586a9ac8606Spatrick OS.indent(Indent + 2);
587a9ac8606Spatrick llvm::errs() << "import " << M->getFullModuleName() << "\n";
588a9ac8606Spatrick }
589a9ac8606Spatrick }
590a9ac8606Spatrick
591e5dd7070Spatrick for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
592e5dd7070Spatrick OS.indent(Indent + 2);
593e5dd7070Spatrick OS << "use ";
594e5dd7070Spatrick OS << DirectUses[I]->getFullModuleName(true);
595e5dd7070Spatrick OS << "\n";
596e5dd7070Spatrick }
597e5dd7070Spatrick
598e5dd7070Spatrick for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
599e5dd7070Spatrick OS.indent(Indent + 2);
600e5dd7070Spatrick OS << "use ";
601e5dd7070Spatrick printModuleId(OS, UnresolvedDirectUses[I]);
602e5dd7070Spatrick OS << "\n";
603e5dd7070Spatrick }
604e5dd7070Spatrick
605e5dd7070Spatrick for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
606e5dd7070Spatrick OS.indent(Indent + 2);
607e5dd7070Spatrick OS << "link ";
608e5dd7070Spatrick if (LinkLibraries[I].IsFramework)
609e5dd7070Spatrick OS << "framework ";
610e5dd7070Spatrick OS << "\"";
611e5dd7070Spatrick OS.write_escaped(LinkLibraries[I].Library);
612e5dd7070Spatrick OS << "\"";
613e5dd7070Spatrick }
614e5dd7070Spatrick
615e5dd7070Spatrick for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
616e5dd7070Spatrick OS.indent(Indent + 2);
617e5dd7070Spatrick OS << "conflict ";
618e5dd7070Spatrick printModuleId(OS, UnresolvedConflicts[I].Id);
619e5dd7070Spatrick OS << ", \"";
620e5dd7070Spatrick OS.write_escaped(UnresolvedConflicts[I].Message);
621e5dd7070Spatrick OS << "\"\n";
622e5dd7070Spatrick }
623e5dd7070Spatrick
624e5dd7070Spatrick for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
625e5dd7070Spatrick OS.indent(Indent + 2);
626e5dd7070Spatrick OS << "conflict ";
627e5dd7070Spatrick OS << Conflicts[I].Other->getFullModuleName(true);
628e5dd7070Spatrick OS << ", \"";
629e5dd7070Spatrick OS.write_escaped(Conflicts[I].Message);
630e5dd7070Spatrick OS << "\"\n";
631e5dd7070Spatrick }
632e5dd7070Spatrick
633e5dd7070Spatrick if (InferSubmodules) {
634e5dd7070Spatrick OS.indent(Indent + 2);
635e5dd7070Spatrick if (InferExplicitSubmodules)
636e5dd7070Spatrick OS << "explicit ";
637e5dd7070Spatrick OS << "module * {\n";
638e5dd7070Spatrick if (InferExportWildcard) {
639e5dd7070Spatrick OS.indent(Indent + 4);
640e5dd7070Spatrick OS << "export *\n";
641e5dd7070Spatrick }
642e5dd7070Spatrick OS.indent(Indent + 2);
643e5dd7070Spatrick OS << "}\n";
644e5dd7070Spatrick }
645e5dd7070Spatrick
646e5dd7070Spatrick OS.indent(Indent);
647e5dd7070Spatrick OS << "}\n";
648e5dd7070Spatrick }
649e5dd7070Spatrick
dump() const650e5dd7070Spatrick LLVM_DUMP_METHOD void Module::dump() const {
651a9ac8606Spatrick print(llvm::errs(), 0, true);
652e5dd7070Spatrick }
653e5dd7070Spatrick
setVisible(Module * M,SourceLocation Loc,VisibleCallback Vis,ConflictCallback Cb)654e5dd7070Spatrick void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
655e5dd7070Spatrick VisibleCallback Vis, ConflictCallback Cb) {
656*12c85518Srobert // We can't import a global module fragment so the location can be invalid.
657*12c85518Srobert assert((M->isGlobalModule() || Loc.isValid()) &&
658*12c85518Srobert "setVisible expects a valid import location");
659e5dd7070Spatrick if (isVisible(M))
660e5dd7070Spatrick return;
661e5dd7070Spatrick
662e5dd7070Spatrick ++Generation;
663e5dd7070Spatrick
664e5dd7070Spatrick struct Visiting {
665e5dd7070Spatrick Module *M;
666e5dd7070Spatrick Visiting *ExportedBy;
667e5dd7070Spatrick };
668e5dd7070Spatrick
669e5dd7070Spatrick std::function<void(Visiting)> VisitModule = [&](Visiting V) {
670e5dd7070Spatrick // Nothing to do for a module that's already visible.
671e5dd7070Spatrick unsigned ID = V.M->getVisibilityID();
672e5dd7070Spatrick if (ImportLocs.size() <= ID)
673e5dd7070Spatrick ImportLocs.resize(ID + 1);
674e5dd7070Spatrick else if (ImportLocs[ID].isValid())
675e5dd7070Spatrick return;
676e5dd7070Spatrick
677e5dd7070Spatrick ImportLocs[ID] = Loc;
678*12c85518Srobert Vis(V.M);
679e5dd7070Spatrick
680e5dd7070Spatrick // Make any exported modules visible.
681e5dd7070Spatrick SmallVector<Module *, 16> Exports;
682e5dd7070Spatrick V.M->getExportedModules(Exports);
683e5dd7070Spatrick for (Module *E : Exports) {
684ec727ea7Spatrick // Don't import non-importable modules.
685ec727ea7Spatrick if (!E->isUnimportable())
686e5dd7070Spatrick VisitModule({E, &V});
687e5dd7070Spatrick }
688e5dd7070Spatrick
689e5dd7070Spatrick for (auto &C : V.M->Conflicts) {
690e5dd7070Spatrick if (isVisible(C.Other)) {
691e5dd7070Spatrick llvm::SmallVector<Module*, 8> Path;
692e5dd7070Spatrick for (Visiting *I = &V; I; I = I->ExportedBy)
693e5dd7070Spatrick Path.push_back(I->M);
694e5dd7070Spatrick Cb(Path, C.Other, C.Message);
695e5dd7070Spatrick }
696e5dd7070Spatrick }
697e5dd7070Spatrick };
698e5dd7070Spatrick VisitModule({M, nullptr});
699e5dd7070Spatrick }
700ec727ea7Spatrick
ASTSourceDescriptor(Module & M)701ec727ea7Spatrick ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
702ec727ea7Spatrick : Signature(M.Signature), ClangModule(&M) {
703ec727ea7Spatrick if (M.Directory)
704ec727ea7Spatrick Path = M.Directory->getName();
705a9ac8606Spatrick if (auto File = M.getASTFile())
706ec727ea7Spatrick ASTFile = File->getName();
707ec727ea7Spatrick }
708ec727ea7Spatrick
getModuleName() const709ec727ea7Spatrick std::string ASTSourceDescriptor::getModuleName() const {
710ec727ea7Spatrick if (ClangModule)
711ec727ea7Spatrick return ClangModule->Name;
712ec727ea7Spatrick else
713ec727ea7Spatrick return std::string(PCHModuleName);
714ec727ea7Spatrick }
715