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