Skip to content

Commit 5afa437

Browse files
authored
Merge pull request #66397 from hyp/5.9/copy-me-timbers
[5.9][interop][SwiftToCxx] support copy-assignment operation for Swift val…
2 parents 01b0102 + b1b0682 commit 5afa437

File tree

6 files changed

+74
-0
lines changed

6 files changed

+74
-0
lines changed

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
288288
os << " vwTable->destroy(_getOpaquePointer(), metadata._0);\n";
289289
os << " }\n";
290290

291+
// copy constructor.
291292
os << " ";
292293
printer.printInlineForThunk();
293294
printer.printBaseName(typeDecl);
@@ -306,6 +307,28 @@ void ClangValueTypePrinter::printValueTypeDecl(
306307
"*>(other._getOpaquePointer()), metadata._0);\n";
307308
os << " }\n";
308309

310+
// copy assignment.
311+
os << " ";
312+
printer.printInlineForThunk();
313+
printer.printBaseName(typeDecl);
314+
os << " &operator =(const ";
315+
printer.printBaseName(typeDecl);
316+
os << " &other) noexcept {\n";
317+
ClangValueTypePrinter::printValueWitnessTableAccessAsVariable(
318+
os, typeMetadataFuncName, typeMetadataFuncGenericParams);
319+
os << " vwTable->assignWithCopy(_getOpaquePointer(), const_cast<char "
320+
"*>(other._getOpaquePointer()), metadata._0);\n";
321+
os << " return *this;\n";
322+
os << " }\n";
323+
324+
// FIXME: implement the move assignment.
325+
os << " ";
326+
printer.printInlineForThunk();
327+
printer.printBaseName(typeDecl);
328+
os << " &operator =(";
329+
printer.printBaseName(typeDecl);
330+
os << " &&other) = delete;\n";
331+
309332
// FIXME: implement the move constructor.
310333
os << " [[noreturn]] ";
311334
// NOTE: Do not apply attribute((used))

test/Interop/SwiftToCxx/stdlib/swift-stdlib-in-cxx.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@
7272
// CHECK: }
7373
// CHECK-NEXT: SWIFT_INLINE_THUNK String(const String &other) noexcept {
7474
// CHECK: }
75+
// CHECK-NEXT: SWIFT_INLINE_THUNK String &operator =(const String &other) noexcept {
76+
// CHECK: }
77+
// CHECK-NEXT: SWIFT_INLINE_THUNK String &operator =(String &&other) = delete;
7578
// CHECK-NEXT: SWIFT_INLINE_PRIVATE_HELPER String(String &&) noexcept {
7679
// CHECK: }
7780
// CHECK-NEXT: static SWIFT_INLINE_THUNK String init() SWIFT_SYMBOL({{.*}});

test/Interop/SwiftToCxx/structs/struct-move-semantics-in-cxx.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
// LINK: fatalError_Cxx_move_of_Swift_value_type_not_supported_yet
1111

12+
// Compile should fail by default when move assignment is attempted in C++:
13+
14+
// RUN: not %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o -DMOVE_ASSIGN 2>&1 | %FileCheck --check-prefix=MOVEASSIGN %s
15+
1216
// Fallback to abort at runtime:
1317

1418
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-structs-execution.o -DLINKS
@@ -34,7 +38,13 @@ int main() {
3438
using namespace Structs;
3539

3640
auto x = returnNewStructSeveralI64(42);
41+
#ifdef MOVE_ASSIGN
42+
auto y = returnNewStructSeveralI64(24);
43+
x = std::move(y);
44+
// MOVEASSIGN: deleted operator '='
45+
#else
3746
StructSeveralI64 x2 = std::move(x);
47+
#endif
3848
return 0;
3949
}
4050

test/Interop/SwiftToCxx/structs/struct-with-refcounted-member-execution.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,19 @@ int main() {
4444
// CHECK-NEXT: destroy RefCountedClass
4545
// CHECK-NEXT: destroy RefCountedClass
4646
// CHECK-NEXT: breakpoint 3
47+
48+
{
49+
StructWithRefcountedMember value = returnNewStructWithRefcountedMember();
50+
StructWithRefcountedMember value2 = returnNewStructWithRefcountedMember();
51+
value = value2;
52+
printBreak(4);
53+
}
54+
printBreak(5);
55+
// CHECK-NEXT: create RefCountedClass
56+
// CHECK-NEXT: create RefCountedClass
57+
// CHECK-NEXT: destroy RefCountedClass
58+
// CHECK-NEXT: breakpoint 4
59+
// CHECK-NEXT: destroy RefCountedClass
60+
// CHECK-NEXT: breakpoint 5
4761
return 0;
4862
}

test/Interop/SwiftToCxx/structs/struct-with-refcounted-member.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ public func printBreak(_ x: Int) {
4747
// CHECK-NEXT: #endif
4848
// CHECK-NEXT: vwTable->initializeWithCopy(_getOpaquePointer(), const_cast<char *>(other._getOpaquePointer()), metadata._0);
4949
// CHECK-NEXT: }
50+
// CHECK-NEXT: SWIFT_INLINE_THUNK StructWithRefcountedMember &operator =(const StructWithRefcountedMember &other) noexcept {
51+
// CHECK-NEXT: auto metadata = _impl::$s7Structs26StructWithRefcountedMemberVMa(0);
52+
// CHECK-NEXT: auto *vwTableAddr = reinterpret_cast<swift::_impl::ValueWitnessTable **>(metadata._0) - 1;
53+
// CHECK-NEXT: #ifdef __arm64e__
54+
// CHECK-NEXT: auto *vwTable = reinterpret_cast<swift::_impl::ValueWitnessTable *>(ptrauth_auth_data(reinterpret_cast<void *>(*vwTableAddr), ptrauth_key_process_independent_data, ptrauth_blend_discriminator(vwTableAddr, 11839)));
55+
// CHECK-NEXT: #else
56+
// CHECK-NEXT: auto *vwTable = *vwTableAddr;
57+
// CHECK-NEXT: #endif
58+
// CHECK-NEXT: vwTable->assignWithCopy(_getOpaquePointer(), const_cast<char *>(other._getOpaquePointer()), metadata._0);
59+
// CHECK-NEXT: return *this;
60+
// CHECK-NEXT: }
61+
// CHECK-NEXT: SWIFT_INLINE_THUNK StructWithRefcountedMember &operator =(StructWithRefcountedMember &&other) = delete;
5062
// CHECK-NEXT: SWIFT_INLINE_PRIVATE_HELPER StructWithRefcountedMember(StructWithRefcountedMember &&) noexcept {
5163
// CHECK-NEXT: swift::_impl::_fatalError_Cxx_move_of_Swift_value_type_not_supported_yet();
5264
// CHECK-NEXT: swift::_impl::_swift_stdlib_reportFatalError("swift", 5, "C++ does not support moving a Swift value yet", 45, 0);

test/Interop/SwiftToCxx/structs/swift-struct-in-cxx.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@
3838
// CHECK: }
3939
// CHECK-NEXT: SWIFT_INLINE_THUNK StructWithIntField(const StructWithIntField &other) noexcept {
4040
// CHECK: }
41+
// CHECK: SWIFT_INLINE_THUNK StructWithIntField &operator =(const StructWithIntField &other) noexcept {
42+
// CHECK-NEXT: auto metadata = _impl::$s7Structs18StructWithIntFieldVMa(0);
43+
// CHECK-NEXT: auto *vwTableAddr = reinterpret_cast<swift::_impl::ValueWitnessTable **>(metadata._0) - 1;
44+
// CHECK-NEXT: #ifdef __arm64e__
45+
// CHECK-NEXT: auto *vwTable = reinterpret_cast<swift::_impl::ValueWitnessTable *>(ptrauth_auth_data(reinterpret_cast<void *>(*vwTableAddr), ptrauth_key_process_independent_data, ptrauth_blend_discriminator(vwTableAddr, 11839)));
46+
// CHECK-NEXT: #else
47+
// CHECK-NEXT: auto *vwTable = *vwTableAddr;
48+
// CHECK-NEXT: #endif
49+
// CHECK-NEXT: vwTable->assignWithCopy(_getOpaquePointer(), const_cast<char *>(other._getOpaquePointer()), metadata._0);
50+
// CHECK-NEXT: return *this;
51+
// CHECK-NEXT: }
52+
// CHECK-NEXT: SWIFT_INLINE_THUNK StructWithIntField &operator =(StructWithIntField &&other) = delete;
4153
// CHECK-NEXT: noreturn]] SWIFT_INLINE_PRIVATE_HELPER StructWithIntField(StructWithIntField &&) noexcept {
4254
// CHECK-NEXT: swift::_impl::_fatalError_Cxx_move_of_Swift_value_type_not_supported_yet();
4355
// CHECK-NEXT: swift::_impl::_swift_stdlib_reportFatalError("swift", 5, "C++ does not support moving a Swift value yet", 45, 0);

0 commit comments

Comments
 (0)