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