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