Skip to content

Commit 8c48d26

Browse files
committed
[interop][SwiftToCxx] expose subscript getter for Array's operator []
1 parent d5c531f commit 8c48d26

File tree

5 files changed

+62
-11
lines changed

5 files changed

+62
-11
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,8 @@ class DeclAndTypePrinter::Implementation
873873

874874
void printAbstractFunctionAsMethod(AbstractFunctionDecl *AFD,
875875
bool isClassMethod,
876-
bool isNSUIntegerSubscript = false) {
876+
bool isNSUIntegerSubscript = false,
877+
const SubscriptDecl *SD = nullptr) {
877878
printDocumentationComment(AFD);
878879

879880
Optional<ForeignAsyncConvention> asyncConvention =
@@ -910,10 +911,15 @@ class DeclAndTypePrinter::Implementation
910911
os, owningPrinter.prologueOS, owningPrinter.typeMapping,
911912
owningPrinter.interopContext, owningPrinter);
912913
if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
913-
declPrinter.printCxxPropertyAccessorMethod(
914-
typeDeclContext, accessor, funcABI->getSignature(),
915-
funcABI->getSymbolName(), resultTy,
916-
/*isDefinition=*/false);
914+
if (SD)
915+
declPrinter.printCxxSubscriptAccessorMethod(
916+
typeDeclContext, accessor, funcABI->getSignature(),
917+
funcABI->getSymbolName(), resultTy, /*isDefinition=*/false);
918+
else
919+
declPrinter.printCxxPropertyAccessorMethod(
920+
typeDeclContext, accessor, funcABI->getSignature(),
921+
funcABI->getSymbolName(), resultTy,
922+
/*isDefinition=*/false);
917923
} else {
918924
declPrinter.printCxxMethod(typeDeclContext, AFD,
919925
funcABI->getSignature(),
@@ -927,11 +933,15 @@ class DeclAndTypePrinter::Implementation
927933
owningPrinter);
928934

929935
if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
930-
931-
defPrinter.printCxxPropertyAccessorMethod(
932-
typeDeclContext, accessor, funcABI->getSignature(),
933-
funcABI->getSymbolName(), resultTy,
934-
/*isDefinition=*/true);
936+
if (SD)
937+
defPrinter.printCxxSubscriptAccessorMethod(
938+
typeDeclContext, accessor, funcABI->getSignature(),
939+
funcABI->getSymbolName(), resultTy, /*isDefinition=*/true);
940+
else
941+
defPrinter.printCxxPropertyAccessorMethod(
942+
typeDeclContext, accessor, funcABI->getSignature(),
943+
funcABI->getSymbolName(), resultTy,
944+
/*isDefinition=*/true);
935945
} else {
936946
defPrinter.printCxxMethod(typeDeclContext, AFD, funcABI->getSignature(),
937947
funcABI->getSymbolName(), resultTy,
@@ -1818,8 +1828,14 @@ class DeclAndTypePrinter::Implementation
18181828
}
18191829

18201830
void visitSubscriptDecl(SubscriptDecl *SD) {
1821-
if (outputLang == OutputLanguageMode::Cxx)
1831+
if (outputLang == OutputLanguageMode::Cxx) {
1832+
if (!SD->isInstanceMember())
1833+
return;
1834+
auto *getter = SD->getOpaqueAccessor(AccessorKind::Get);
1835+
printAbstractFunctionAsMethod(getter, false,
1836+
/*isNSUIntegerSubscript=*/false, SD);
18221837
return;
1838+
}
18231839
assert(SD->isInstanceMember() && "static subscripts not supported");
18241840

18251841
bool isNSUIntegerSubscript = false;

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,32 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
12081208
os << " }\n";
12091209
}
12101210

1211+
void DeclAndTypeClangFunctionPrinter::printCxxSubscriptAccessorMethod(
1212+
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
1213+
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
1214+
Type resultTy, bool isDefinition) {
1215+
assert(accessor->isGetter());
1216+
FunctionSignatureModifiers modifiers;
1217+
if (isDefinition)
1218+
modifiers.qualifierContext = typeDeclContext;
1219+
modifiers.isInline = true;
1220+
modifiers.isConst = true;
1221+
auto result =
1222+
printFunctionSignature(accessor, signature, "operator []", resultTy,
1223+
FunctionSignatureKind::CxxInlineThunk, modifiers);
1224+
assert(!result.isUnsupported() && "C signature should be unsupported too!");
1225+
if (!isDefinition) {
1226+
os << ";\n";
1227+
return;
1228+
}
1229+
os << " {\n";
1230+
// FIXME: should it be objTy for resultTy?
1231+
printCxxThunkBody(accessor, signature, swiftSymbolName,
1232+
accessor->getModuleContext(), resultTy,
1233+
accessor->getParameters());
1234+
os << " }\n";
1235+
}
1236+
12111237
bool DeclAndTypeClangFunctionPrinter::hasKnownOptionalNullableCxxMapping(
12121238
Type type) {
12131239
if (auto optionalObjectType = type->getOptionalObjectType()) {

lib/PrintAsClang/PrintClangFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ class DeclAndTypeClangFunctionPrinter {
123123
StringRef swiftSymbolName, Type resultTy,
124124
bool isDefinition);
125125

126+
/// Print the C++ subscript method.
127+
void printCxxSubscriptAccessorMethod(
128+
const NominalTypeDecl *typeDeclContext, const AccessorDecl *accessor,
129+
const LoweredFunctionSignature &signature, StringRef swiftSymbolName,
130+
Type resultTy, bool isDefinition);
131+
126132
/// Print Swift type as C/C++ type, as the return type of a C/C++ function.
127133
ClangRepresentation
128134
printClangFunctionReturnType(Type ty, OptionalTypeKind optKind,

test/Interop/SwiftToCxx/stdlib/array/array-execution.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ int main() {
4848
UseArray::printArray(val);
4949
assert(val.getCount() == 1);
5050
assert(val.getCapacity() >= 1);
51+
auto zeroInt = val[0];
52+
assert(zeroInt == -11);
5153
auto firstInt = val.remove(0);
5254
assert(firstInt == -11);
5355
assert(val.getCount() == 0);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// CHECK: static inline Array<T_0_0> init();
2121
// CHECK: inline void append(const T_0_0& newElement);
2222
// CHECK: inline T_0_0 remove(swift::Int index);
23+
// CHECK: inline T_0_0 operator [](swift::Int index) const;
2324
// CHECK: inline swift::Int getCount() const;
2425
// CHECK: inline swift::Int getCapacity() const;
2526

0 commit comments

Comments
 (0)