From 01e5d4433f3a0dd0c6a5c17cf39c82c06a685620 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Wed, 2 Jul 2025 15:50:27 -0700 Subject: [PATCH] [Dependency Scanning][C++ Interop] Do not skip lookup of 'CxxStdlib' overlay for the source module A prior change ensured that we forego this query when looking up Swift overlays for a textual interface which was built without C++ interop. This change introduced a bug where it also caused us to skip this lookup for the main source module. This commit resolves that by preserving the fix above but also ensuring we perform the lookup for the main source module under scan. --- .../ModuleDependencyScanner.cpp | 50 ++++++++++--------- .../cxx-overlay-source-lookup.swift | 41 +++++++++++++++ 2 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 test/ScanDependencies/cxx-overlay-source-lookup.swift diff --git a/lib/DependencyScan/ModuleDependencyScanner.cpp b/lib/DependencyScan/ModuleDependencyScanner.cpp index fadd930d05c2d..b66e4ba178f20 100644 --- a/lib/DependencyScan/ModuleDependencyScanner.cpp +++ b/lib/DependencyScan/ModuleDependencyScanner.cpp @@ -1408,11 +1408,10 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule( recordResult(clangDep); // C++ Interop requires additional handling - if (ScanCompilerInvocation.getLangOptions().EnableCXXInterop && - moduleID.Kind == ModuleDependencyKind::SwiftInterface) { + bool lookupCxxStdLibOverlay = ScanCompilerInvocation.getLangOptions().EnableCXXInterop; + if (lookupCxxStdLibOverlay && moduleID.Kind == ModuleDependencyKind::SwiftInterface) { const auto &moduleInfo = cache.findKnownDependency(moduleID); const auto commandLine = moduleInfo.getCommandline(); - // If the textual interface was built without C++ interop, do not query // the C++ Standard Library Swift overlay for its compilation. // @@ -1420,27 +1419,30 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule( // without C++Interop, for compatibility with prior versions. Once we are certain // that we are only building against modules built with support of // '-formal-cxx-interoperability-mode', this hard-coded check should be removed. - if (moduleID.ModuleName != "Darwin" && - llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") == - commandLine.end()) { - for (const auto &clangDepName : allClangDependencies) { - // If this Clang module is a part of the C++ stdlib, and we haven't - // loaded the overlay for it so far, it is a split libc++ module (e.g. - // std_vector). Load the CxxStdlib overlay explicitly. - const auto &clangDepInfo = - cache.findDependency(clangDepName, ModuleDependencyKind::Clang) - .value() - ->getAsClangModule(); - if (importer::isCxxStdModule(clangDepName, clangDepInfo->IsSystem) && - !swiftOverlayDependencies.contains( - {clangDepName, ModuleDependencyKind::SwiftInterface}) && - !swiftOverlayDependencies.contains( - {clangDepName, ModuleDependencyKind::SwiftBinary})) { - scanForSwiftDependency( - getModuleImportIdentifier(ScanASTContext.Id_CxxStdlib.str())); - recordResult(ScanASTContext.Id_CxxStdlib.str().str()); - break; - } + if (moduleID.ModuleName == "Darwin" || + llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") != + commandLine.end()) + lookupCxxStdLibOverlay = false; + } + + if (lookupCxxStdLibOverlay) { + for (const auto &clangDepName : allClangDependencies) { + // If this Clang module is a part of the C++ stdlib, and we haven't + // loaded the overlay for it so far, it is a split libc++ module (e.g. + // std_vector). Load the CxxStdlib overlay explicitly. + const auto &clangDepInfo = + cache.findDependency(clangDepName, ModuleDependencyKind::Clang) + .value() + ->getAsClangModule(); + if (importer::isCxxStdModule(clangDepName, clangDepInfo->IsSystem) && + !swiftOverlayDependencies.contains( + {clangDepName, ModuleDependencyKind::SwiftInterface}) && + !swiftOverlayDependencies.contains( + {clangDepName, ModuleDependencyKind::SwiftBinary})) { + scanForSwiftDependency( + getModuleImportIdentifier(ScanASTContext.Id_CxxStdlib.str())); + recordResult(ScanASTContext.Id_CxxStdlib.str().str()); + break; } } } diff --git a/test/ScanDependencies/cxx-overlay-source-lookup.swift b/test/ScanDependencies/cxx-overlay-source-lookup.swift new file mode 100644 index 0000000000000..bcc978d3931e3 --- /dev/null +++ b/test/ScanDependencies/cxx-overlay-source-lookup.swift @@ -0,0 +1,41 @@ +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/deps) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %t/client.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import +// RUN: cat %t/deps.json | %FileCheck %s + +/// --------Main module +// CHECK-LABEL: "modulePath": "deps.swiftmodule", +// CHECK-NEXT: "sourceFiles": [ +// CHECK-NEXT: cxx-overlay-source-lookup.swift +// CHECK-NEXT: ], +// CHECK: "directDependencies": [ +// CHECK-DAG: "swift": "Swift" +// CHECK-DAG: "swift": "SwiftOnoneSupport" +// CHECK-DAG: "swift": "Cxx" +// CHECK-DAG: "swift": "CxxStdlib" +// CHECK-DAG: "clang": "CxxShim" +// CHECK-DAG: "clang": "Foo" +// CHECK: ], + +//--- deps/bar.h +void bar(void); + +//--- deps/foo.h +#include "bar.h" +void foo(void); + +//--- deps/module.modulemap +module std_Bar [system] { + header "bar.h" + export * +} + +module Foo { + header "foo.h" + export * +} + +//--- client.swift +import Foo