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