|
74 | 74 | #include "llvm/Support/Allocator.h"
|
75 | 75 | #include "llvm/Support/Compiler.h"
|
76 | 76 | #include "llvm/Support/FormatVariadic.h"
|
| 77 | +#include "llvm/Support/VersionTuple.h" |
77 | 78 | #include "llvm/Support/VirtualOutputBackend.h"
|
78 | 79 | #include "llvm/Support/VirtualOutputBackends.h"
|
79 | 80 | #include <algorithm>
|
@@ -786,6 +787,12 @@ ASTContext::ASTContext(
|
786 | 787 | registerAccessRequestFunctions(evaluator);
|
787 | 788 | registerNameLookupRequestFunctions(evaluator);
|
788 | 789 |
|
| 790 | + // Register canImport module info. |
| 791 | + for (auto &info: SearchPathOpts.CanImportModuleInfo) { |
| 792 | + addSucceededCanImportModule(info.ModuleName, false, info.Version); |
| 793 | + addSucceededCanImportModule(info.ModuleName, true, info.UnderlyingVersion); |
| 794 | + } |
| 795 | + |
789 | 796 | // Provide a default OnDiskOutputBackend if user didn't supply one.
|
790 | 797 | if (!OutputBackend)
|
791 | 798 | OutputBackend = llvm::makeIntrusiveRefCnt<llvm::vfs::OnDiskOutputBackend>();
|
@@ -2385,23 +2392,56 @@ getModuleVersionKindString(const ModuleLoader::ModuleVersionInfo &info) {
|
2385 | 2392 | }
|
2386 | 2393 | }
|
2387 | 2394 |
|
2388 |
| -bool ASTContext::canImportModuleImpl(ImportPath::Module ModuleName, |
2389 |
| - llvm::VersionTuple version, |
2390 |
| - bool underlyingVersion, |
2391 |
| - bool updateFailingList) const { |
| 2395 | +void ASTContext::addSucceededCanImportModule( |
| 2396 | + StringRef moduleName, bool underlyingVersion, |
| 2397 | + const llvm::VersionTuple &versionInfo) { |
| 2398 | + auto &entry = CanImportModuleVersions[moduleName.str()]; |
| 2399 | + if (!versionInfo.empty()) { |
| 2400 | + if (underlyingVersion) |
| 2401 | + entry.UnderlyingVersion = versionInfo; |
| 2402 | + else |
| 2403 | + entry.Version = versionInfo; |
| 2404 | + } |
| 2405 | +} |
| 2406 | + |
| 2407 | +bool ASTContext::canImportModuleImpl( |
| 2408 | + ImportPath::Module ModuleName, llvm::VersionTuple version, |
| 2409 | + bool underlyingVersion, bool updateFailingList, |
| 2410 | + llvm::VersionTuple &foundVersion) const { |
2392 | 2411 | SmallString<64> FullModuleName;
|
2393 | 2412 | ModuleName.getString(FullModuleName);
|
2394 |
| - auto ModuleNameStr = FullModuleName.str(); |
| 2413 | + auto ModuleNameStr = FullModuleName.str().str(); |
2395 | 2414 |
|
2396 | 2415 | // If we've failed loading this module before, don't look for it again.
|
2397 | 2416 | if (FailedModuleImportNames.count(ModuleNameStr))
|
2398 | 2417 | return false;
|
2399 | 2418 |
|
2400 |
| - if (version.empty()) { |
2401 |
| - // If this module has already been checked successfully, it is importable. |
2402 |
| - if (SucceededModuleImportNames.count(ModuleNameStr)) |
| 2419 | + // If this module has already been checked or there is information for the |
| 2420 | + // module from commandline, use that information instead of loading the |
| 2421 | + // module. |
| 2422 | + auto Found = CanImportModuleVersions.find(ModuleNameStr); |
| 2423 | + if (Found != CanImportModuleVersions.end()) { |
| 2424 | + if (version.empty()) |
2403 | 2425 | return true;
|
2404 | 2426 |
|
| 2427 | + if (underlyingVersion) { |
| 2428 | + if (!Found->second.UnderlyingVersion.empty()) |
| 2429 | + return version <= Found->second.UnderlyingVersion; |
| 2430 | + } else { |
| 2431 | + if (!Found->second.Version.empty()) |
| 2432 | + return version <= Found->second.Version; |
| 2433 | + } |
| 2434 | + |
| 2435 | + // If the canImport information is coming from the command-line, then no |
| 2436 | + // need to continue the search, return false. For checking modules that are |
| 2437 | + // not passed from command-line, allow fallback to the module loading since |
| 2438 | + // this is not in a canImport request context that has already been resolved |
| 2439 | + // by scanner. |
| 2440 | + if (!SearchPathOpts.CanImportModuleInfo.empty()) |
| 2441 | + return false; |
| 2442 | + } |
| 2443 | + |
| 2444 | + if (version.empty()) { |
2405 | 2445 | // If this module has already been successfully imported, it is importable.
|
2406 | 2446 | if (getLoadedModule(ModuleName) != nullptr)
|
2407 | 2447 | return true;
|
@@ -2453,28 +2493,38 @@ bool ASTContext::canImportModuleImpl(ImportPath::Module ModuleName,
|
2453 | 2493 | return true;
|
2454 | 2494 | }
|
2455 | 2495 |
|
| 2496 | + foundVersion = bestVersionInfo.getVersion(); |
2456 | 2497 | return version <= bestVersionInfo.getVersion();
|
2457 | 2498 | }
|
2458 | 2499 |
|
2459 |
| -bool ASTContext::canImportModule(ImportPath::Module ModuleName, |
| 2500 | +void ASTContext::forEachCanImportVersionCheck( |
| 2501 | + std::function<void(StringRef, const llvm::VersionTuple &, |
| 2502 | + const llvm::VersionTuple &)> |
| 2503 | + Callback) const { |
| 2504 | + for (auto &entry : CanImportModuleVersions) |
| 2505 | + Callback(entry.first, entry.second.Version, entry.second.UnderlyingVersion); |
| 2506 | +} |
| 2507 | + |
| 2508 | +bool ASTContext::canImportModule(ImportPath::Module moduleName, |
2460 | 2509 | llvm::VersionTuple version,
|
2461 | 2510 | bool underlyingVersion) {
|
2462 |
| - if (!canImportModuleImpl(ModuleName, version, underlyingVersion, true)) |
| 2511 | + llvm::VersionTuple versionInfo; |
| 2512 | + if (!canImportModuleImpl(moduleName, version, underlyingVersion, true, |
| 2513 | + versionInfo)) |
2463 | 2514 | return false;
|
2464 | 2515 |
|
2465 |
| - // If checked successfully, add the top level name to success list as |
2466 |
| - // dependency to handle clang submodule correctly. Swift does not have |
2467 |
| - // submodule so the name should be the same. |
2468 |
| - SmallString<64> TopModuleName; |
2469 |
| - ModuleName.getTopLevelPath().getString(TopModuleName); |
2470 |
| - SucceededModuleImportNames.insert(TopModuleName.str()); |
| 2516 | + SmallString<64> fullModuleName; |
| 2517 | + moduleName.getString(fullModuleName); |
| 2518 | + addSucceededCanImportModule(fullModuleName, underlyingVersion, versionInfo); |
2471 | 2519 | return true;
|
2472 | 2520 | }
|
2473 | 2521 |
|
2474 | 2522 | bool ASTContext::testImportModule(ImportPath::Module ModuleName,
|
2475 | 2523 | llvm::VersionTuple version,
|
2476 | 2524 | bool underlyingVersion) const {
|
2477 |
| - return canImportModuleImpl(ModuleName, version, underlyingVersion, false); |
| 2525 | + llvm::VersionTuple versionInfo; |
| 2526 | + return canImportModuleImpl(ModuleName, version, underlyingVersion, false, |
| 2527 | + versionInfo); |
2478 | 2528 | }
|
2479 | 2529 |
|
2480 | 2530 | ModuleDecl *
|
|
0 commit comments