Merge pull request #81416 from artemcm/CXXInteropDarwinCycleFix-62

This commit is contained in:
Artem Chikin
2025-05-15 05:49:39 -07:00
committed by GitHub
4 changed files with 118 additions and 32 deletions

View File

@@ -690,7 +690,7 @@ public:
storage->importedSwiftModules.assign(dependencyIDs.begin(), storage->importedSwiftModules.assign(dependencyIDs.begin(),
dependencyIDs.end()); dependencyIDs.end());
} }
const ArrayRef<ModuleDependencyID> getImportedSwiftDependencies() const { ArrayRef<ModuleDependencyID> getImportedSwiftDependencies() const {
return storage->importedSwiftModules; return storage->importedSwiftModules;
} }
@@ -699,7 +699,7 @@ public:
storage->importedClangModules.assign(dependencyIDs.begin(), storage->importedClangModules.assign(dependencyIDs.begin(),
dependencyIDs.end()); dependencyIDs.end());
} }
const ArrayRef<ModuleDependencyID> getImportedClangDependencies() const { ArrayRef<ModuleDependencyID> getImportedClangDependencies() const {
return storage->importedClangModules; return storage->importedClangModules;
} }
@@ -733,7 +733,7 @@ public:
} }
} }
} }
const ArrayRef<ModuleDependencyID> getHeaderClangDependencies() const { ArrayRef<ModuleDependencyID> getHeaderClangDependencies() const {
switch (getKind()) { switch (getKind()) {
case swift::ModuleDependencyKind::SwiftInterface: { case swift::ModuleDependencyKind::SwiftInterface: {
auto swiftInterfaceStorage = auto swiftInterfaceStorage =
@@ -761,7 +761,7 @@ public:
storage->swiftOverlayDependencies.assign(dependencyIDs.begin(), storage->swiftOverlayDependencies.assign(dependencyIDs.begin(),
dependencyIDs.end()); dependencyIDs.end());
} }
const ArrayRef<ModuleDependencyID> getSwiftOverlayDependencies() const { ArrayRef<ModuleDependencyID> getSwiftOverlayDependencies() const {
return storage->swiftOverlayDependencies; return storage->swiftOverlayDependencies;
} }
@@ -771,11 +771,11 @@ public:
storage->crossImportOverlayModules.assign(dependencyIDs.begin(), storage->crossImportOverlayModules.assign(dependencyIDs.begin(),
dependencyIDs.end()); dependencyIDs.end());
} }
const ArrayRef<ModuleDependencyID> getCrossImportOverlayDependencies() const { ArrayRef<ModuleDependencyID> getCrossImportOverlayDependencies() const {
return storage->crossImportOverlayModules; return storage->crossImportOverlayModules;
} }
const ArrayRef<LinkLibrary> getLinkLibraries() const { ArrayRef<LinkLibrary> getLinkLibraries() const {
return storage->linkLibraries; return storage->linkLibraries;
} }
@@ -784,7 +784,7 @@ public:
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end()); storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
} }
const ArrayRef<std::string> getAuxiliaryFiles() const { ArrayRef<std::string> getAuxiliaryFiles() const {
return storage->auxiliaryFiles; return storage->auxiliaryFiles;
} }
@@ -796,7 +796,7 @@ public:
return false; return false;
} }
const ArrayRef<std::string> getHeaderInputSourceFiles() const { ArrayRef<std::string> getHeaderInputSourceFiles() const {
if (auto *detail = getAsSwiftInterfaceModule()) if (auto *detail = getAsSwiftInterfaceModule())
return detail->textualModuleDetails.bridgingSourceFiles; return detail->textualModuleDetails.bridgingSourceFiles;
if (auto *detail = getAsSwiftSourceModule()) if (auto *detail = getAsSwiftSourceModule())
@@ -806,7 +806,7 @@ public:
return {}; return {};
} }
std::vector<std::string> getCommandline() const { ArrayRef<std::string> getCommandline() const {
if (auto *detail = getAsClangModule()) if (auto *detail = getAsClangModule())
return detail->buildCommandLine; return detail->buildCommandLine;
if (auto *detail = getAsSwiftInterfaceModule()) if (auto *detail = getAsSwiftInterfaceModule())
@@ -829,7 +829,7 @@ public:
llvm_unreachable("Unexpected type"); llvm_unreachable("Unexpected type");
} }
std::vector<std::string> getBridgingHeaderCommandline() const { ArrayRef<std::string> getBridgingHeaderCommandline() const {
if (auto *detail = getAsSwiftSourceModule()) if (auto *detail = getAsSwiftSourceModule())
return detail->bridgingHeaderBuildCommandLine; return detail->bridgingHeaderBuildCommandLine;
return {}; return {};

View File

@@ -675,7 +675,7 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) {
// build command to main module to ensure frontend gets the same result. // build command to main module to ensure frontend gets the same result.
// This needs to happen after visiting all the top-level decls from all // This needs to happen after visiting all the top-level decls from all
// SourceFiles. // SourceFiles.
auto buildArgs = mainDependencies.getCommandline(); std::vector<std::string> buildArgs = mainDependencies.getCommandline();
mainModule->getASTContext().forEachCanImportVersionCheck( mainModule->getASTContext().forEachCanImportVersionCheck(
[&](StringRef moduleName, const llvm::VersionTuple &Version, [&](StringRef moduleName, const llvm::VersionTuple &Version,
const llvm::VersionTuple &UnderlyingVersion) { const llvm::VersionTuple &UnderlyingVersion) {
@@ -1542,25 +1542,33 @@ void ModuleDependencyScanner::resolveSwiftOverlayDependenciesForModule(
recordResult(clangDep); recordResult(clangDep);
// C++ Interop requires additional handling // C++ Interop requires additional handling
if (ScanCompilerInvocation.getLangOptions().EnableCXXInterop) { if (ScanCompilerInvocation.getLangOptions().EnableCXXInterop &&
for (const auto &clangDepName : allClangDependencies) { moduleID.Kind == ModuleDependencyKind::SwiftInterface) {
// If this Clang module is a part of the C++ stdlib, and we haven't loaded const auto &moduleInfo = cache.findKnownDependency(moduleID);
// the overlay for it so far, it is a split libc++ module (e.g. const auto commandLine = moduleInfo.getCommandline();
// std_vector). Load the CxxStdlib overlay explicitly.
const auto &clangDepInfo = // If the textual interface was built without C++ interop, do not query
cache.findDependency(clangDepName, ModuleDependencyKind::Clang) // the C++ Standard Library Swift overlay for its compilation.
.value() if (llvm::find(commandLine, "-formal-cxx-interoperability-mode=off") ==
->getAsClangModule(); commandLine.end()) {
if (importer::isCxxStdModule(clangDepName, clangDepInfo->IsSystem) && for (const auto &clangDepName : allClangDependencies) {
!swiftOverlayDependencies.contains( // If this Clang module is a part of the C++ stdlib, and we haven't
{clangDepName, ModuleDependencyKind::SwiftInterface}) && // loaded the overlay for it so far, it is a split libc++ module (e.g.
!swiftOverlayDependencies.contains( // std_vector). Load the CxxStdlib overlay explicitly.
{clangDepName, ModuleDependencyKind::SwiftBinary})) { const auto &clangDepInfo =
ScanningThreadPool.async( cache.findDependency(clangDepName, ModuleDependencyKind::Clang)
scanForSwiftDependency, .value()
getModuleImportIdentifier(ScanASTContext.Id_CxxStdlib.str())); ->getAsClangModule();
ScanningThreadPool.wait(); if (importer::isCxxStdModule(clangDepName, clangDepInfo->IsSystem) &&
recordResult(ScanASTContext.Id_CxxStdlib.str().str()); !swiftOverlayDependencies.contains(
{clangDepName, ModuleDependencyKind::SwiftInterface}) &&
!swiftOverlayDependencies.contains(
{clangDepName, ModuleDependencyKind::SwiftBinary})) {
scanForSwiftDependency(
getModuleImportIdentifier(ScanASTContext.Id_CxxStdlib.str()));
recordResult(ScanASTContext.Id_CxxStdlib.str().str());
break;
}
} }
} }
} }
@@ -1615,7 +1623,7 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
// Update the command-line on the main module to // Update the command-line on the main module to
// disable implicit cross-import overlay search. // disable implicit cross-import overlay search.
auto mainDep = cache.findKnownDependency(actualMainID); auto mainDep = cache.findKnownDependency(actualMainID);
auto cmdCopy = mainDep.getCommandline(); std::vector<std::string> cmdCopy = mainDep.getCommandline();
cmdCopy.push_back("-disable-cross-import-overlay-search"); cmdCopy.push_back("-disable-cross-import-overlay-search");
for (auto &entry : overlayFiles) { for (auto &entry : overlayFiles) {
mainDep.addAuxiliaryFile(entry.second); mainDep.addAuxiliaryFile(entry.second);

View File

@@ -933,7 +933,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
moduleInfo->details = getModuleDetails(); moduleInfo->details = getModuleDetails();
// Create a link libraries set for this module // Create a link libraries set for this module
auto &linkLibraries = moduleDependencyInfo.getLinkLibraries(); auto linkLibraries = moduleDependencyInfo.getLinkLibraries();
swiftscan_link_library_set_t *linkLibrarySet = swiftscan_link_library_set_t *linkLibrarySet =
new swiftscan_link_library_set_t; new swiftscan_link_library_set_t;
linkLibrarySet->count = linkLibraries.size(); linkLibrarySet->count = linkLibraries.size();

View File

@@ -0,0 +1,78 @@
// 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/clientWithInteropDep.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -verify
// RUN: cat %t/deps.json | %FileCheck %s -check-prefix=ENABLE-CHECK
// RUN: %target-swift-frontend -scan-dependencies -o %t/deps_no_interop_dep.json %t/clientNoInteropDep.swift -I %t/deps -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -verify
// RUN: cat %t/deps_no_interop_dep.json | %FileCheck %s -check-prefix=DISABLE-CHECK
//--- deps/bar.h
void bar(void);
//--- deps/module.modulemap
module std_Bar [system] {
header "bar.h"
export *
}
//--- deps/Foo.swiftinterface
// swift-interface-format-version: 1.0
// swift-module-flags: -module-name Foo -enable-library-evolution
import std_Bar
public struct Foo1 {}
//--- deps/FooNoInterop.swiftinterface
// swift-interface-format-version: 1.0
// swift-module-flags: -module-name FooNoInterop -enable-library-evolution
// swift-module-flags-ignorable: -formal-cxx-interoperability-mode=off
import std_Bar
public struct Foo2 {}
//--- clientWithInteropDep.swift
import Foo
//--- clientNoInteropDep.swift
import FooNoInterop
// Ensure that when the 'Foo' dependency was built with C++ interop enabled,
// it gets the C++ standard library overlay for its 'std_*' dependency
//
// 'Foo' as it appears in direct deps
// ENABLE-CHECK: "swift": "Foo"
// 'Foo' as it appears in source-import deps
// ENABLE-CHECK: "swift": "Foo"
// Actual dependency info node
// ENABLE-CHECK: "swift": "Foo"
// ENABLE-CHECK: "directDependencies": [
// ENABLE-CHECK: {
// ENABLE-CHECK: "swift": "SwiftOnoneSupport"
// ENABLE-CHECK: },
// ENABLE-CHECK: {
// ENABLE-CHECK: "swift": "CxxStdlib"
// ENABLE-CHECK: },
// ENABLE-CHECK: {
// ENABLE-CHECK: "clang": "std_Bar"
// ENABLE-CHECK: }
// ENABLE-CHECK: ],
// Ensure that when the 'Foo' dependency was *not* built with C++ interop enabled,
// it does not get the C++ standard library overlay for its 'std_*' dependency
//
// 'Foo' as it appears in direct deps
// DISABLE-CHECK: "swift": "FooNoInterop"
// 'Foo' as it appears in source-import deps
// DISABLE-CHECK: "swift": "FooNoInterop"
// Actual dependency info node
// DISABLE-CHECK: "swift": "FooNoInterop"
// DISABLE-CHECK: "directDependencies": [
// DISABLE-CHECK: {
// DISABLE-CHECK: "swift": "SwiftOnoneSupport"
// DISABLE-CHECK: },
// DISABLE-CHECK: {
// DISABLE-CHECK: "clang": "std_Bar"
// DISABLE-CHECK: }
// DISABLE-CHECK: ],