@@ -1100,9 +1100,41 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM,
1100
1100
return IGM.getAddrOfGlobalString (encodingString);
1101
1101
}
1102
1102
1103
- static llvm::Constant *getObjCEncodingForMethodType (IRGenModule &IGM,
1104
- CanSILFunctionType fnType,
1105
- bool useExtendedEncoding) {
1103
+ static llvm::Constant *
1104
+ getObjectEncodingFromClangNode (IRGenModule &IGM, Decl *d,
1105
+ bool useExtendedEncoding) {
1106
+ // Use the clang node's encoding if there is a clang node.
1107
+ if (d->getClangNode ()) {
1108
+ auto clangDecl = d->getClangNode ().castAsDecl ();
1109
+ auto &clangASTContext = IGM.getClangASTContext ();
1110
+ std::string typeStr;
1111
+ if (auto objcMethodDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
1112
+ typeStr = clangASTContext.getObjCEncodingForMethodDecl (
1113
+ objcMethodDecl, useExtendedEncoding /* extended*/ );
1114
+ }
1115
+ if (auto objcPropertyDecl = dyn_cast<clang::ObjCPropertyDecl>(clangDecl)) {
1116
+ typeStr = clangASTContext.getObjCEncodingForPropertyDecl (objcPropertyDecl,
1117
+ nullptr );
1118
+ }
1119
+ if (!typeStr.empty ()) {
1120
+ return IGM.getAddrOfGlobalString (typeStr.c_str ());
1121
+ }
1122
+ }
1123
+ return nullptr ;
1124
+ }
1125
+
1126
+ static llvm::Constant *getObjCEncodingForMethod (IRGenModule &IGM,
1127
+ CanSILFunctionType fnType,
1128
+ bool useExtendedEncoding,
1129
+ Decl *optionalDecl) {
1130
+ // Use the decl's ClangNode to get the encoding if possible.
1131
+ if (optionalDecl) {
1132
+ if (auto *enc = getObjectEncodingFromClangNode (IGM, optionalDecl,
1133
+ useExtendedEncoding)) {
1134
+ return enc;
1135
+ }
1136
+ }
1137
+
1106
1138
// Get the inputs without 'self'.
1107
1139
auto inputs = fnType->getParameters ().drop_back ();
1108
1140
@@ -1128,11 +1160,13 @@ irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
1128
1160
// / The first element is the selector.
1129
1161
descriptor.selectorRef = IGM.getAddrOfObjCMethodName (selector.str ());
1130
1162
1131
- // / The second element is the method signature. A method signature is made of
1132
- // / the return type @encoding and every parameter type @encoding, glued with
1133
- // / numbers that used to represent stack offsets for each of these elements.
1163
+ // / The second element is the method signature. A method signature is made
1164
+ // / of the return type @encoding and every parameter type @encoding, glued
1165
+ // / with numbers that used to represent stack offsets for each of these
1166
+ // / elements.
1134
1167
CanSILFunctionType methodType = getObjCMethodType (IGM, method);
1135
- descriptor.typeEncoding = getObjCEncodingForMethodType (IGM, methodType, /* extended*/ false );
1168
+ descriptor.typeEncoding =
1169
+ getObjCEncodingForMethod (IGM, methodType, /* extended*/ false , method);
1136
1170
1137
1171
// / The third element is the method implementation pointer.
1138
1172
if (!concrete) {
@@ -1191,10 +1225,13 @@ irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
1191
1225
Selector getterSel (subscript, Selector::ForGetter);
1192
1226
ObjCMethodDescriptor descriptor{};
1193
1227
descriptor.selectorRef = IGM.getAddrOfObjCMethodName (getterSel.str ());
1194
- auto methodTy = getObjCMethodType (IGM,
1195
- subscript->getOpaqueAccessor (AccessorKind::Get));
1196
- descriptor.typeEncoding = getObjCEncodingForMethodType (IGM, methodTy,
1197
- /* extended*/ false );
1228
+
1229
+ auto methodTy =
1230
+ getObjCMethodType (IGM, subscript->getOpaqueAccessor (AccessorKind::Get));
1231
+ descriptor.typeEncoding =
1232
+ getObjCEncodingForMethod (IGM, methodTy,
1233
+ /* extended*/ false , subscript);
1234
+
1198
1235
descriptor.silFunction = nullptr ;
1199
1236
descriptor.impl = getObjCGetterPointer (IGM, subscript,
1200
1237
descriptor.silFunction );
@@ -1266,8 +1303,9 @@ irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
1266
1303
descriptor.selectorRef = IGM.getAddrOfObjCMethodName (setterSel.str ());
1267
1304
auto methodTy = getObjCMethodType (IGM,
1268
1305
subscript->getOpaqueAccessor (AccessorKind::Set));
1269
- descriptor.typeEncoding = getObjCEncodingForMethodType (IGM, methodTy,
1270
- /* extended*/ false );
1306
+ descriptor.typeEncoding =
1307
+ getObjCEncodingForMethod (IGM, methodTy,
1308
+ /* extended*/ false , subscript);
1271
1309
descriptor.silFunction = nullptr ;
1272
1310
descriptor.impl = getObjCSetterPointer (IGM, subscript,
1273
1311
descriptor.silFunction );
@@ -1358,11 +1396,12 @@ void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM,
1358
1396
buildMethodDescriptor (IGM, descriptors, descriptor);
1359
1397
}
1360
1398
1399
+
1361
1400
llvm::Constant *
1362
1401
irgen::getMethodTypeExtendedEncoding (IRGenModule &IGM,
1363
1402
AbstractFunctionDecl *method) {
1364
1403
CanSILFunctionType methodType = getObjCMethodType (IGM, method);
1365
- return getObjCEncodingForMethodType (IGM, methodType, true /* Extended*/ );
1404
+ return getObjCEncodingForMethod (IGM, methodType, true /* Extended*/ , method );
1366
1405
}
1367
1406
1368
1407
llvm::Constant *
0 commit comments