Skip to content

Commit 4882c93

Browse files
committed
[interop][SwiftToCxx] use vtable/thunk to dispatch class subscript getters
1 parent f15fe69 commit 4882c93

6 files changed

+48
-8
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ class DeclAndTypePrinter::Implementation
10131013
declPrinter.printCxxSubscriptAccessorMethod(
10141014
typeDeclContext, accessor, funcABI->getSignature(),
10151015
funcABI->getSymbolName(), resultTy,
1016-
/*isDefinition=*/false);
1016+
/*isDefinition=*/false, dispatchInfo);
10171017
else
10181018
declPrinter.printCxxPropertyAccessorMethod(
10191019
typeDeclContext, accessor, funcABI->getSignature(),
@@ -1037,7 +1037,8 @@ class DeclAndTypePrinter::Implementation
10371037
if (SD)
10381038
defPrinter.printCxxSubscriptAccessorMethod(
10391039
typeDeclContext, accessor, funcABI->getSignature(),
1040-
funcABI->getSymbolName(), resultTy, /*isDefinition=*/true);
1040+
funcABI->getSymbolName(), resultTy, /*isDefinition=*/true,
1041+
dispatchInfo);
10411042
else
10421043
defPrinter.printCxxPropertyAccessorMethod(
10431044
typeDeclContext, accessor, funcABI->getSignature(),

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,8 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
14591459
void DeclAndTypeClangFunctionPrinter::printCxxSubscriptAccessorMethod(
14601460
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
14611461
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
1462-
Type resultTy, bool isDefinition) {
1462+
Type resultTy, bool isDefinition,
1463+
Optional<IRABIDetailsProvider::MethodDispatchInfo> dispatchInfo) {
14631464
assert(accessor->isGetter());
14641465
FunctionSignatureModifiers modifiers;
14651466
if (isDefinition)
@@ -1476,9 +1477,10 @@ void DeclAndTypeClangFunctionPrinter::printCxxSubscriptAccessorMethod(
14761477
}
14771478
os << " {\n";
14781479
// FIXME: should it be objTy for resultTy?
1479-
printCxxThunkBody(accessor, signature, swiftSymbolName, typeDeclContext,
1480-
accessor->getModuleContext(), resultTy,
1481-
accessor->getParameters());
1480+
printCxxThunkBody(
1481+
accessor, signature, swiftSymbolName, typeDeclContext,
1482+
accessor->getModuleContext(), resultTy, accessor->getParameters(),
1483+
/*hasThrows=*/false, nullptr, /*isStatic=*/false, dispatchInfo);
14821484
os << " }\n";
14831485
}
14841486

lib/PrintAsClang/PrintClangFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ class DeclAndTypeClangFunctionPrinter {
135135
void printCxxSubscriptAccessorMethod(
136136
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
137137
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
138-
Type resultTy, bool isDefinition);
138+
Type resultTy, bool isDefinition,
139+
Optional<IRABIDetailsProvider::MethodDispatchInfo> dispatchInfo);
139140

140141
/// Print Swift type as C/C++ type, as the return type of a C/C++ function.
141142
ClangRepresentation

test/Interop/SwiftToCxx/class/swift-class-virtual-method-dispatch-execution.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,5 +149,16 @@ int main() {
149149
x = derivedDerived.getComputedPropInDerivedDerived();
150150
assert(x == 11);
151151
}
152+
153+
{
154+
swift::Int x;
155+
x = base[23];
156+
assert(x == 23);
157+
158+
x = derivedAsBase[23];
159+
assert(x == 46);
160+
x = derivedDerivedAsBase[-11];
161+
assert(x == -22);
162+
}
152163
return 0;
153164
}

test/Interop/SwiftToCxx/class/swift-class-virtual-method-dispatch.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public class BaseClass {
3232
}
3333
}
3434
public var storedProp: Int = 0
35+
36+
public subscript(_ i: Int) -> Int {
37+
return i
38+
}
3539
}
3640

3741
public class DerivedClass: BaseClass {
@@ -67,6 +71,10 @@ public class DerivedClass: BaseClass {
6771
super.storedProp = newValue
6872
}
6973
}
74+
75+
override public subscript(_ i: Int) -> Int {
76+
return i * 2
77+
}
7078
}
7179

