Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/IRGen/GenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,7 @@ namespace {
}

llvm::Constant *buildOptExtendedMethodTypes() {
if (!isBuildingProtocol()) return null();
assert(isBuildingProtocol());

ConstantInitBuilder builder(IGM);
auto array = builder.beginArray();
Expand All @@ -1670,6 +1670,8 @@ namespace {

void buildExtMethodTypes(ConstantArrayBuilder &array,
ArrayRef<MethodDescriptor> methods) {
assert(isBuildingProtocol());

for (auto descriptor : methods) {
assert(descriptor.getKind() == MethodDescriptor::Kind::Method &&
"cannot emit descriptor for non-method");
Expand Down
18 changes: 10 additions & 8 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,7 @@ class CategoryInitializerVisitor
return;

llvm::Constant *name, *imp, *types;
emitObjCMethodDescriptorParts(IGM, method,
/*extended*/false,
/*concrete*/true,
emitObjCMethodDescriptorParts(IGM, method, /*concrete*/true,
name, types, imp);

// When generating JIT'd code, we need to call sel_registerName() to force
Expand All @@ -215,8 +213,7 @@ class CategoryInitializerVisitor
void visitConstructorDecl(ConstructorDecl *constructor) {
if (!requiresObjCMethodDescriptor(constructor)) return;
llvm::Constant *name, *imp, *types;
emitObjCMethodDescriptorParts(IGM, constructor, /*extended*/false,
/*concrete*/true,
emitObjCMethodDescriptorParts(IGM, constructor, /*concrete*/true,
name, types, imp);

// When generating JIT'd code, we need to call sel_registerName() to force
Expand Down Expand Up @@ -391,9 +388,13 @@ class ObjCProtocolInitializerVisitor
void visitMissingMemberDecl(MissingMemberDecl *placeholder) {}

void visitAbstractFunctionDecl(AbstractFunctionDecl *method) {
if (isa<AccessorDecl>(method)) {
// Accessors are handled as part of their AbstractStorageDecls.
return;
}

llvm::Constant *name, *imp, *types;
emitObjCMethodDescriptorParts(IGM, method, /*extended*/true,
/*concrete*/false,
emitObjCMethodDescriptorParts(IGM, method, /*concrete*/false,
name, types, imp);

// When generating JIT'd code, we need to call sel_registerName() to force
Expand Down Expand Up @@ -438,7 +439,8 @@ class ObjCProtocolInitializerVisitor
Builder.CreateCall(protocol_addMethodDescription, getterArgs);

if (prop->isSettable(nullptr)) {
emitObjCSetterDescriptorParts(IGM, prop, name, types, imp);
emitObjCSetterDescriptorParts(IGM, prop,
name, types, imp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there rhyme or reason for why some of these use extended encodings and others don't?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Protocols do, non-protocols don't. I don't know the story further than that, though; I just imitated what was already there. (That's why I tagged Greg for review, really.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I guess that makes as much sense as anything. Could you make the fact that that's the reason behind the decision more explicit in the source?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I don't think this is correct after all. There's already a separate path for getting extended type encodings for protocols. @gparker42, how is this supposed to work?

sel = Builder.CreateCall(IGM.getObjCSelRegisterNameFn(), name);
llvm::Value *setterArgs[] = {
NewProto, sel, types,
Expand Down
23 changes: 11 additions & 12 deletions lib/IRGen/GenObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,6 @@ static llvm::Constant *getObjCEncodingForMethodType(IRGenModule &IGM,
/// type encoding, and IMP pointer.
SILFunction *irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
AbstractFunctionDecl *method,
bool extendedEncoding,
bool concrete,
llvm::Constant *&selectorRef,
llvm::Constant *&atEncoding,
Expand All @@ -1138,7 +1137,7 @@ SILFunction *irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
/// the return type @encoding and every parameter type @encoding, glued with
/// numbers that used to represent stack offsets for each of these elements.
CanSILFunctionType methodType = getObjCMethodType(IGM, method);
atEncoding = getObjCEncodingForMethodType(IGM, methodType, extendedEncoding);
atEncoding = getObjCEncodingForMethodType(IGM, methodType, /*extended*/false);

/// The third element is the method implementation pointer.
if (!concrete) {
Expand Down Expand Up @@ -1196,7 +1195,8 @@ SILFunction *irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
llvm::Constant *&impl) {
Selector getterSel(subscript, Selector::ForGetter);
selectorRef = IGM.getAddrOfObjCMethodName(getterSel.str());
atEncoding = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
CanSILFunctionType methodTy = getObjCMethodType(IGM, subscript->getGetter());
atEncoding = getObjCEncodingForMethodType(IGM, methodTy, /*extended*/false);
SILFunction *silFn = nullptr;
impl = getObjCGetterPointer(IGM, subscript, silFn);
return silFn;
Expand Down Expand Up @@ -1271,7 +1271,8 @@ SILFunction *irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,

Selector setterSel(subscript, Selector::ForSetter);
selectorRef = IGM.getAddrOfObjCMethodName(setterSel.str());
atEncoding = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
CanSILFunctionType methodTy = getObjCMethodType(IGM, subscript->getSetter());
atEncoding = getObjCEncodingForMethodType(IGM, methodTy, /*extended*/false);
SILFunction *silFn = nullptr;
impl = getObjCSetterPointer(IGM, subscript, silFn);
return silFn;
Expand Down Expand Up @@ -1315,10 +1316,8 @@ void irgen::emitObjCMethodDescriptor(IRGenModule &IGM,
ConstantArrayBuilder &descriptors,
AbstractFunctionDecl *method) {
llvm::Constant *selectorRef, *atEncoding, *impl;
auto silFn = emitObjCMethodDescriptorParts(IGM, method,
/*extended*/ false,
/*concrete*/ true,
selectorRef, atEncoding, impl);
auto silFn = emitObjCMethodDescriptorParts(IGM, method, /*concrete*/ true,
selectorRef, atEncoding, impl);
buildMethodDescriptor(descriptors, selectorRef, atEncoding, impl);

if (silFn && silFn->hasObjCReplacement()) {
Expand Down Expand Up @@ -1382,8 +1381,8 @@ void irgen::emitObjCGetterDescriptor(IRGenModule &IGM,
ConstantArrayBuilder &descriptors,
AbstractStorageDecl *storage) {
llvm::Constant *selectorRef, *atEncoding, *impl;
auto *silFn = emitObjCGetterDescriptorParts(IGM, storage, selectorRef,
atEncoding, impl);
auto *silFn = emitObjCGetterDescriptorParts(IGM, storage,
selectorRef, atEncoding, impl);
buildMethodDescriptor(descriptors, selectorRef, atEncoding, impl);
if (silFn && silFn->hasObjCReplacement()) {
auto replacedSelector =
Expand All @@ -1396,8 +1395,8 @@ void irgen::emitObjCSetterDescriptor(IRGenModule &IGM,
ConstantArrayBuilder &descriptors,
AbstractStorageDecl *storage) {
llvm::Constant *selectorRef, *atEncoding, *impl;
auto *silFn = emitObjCSetterDescriptorParts(IGM, storage, selectorRef,
atEncoding, impl);
auto *silFn = emitObjCSetterDescriptorParts(IGM, storage,
selectorRef, atEncoding, impl);
buildMethodDescriptor(descriptors, selectorRef, atEncoding, impl);
if (silFn && silFn->hasObjCReplacement()) {
auto replacedSelector =
Expand Down
1 change: 0 additions & 1 deletion lib/IRGen/GenObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ namespace irgen {
/// method or constructor implementation.
SILFunction *emitObjCMethodDescriptorParts(IRGenModule &IGM,
AbstractFunctionDecl *method,
bool extendedEncoding,
bool concrete,
llvm::Constant *&selectorRef,
llvm::Constant *&atEncoding,
Expand Down
106 changes: 97 additions & 9 deletions test/IRGen/objc_protocol_extended_method_types.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
// RUN: %empty-directory(%t)
// RUN: %build-irgen-test-overlays
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir | %FileCheck %s
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir -use-jit | %FileCheck -check-prefix=CHECK-JIT %s

// REQUIRES: CPU=x86_64
// REQUIRES: OS=macosx
// REQUIRES: objc_interop

import Foundation

// CHECK: [[INIT:@.*]] = private unnamed_addr constant [8 x i8] c"@16@0:8\00"
// CHECK: [[NSNUMBER:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSNumber\2224@0:8@\22NSNumber\2216\00"
// CHECK: [[NSMUTABLEARRAY_GET:@.*]] = private unnamed_addr constant [24 x i8] c"@\22NSMutableArray\2216@0:8\00"
// CHECK: [[NSMUTABLEARRAY_SET:@.*]] = private unnamed_addr constant [27 x i8] c"v24@0:8@\22NSMutableArray\2216\00"
// CHECK: [[SUBSCRIPT:@.*]] = private unnamed_addr constant [11 x i8] c"q24@0:8q16\00"
// CHECK: [[NSSTRING:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSString\2224@0:8@\22NSString\2216\00"
// CHECK: [[NSOBJECT:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSObject\2224@0:8@\22NSObject\2216\00"
// CHECK: [[NSMUTABLESTRING:@.*]] = private unnamed_addr constant [28 x i8] c"v24@0:8@\22NSMutableString\2216\00"
// CHECK-JIT-DAG: [[PROTOCOL_NAME:@.+]] = private unnamed_addr constant [45 x i8] c"_TtP35objc_protocol_extended_method_types1P_\00"


// CHECK-DAG: [[INIT:@.*]] = private unnamed_addr constant [8 x i8] c"@16@0:8\00"
// CHECK-DAG: [[NSNUMBER:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSNumber\2224@0:8@\22NSNumber\2216\00"
// CHECK-DAG: [[NSMUTABLEARRAY_GET:@.*]] = private unnamed_addr constant [24 x i8] c"@\22NSMutableArray\2216@0:8\00"
// CHECK-DAG: [[NSMUTABLEARRAY_SET:@.*]] = private unnamed_addr constant [27 x i8] c"v24@0:8@\22NSMutableArray\2216\00"
// CHECK-DAG: [[SUBSCRIPT:@.*]] = private unnamed_addr constant [11 x i8] c"q24@0:8q16\00"
// CHECK-DAG: [[NSSTRING:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSString\2224@0:8@\22NSString\2216\00"
// CHECK-DAG: [[NSOBJECT:@.*]] = private unnamed_addr constant [31 x i8] c"@\22NSObject\2224@0:8@\22NSObject\2216\00"
// CHECK-DAG: [[NSMUTABLESTRING:@.*]] = private unnamed_addr constant [28 x i8] c"v24@0:8@\22NSMutableString\2216\00"

// The JIT registration logic doesn't use extended types.
// CHECK-JIT-DAG: [[TY_ID_ID:@.*]] = private unnamed_addr constant [11 x i8] c"@24@0:8@16\00"
// CHECK-JIT-DAG: [[TY_VOID_ID:@.*]] = private unnamed_addr constant [11 x i8] c"v24@0:8@16\00"
// CHECK-JIT-DAG: [[TY_ID:@.*]] = private unnamed_addr constant [8 x i8] c"@16@0:8\00"
// CHECK-JIT-DAG: [[TY_INT_INT:@.*]] = private unnamed_addr constant [11 x i8] c"q24@0:8q16\00"

// CHECK-LABEL: @_PROTOCOL_METHOD_TYPES__TtP35objc_protocol_extended_method_types1P_ = private constant [16 x i8*] [
// -- required instance methods:
Expand Down Expand Up @@ -75,3 +85,81 @@ import Foundation
init()
}

print(P.self)

// CHECK-JIT-LABEL: define private void @runtime_registration
// CHECK-JIT: [[EXISTING_PROTOCOL:%.+]] = call %swift.protocol* @objc_getProtocol(i8* getelementptr inbounds ([45 x i8], [45 x i8]* [[PROTOCOL_NAME]], i64 0, i64 0))
// CHECK-JIT: [[EXISTS:%.+]] = icmp eq %swift.protocol* [[EXISTING_PROTOCOL]], null
// CHECK-JIT: br i1 [[EXISTS]], label %[[NEW_PROTOCOL_LABEL:[^ ]+]], label %[[EXISTING_PROTOCOL_LABEL:[^ ]+]]

// CHECK-JIT: [[EXISTING_PROTOCOL_LABEL]]:
// CHECK-JIT: br label %[[FINISH_LABEL:[^ ]+]]

// CHECK-JIT: [[NEW_PROTOCOL_LABEL]]:
// CHECK-JIT: [[NEW_PROTOCOL:%.+]] = call %swift.protocol* @objc_allocateProtocol(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @2, i64 0, i64 0))
// -- requiredInstanceMethod:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceMethod:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 1)
// -- optionalInstanceMethod:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalInstanceMethod:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 0, i8 1)
// -- requiredClassMethod:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredClassMethod:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 0)
// -- optionalClassMethod:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalClassMethod:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 0, i8 0)
// -- requiredInstanceProperty
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceProperty)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)

// Make sure we don't emit storage accessors multiple times.
// CHECK-JIT-NOT: requiredInstanceProperty

// -- setRequiredInstanceProperty:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(setRequiredInstanceProperty:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 1, i8 1)

// Make sure we don't emit storage accessors multiple times.
// CHECK-JIT-NOT: requiredInstanceProperty
// CHECK-JIT-NOT: setRequiredInstanceProperty

// -- requiredROInstanceProperty
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredROInstanceProperty)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
// -- requiredInstanceMethod2:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceMethod2:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 1)
// -- optionalInstanceMethod2:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalInstanceMethod2:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 0, i8 1)
// -- requiredClassMethod2:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredClassMethod2:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID_ID]], i64 0, i64 0), i8 1, i8 0)
// -- optionalClassMethod2:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(optionalClassMethod2:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 0, i8 0)
// -- requiredInstanceProperty2
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredInstanceProperty2)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
// -- setRequiredInstanceProperty2:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(setRequiredInstanceProperty2:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_VOID_ID]], i64 0, i64 0), i8 1, i8 1)
// -- requiredROInstanceProperty2
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(requiredROInstanceProperty2)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
// -- objectAtIndexedSubscript:
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(objectAtIndexedSubscript:)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_INT_INT]], i64 0, i64 0), i8 1, i8 1)
// -- init
// CHECK-JIT: [[SELECTOR:%.+]] = call i8* @sel_registerName(i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @"\01L_selector_data(init)", i64 0, i64 0))
// CHECK-JIT: call void @protocol_addMethodDescription(%swift.protocol* [[NEW_PROTOCOL]], i8* [[SELECTOR]], i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* [[TY_ID]], i64 0, i64 0), i8 1, i8 1)
// CHECK-JIT: call void @objc_registerProtocol(%swift.protocol* [[NEW_PROTOCOL]])
// CHECK-JIT: br label %[[FINISH_LABEL]]

// CHECK-JIT: [[FINISH_LABEL]]:
// CHECK-JIT: [[RESOLVED_PROTOCOL:%.+]] = phi %swift.protocol* [ [[EXISTING_PROTOCOL]], %[[EXISTING_PROTOCOL_LABEL]] ], [ [[NEW_PROTOCOL]], %[[NEW_PROTOCOL_LABEL]] ]{{$}}
// CHECK-JIT: store %swift.protocol* [[RESOLVED_PROTOCOL]], %swift.protocol** bitcast (i8** @"\01l_OBJC_PROTOCOL_REFERENCE_$__TtP35objc_protocol_extended_method_types1P_" to %swift.protocol**), align 8
// CHECK-JIT: ret void
// CHECK-JIT-NEXT: {{^}$}}

Loading