xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Module.cpp (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
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) const {
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   return false;
286 }
287 
288 void Module::addRequirement(StringRef Feature, bool RequiredState,
289                             const LangOptions &LangOpts,
290                             const TargetInfo &Target) {
291   Requirements.push_back(Requirement(std::string(Feature), RequiredState));
292 
293   // If this feature is currently available, we're done.
294   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
295     return;
296 
297   markUnavailable(/*Unimportable*/true);
298 }
299 
300 void Module::markUnavailable(bool Unimportable) {
301   auto needUpdate = [Unimportable](Module *M) {
302     return M->IsAvailable || (!M->IsUnimportable && Unimportable);
303   };
304 
305   if (!needUpdate(this))
306     return;
307 
308   SmallVector<Module *, 2> Stack;
309   Stack.push_back(this);
310   while (!Stack.empty()) {
311     Module *Current = Stack.back();
312     Stack.pop_back();
313 
314     if (!needUpdate(Current))
315       continue;
316 
317     Current->IsAvailable = false;
318     Current->IsUnimportable |= Unimportable;
319     for (submodule_iterator Sub = Current->submodule_begin(),
320                          SubEnd = Current->submodule_end();
321          Sub != SubEnd; ++Sub) {
322       if (needUpdate(*Sub))
323         Stack.push_back(*Sub);
324     }
325   }
326 }
327 
328 Module *Module::findSubmodule(StringRef Name) const {
329   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
330   if (Pos == SubModuleIndex.end())
331     return nullptr;
332 
333   return SubModules[Pos->getValue()];
334 }
335 
336 Module *Module::findOrInferSubmodule(StringRef Name) {
337   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
338   if (Pos != SubModuleIndex.end())
339     return SubModules[Pos->getValue()];
340   if (!InferSubmodules)
341     return nullptr;
342   Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
343   Result->InferExplicitSubmodules = InferExplicitSubmodules;
344   Result->InferSubmodules = InferSubmodules;
345   Result->InferExportWildcard = InferExportWildcard;
346   if (Result->InferExportWildcard)
347     Result->Exports.push_back(Module::ExportDecl(nullptr, true));
348   return Result;
349 }
350 
351 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
352   // All non-explicit submodules are exported.
353   for (std::vector<Module *>::const_iterator I = SubModules.begin(),
354                                              E = SubModules.end();
355        I != E; ++I) {
356     Module *Mod = *I;
357     if (!Mod->IsExplicit)
358       Exported.push_back(Mod);
359   }
360 
361   // Find re-exported modules by filtering the list of imported modules.
362   bool AnyWildcard = false;
363   bool UnrestrictedWildcard = false;
364   SmallVector<Module *, 4> WildcardRestrictions;
365   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
366     Module *Mod = Exports[I].getPointer();
367     if (!Exports[I].getInt()) {
368       // Export a named module directly; no wildcards involved.
369       Exported.push_back(Mod);
370 
371       continue;
372     }
373 
374     // Wildcard export: export all of the imported modules that match
375     // the given pattern.
376     AnyWildcard = true;
377     if (UnrestrictedWildcard)
378       continue;
379 
380     if (Module *Restriction = Exports[I].getPointer())
381       WildcardRestrictions.push_back(Restriction);
382     else {
383       WildcardRestrictions.clear();
384       UnrestrictedWildcard = true;
385     }
386   }
387 
388   // If there were any wildcards, push any imported modules that were
389   // re-exported by the wildcard restriction.
390   if (!AnyWildcard)
391     return;
392 
393   for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
394     Module *Mod = Imports[I];
395     bool Acceptable = UnrestrictedWildcard;
396     if (!Acceptable) {
397       // Check whether this module meets one of the restrictions.
398       for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
399         Module *Restriction = WildcardRestrictions[R];
400         if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
401           Acceptable = true;
402           break;
403         }
404       }
405     }
406 
407     if (!Acceptable)
408       continue;
409 
410     Exported.push_back(Mod);
411   }
412 }
413 
414 void Module::buildVisibleModulesCache() const {
415   assert(VisibleModulesCache.empty() && "cache does not need building");
416 
417   // This module is visible to itself.
418   VisibleModulesCache.insert(this);
419 
420   // Every imported module is visible.
421   SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
422   while (!Stack.empty()) {
423     Module *CurrModule = Stack.pop_back_val();
424 
425     // Every module transitively exported by an imported module is visible.
426     if (VisibleModulesCache.insert(CurrModule).second)
427       CurrModule->getExportedModules(Stack);
428   }
429 }
430 
431 void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
432   OS.indent(Indent);
433   if (IsFramework)
434     OS << "framework ";
435   if (IsExplicit)
436     OS << "explicit ";
437   OS << "module ";
438   printModuleId(OS, &Name, &Name + 1);
439 
440   if (IsSystem || IsExternC) {
441     OS.indent(Indent + 2);
442     if (IsSystem)
443       OS << " [system]";
444     if (IsExternC)
445       OS << " [extern_c]";
446   }
447 
448   OS << " {\n";
449 
450   if (!Requirements.empty()) {
451     OS.indent(Indent + 2);
452     OS << "requires ";
453     for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
454       if (I)
455         OS << ", ";
456       if (!Requirements[I].second)
457         OS << "!";
458       OS << Requirements[I].first;
459     }
460     OS << "\n";
461   }
462 
463   if (Header H = getUmbrellaHeader()) {
464     OS.indent(Indent + 2);
465     OS << "umbrella header \"";
466     OS.write_escaped(H.NameAsWritten);
467     OS << "\"\n";
468   } else if (DirectoryName D = getUmbrellaDir()) {
469     OS.indent(Indent + 2);
470     OS << "umbrella \"";
471     OS.write_escaped(D.NameAsWritten);
472     OS << "\"\n";
473   }
474 
475   if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
476     OS.indent(Indent + 2);
477     OS << "config_macros ";
478     if (ConfigMacrosExhaustive)
479       OS << "[exhaustive]";
480     for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
481       if (I)
482         OS << ", ";
483       OS << ConfigMacros[I];
484     }
485     OS << "\n";
486   }
487 
488   struct {
489     StringRef Prefix;
490     HeaderKind Kind;
491   } Kinds[] = {{"", HK_Normal},
492                {"textual ", HK_Textual},
493                {"private ", HK_Private},
494                {"private textual ", HK_PrivateTextual},
495                {"exclude ", HK_Excluded}};
496 
497   for (auto &K : Kinds) {
498     assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
499     for (auto &H : Headers[K.Kind]) {
500       OS.indent(Indent + 2);
501       OS << K.Prefix << "header \"";
502       OS.write_escaped(H.NameAsWritten);
503       OS << "\" { size " << H.Entry->getSize()
504          << " mtime " << H.Entry->getModificationTime() << " }\n";
505     }
506   }
507   for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
508     for (auto &U : *Unresolved) {
509       OS.indent(Indent + 2);
510       OS << Kinds[U.Kind].Prefix << "header \"";
511       OS.write_escaped(U.FileName);
512       OS << "\"";
513       if (U.Size || U.ModTime) {
514         OS << " {";
515         if (U.Size)
516           OS << " size " << *U.Size;
517         if (U.ModTime)
518           OS << " mtime " << *U.ModTime;
519         OS << " }";
520       }
521       OS << "\n";
522     }
523   }
524 
525   if (!ExportAsModule.empty()) {
526     OS.indent(Indent + 2);
527     OS << "export_as" << ExportAsModule << "\n";
528   }
529 
530   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
531        MI != MIEnd; ++MI)
532     // Print inferred subframework modules so that we don't need to re-infer
533     // them (requires expensive directory iteration + stat calls) when we build
534     // the module. Regular inferred submodules are OK, as we need to look at all
535     // those header files anyway.
536     if (!(*MI)->IsInferred || (*MI)->IsFramework)
537       (*MI)->print(OS, Indent + 2, Dump);
538 
539   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
540     OS.indent(Indent + 2);
541     OS << "export ";
542     if (Module *Restriction = Exports[I].getPointer()) {
543       OS << Restriction->getFullModuleName(true);
544       if (Exports[I].getInt())
545         OS << ".*";
546     } else {
547       OS << "*";
548     }
549     OS << "\n";
550   }
551 
552   for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
553     OS.indent(Indent + 2);
554     OS << "export ";
555     printModuleId(OS, UnresolvedExports[I].Id);
556     if (UnresolvedExports[I].Wildcard)
557       OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
558     OS << "\n";
559   }
560 
561   if (Dump) {
562     for (Module *M : Imports) {
563       OS.indent(Indent + 2);
564       llvm::errs() << "import " << M->getFullModuleName() << "\n";
565     }
566   }
567 
568   for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
569     OS.indent(Indent + 2);
570     OS << "use ";
571     OS << DirectUses[I]->getFullModuleName(true);
572     OS << "\n";
573   }
574 
575   for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
576     OS.indent(Indent + 2);
577     OS << "use ";
578     printModuleId(OS, UnresolvedDirectUses[I]);
579     OS << "\n";
580   }
581 
582   for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
583     OS.indent(Indent + 2);
584     OS << "link ";
585     if (LinkLibraries[I].IsFramework)
586       OS << "framework ";
587     OS << "\"";
588     OS.write_escaped(LinkLibraries[I].Library);
589     OS << "\"";
590   }
591 
592   for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
593     OS.indent(Indent + 2);
594     OS << "conflict ";
595     printModuleId(OS, UnresolvedConflicts[I].Id);
596     OS << ", \"";
597     OS.write_escaped(UnresolvedConflicts[I].Message);
598     OS << "\"\n";
599   }
600 
601   for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
602     OS.indent(Indent + 2);
603     OS << "conflict ";
604     OS << Conflicts[I].Other->getFullModuleName(true);
605     OS << ", \"";
606     OS.write_escaped(Conflicts[I].Message);
607     OS << "\"\n";
608   }
609 
610   if (InferSubmodules) {
611     OS.indent(Indent + 2);
612     if (InferExplicitSubmodules)
613       OS << "explicit ";
614     OS << "module * {\n";
615     if (InferExportWildcard) {
616       OS.indent(Indent + 4);
617       OS << "export *\n";
618     }
619     OS.indent(Indent + 2);
620     OS << "}\n";
621   }
622 
623   OS.indent(Indent);
624   OS << "}\n";
625 }
626 
627 LLVM_DUMP_METHOD void Module::dump() const {
628   print(llvm::errs(), 0, true);
629 }
630 
631 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
632                                   VisibleCallback Vis, ConflictCallback Cb) {
633   assert(Loc.isValid() && "setVisible expects a valid import location");
634   if (isVisible(M))
635     return;
636 
637   ++Generation;
638 
639   struct Visiting {
640     Module *M;
641     Visiting *ExportedBy;
642   };
643 
644   std::function<void(Visiting)> VisitModule = [&](Visiting V) {
645     // Nothing to do for a module that's already visible.
646     unsigned ID = V.M->getVisibilityID();
647     if (ImportLocs.size() <= ID)
648       ImportLocs.resize(ID + 1);
649     else if (ImportLocs[ID].isValid())
650       return;
651 
652     ImportLocs[ID] = Loc;
653     Vis(M);
654 
655     // Make any exported modules visible.
656     SmallVector<Module *, 16> Exports;
657     V.M->getExportedModules(Exports);
658     for (Module *E : Exports) {
659       // Don't import non-importable modules.
660       if (!E->isUnimportable())
661         VisitModule({E, &V});
662     }
663 
664     for (auto &C : V.M->Conflicts) {
665       if (isVisible(C.Other)) {
666         llvm::SmallVector<Module*, 8> Path;
667         for (Visiting *I = &V; I; I = I->ExportedBy)
668           Path.push_back(I->M);
669         Cb(Path, C.Other, C.Message);
670       }
671     }
672   };
673   VisitModule({M, nullptr});
674 }
675 
676 ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
677     : Signature(M.Signature), ClangModule(&M) {
678   if (M.Directory)
679     Path = M.Directory->getName();
680   if (auto File = M.getASTFile())
681     ASTFile = File->getName();
682 }
683 
684 std::string ASTSourceDescriptor::getModuleName() const {
685   if (ClangModule)
686     return ClangModule->Name;
687   else
688     return std::string(PCHModuleName);
689 }
690