Skip to content

Commit 69f95a2

Browse files
Merge pull request #31069 from aschwaighofer/irgen_use_clangs_objc_type_encoding
IRGen: Use clang's objc encoding for types when there is a ClangNode
2 parents 5b91742 + 9c4bbc1 commit 69f95a2

File tree

3 files changed

+65
-14
lines changed

3 files changed

+65
-14
lines changed

lib/IRGen/GenObjC.cpp

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,9 +1100,41 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM,
11001100
return IGM.getAddrOfGlobalString(encodingString);
11011101
}
11021102

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+
11061138
// Get the inputs without 'self'.
11071139
auto inputs = fnType->getParameters().drop_back();
11081140

@@ -1128,11 +1160,13 @@ irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
11281160
/// The first element is the selector.
11291161
descriptor.selectorRef = IGM.getAddrOfObjCMethodName(selector.str());
11301162

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.
11341167
CanSILFunctionType methodType = getObjCMethodType(IGM, method);
1135-
descriptor.typeEncoding = getObjCEncodingForMethodType(IGM, methodType, /*extended*/false);
1168+
descriptor.typeEncoding =
1169+
getObjCEncodingForMethod(IGM, methodType, /*extended*/ false, method);
11361170

11371171
/// The third element is the method implementation pointer.
11381172
if (!concrete) {
@@ -1191,10 +1225,13 @@ irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
11911225
Selector getterSel(subscript, Selector::ForGetter);
11921226
ObjCMethodDescriptor descriptor{};
11931227
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+
11981235
descriptor.silFunction = nullptr;
11991236
descriptor.impl = getObjCGetterPointer(IGM, subscript,
12001237
descriptor.silFunction);
@@ -1266,8 +1303,9 @@ irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
12661303
descriptor.selectorRef = IGM.getAddrOfObjCMethodName(setterSel.str());
12671304
auto methodTy = getObjCMethodType(IGM,
12681305
subscript->getOpaqueAccessor(AccessorKind::Set));
1269-
descriptor.typeEncoding = getObjCEncodingForMethodType(IGM, methodTy,
1270-
/*extended*/false);
1306+
descriptor.typeEncoding =
1307+
getObjCEncodingForMethod(IGM, methodTy,
1308+
/*extended*/ false, subscript);
12711309
descriptor.silFunction = nullptr;
12721310
descriptor.impl = getObjCSetterPointer(IGM, subscript,
12731311
descriptor.silFunction);
@@ -1358,11 +1396,12 @@ void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM,
13581396
buildMethodDescriptor(IGM, descriptors, descriptor);
13591397
}
13601398

1399+
13611400
llvm::Constant *
13621401
irgen::getMethodTypeExtendedEncoding(IRGenModule &IGM,
13631402
AbstractFunctionDecl *method) {
13641403
CanSILFunctionType methodType = getObjCMethodType(IGM, method);
1365-
return getObjCEncodingForMethodType(IGM, methodType, true/*Extended*/);
1404+
return getObjCEncodingForMethod(IGM, methodType, true /*Extended*/, method);
13661405
}
13671406

13681407
llvm::Constant *

test/IRGen/Inputs/usr/include/Gizmo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,7 @@ struct StructOfNSStrings useStructOfNSStringsInObjC(struct StructOfNSStrings);
159159
__attribute__((swift_name("OuterType.InnerType")))
160160
@interface OuterTypeInnerType : NSObject<NSRuncing>
161161
@end
162+
163+
@protocol P
164+
- (oneway void)stuff;
165+
@end

test/IRGen/objc_type_encoding.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ import gizmo
166166
func subclassComposition(_: MyCustomObject & NSRuncing & NSFunging)
167167
}
168168

169+
169170
// CHECK-macosx: [[ENC1:@.*]] = private unnamed_addr constant [35 x i8] c"v24@0:8@\22<NSFunging><NSRuncing>\2216\00"
170171
// CHECK-macosx: [[ENC2:@.*]] = private unnamed_addr constant [46 x i8] c"v32@0:8@\22Gizmo\2216@?<v@?@\22NSView\22@\22NSSpoon\22>24\00"
171172
// CHECK-macosx: [[ENC3:@.*]] = private unnamed_addr constant [53 x i8] c"v24@0:8@\22_TtC18objc_type_encoding14MyCustomObject\2216\00"
@@ -181,3 +182,10 @@ import gizmo
181182
// CHECK-tvos: [[ENC3:@.*]] = private unnamed_addr constant [53 x i8] c"v24@0:8@\22_TtC18objc_type_encoding14MyCustomObject\2216\00"
182183
// CHECK-tvos: [[ENC4:@.*]] = private unnamed_addr constant [75 x i8] c"v24@0:8@\22_TtC18objc_type_encoding14MyCustomObject<NSFunging><NSRuncing>\2216\00"
183184
// CHECK-tvos: @_PROTOCOL_METHOD_TYPES__TtP18objc_type_encoding10MyProtocol_ = private constant [4 x i8*] [i8* getelementptr inbounds ([35 x i8], [35 x i8]* [[ENC1]], i64 0, i64 0), i8* getelementptr inbounds ([46 x i8], [46 x i8]* [[ENC2]], i64 0, i64 0), i8* getelementptr inbounds ([53 x i8], [53 x i8]* [[ENC3]], i64 0, i64 0), i8* getelementptr inbounds ([75 x i8], [75 x i8]* [[ENC4]], i64 0, i64 0)]
185+
186+
class C: P {
187+
func stuff() {}
188+
}
189+
190+
// CHECK-macosx: [[ENC5:@.*]] = private unnamed_addr constant [9 x i8] c"Vv16@0:8\00"
191+
// CHECK-macosx: @_PROTOCOL_INSTANCE_METHODS_P = {{.*}}@"\01L_selector_data(stuff)"{{.*}}[[ENC5]]{{.*}}, section "__DATA, __objc_const", align 8

0 commit comments

Comments
 (0)