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