7280
public final class DerivedDerivedClass: DerivedClass {
@@ -166,6 +174,13 @@ public func returnDerivedDerivedClass() -> DerivedDerivedClass {
166174
// CHECK-NEXT: return (* fptr_)(value, ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
167175
// CHECK-NEXT: }
168176

177+
// CHECK: swift::Int BaseClass::operator [](swift::Int i) const
178+
// CHECK-NEXT: void ***selfPtr_ = reinterpret_cast<void ***>( ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
179+
// CHECK-NEXT: void **vtable_ = *selfPtr_;
180+
// CHECK-NEXT: using FType = decltype(_impl::$s5Class04BaseA0CyS2icig);
181+
// CHECK-NEXT: FType *fptr_ = reinterpret_cast<FType *>(*(vtable_ + [[#VM1 + 9]]));
182+
// CHECK-NEXT: return (* fptr_)(i, ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
183+
169184
// CHECK: void DerivedClass::virtualMethod() {
170185
// CHECK-NEXT: void ***selfPtr_ = reinterpret_cast<void ***>( ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
171186
// CHECK-NEXT: void **vtable_ = *selfPtr_;
@@ -186,7 +201,7 @@ public func returnDerivedDerivedClass() -> DerivedDerivedClass {
186201
// CHECK-NEXT: void ***selfPtr_ = reinterpret_cast<void ***>( ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
187202
// CHECK-NEXT: void **vtable_ = *selfPtr_;
188203
// CHECK-NEXT: using FType = decltype(_impl::$s5Class07DerivedA0C015virtualMethodInB0yAA04BaseA0CAFF);
189-
// CHECK-NEXT: FType *fptr_ = reinterpret_cast<FType *>(*(vtable_ + [[#VM1 + 9]]));
204+
// CHECK-NEXT: FType *fptr_ = reinterpret_cast<FType *>(*(vtable_ + [[#VM1 + 10]]));
190205
// CHECK-NEXT: return _impl::_impl_BaseClass::makeRetained((* fptr_)(::swift::_impl::_impl_RefCountedClass::getOpaquePointer(x), ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this)));
191206
// CHECK-NEXT: }
192207

@@ -230,6 +245,13 @@ public func returnDerivedDerivedClass() -> DerivedDerivedClass {
230245
// CHECK-NEXT: return (* fptr_)(newValue, ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
231246
// CHECK-NEXT: }
232247

248+
// CHECK: swift::Int DerivedClass::operator [](swift::Int i) const
249+
// CHECK-NEXT: void ***selfPtr_ = reinterpret_cast<void ***>( ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
250+
// CHECK-NEXT: void **vtable_ = *selfPtr_;
251+
// CHECK-NEXT: using FType = decltype(_impl::$s5Class07DerivedA0CyS2icig);
252+
// CHECK-NEXT: FType *fptr_ = reinterpret_cast<FType *>(*(vtable_ + [[#VM1 + 9]]));
253+
// CHECK-NEXT: return (* fptr_)(i, ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
254+
233255
// CHECK: void DerivedDerivedClass::virtualMethod() {
234256
// CHECK-NEXT: return _impl::$s5Class07DerivedbA0C13virtualMethodyyF(::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
235257
// CHECK-NEXT: }

test/Interop/SwiftToCxx/class/swift-resilient-class-virtual-method-dispatch.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
// CHECK: void BaseClass::setStoredProp(swift::Int value) {
4040
// CHECK-NEXT: _impl::$s5Class04BaseA0C10storedPropSivsTj(value, ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
4141

42+
// CHECK: swift::Int BaseClass::operator [](swift::Int i) const
43+
// CHECK-NEXT: return _impl::$s5Class04BaseA0CyS2icigTj(i, ::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
44+
4245
// CHECK: void DerivedClass::virtualMethod() {
4346
// CHECK-NEXT: return _impl::$s5Class04BaseA0C13virtualMethodyyFTj(::swift::_impl::_impl_RefCountedClass::getOpaquePointer(*this));
4447
// CHECK-NEXT: }

0 commit comments

Comments
 (0)