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 NamedModuleHasInit(true), 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 (auto *Submodule : SubModules) { 63 delete Submodule; 64 } 65 } 66 67 static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { 68 StringRef Platform = Target.getPlatformName(); 69 StringRef Env = Target.getTriple().getEnvironmentName(); 70 71 // Attempt to match platform and environment. 72 if (Platform == Feature || Target.getTriple().getOSName() == Feature || 73 Env == Feature) 74 return true; 75 76 auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) { 77 auto Pos = LHS.find('-'); 78 if (Pos == StringRef::npos) 79 return false; 80 SmallString<128> NewLHS = LHS.slice(0, Pos); 81 NewLHS += LHS.slice(Pos+1, LHS.size()); 82 return NewLHS == RHS; 83 }; 84 85 SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName(); 86 // Darwin has different but equivalent variants for simulators, example: 87 // 1. x86_64-apple-ios-simulator 88 // 2. x86_64-apple-iossimulator 89 // where both are valid examples of the same platform+environment but in the 90 // variant (2) the simulator is hardcoded as part of the platform name. Both 91 // forms above should match for "iossimulator" requirement. 92 if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")) 93 return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); 94 95 return PlatformEnv == Feature; 96 } 97 98 /// Determine whether a translation unit built using the current 99 /// language options has the given feature. 100 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, 101 const TargetInfo &Target) { 102 bool HasFeature = llvm::StringSwitch<bool>(Feature) 103 .Case("altivec", LangOpts.AltiVec) 104 .Case("blocks", LangOpts.Blocks) 105 .Case("coroutines", LangOpts.Coroutines) 106 .Case("cplusplus", LangOpts.CPlusPlus) 107 .Case("cplusplus11", LangOpts.CPlusPlus11) 108 .Case("cplusplus14", LangOpts.CPlusPlus14) 109 .Case("cplusplus17", LangOpts.CPlusPlus17) 110 .Case("cplusplus20", LangOpts.CPlusPlus20) 111 .Case("cplusplus23", LangOpts.CPlusPlus23) 112 .Case("cplusplus26", LangOpts.CPlusPlus26) 113 .Case("c99", LangOpts.C99) 114 .Case("c11", LangOpts.C11) 115 .Case("c17", LangOpts.C17) 116 .Case("c23", LangOpts.C23) 117 .Case("freestanding", LangOpts.Freestanding) 118 .Case("gnuinlineasm", LangOpts.GNUAsm) 119 .Case("objc", LangOpts.ObjC) 120 .Case("objc_arc", LangOpts.ObjCAutoRefCount) 121 .Case("opencl", LangOpts.OpenCL) 122 .Case("tls", Target.isTLSSupported()) 123 .Case("zvector", LangOpts.ZVector) 124 .Default(Target.hasFeature(Feature) || 125 isPlatformEnvironment(Target, Feature)); 126 if (!HasFeature) 127 HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature); 128 return HasFeature; 129 } 130 131 bool Module::isUnimportable(const LangOptions &LangOpts, 132 const TargetInfo &Target, Requirement &Req, 133 Module *&ShadowingModule) const { 134 if (!IsUnimportable) 135 return false; 136 137 for (const Module *Current = this; Current; Current = Current->Parent) { 138 if (Current->ShadowingModule) { 139 ShadowingModule = Current->ShadowingModule; 140 return true; 141 } 142 for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { 143 if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != 144 Current->Requirements[I].second) { 145 Req = Current->Requirements[I]; 146 return true; 147 } 148 } 149 } 150 151 llvm_unreachable("could not find a reason why module is unimportable"); 152 } 153 154 // The -fmodule-name option tells the compiler to textually include headers in 155 // the specified module, meaning Clang won't build the specified module. This 156 // is useful in a number of situations, for instance, when building a library 157 // that vends a module map, one might want to avoid hitting intermediate build 158 // products containing the module map or avoid finding the system installed 159 // modulemap for that library. 160 bool Module::isForBuilding(const LangOptions &LangOpts) const { 161 StringRef TopLevelName = getTopLevelModuleName(); 162 StringRef CurrentModule = LangOpts.CurrentModule; 163 164 // When building framework Foo, we want to make sure that Foo *and* 165 // Foo_Private are textually included and no modules are built for both. 166 if (getTopLevelModule()->IsFramework && 167 CurrentModule == LangOpts.ModuleName && 168 !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private")) 169 TopLevelName = TopLevelName.drop_back(8); 170 171 return TopLevelName == CurrentModule; 172 } 173 174 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, 175 Requirement &Req, 176 UnresolvedHeaderDirective &MissingHeader, 177 Module *&ShadowingModule) const { 178 if (IsAvailable) 179 return true; 180 181 if (isUnimportable(LangOpts, Target, Req, ShadowingModule)) 182 return false; 183 184 // FIXME: All missing headers are listed on the top-level module. Should we 185 // just look there? 186 for (const Module *Current = this; Current; Current = Current->Parent) { 187 if (!Current->MissingHeaders.empty()) { 188 MissingHeader = Current->MissingHeaders.front(); 189 return false; 190 } 191 } 192 193 llvm_unreachable("could not find a reason why module is unavailable"); 194 } 195 196 bool Module::isSubModuleOf(const Module *Other) const { 197 for (auto *Parent = this; Parent; Parent = Parent->Parent) { 198 if (Parent == Other) 199 return true; 200 } 201 return false; 202 } 203 204 const Module *Module::getTopLevelModule() const { 205 const Module *Result = this; 206 while (Result->Parent) 207 Result = Result->Parent; 208 209 return Result; 210 } 211 212 static StringRef getModuleNameFromComponent( 213 const std::pair<std::string, SourceLocation> &IdComponent) { 214 return IdComponent.first; 215 } 216 217 static StringRef getModuleNameFromComponent(StringRef R) { return R; } 218 219 template<typename InputIter> 220 static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, 221 bool AllowStringLiterals = true) { 222 for (InputIter It = Begin; It != End; ++It) { 223 if (It != Begin) 224 OS << "."; 225 226 StringRef Name = getModuleNameFromComponent(*It); 227 if (!AllowStringLiterals || isValidAsciiIdentifier(Name)) 228 OS << Name; 229 else { 230 OS << '"'; 231 OS.write_escaped(Name); 232 OS << '"'; 233 } 234 } 235 } 236 237 template<typename Container> 238 static void printModuleId(raw_ostream &OS, const Container &C) { 239 return printModuleId(OS, C.begin(), C.end()); 240 } 241 242 std::string Module::getFullModuleName(bool AllowStringLiterals) const { 243 SmallVector<StringRef, 2> Names; 244 245 // Build up the set of module names (from innermost to outermost). 246 for (const Module *M = this; M; M = M->Parent) 247 Names.push_back(M->Name); 248 249 std::string Result; 250 251 llvm::raw_string_ostream Out(Result); 252 printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); 253 Out.flush(); 254 255 return Result; 256 } 257 258 bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { 259 for (const Module *M = this; M; M = M->Parent) { 260 if (nameParts.empty() || M->Name != nameParts.back()) 261 return false; 262 nameParts = nameParts.drop_back(); 263 } 264 return nameParts.empty(); 265 } 266 267 OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const { 268 if (Umbrella && Umbrella.is<FileEntryRef>()) 269 return Umbrella.get<FileEntryRef>().getDir(); 270 if (Umbrella && Umbrella.is<DirectoryEntryRef>()) 271 return Umbrella.get<DirectoryEntryRef>(); 272 return std::nullopt; 273 } 274 275 void Module::addTopHeader(FileEntryRef File) { 276 assert(File); 277 TopHeaders.insert(File); 278 } 279 280 ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) { 281 if (!TopHeaderNames.empty()) { 282 for (StringRef TopHeaderName : TopHeaderNames) 283 if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName)) 284 TopHeaders.insert(*FE); 285 TopHeaderNames.clear(); 286 } 287 288 return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end()); 289 } 290 291 bool Module::directlyUses(const Module *Requested) { 292 auto *Top = getTopLevelModule(); 293 294 // A top-level module implicitly uses itself. 295 if (Requested->isSubModuleOf(Top)) 296 return true; 297 298 for (auto *Use : Top->DirectUses) 299 if (Requested->isSubModuleOf(Use)) 300 return true; 301 302 // Anyone is allowed to use our builtin stdarg.h and stddef.h and their 303 // accompanying modules. 304 if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" || 305 Requested->getTopLevelModuleName() == "_Builtin_stddef") 306 return true; 307 308 if (NoUndeclaredIncludes) 309 UndeclaredUses.insert(Requested); 310 311 return false; 312 } 313 314 void Module::addRequirement(StringRef Feature, bool RequiredState, 315 const LangOptions &LangOpts, 316 const TargetInfo &Target) { 317 Requirements.push_back(Requirement(std::string(Feature), RequiredState)); 318 319 // If this feature is currently available, we're done. 320 if (hasFeature(Feature, LangOpts, Target) == RequiredState) 321 return; 322 323 markUnavailable(/*Unimportable*/true); 324 } 325 326 void Module::markUnavailable(bool Unimportable) { 327 auto needUpdate = [Unimportable](Module *M) { 328 return M->IsAvailable || (!M->IsUnimportable && Unimportable); 329 }; 330 331 if (!needUpdate(this)) 332 return; 333 334 SmallVector<Module *, 2> Stack; 335 Stack.push_back(this); 336 while (!Stack.empty()) { 337 Module *Current = Stack.back(); 338 Stack.pop_back(); 339 340 if (!needUpdate(Current)) 341 continue; 342 343 Current->IsAvailable = false; 344 Current->IsUnimportable |= Unimportable; 345 for (auto *Submodule : Current->submodules()) { 346 if (needUpdate(Submodule)) 347 Stack.push_back(Submodule); 348 } 349 } 350 } 351 352 Module *Module::findSubmodule(StringRef Name) const { 353 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 354 if (Pos == SubModuleIndex.end()) 355 return nullptr; 356 357 return SubModules[Pos->getValue()]; 358 } 359 360 Module *Module::findOrInferSubmodule(StringRef Name) { 361 llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); 362 if (Pos != SubModuleIndex.end()) 363 return SubModules[Pos->getValue()]; 364 if (!InferSubmodules) 365 return nullptr; 366 Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0); 367 Result->InferExplicitSubmodules = InferExplicitSubmodules; 368 Result->InferSubmodules = InferSubmodules; 369 Result->InferExportWildcard = InferExportWildcard; 370 if (Result->InferExportWildcard) 371 Result->Exports.push_back(Module::ExportDecl(nullptr, true)); 372 return Result; 373 } 374 375 Module *Module::getGlobalModuleFragment() const { 376 assert(isNamedModuleUnit() && "We should only query the global module " 377 "fragment from the C++ 20 Named modules"); 378 379 for (auto *SubModule : SubModules) 380 if (SubModule->isExplicitGlobalModule()) 381 return SubModule; 382 383 return nullptr; 384 } 385 386 Module *Module::getPrivateModuleFragment() const { 387 assert(isNamedModuleUnit() && "We should only query the private module " 388 "fragment from the C++ 20 Named modules"); 389 390 for (auto *SubModule : SubModules) 391 if (SubModule->isPrivateModule()) 392 return SubModule; 393 394 return nullptr; 395 } 396 397 void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { 398 // All non-explicit submodules are exported. 399 for (std::vector<Module *>::const_iterator I = SubModules.begin(), 400 E = SubModules.end(); 401 I != E; ++I) { 402 Module *Mod = *I; 403 if (!Mod->IsExplicit) 404 Exported.push_back(Mod); 405 } 406 407 // Find re-exported modules by filtering the list of imported modules. 408 bool AnyWildcard = false; 409 bool UnrestrictedWildcard = false; 410 SmallVector<Module *, 4> WildcardRestrictions; 411 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 412 Module *Mod = Exports[I].getPointer(); 413 if (!Exports[I].getInt()) { 414 // Export a named module directly; no wildcards involved. 415 Exported.push_back(Mod); 416 417 continue; 418 } 419 420 // Wildcard export: export all of the imported modules that match 421 // the given pattern. 422 AnyWildcard = true; 423 if (UnrestrictedWildcard) 424 continue; 425 426 if (Module *Restriction = Exports[I].getPointer()) 427 WildcardRestrictions.push_back(Restriction); 428 else { 429 WildcardRestrictions.clear(); 430 UnrestrictedWildcard = true; 431 } 432 } 433 434 // If there were any wildcards, push any imported modules that were 435 // re-exported by the wildcard restriction. 436 if (!AnyWildcard) 437 return; 438 439 for (unsigned I = 0, N = Imports.size(); I != N; ++I) { 440 Module *Mod = Imports[I]; 441 bool Acceptable = UnrestrictedWildcard; 442 if (!Acceptable) { 443 // Check whether this module meets one of the restrictions. 444 for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { 445 Module *Restriction = WildcardRestrictions[R]; 446 if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { 447 Acceptable = true; 448 break; 449 } 450 } 451 } 452 453 if (!Acceptable) 454 continue; 455 456 Exported.push_back(Mod); 457 } 458 } 459 460 void Module::buildVisibleModulesCache() const { 461 assert(VisibleModulesCache.empty() && "cache does not need building"); 462 463 // This module is visible to itself. 464 VisibleModulesCache.insert(this); 465 466 // Every imported module is visible. 467 SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); 468 while (!Stack.empty()) { 469 Module *CurrModule = Stack.pop_back_val(); 470 471 // Every module transitively exported by an imported module is visible. 472 if (VisibleModulesCache.insert(CurrModule).second) 473 CurrModule->getExportedModules(Stack); 474 } 475 } 476 477 void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { 478 OS.indent(Indent); 479 if (IsFramework) 480 OS << "framework "; 481 if (IsExplicit) 482 OS << "explicit "; 483 OS << "module "; 484 printModuleId(OS, &Name, &Name + 1); 485 486 if (IsSystem || IsExternC) { 487 OS.indent(Indent + 2); 488 if (IsSystem) 489 OS << " [system]"; 490 if (IsExternC) 491 OS << " [extern_c]"; 492 } 493 494 OS << " {\n"; 495 496 if (!Requirements.empty()) { 497 OS.indent(Indent + 2); 498 OS << "requires "; 499 for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { 500 if (I) 501 OS << ", "; 502 if (!Requirements[I].second) 503 OS << "!"; 504 OS << Requirements[I].first; 505 } 506 OS << "\n"; 507 } 508 509 if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) { 510 OS.indent(Indent + 2); 511 OS << "umbrella header \""; 512 OS.write_escaped(H->NameAsWritten); 513 OS << "\"\n"; 514 } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) { 515 OS.indent(Indent + 2); 516 OS << "umbrella \""; 517 OS.write_escaped(D->NameAsWritten); 518 OS << "\"\n"; 519 } 520 521 if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { 522 OS.indent(Indent + 2); 523 OS << "config_macros "; 524 if (ConfigMacrosExhaustive) 525 OS << "[exhaustive]"; 526 for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { 527 if (I) 528 OS << ", "; 529 OS << ConfigMacros[I]; 530 } 531 OS << "\n"; 532 } 533 534 struct { 535 StringRef Prefix; 536 HeaderKind Kind; 537 } Kinds[] = {{"", HK_Normal}, 538 {"textual ", HK_Textual}, 539 {"private ", HK_Private}, 540 {"private textual ", HK_PrivateTextual}, 541 {"exclude ", HK_Excluded}}; 542 543 for (auto &K : Kinds) { 544 assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); 545 for (auto &H : Headers[K.Kind]) { 546 OS.indent(Indent + 2); 547 OS << K.Prefix << "header \""; 548 OS.write_escaped(H.NameAsWritten); 549 OS << "\" { size " << H.Entry.getSize() 550 << " mtime " << H.Entry.getModificationTime() << " }\n"; 551 } 552 } 553 for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { 554 for (auto &U : *Unresolved) { 555 OS.indent(Indent + 2); 556 OS << Kinds[U.Kind].Prefix << "header \""; 557 OS.write_escaped(U.FileName); 558 OS << "\""; 559 if (U.Size || U.ModTime) { 560 OS << " {"; 561 if (U.Size) 562 OS << " size " << *U.Size; 563 if (U.ModTime) 564 OS << " mtime " << *U.ModTime; 565 OS << " }"; 566 } 567 OS << "\n"; 568 } 569 } 570 571 if (!ExportAsModule.empty()) { 572 OS.indent(Indent + 2); 573 OS << "export_as" << ExportAsModule << "\n"; 574 } 575 576 for (auto *Submodule : submodules()) 577 // Print inferred subframework modules so that we don't need to re-infer 578 // them (requires expensive directory iteration + stat calls) when we build 579 // the module. Regular inferred submodules are OK, as we need to look at all 580 // those header files anyway. 581 if (!Submodule->IsInferred || Submodule->IsFramework) 582 Submodule->print(OS, Indent + 2, Dump); 583 584 for (unsigned I = 0, N = Exports.size(); I != N; ++I) { 585 OS.indent(Indent + 2); 586 OS << "export "; 587 if (Module *Restriction = Exports[I].getPointer()) { 588 OS << Restriction->getFullModuleName(true); 589 if (Exports[I].getInt()) 590 OS << ".*"; 591 } else { 592 OS << "*"; 593 } 594 OS << "\n"; 595 } 596 597 for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) { 598 OS.indent(Indent + 2); 599 OS << "export "; 600 printModuleId(OS, UnresolvedExports[I].Id); 601 if (UnresolvedExports[I].Wildcard) 602 OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); 603 OS << "\n"; 604 } 605 606 if (Dump) { 607 for (Module *M : Imports) { 608 OS.indent(Indent + 2); 609 llvm::errs() << "import " << M->getFullModuleName() << "\n"; 610 } 611 } 612 613 for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) { 614 OS.indent(Indent + 2); 615 OS << "use "; 616 OS << DirectUses[I]->getFullModuleName(true); 617 OS << "\n"; 618 } 619 620 for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) { 621 OS.indent(Indent + 2); 622 OS << "use "; 623 printModuleId(OS, UnresolvedDirectUses[I]); 624 OS << "\n"; 625 } 626 627 for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { 628 OS.indent(Indent + 2); 629 OS << "link "; 630 if (LinkLibraries[I].IsFramework) 631 OS << "framework "; 632 OS << "\""; 633 OS.write_escaped(LinkLibraries[I].Library); 634 OS << "\""; 635 } 636 637 for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { 638 OS.indent(Indent + 2); 639 OS << "conflict "; 640 printModuleId(OS, UnresolvedConflicts[I].Id); 641 OS << ", \""; 642 OS.write_escaped(UnresolvedConflicts[I].Message); 643 OS << "\"\n"; 644 } 645 646 for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { 647 OS.indent(Indent + 2); 648 OS << "conflict "; 649 OS << Conflicts[I].Other->getFullModuleName(true); 650 OS << ", \""; 651 OS.write_escaped(Conflicts[I].Message); 652 OS << "\"\n"; 653 } 654 655 if (InferSubmodules) { 656 OS.indent(Indent + 2); 657 if (InferExplicitSubmodules) 658 OS << "explicit "; 659 OS << "module * {\n"; 660 if (InferExportWildcard) { 661 OS.indent(Indent + 4); 662 OS << "export *\n"; 663 } 664 OS.indent(Indent + 2); 665 OS << "}\n"; 666 } 667 668 OS.indent(Indent); 669 OS << "}\n"; 670 } 671 672 LLVM_DUMP_METHOD void Module::dump() const { 673 print(llvm::errs(), 0, true); 674 } 675 676 void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, 677 VisibleCallback Vis, ConflictCallback Cb) { 678 // We can't import a global module fragment so the location can be invalid. 679 assert((M->isGlobalModule() || Loc.isValid()) && 680 "setVisible expects a valid import location"); 681 if (isVisible(M)) 682 return; 683 684 ++Generation; 685 686 struct Visiting { 687 Module *M; 688 Visiting *ExportedBy; 689 }; 690 691 std::function<void(Visiting)> VisitModule = [&](Visiting V) { 692 // Nothing to do for a module that's already visible. 693 unsigned ID = V.M->getVisibilityID(); 694 if (ImportLocs.size() <= ID) 695 ImportLocs.resize(ID + 1); 696 else if (ImportLocs[ID].isValid()) 697 return; 698 699 ImportLocs[ID] = Loc; 700 Vis(V.M); 701 702 // Make any exported modules visible. 703 SmallVector<Module *, 16> Exports; 704 V.M->getExportedModules(Exports); 705 for (Module *E : Exports) { 706 // Don't import non-importable modules. 707 if (!E->isUnimportable()) 708 VisitModule({E, &V}); 709 } 710 711 for (auto &C : V.M->Conflicts) { 712 if (isVisible(C.Other)) { 713 llvm::SmallVector<Module*, 8> Path; 714 for (Visiting *I = &V; I; I = I->ExportedBy) 715 Path.push_back(I->M); 716 Cb(Path, C.Other, C.Message); 717 } 718 } 719 }; 720 VisitModule({M, nullptr}); 721 } 722 723 void VisibleModuleSet::makeTransitiveImportsVisible(Module *M, 724 SourceLocation Loc, 725 VisibleCallback Vis, 726 ConflictCallback Cb) { 727 for (auto *I : M->Imports) 728 setVisible(I, Loc, Vis, Cb); 729 } 730 731 ASTSourceDescriptor::ASTSourceDescriptor(Module &M) 732 : Signature(M.Signature), ClangModule(&M) { 733 if (M.Directory) 734 Path = M.Directory->getName(); 735 if (auto File = M.getASTFile()) 736 ASTFile = File->getName(); 737 } 738 739 std::string ASTSourceDescriptor::getModuleName() const { 740 if (ClangModule) 741 return ClangModule->Name; 742 else 743 return std::string(PCHModuleName); 744 } 745