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