xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Module.cpp (revision a9174861eab9e786f6873fbe6374a1ac19a5e46a)
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