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