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