Skip to content

[cxx-interop] Pull changes from swift-6 compat mode into swift-5.9 #72912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions include/swift/AST/DiagnosticsClangImporter.def
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,6 @@ ERROR(conforms_to_ambiguous,none,
ERROR(conforms_to_not_protocol,none,
"%0 %1 referenced in protocol conformance '%2' is not a protocol", (DescriptiveDeclKind, ValueDecl *, StringRef))

ERROR(move_only_requires_move_only,none,
"use of noncopyable C++ type '%0' requires -enable-experimental-move-only",
(StringRef))

ERROR(failed_base_method_call_synthesis,none,
"failed to synthesize call to the base method %0 of type %0",
(ValueDecl *, ValueDecl *))
Expand Down
97 changes: 39 additions & 58 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2192,22 +2192,12 @@ namespace {
Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;

if (recordHasMoveOnlySemantics(decl)) {
if (Impl.isCxxInteropCompatVersionAtLeast(6)) {
if (decl->isInStdNamespace() && decl->getName() == "promise") {
// Do not import std::promise.
return nullptr;
}
result->getAttrs().add(new (Impl.SwiftContext)
MoveOnlyAttr(/*Implicit=*/true));
} else {
Impl.addImportDiagnostic(
decl,
Diagnostic(
diag::move_only_requires_move_only,
Impl.SwiftContext.AllocateCopy(decl->getNameAsString())),
decl->getLocation());
if (decl->isInStdNamespace() && decl->getName() == "promise") {
// Do not import std::promise.
return nullptr;
}
result->getAttrs().add(new (Impl.SwiftContext)
MoveOnlyAttr(/*Implicit=*/true));
}

// FIXME: Figure out what to do with superclasses in C++. One possible
Expand Down Expand Up @@ -2666,8 +2656,7 @@ namespace {
// SemaLookup.cpp).
if (!decl->isBeingDefined() && !decl->isDependentContext() &&
areRecordFieldsComplete(decl)) {
if (decl->hasInheritedConstructor() &&
Impl.isCxxInteropCompatVersionAtLeast(6)) {
if (decl->hasInheritedConstructor()) {
for (auto member : decl->decls()) {
if (auto usingDecl = dyn_cast<clang::UsingDecl>(member)) {
for (auto usingShadowDecl : usingDecl->shadows()) {
Expand Down Expand Up @@ -2838,14 +2827,12 @@ namespace {
void
addExplicitProtocolConformances(NominalTypeDecl *decl,
const clang::CXXRecordDecl *clangDecl) {
if (Impl.isCxxInteropCompatVersionAtLeast(6)) {
// Propagate conforms_to attribute from public base classes.
for (auto base : clangDecl->bases()) {
if (base.getAccessSpecifier() != clang::AccessSpecifier::AS_public)
continue;
if (auto *baseClangDecl = base.getType()->getAsCXXRecordDecl())
addExplicitProtocolConformances(decl, baseClangDecl);
}
// Propagate conforms_to attribute from public base classes.
for (auto base : clangDecl->bases()) {
if (base.getAccessSpecifier() != clang::AccessSpecifier::AS_public)
continue;
if (auto *baseClangDecl = base.getType()->getAsCXXRecordDecl())
addExplicitProtocolConformances(decl, baseClangDecl);
}

if (!clangDecl->hasAttrs())
Expand Down Expand Up @@ -3763,39 +3750,34 @@ namespace {

if (decl->isVirtual()) {
if (auto funcDecl = dyn_cast_or_null<FuncDecl>(method)) {
if (Impl.isCxxInteropCompatVersionAtLeast(6)) {
if (auto structDecl =
dyn_cast_or_null<StructDecl>(method->getDeclContext())) {
// If this is a method of a Swift struct, any possible override of
// this method would get sliced away, and an invocation would get
// dispatched statically. This is fine because it matches the C++
// behavior.
if (decl->isPure()) {
// If this is a pure virtual method, we won't have any
// implementation of it to invoke.
Impl.markUnavailable(
funcDecl, "virtual function is not available in Swift "
"because it is pure");
}
} else if (auto classDecl = dyn_cast_or_null<ClassDecl>(
funcDecl->getDeclContext())) {
// This is a foreign reference type. Since `class T` on the Swift
// side is mapped from `T*` on the C++ side, an invocation of a
// virtual method `t->method()` should get dispatched dynamically.
// Create a thunk that will perform dynamic dispatch.
// TODO: we don't have to import the actual `method` in this case,
// we can just synthesize a thunk and import that instead.
auto result = synthesizer.makeVirtualMethod(decl);
if (result) {
return result;
} else {
Impl.markUnavailable(
funcDecl, "virtual function is not available in Swift");
}
if (auto structDecl =
dyn_cast_or_null<StructDecl>(method->getDeclContext())) {
// If this is a method of a Swift struct, any possible override of
// this method would get sliced away, and an invocation would get
// dispatched statically. This is fine because it matches the C++
// behavior.
if (decl->isPure()) {
// If this is a pure virtual method, we won't have any
// implementation of it to invoke.
Impl.markUnavailable(funcDecl,
"virtual function is not available in Swift "
"because it is pure");
}
} else if (auto classDecl = dyn_cast_or_null<ClassDecl>(
funcDecl->getDeclContext())) {
// This is a foreign reference type. Since `class T` on the Swift
// side is mapped from `T*` on the C++ side, an invocation of a
// virtual method `t->method()` should get dispatched dynamically.
// Create a thunk that will perform dynamic dispatch.
// TODO: we don't have to import the actual `method` in this case,
// we can just synthesize a thunk and import that instead.
auto result = synthesizer.makeVirtualMethod(decl);
if (result) {
return result;
} else {
Impl.markUnavailable(
funcDecl, "virtual function is not available in Swift");
}
} else {
Impl.markUnavailable(
funcDecl, "virtual functions are not yet available in Swift");
}
}
}
Expand Down Expand Up @@ -4053,8 +4035,7 @@ namespace {
// 1. Types
// 2. C++ methods from privately inherited base classes
if (!isa<clang::TypeDecl>(decl->getTargetDecl()) &&
!(isa<clang::CXXMethodDecl>(decl->getTargetDecl()) &&
Impl.isCxxInteropCompatVersionAtLeast(6)))
!isa<clang::CXXMethodDecl>(decl->getTargetDecl()))
return nullptr;
// Constructors (e.g. `using BaseClass::BaseClass`) are handled in
// VisitCXXRecordDecl, since we need them to determine whether a struct
Expand Down
1 change: 0 additions & 1 deletion lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2623,7 +2623,6 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
// (https://github.com/apple/swift/issues/70124)
if (param->hasDefaultArg() && !isInOut &&
!isa<clang::CXXConstructorDecl>(param->getDeclContext()) &&
impl->isCxxInteropCompatVersionAtLeast(6) &&
impl->isDefaultArgSafeToImport(param)) {
SwiftDeclSynthesizer synthesizer(*impl);
if (CallExpr *defaultArgExpr = synthesizer.makeDefaultArgument(
Expand Down
11 changes: 3 additions & 8 deletions test/Interop/Cxx/class/conforms-to.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// RUN: %target-swift-frontend %S/Inputs/conforms-to-imported.swift -module-name ImportedModule -emit-module -emit-module-path %t/ImportedModule.swiftmodule

// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -enable-experimental-cxx-interop
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -cxx-interoperability-mode=swift-6 -D UPCOMING_SWIFT
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -cxx-interoperability-mode=upcoming-swift -D UPCOMING_SWIFT
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -cxx-interoperability-mode=swift-6
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -cxx-interoperability-mode=upcoming-swift

import ConformsTo
import ImportedModule
Expand All @@ -23,11 +24,9 @@ func callee(_ _: Testable) {
func caller(_ x: HasTest) {
callee(x)
}
#if UPCOMING_SWIFT
func caller(_ x: DerivedFromHasTest) { callee(x) }
func caller(_ x: DerivedFromDerivedFromHasTest) { callee(x) }
func caller(_ x: DerivedFromDerivedFromHasTestWithDuplicateArg) { callee(x) }
#endif

func callee(_ _: Playable) {

Expand All @@ -36,7 +35,6 @@ func callee(_ _: Playable) {
func caller(_ x: Playable) {
callee(x)
}
#if UPCOMING_SWIFT
func caller(_ x: DerivedFromHasPlay) { callee(x) }
func caller(_ x: DerivedFromDerivedFromHasPlay) { callee(x) }

Expand All @@ -48,15 +46,12 @@ func caller(_ x: DerivedFromHasTestAndPlay) {
callee(x as Testable)
callee(x as Playable)
}
#endif

func callee(_ _: ProtocolFromImportedModule) {
}

func caller(_ x: HasImportedConf) {
callee(x)
}
#if UPCOMING_SWIFT
func caller(_ x: DerivedFromHasImportedConf) { callee(x) }
func caller(_ x: DerivedFromDerivedFromHasImportedConf) { callee(x) }
#endif
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=swift-6
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=upcoming-swift

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -cxx-interoperability-mode=upcoming-swift)
//
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-swift-emit-ir -I %S/Inputs -cxx-interoperability-mode=upcoming-swift %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s
// RUN: %target-swift-emit-ir -I %S/Inputs -cxx-interoperability-mode=swift-5.9 %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s
// RUN: %target-swift-emit-ir -I %S/Inputs -cxx-interoperability-mode=swift-6 %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s

import VirtualMethods
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-swift-ide-test -print-module -cxx-interoperability-mode=swift-5.9 -print-implicit-attrs -module-to-print=VirtualMethods -I %S/Inputs -source-filename=x | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -cxx-interoperability-mode=swift-6 -print-implicit-attrs -module-to-print=VirtualMethods -I %S/Inputs -source-filename=x | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -cxx-interoperability-mode=upcoming-swift -print-implicit-attrs -module-to-print=VirtualMethods -I %S/Inputs -source-filename=x | %FileCheck %s

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=upcoming-swift
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=swift-6

import VirtualMethods
Expand Down
1 change: 1 addition & 0 deletions test/Interop/Cxx/class/inheritance/virtual-methods.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=upcoming-swift)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Tests that a C++ class can conform to a Swift protocol.

// RUN: %target-typecheck-verify-swift -I %S/Inputs -enable-experimental-cxx-interop
// RUN: %target-typecheck-verify-swift -I %S/Inputs -D VIRTUAL_METHODS -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -I %S/Inputs -D VIRTUAL_METHODS -cxx-interoperability-mode=swift-6
// RUN: %target-typecheck-verify-swift -I %S/Inputs -D VIRTUAL_METHODS -cxx-interoperability-mode=upcoming-swift

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=TypeClassification -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-5.9 | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=TypeClassification -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-6 | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=TypeClassification -I %S/Inputs -source-filename=x -cxx-interoperability-mode=upcoming-swift | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -skip-unsafe-cxx-methods -module-to-print=TypeClassification -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-6 | %FileCheck %s -check-prefix=CHECK-SKIP-UNSAFE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=swift-6
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=upcoming-swift

Expand Down
1 change: 1 addition & 0 deletions test/Interop/Cxx/function/default-arguments-irgen.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=swift-5.9 %s | %FileCheck %s
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=swift-6 %s | %FileCheck %s
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=upcoming-swift %s | %FileCheck %s

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=DefaultArguments -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-5.9 | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=DefaultArguments -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-6 | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=DefaultArguments -I %S/Inputs -source-filename=x -cxx-interoperability-mode=upcoming-swift | %FileCheck %s

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=swift-6
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -cxx-interoperability-mode=upcoming-swift

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=MemberInline -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-5.9 | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=MemberInline -I %S/Inputs -source-filename=x -cxx-interoperability-mode=swift-6 | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=MemberInline -I %S/Inputs -source-filename=x -cxx-interoperability-mode=upcoming-swift | %FileCheck %s

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=swift-5.9
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=swift-6
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=upcoming-swift

Expand Down
1 change: 1 addition & 0 deletions test/Interop/Cxx/operators/member-inline.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift)
//
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=swift-5.9 -DNO_CONSUME
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=swift-6 -DNO_CONSUME
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=upcoming-swift -DNO_CONSUME

Expand Down
1 change: 1 addition & 0 deletions test/Interop/Cxx/stdlib/use-std-chrono.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=upcoming-swift -Xcc -std=c++14)
Expand Down
1 change: 1 addition & 0 deletions test/Interop/Cxx/stdlib/use-std-optional.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift -Xcc -std=c++20)
Expand Down
Loading