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