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