@@ -1116,6 +1116,29 @@ static llvm::Constant *getObjCEncodingForMethodType(IRGenModule &IGM,
1116
1116
ptrSize * 2 , useExtendedEncoding);
1117
1117
}
1118
1118
1119
+ static llvm::Constant *
1120
+ getObjectEncodingFromClangNode (IRGenModule &IGM, Decl *d,
1121
+ bool useExtendedEncoding) {
1122
+ // Use the clang node's encoding if there is a clang node.
1123
+ if (d->getClangNode ()) {
1124
+ auto clangDecl = d->getClangNode ().castAsDecl ();
1125
+ auto &clangASTContext = IGM.getClangASTContext ();
1126
+ std::string typeStr;
1127
+ if (auto objcMethodDecl = dyn_cast<clang::ObjCMethodDecl>(clangDecl)) {
1128
+ typeStr = clangASTContext.getObjCEncodingForMethodDecl (
1129
+ objcMethodDecl, useExtendedEncoding /* extended*/ );
1130
+ }
1131
+ if (auto objcPropertyDecl = dyn_cast<clang::ObjCPropertyDecl>(clangDecl)) {
1132
+ typeStr = clangASTContext.getObjCEncodingForPropertyDecl (objcPropertyDecl,
1133
+ nullptr );
1134
+ }
1135
+ if (!typeStr.empty ()) {
1136
+ return IGM.getAddrOfGlobalString (typeStr.c_str ());
1137
+ }
1138
+ }
1139
+ return nullptr ;
1140
+ }
1141
+
1119
1142
// / Emit the components of an Objective-C method descriptor: its selector,
1120
1143
// / type encoding, and IMP pointer.
1121
1144
ObjCMethodDescriptor
@@ -1128,11 +1151,18 @@ irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
1128
1151
// / The first element is the selector.
1129
1152
descriptor.selectorRef = IGM.getAddrOfObjCMethodName (selector.str ());
1130
1153
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.
1134
- CanSILFunctionType methodType = getObjCMethodType (IGM, method);
1135
- descriptor.typeEncoding = getObjCEncodingForMethodType (IGM, methodType, /* extended*/ false );
1154
+ if (auto e =
1155
+ getObjectEncodingFromClangNode (IGM, method, false /* extended*/ )) {
1156
+ descriptor.typeEncoding = e;
1157
+ } else {
1158
+ // / The second element is the method signature. A method signature is made
1159
+ // / of the return type @encoding and every parameter type @encoding, glued
1160
+ // / with numbers that used to represent stack offsets for each of these
1161
+ // / elements.
1162
+ CanSILFunctionType methodType = getObjCMethodType (IGM, method);
1163
+ descriptor.typeEncoding =
1164
+ getObjCEncodingForMethodType (IGM, methodType, /* extended*/ false );
1165
+ }
1136
1166
1137
1167
// / The third element is the method implementation pointer.
1138
1168
if (!concrete) {
@@ -1191,10 +1221,17 @@ irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
1191
1221
Selector getterSel (subscript, Selector::ForGetter);
1192
1222
ObjCMethodDescriptor descriptor{};
1193
1223
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 );
1224
+
1225
+ if (auto e =
1226
+ getObjectEncodingFromClangNode (IGM, subscript, false /* extended*/ )) {
1227
+ descriptor.typeEncoding = e;
1228
+ } else {
1229
+ auto methodTy =
1230
+ getObjCMethodType (IGM, subscript->getOpaqueAccessor (AccessorKind::Get));
1231
+ descriptor.typeEncoding = getObjCEncodingForMethodType (IGM, methodTy,
1232
+ /* extended*/ false );
1233
+ }
1234
+
1198
1235
descriptor.silFunction = nullptr ;
1199
1236
descriptor.impl = getObjCGetterPointer (IGM, subscript,
1200
1237
descriptor.silFunction );
@@ -1266,8 +1303,13 @@ 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
+ if (auto e =
1307
+ getObjectEncodingFromClangNode (IGM, subscript, false /* extended*/ )) {
1308
+ descriptor.typeEncoding = e;
1309
+ } else {
1310
+ descriptor.typeEncoding = getObjCEncodingForMethodType (IGM, methodTy,
1311
+ /* extended*/ false );
1312
+ }
1271
1313
descriptor.silFunction = nullptr ;
1272
1314
descriptor.impl = getObjCSetterPointer (IGM, subscript,
1273
1315
descriptor.silFunction );
@@ -1359,9 +1401,15 @@ void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM,
1359
1401
buildMethodDescriptor (IGM, descriptors, descriptor);
1360
1402
}
1361
1403
1404
+
1362
1405
llvm::Constant *
1363
1406
irgen::getMethodTypeExtendedEncoding (IRGenModule &IGM,
1364
1407
AbstractFunctionDecl *method) {
1408
+ // Use the clang node's encoding if there is a clang node.
1409
+ if (auto e = getObjectEncodingFromClangNode (IGM, method, true /* extended*/ )) {
1410
+ return e;
1411
+ }
1412
+
1365
1413
CanSILFunctionType methodType = getObjCMethodType (IGM, method);
1366
1414
return getObjCEncodingForMethodType (IGM, methodType, true /* Extended*/ );
1367
1415
}
0 commit comments