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