From 93da5b4797d14ef40af2845ea1816227b1a824ff Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Tue, 20 May 2025 14:16:23 -0700 Subject: [PATCH] [Dependency Scanning][C++ Interop] Remap lookup of Clang module 'CxxStdlib' to 'std' Otherwise querying this clang module, e.g. from the corresponding Swift overlay's underlying module import, will fail, since no such module exists. Resolves rdar://151718115 --- include/swift/AST/ModuleDependencies.h | 5 + .../DependencyScan/ModuleDependencyScanner.h | 13 -- .../ModuleDependencyScanner.cpp | 121 +++++------------- lib/DependencyScan/ScanDependencies.cpp | 3 +- ...cxx-overlay-underlying-module-lookup.swift | 35 +++++ 5 files changed, 71 insertions(+), 106 deletions(-) create mode 100644 test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index 998a57650f637..cf22b5f0a42eb 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -164,6 +164,11 @@ struct ScannerImportStatementInfo { : importLocations({location}), importIdentifier(importIdentifier), isExported(isExported) {} + ScannerImportStatementInfo(std::string importIdentifier, bool isExported, + SmallVector locations) + : importLocations(locations), importIdentifier(importIdentifier), + isExported(isExported) {} + void addImportLocation(ImportDiagnosticLocationInfo location) { importLocations.push_back(location); } diff --git a/include/swift/DependencyScan/ModuleDependencyScanner.h b/include/swift/DependencyScan/ModuleDependencyScanner.h index 6d8b90aaafb62..a090940930dda 100644 --- a/include/swift/DependencyScan/ModuleDependencyScanner.h +++ b/include/swift/DependencyScan/ModuleDependencyScanner.h @@ -128,19 +128,6 @@ class ModuleDependencyScanner { performDependencyScan(ModuleDependencyID rootModuleID, ModuleDependenciesCache &cache); - /// Query the module dependency info for the Clang module with the given name. - /// Explicit by-name lookups are useful for batch mode scanning. - std::optional - getNamedClangModuleDependencyInfo(StringRef moduleName, - ModuleDependenciesCache &cache, - ModuleDependencyIDSetVector &discoveredClangModules); - - /// Query the module dependency info for the Swift module with the given name. - /// Explicit by-name lookups are useful for batch mode scanning. - std::optional - getNamedSwiftModuleDependencyInfo(StringRef moduleName, - ModuleDependenciesCache &cache); - /// How many filesystem lookups were performed by the scanner unsigned getNumLookups() { return NumLookups; } diff --git a/lib/DependencyScan/ModuleDependencyScanner.cpp b/lib/DependencyScan/ModuleDependencyScanner.cpp index 358f4904ecfd7..25b3222b7a120 100644 --- a/lib/DependencyScan/ModuleDependencyScanner.cpp +++ b/lib/DependencyScan/ModuleDependencyScanner.cpp @@ -695,88 +695,6 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) { return mainDependencies; } -/// Retrieve the module dependencies for the Clang module with the given name. -std::optional -ModuleDependencyScanner::getNamedClangModuleDependencyInfo( - StringRef moduleName, ModuleDependenciesCache &cache, - ModuleDependencyIDSetVector &discoveredClangModules) { - // Check whether we've cached this result. - auto moduleID = ModuleDependencyID{moduleName.str(), - ModuleDependencyKind::Clang}; - if (auto found = cache.findDependency(moduleID)) { - discoveredClangModules.insert(moduleID); - auto directClangDeps = cache.getImportedClangDependencies(moduleID); - ModuleDependencyIDSetVector reachableClangModules; - reachableClangModules.insert(directClangDeps.begin(), - directClangDeps.end()); - for (unsigned currentModuleIdx = 0; - currentModuleIdx < reachableClangModules.size(); - ++currentModuleIdx) { - auto moduleID = reachableClangModules[currentModuleIdx]; - auto dependencies = - cache.findKnownDependency(moduleID).getImportedClangDependencies(); - reachableClangModules.insert(dependencies.begin(), dependencies.end()); - } - discoveredClangModules.insert(reachableClangModules.begin(), - reachableClangModules.end()); - return found; - } - - // Otherwise perform filesystem scan - auto moduleIdentifier = getModuleImportIdentifier(moduleName); - auto moduleDependencies = withDependencyScanningWorker( - [&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) { - return ScanningWorker->scanFilesystemForClangModuleDependency( - moduleIdentifier, cache.getModuleOutputPath(), - cache.getSDKModuleOutputPath(), - cache.getAlreadySeenClangModules(), - cache.getScanService().getPrefixMapper()); - }); - if (moduleDependencies.empty()) - return std::nullopt; - - discoveredClangModules.insert(moduleID); - for (const auto &dep : moduleDependencies) - discoveredClangModules.insert(dep.first); - - cache.recordDependencies(moduleDependencies, Diagnostics); - return cache.findDependency(moduleID); -} - -/// Retrieve the module dependencies for the Swift module with the given name. -std::optional -ModuleDependencyScanner::getNamedSwiftModuleDependencyInfo( - StringRef moduleName, ModuleDependenciesCache &cache) { - // Check whether we've cached this result. - if (auto found = - cache.findDependency(moduleName, ModuleDependencyKind::SwiftSource)) - return found; - if (auto found = cache.findDependency(moduleName, - ModuleDependencyKind::SwiftInterface)) - return found; - if (auto found = - cache.findDependency(moduleName, ModuleDependencyKind::SwiftBinary)) - return found; - if (auto found = cache.findDependency(moduleName, - ModuleDependencyKind::SwiftPlaceholder)) - return found; - - // Otherwise perform filesystem scan - auto moduleIdentifier = getModuleImportIdentifier(moduleName); - auto moduleDependencies = withDependencyScanningWorker( - [&cache, moduleIdentifier](ModuleDependencyScanningWorker *ScanningWorker) { - return ScanningWorker->scanFilesystemForSwiftModuleDependency( - moduleIdentifier, cache.getModuleOutputPath(), - cache.getSDKModuleOutputPath(), - cache.getScanService().getPrefixMapper()); - }); - if (moduleDependencies.empty()) - return std::nullopt; - - cache.recordDependencies(moduleDependencies, Diagnostics); - return cache.findDependency(moduleName); -} - /// For the dependency set of the main module, discover all /// cross-import overlays and their corresponding '.swiftcrossimport' /// files. Cross-import overlay dependencies are required when @@ -1088,19 +1006,38 @@ void ModuleDependencyScanner::resolveAllClangModuleDependencies( // We need to query the Clang dependency scanner for this module's // unresolved imports llvm::StringSet<> resolvedImportIdentifiers; - for (const auto &resolvedDep : moduleDependencyInfo.getImportedSwiftDependencies()) + for (const auto &resolvedDep : + moduleDependencyInfo.getImportedSwiftDependencies()) resolvedImportIdentifiers.insert(resolvedDep.ModuleName); + // When querying a *clang* module 'CxxStdlib' we must + // instead expect a module called 'std'... + auto addCanonicalClangModuleImport = + [this](const ScannerImportStatementInfo &importInfo, + std::vector &unresolvedImports, + llvm::StringSet<> &unresolvedImportIdentifiers) { + if (importInfo.importIdentifier == + ScanASTContext.Id_CxxStdlib.str()) { + auto canonicalImportInfo = ScannerImportStatementInfo( + "std", importInfo.isExported, importInfo.importLocations); + unresolvedImports.push_back(canonicalImportInfo); + unresolvedImportIdentifiers.insert( + canonicalImportInfo.importIdentifier); + } else { + unresolvedImports.push_back(importInfo); + unresolvedImportIdentifiers.insert(importInfo.importIdentifier); + } + }; + for (const auto &depImport : moduleDependencyInfo.getModuleImports()) - if (!resolvedImportIdentifiers.contains(depImport.importIdentifier)) { - unresolvedImports->push_back(depImport); - unresolvedImportIdentifiers.insert(depImport.importIdentifier); - } - for (const auto &depImport : moduleDependencyInfo.getOptionalModuleImports()) - if (!resolvedImportIdentifiers.contains(depImport.importIdentifier)) { - unresolvedOptionalImports->push_back(depImport); - unresolvedOptionalImportIdentifiers.insert(depImport.importIdentifier); - } + if (!resolvedImportIdentifiers.contains(depImport.importIdentifier)) + addCanonicalClangModuleImport(depImport, *unresolvedImports, + unresolvedImportIdentifiers); + for (const auto &depImport : + moduleDependencyInfo.getOptionalModuleImports()) + if (!resolvedImportIdentifiers.contains(depImport.importIdentifier)) + addCanonicalClangModuleImport(depImport, *unresolvedOptionalImports, + unresolvedOptionalImportIdentifiers); } } diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 8547191c93df1..76e07dfe580ae 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -1377,7 +1377,8 @@ static void resolveImplicitLinkLibraries(const CompilerInstance &instance, if (langOpts.EnableCXXInterop) { auto OptionalCxxDep = cache.findDependency(CXX_MODULE_NAME); - auto OptionalCxxStdLibDep = cache.findDependency("CxxStdlib"); + auto OptionalCxxStdLibDep = + cache.findDependency(instance.getASTContext().Id_CxxStdlib.str()); bool hasStaticCxx = OptionalCxxDep.has_value() && OptionalCxxDep.value()->isStaticLibrary(); bool hasStaticCxxStdlib = OptionalCxxStdLibDep.has_value() && diff --git a/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift b/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift new file mode 100644 index 0000000000000..26605cd974781 --- /dev/null +++ b/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift @@ -0,0 +1,35 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %s -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import +// RUN: %validate-json %t/deps.json | %FileCheck %s + +// rdar://151780437: libstdc++ VFS modulemap redirects not functioning with EBM enabled +// REQUIRES: OS=macosx + +import CxxStdlib + +// CHECK: "mainModuleName": "deps" + +/// --------Main module +// CHECK-LABEL: "modulePath": "deps.swiftmodule", +// CHECK-NEXT: "sourceFiles": [ +// CHECK-NEXT: cxx-overlay-underlying-module-lookup.swift +// CHECK-NEXT: ], + +// CHECK-NEXT: "directDependencies": [ +// CHECK-DAG: "clang": "CxxShim" +// CHECK-DAG: "swift": "CxxStdlib" +// CHECK-DAG: "swift": "Cxx" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK: ], + +/// ---------- +// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}CxxStdlib-{{.*}}.swiftmodule" +// CHECK-NEXT: "sourceFiles": [] +// CHECK-NEXT: "directDependencies": [ +// CHECK-DAG: "swift": "Cxx" +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "clang": "std" +// CHECK-DAG: "clang": "CxxStdlibShim" +// CHECK: ],