xref: /llvm-project/clang/lib/Basic/Module.cpp (revision 7db641af13670aa1f1ecd3106eda3ce447afd752)
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(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 
61 Module::~Module() {
62   for (auto *Submodule : SubModules) {
63     delete Submodule;
64   }
65 }
66 
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.
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 
131 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.
160 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 
176 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 
198 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 
206 const Module *Module::getTopLevelModule() const {
207   const Module *Result = this;
208   while (Result->Parent)
209     Result = Result->Parent;
210 
211   return Result;
212 }
213 
214 static StringRef getModuleNameFromComponent(
215     const std::pair<std::string, SourceLocation> &IdComponent) {
216   return IdComponent.first;
217 }
218 
219 static StringRef getModuleNameFromComponent(StringRef R) { return R; }
220 
221 template<typename InputIter>
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>
240 static void printModuleId(raw_ostream &OS, const Container &C) {
241   return printModuleId(OS, C.begin(), C.end());
242 }
243 
244 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 
256   return Result;
257 }
258 
259 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
260   for (const Module *M = this; M; M = M->Parent) {
261     if (nameParts.empty() || M->Name != nameParts.back())
262       return false;
263     nameParts = nameParts.drop_back();
264   }
265   return nameParts.empty();
266 }
267 
268 OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
269   if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
270     return Hdr->getDir();
271   if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
272     return *Dir;
273   return std::nullopt;
274 }
275 
276 void Module::addTopHeader(FileEntryRef File) {
277   assert(File);
278   TopHeaders.insert(File);
279 }
280 
281 ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
282   if (!TopHeaderNames.empty()) {
283     for (StringRef TopHeaderName : TopHeaderNames)
284       if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
285         TopHeaders.insert(*FE);
286     TopHeaderNames.clear();
287   }
288 
289   return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
290 }
291 
292 bool Module::directlyUses(const Module *Requested) {
293   auto *Top = getTopLevelModule();
294 
295   // A top-level module implicitly uses itself.
296   if (Requested->isSubModuleOf(Top))
297     return true;
298 
299   for (auto *Use : Top->DirectUses)
300     if (Requested->isSubModuleOf(Use))
301       return true;
302 
303   // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
304   if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
305       Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
306     return true;
307   // Darwin is allowed is to use our builtin 'ptrauth.h' and its accompanying
308   // module.
309   if (!Requested->Parent && Requested->Name == "ptrauth")
310     return true;
311 
312   if (NoUndeclaredIncludes)
313     UndeclaredUses.insert(Requested);
314 
315   return false;
316 }
317 
318 void Module::addRequirement(StringRef Feature, bool RequiredState,
319                             const LangOptions &LangOpts,
320                             const TargetInfo &Target) {
321   Requirements.push_back(Requirement{std::string(Feature), RequiredState});
322 
323   // If this feature is currently available, we're done.
324   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
325     return;
326 
327   markUnavailable(/*Unimportable*/true);
328 }
329 
330 void Module::markUnavailable(bool Unimportable) {
331   auto needUpdate = [Unimportable](Module *M) {
332     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
333   };
334 
335   if (!needUpdate(this))
336     return;
337 
338   SmallVector<Module *, 2> Stack;
339   Stack.push_back(this);
340   while (!Stack.empty()) {
341     Module *Current = Stack.back();
342     Stack.pop_back();
343 
344     if (!needUpdate(Current))
345       continue;
346 
347     Current->IsAvailable = false;
348     Current->IsUnimportable |= Unimportable;
349     for (auto *Submodule : Current->submodules()) {
350       if (needUpdate(Submodule))
351         Stack.push_back(Submodule);
352     }
353   }
354 }
355 
356 Module *Module::findSubmodule(StringRef Name) const {
357   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
358   if (Pos == SubModuleIndex.end())
359     return nullptr;
360 
361   return SubModules[Pos->getValue()];
362 }
363 
364 Module *Module::findOrInferSubmodule(StringRef Name) {
365   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
366   if (Pos != SubModuleIndex.end())
367     return SubModules[Pos->getValue()];
368   if (!InferSubmodules)
369     return nullptr;
370   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
371   Result->InferExplicitSubmodules = InferExplicitSubmodules;
372   Result->InferSubmodules = InferSubmodules;
373   Result->InferExportWildcard = InferExportWildcard;
374   if (Result->InferExportWildcard)
375     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
376   return Result;
377 }
378 
379 Module *Module::getGlobalModuleFragment() const {
380   assert(isNamedModuleUnit() && "We should only query the global module "
381                                 "fragment from the C++20 Named modules");
382 
383   for (auto *SubModule : SubModules)
384     if (SubModule->isExplicitGlobalModule())
385       return SubModule;
386 
387   return nullptr;
388 }
389 
390 Module *Module::getPrivateModuleFragment() const {
391   assert(isNamedModuleUnit() && "We should only query the private module "
392                                 "fragment from the C++20 Named modules");
393 
394   for (auto *SubModule : SubModules)
395     if (SubModule->isPrivateModule())
396       return SubModule;
397 
398   return nullptr;
399 }
400 
401 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
402   // All non-explicit submodules are exported.
403   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
404                                              E = SubModules.end();
405        I != E; ++I) {
406     Module *Mod = *I;
407     if (!Mod->IsExplicit)
408       Exported.push_back(Mod);
409   }
410 
411   // Find re-exported modules by filtering the list of imported modules.
412   bool AnyWildcard = false;
413   bool UnrestrictedWildcard = false;
414   SmallVector<Module *, 4> WildcardRestrictions;
415   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
416     Module *Mod = Exports[I].getPointer();
417     if (!Exports[I].getInt()) {
418       // Export a named module directly; no wildcards involved.
419       Exported.push_back(Mod);
420 
421       continue;
422     }
423 
424     // Wildcard export: export all of the imported modules that match
425     // the given pattern.
426     AnyWildcard = true;
427     if (UnrestrictedWildcard)
428       continue;
429 
430     if (Module *Restriction = Exports[I].getPointer())
431       WildcardRestrictions.push_back(Restriction);
432     else {
433       WildcardRestrictions.clear();
434       UnrestrictedWildcard = true;
435     }
436   }
437 
438   // If there were any wildcards, push any imported modules that were
439   // re-exported by the wildcard restriction.
440   if (!AnyWildcard)
441     return;
442 
443   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
444     Module *Mod = Imports[I];
445     bool Acceptable = UnrestrictedWildcard;
446     if (!Acceptable) {
447       // Check whether this module meets one of the restrictions.
448       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
449         Module *Restriction = WildcardRestrictions[R];
450         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
451           Acceptable = true;
452           break;
453         }
454       }
455     }
456 
457     if (!Acceptable)
458       continue;
459 
460     Exported.push_back(Mod);
461   }
462 }
463 
464 void Module::buildVisibleModulesCache() const {
465   assert(VisibleModulesCache.empty() && "cache does not need building");
466 
467   // This module is visible to itself.
468   VisibleModulesCache.insert(this);
469 
470   // Every imported module is visible.
471   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
472   while (!Stack.empty()) {
473     Module *CurrModule = Stack.pop_back_val();
474 
475     // Every module transitively exported by an imported module is visible.
476     if (VisibleModulesCache.insert(CurrModule).second)
477       CurrModule->getExportedModules(Stack);
478   }
479 }
480 
481 void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
482   OS.indent(Indent);
483   if (IsFramework)
484     OS << "framework ";
485   if (IsExplicit)
486     OS << "explicit ";
487   OS << "module ";
488   printModuleId(OS, &Name, &Name + 1);
489 
490   if (IsSystem || IsExternC) {
491     OS.indent(Indent + 2);
492     if (IsSystem)
493       OS << " [system]";
494     if (IsExternC)
495       OS << " [extern_c]";
496   }
497 
498   OS << " {\n";
499 
500   if (!Requirements.empty()) {
501     OS.indent(Indent + 2);
502     OS << "requires ";
503     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
504       if (I)
505         OS << ", ";
506       if (!Requirements[I].RequiredState)
507         OS << "!";
508       OS << Requirements[I].FeatureName;
509     }
510     OS << "\n";
511   }
512 
513   if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
514     OS.indent(Indent + 2);
515     OS << "umbrella header \"";
516     OS.write_escaped(H->NameAsWritten);
517     OS << "\"\n";
518   } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
519     OS.indent(Indent + 2);
520     OS << "umbrella \"";
521     OS.write_escaped(D->NameAsWritten);
522     OS << "\"\n";
523   }
524 
525   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
526     OS.indent(Indent + 2);
527     OS << "config_macros ";
528     if (ConfigMacrosExhaustive)
529       OS << "[exhaustive]";
530     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
531       if (I)
532         OS << ", ";
533       OS << ConfigMacros[I];
534     }
535     OS << "\n";
536   }
537 
538   struct {
539     StringRef Prefix;
540     HeaderKind Kind;
541   } Kinds[] = {{"", HK_Normal},
542                {"textual ", HK_Textual},
543                {"private ", HK_Private},
544                {"private textual ", HK_PrivateTextual},
545                {"exclude ", HK_Excluded}};
546 
547   for (auto &K : Kinds) {
548     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
549     for (auto &H : Headers[K.Kind]) {
550       OS.indent(Indent + 2);
551       OS << K.Prefix << "header \"";
552       OS.write_escaped(H.NameAsWritten);
553       OS << "\" { size " << H.Entry.getSize()
554          << " mtime " << H.Entry.getModificationTime() << " }\n";
555     }
556   }
557   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
558     for (auto &U : *Unresolved) {
559       OS.indent(Indent + 2);
560       OS << Kinds[U.Kind].Prefix << "header \"";
561       OS.write_escaped(U.FileName);
562       OS << "\"";
563       if (U.Size || U.ModTime) {
564         OS << " {";
565         if (U.Size)
566           OS << " size " << *U.Size;
567         if (U.ModTime)
568           OS << " mtime " << *U.ModTime;
569         OS << " }";
570       }
571       OS << "\n";
572     }
573   }
574 
575   if (!ExportAsModule.empty()) {
576     OS.indent(Indent + 2);
577     OS << "export_as" << ExportAsModule << "\n";
578   }
579 
580   for (auto *Submodule : submodules())
581     // Print inferred subframework modules so that we don't need to re-infer
582     // them (requires expensive directory iteration + stat calls) when we build
583     // the module. Regular inferred submodules are OK, as we need to look at all
584     // those header files anyway.
585     if (!Submodule->IsInferred || Submodule->IsFramework)
586       Submodule->print(OS, Indent + 2, Dump);
587 
588   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
589     OS.indent(Indent + 2);
590     OS << "export ";
591     if (Module *Restriction = Exports[I].getPointer()) {
592       OS << Restriction->getFullModuleName(true);
593       if (Exports[I].getInt())
594         OS << ".*";
595     } else {
596       OS << "*";
597     }
598     OS << "\n";
599   }
600 
601   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
602     OS.indent(Indent + 2);
603     OS << "export ";
604     printModuleId(OS, UnresolvedExports[I].Id);
605     if (UnresolvedExports[I].Wildcard)
606       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
607     OS << "\n";
608   }
609 
610   if (Dump) {
611     for (Module *M : Imports) {
612       OS.indent(Indent + 2);
613       llvm::errs() << "import " << M->getFullModuleName() << "\n";
614     }
615   }
616 
617   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
618     OS.indent(Indent + 2);
619     OS << "use ";
620     OS << DirectUses[I]->getFullModuleName(true);
621     OS << "\n";
622   }
623 
624   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
625     OS.indent(Indent + 2);
626     OS << "use ";
627     printModuleId(OS, UnresolvedDirectUses[I]);
628     OS << "\n";
629   }
630 
631   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
632     OS.indent(Indent + 2);
633     OS << "link ";
634     if (LinkLibraries[I].IsFramework)
635       OS << "framework ";
636     OS << "\"";
637     OS.write_escaped(LinkLibraries[I].Library);
638     OS << "\"";
639   }
640 
641   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
642     OS.indent(Indent + 2);
643     OS << "conflict ";
644     printModuleId(OS, UnresolvedConflicts[I].Id);
645     OS << ", \"";
646     OS.write_escaped(UnresolvedConflicts[I].Message);
647     OS << "\"\n";
648   }
649 
650   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
651     OS.indent(Indent + 2);
652     OS << "conflict ";
653     OS << Conflicts[I].Other->getFullModuleName(true);
654     OS << ", \"";
655     OS.write_escaped(Conflicts[I].Message);
656     OS << "\"\n";
657   }
658 
659   if (InferSubmodules) {
660     OS.indent(Indent + 2);
661     if (InferExplicitSubmodules)
662       OS << "explicit ";
663     OS << "module * {\n";
664     if (InferExportWildcard) {
665       OS.indent(Indent + 4);
666       OS << "export *\n";
667     }
668     OS.indent(Indent + 2);
669     OS << "}\n";
670   }
671 
672   OS.indent(Indent);
673   OS << "}\n";
674 }
675 
676 LLVM_DUMP_METHOD void Module::dump() const {
677   print(llvm::errs(), 0, true);
678 }
679 
680 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
681                                   VisibleCallback Vis, ConflictCallback Cb) {
682   // We can't import a global module fragment so the location can be invalid.
683   assert((M->isGlobalModule() || Loc.isValid()) &&
684          "setVisible expects a valid import location");
685   if (isVisible(M))
686     return;
687 
688   ++Generation;
689 
690   struct Visiting {
691     Module *M;
692     Visiting *ExportedBy;
693   };
694 
695   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
696     // Nothing to do for a module that's already visible.
697     unsigned ID = V.M->getVisibilityID();
698     if (ImportLocs.size() <= ID)
699       ImportLocs.resize(ID + 1);
700     else if (ImportLocs[ID].isValid())
701       return;
702 
703     ImportLocs[ID] = Loc;
704     Vis(V.M);
705 
706     // Make any exported modules visible.
707     SmallVector<Module *, 16> Exports;
708     V.M->getExportedModules(Exports);
709     for (Module *E : Exports) {
710       // Don't import non-importable modules.
711       if (!E->isUnimportable())
712         VisitModule({E, &V});
713     }
714 
715     for (auto &C : V.M->Conflicts) {
716       if (isVisible(C.Other)) {
717         llvm::SmallVector<Module*, 8> Path;
718         for (Visiting *I = &V; I; I = I->ExportedBy)
719           Path.push_back(I->M);
720         Cb(Path, C.Other, C.Message);
721       }
722     }
723   };
724   VisitModule({M, nullptr});
725 }
726