xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Module.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
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