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