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