| // RUN: %empty-directory(%t) |
| // RUN: %utils/chex.py < %s > %t/generic_classes.sil |
| // RUN: %target-swift-frontend %t/generic_classes.sil -emit-ir | %FileCheck %t/generic_classes.sil --check-prefix=CHECK --check-prefix=CHECK-%target-runtime |
| // RUN: %target-swift-frontend -Osize %t/generic_classes.sil -emit-ir | %FileCheck %t/generic_classes.sil --check-prefix=OSIZE |
| |
| // REQUIRES: CPU=x86_64 |
| |
| import Builtin |
| import Swift |
| |
| // CHECK: [[ROOTGENERIC:%T15generic_classes11RootGenericC]] = type <{ %swift.refcounted, %Ts5UInt8V }> |
| |
| // -- offset of RootGeneric<T>.x |
| // FIXME: Strings should be unnamed_addr. rdar://problem/22674524 |
| // CHECK: [[ROOTGENERIC_NAME:@.*]] = private constant [12 x i8] c"RootGeneric\00" |
| |
| // CHECK-LABEL: @"$S15generic_classes11RootGenericCMn" = |
| // -- flags: class, generic, unique, reflectable, has vtable |
| // CHECK-SAME: <i32 0x8004_00D0> |
| // -- name |
| // CHECK-SAME: [12 x i8]* [[ROOTGENERIC_NAME]] |
| // -- negative size in words |
| // CHECK-SAME: i32 2, |
| // -- positive size in words |
| // CHECK-SAME: i32 18, |
| // -- num immediate members |
| // CHECK-SAME: i32 8, |
| // -- num fields |
| // CHECK-SAME: i32 3, |
| // -- field offset vector offset |
| // CHECK-SAME: i32 15, |
| // -- template instantiation cache |
| // CHECK-SAME: [16 x i8*]* @"$S15generic_classes11RootGenericCMI" |
| // -- template instantiation pattern |
| // CHECK-SAME: @"$S15generic_classes11RootGenericCMP" |
| // -- generic parameters, requirements, key arguments, extra arguments |
| // CHECK-SAME: i32 1, i32 0, i32 1, i32 0 |
| // -- vtable offset |
| // CHECK-SAME: i32 11, |
| // -- vtable size |
| // CHECK-SAME: i32 4 |
| // CHECK-SAME: } |
| |
| // CHECK-LABEL: @"$S15generic_classes11RootGenericCMP" = internal constant |
| // CHECK-SAME: <{ |
| // -- template instantiation function |
| // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_classes11RootGenericCMi" |
| // -- heap destructor |
| // CHECK-SAME: @"$S15generic_classes11RootGenericCfD" |
| // -- ivar destroyer |
| // CHECK-SAME: i32 0, |
| // -- flags |
| // CHECK_SAME: i32 3, |
| // -- immediate pattern size |
| // CHECK-SAME: i16 0, |
| // -- immediate pattern target offset |
| // CHECK-SAME: i16 0, |
| // -- extra data size |
| // CHECK-SAME-native: i16 0, |
| // CHECK-SAME-objc: i16 23, |
| // -- class ro-data offset |
| // CHECK-SAME-native: i16 0, |
| // CHECK-SAME-objc: i16 5, |
| // -- metaclass object offset |
| // CHECK-SAME-native: i16 0, |
| // CHECK-SAME-objc: i16 0, |
| // -- class ro-data offset |
| // CHECK-SAME-native: i16 0 |
| // CHECK-SAME-objc: i16 14, |
| // CHECK-SAME: }> |
| |
| // -- Check that offset vars are emitted for fixed-layout generics |
| // <rdar://problem/15081049> |
| // CHECK: @"$S15generic_classes22RootGenericFixedLayoutC1xs5UInt8VvpWvd" = hidden constant i64 16, align 8 |
| // CHECK: @"$S15generic_classes22RootGenericFixedLayoutC1ySayxGvpWvd" = hidden constant i64 24, align 8 |
| // CHECK: @"$S15generic_classes22RootGenericFixedLayoutC1zs5UInt8VvpWvd" = hidden constant i64 32, align 8 |
| |
| // -- fixed-layout nongeneric descriptor |
| // FIXME: Strings should be unnamed_addr. rdar://problem/22674524 |
| // CHECK: [[ROOTNONGENERIC_NAME:@.*]] = private constant [15 x i8] c"RootNonGeneric\00" |
| // CHECK: @"$S15generic_classes14RootNonGenericCMn" = hidden constant <{ {{.*}} %swift.method_descriptor }> <{ |
| // -- flags: class, unique, has vtable, reflectable |
| // CHECK-SAME: <i32 0x8004_0050> |
| // -- name |
| // CHECK-SAME: [15 x i8]* [[ROOTNONGENERIC_NAME]] |
| // -- num fields |
| // CHECK-SAME: i32 3, |
| // -- -- field offset vector offset |
| // CHECK-SAME: i32 11, |
| // CHECK-SAME: }> |
| |
| // CHECK: @"$S15generic_classes14RootNonGenericCMf" = internal global <{ {{.*}} }> <{ |
| // CHECK-SAME: void (%T15generic_classes14RootNonGenericC*)* @"$S15generic_classes14RootNonGenericCfD", |
| // CHECK-SAME: i8** @"$SBoWV", |
| // CHECK-SAME-native: i64 0, |
| // CHECK-SAME-native: %swift.type* null, |
| // CHECK-SAME-native: %swift.opaque* null, |
| // CHECK-SAME-objc: i64 ptrtoint (%objc_class* @"$S15generic_classes14RootNonGenericCMm" to i64), |
| // CHECK-SAME-objc: %objc_class* @"OBJC_CLASS_$__TtCs12_SwiftObject", |
| // CHECK-SAME-objc: %swift.opaque* @_objc_empty_cache, |
| // CHECK-SAME: %swift.opaque* null, |
| // CHECK-SAME-native: i64 1, |
| // CHECK-SAME-objc: @_DATA__TtC15generic_classes14RootNonGeneric |
| // CHECK-SAME: i32 33, |
| // CHECK-SAME: i16 7, |
| // CHECK-SAME: i16 0, |
| // CHECK-SAME: {{.*}}* @"$S15generic_classes14RootNonGenericCMn" |
| // CHECK-SAME: }> |
| |
| // CHECK: @"$S15generic_classes015GenericInheritsC0CMn" = hidden constant |
| // -- template instantiation pattern |
| // CHECK-SAME: @"$S15generic_classes015GenericInheritsC0CMP" |
| |
| // CHECK: @"$S15generic_classes015GenericInheritsC0CMP" = internal constant |
| // -- template instantiation function |
| // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8**)* @"$S15generic_classes015GenericInheritsC0CMi" |
| // -- pattern flags (1 == has extra data pattern) |
| // CHECK-SAME-native: i32 0, |
| // CHECK-SAME-objc: i32 1, |
| // -- heap destructor |
| // CHECK-SAME: @"$S15generic_classes015GenericInheritsC0CfD" |
| // -- ivar destroyer |
| // CHECK-SAME: i32 0, |
| // -- class flags |
| // CHECK_SAME: i32 3, |
| // -- extra data pattern offset |
| // CHECK-SAME-objc: i16 0, |
| // -- extra data pattern size |
| // CHECK-SAME-objc: i16 23, |
| // -- class ro-data offset |
| // CHECK-SAME-native: i16 0, |
| // CHECK-SAME-objc: i16 5, |
| // -- metaclass object offset |
| // CHECK-SAME-native: i16 0, |
| // CHECK-SAME-objc: i16 0, |
| // -- class ro-data offset |
| // CHECK-SAME-native: i16 0, |
| // CHECK-SAME-objc: i16 14, |
| // -- reserved |
| // CHECK-SAME: i16 0 |
| // CHECK-SAME: } |
| |
| // CHECK: @"$S15generic_classes018GenericInheritsNonC0CMP" |
| |
| class RootGeneric<T> { |
| var x : UInt8 |
| |
| init() |
| |
| // Test that declaration order doesn't cause the field offset vector to end |
| // up interleaved with the vtable. |
| func foo() |
| |
| var y : T |
| |
| func bar() |
| |
| var z : UInt8 |
| |
| func bas() |
| } |
| sil @$S15generic_classes11RootGenericCfD : $@convention(method) <T> (RootGeneric<T>) -> () |
| |
| sil @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_ : $@convention(method) <T> (@guaranteed RootGeneric<T>) -> () |
| |
| sil @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_ : $@convention(method) <T> (@guaranteed RootGeneric<T>) -> () |
| |
| sil @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_ : $@convention(method) <T> (@guaranteed RootGeneric<T>) -> () |
| |
| sil_vtable RootGeneric { |
| #RootGeneric.foo!1: @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_ |
| #RootGeneric.bar!1: @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_ |
| #RootGeneric.bas!1: @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_ |
| } |
| |
| class RootGenericFixedLayout<T> { |
| var x : UInt8 |
| var y : [T] |
| var z : UInt8 |
| |
| init() |
| } |
| sil_vtable RootGenericFixedLayout {} |
| sil @$S15generic_classes22RootGenericFixedLayoutCfD : $@convention(method) <T> (RootGenericFixedLayout<T>) -> () |
| |
| class RootNonGeneric { |
| var x : UInt8 |
| var y : Int |
| var z : UInt8 |
| |
| init() |
| } |
| sil_vtable RootNonGeneric {} |
| sil @$S15generic_classes14RootNonGenericCfD : $@convention(method) (RootNonGeneric) -> () |
| |
| class GenericInheritsGeneric<A, B> : RootGeneric<A> { |
| var w : B |
| |
| func zippity() |
| func doo() |
| func dah() |
| |
| override init() |
| } |
| sil @$S15generic_classes015GenericInheritsC0CfD : $@convention(method) <T, U> (GenericInheritsGeneric<T, U>) -> () |
| |
| sil @_TFC15generic_classes22GenericInheritsGeneric7zippityU___fGS0_Q_Q0__FT_T_ : $@convention(method) <A, B> (@guaranteed GenericInheritsGeneric<A, B>) -> () |
| |
| sil @_TFC15generic_classes22GenericInheritsGeneric3dooU___fGS0_Q_Q0__FT_T_ : $@convention(method) <A, B> (@guaranteed GenericInheritsGeneric<A, B>) -> () |
| |
| sil @_TFC15generic_classes22GenericInheritsGeneric3dahU___fGS0_Q_Q0__FT_T_ : $@convention(method) <A, B> (@guaranteed GenericInheritsGeneric<A, B>) -> () |
| |
| sil_vtable GenericInheritsGeneric { |
| #RootGeneric.foo!1: @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_ [inherited] |
| #RootGeneric.bar!1: @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_ [inherited] |
| #RootGeneric.bas!1: @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_ [inherited] |
| #GenericInheritsGeneric.zippity!1: @_TFC15generic_classes22GenericInheritsGeneric7zippityU___fGS0_Q_Q0__FT_T_ |
| #GenericInheritsGeneric.doo!1: @_TFC15generic_classes22GenericInheritsGeneric3dooU___fGS0_Q_Q0__FT_T_ |
| #GenericInheritsGeneric.dah!1: @_TFC15generic_classes22GenericInheritsGeneric3dahU___fGS0_Q_Q0__FT_T_ |
| } |
| |
| class GenericInheritsNonGeneric<C> : RootNonGeneric { |
| var w : UInt8 |
| |
| override init() |
| } |
| sil_vtable GenericInheritsNonGeneric {} |
| sil @$S15generic_classes018GenericInheritsNonC0CfD : $@convention(method) <T> (GenericInheritsNonGeneric<T>) -> () |
| |
| // rdar://18067671 |
| class RecursiveGenericInheritsGeneric<A, B> : RootGeneric<A> { |
| var w : B |
| var r : RecursiveGenericInheritsGeneric<A, B>? |
| |
| func zippity() |
| func doo() |
| func dah() |
| |
| override init() |
| } |
| sil_vtable RecursiveGenericInheritsGeneric {} |
| sil @$S15generic_classes024RecursiveGenericInheritsD0CfD : $@convention(method) <T, U> (RecursiveGenericInheritsGeneric<T, U>) -> () |
| |
| |
| // CHECK: define{{( protected)?}} swiftcc [[ROOTGENERIC]]* @RootGeneric_fragile_dependent_alloc |
| // CHECK: [[METADATA:%.*]] = call %swift.type* @"$S15generic_classes11RootGenericCMa" |
| // CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8* |
| // CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[METADATA_ARRAY]], i32 48 |
| // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i32* |
| // CHECK: [[SIZE32:%.*]] = load i32, i32* [[T1]], align 8 |
| // CHECK: [[SIZE:%.*]] = zext i32 [[SIZE32]] to i64 |
| // CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[METADATA_ARRAY]], i32 52 |
| // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i16* |
| // CHECK: [[ALIGN16:%.*]] = load i16, i16* [[T1]], align 4 |
| // CHECK: [[ALIGN:%.*]] = zext i16 [[ALIGN16]] to i64 |
| // CHECK: call noalias %swift.refcounted* @swift_allocObject(%swift.type* [[METADATA]], i64 [[SIZE]], i64 [[ALIGN]]) |
| sil @RootGeneric_fragile_dependent_alloc : $<G> () -> RootGeneric<G> { |
| entry: |
| %x = alloc_ref $RootGeneric<G> |
| return %x : $RootGeneric<G> |
| } |
| |
| // RootGeneric.x has fixed layout |
| // CHECK: define{{( protected)?}} swiftcc i8 @RootGeneric_concrete_fragile_dependent_member_access_x |
| // CHECK: getelementptr inbounds [[ROOTGENERIC]], [[ROOTGENERIC]]* %0, i32 0, i32 1 |
| sil @RootGeneric_concrete_fragile_dependent_member_access_x : $<F> RootGeneric<F> -> UInt8 { |
| entry(%c : $RootGeneric<F>): |
| %p = ref_element_addr %c : $RootGeneric<F>, #RootGeneric.x |
| %x = load_borrow %p : $*UInt8 |
| return %x : $UInt8 |
| } |
| |
| // RootGeneric.y has dependent layout; load the offset from the metadata |
| // CHECK-LABEL: define{{( protected)?}} swiftcc void @RootGeneric_concrete_fragile_dependent_member_access_y |
| // CHECK: [[TYPE_METADATA_ARRAY:%.*]] = bitcast %swift.type* {{%.*}} to i64* |
| // CHECK: [[Y_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[TYPE_METADATA_ARRAY]], i64 16 |
| // CHECK: [[Y_OFFSET:%.*]] = load i64, i64* [[Y_OFFSET_ADDR]], align 8 |
| // CHECK: [[CLASS_BYTE_ARRAY:%.*]] = bitcast [[ROOTGENERIC]]* {{%.*}} to i8* |
| // CHECK: [[Y_ADDR:%.*]] = getelementptr inbounds i8, i8* [[CLASS_BYTE_ARRAY]], i64 [[Y_OFFSET]] |
| // CHECK: bitcast i8* [[Y_ADDR]] to %swift.opaque* |
| sil @RootGeneric_concrete_fragile_dependent_member_access_y : $<F> (RootGeneric<F>) -> @out F { |
| entry(%z : $*F, %c : $RootGeneric<F>): |
| %p = ref_element_addr %c : $RootGeneric<F>, #RootGeneric.y |
| copy_addr %p to [initialization] %z : $*F |
| %t = tuple () |
| return %t : $() |
| } |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc void @RootGeneric_subst_concrete_fragile_dependent_member_access_y |
| // CHECK: [[Y_ADDR:%.*]] = getelementptr inbounds {{.*}}, {{.*}}* %1, i32 0, i32 3 |
| // CHECK: bitcast %TSi* [[Y_ADDR]] to i8* |
| sil @RootGeneric_subst_concrete_fragile_dependent_member_access_y : $(RootGeneric<Int>) -> @out Int { |
| entry(%z : $*Int, %c : $RootGeneric<Int>): |
| %p = ref_element_addr %c : $RootGeneric<Int>, #RootGeneric.y |
| copy_addr %p to [initialization] %z : $*Int |
| %t = tuple () |
| return %t : $() |
| } |
| |
| // RootGeneric.z has dependent layout; load the offset from the metadata |
| // CHECK-LABEL: define{{( protected)?}} swiftcc i8 @RootGeneric_concrete_fragile_dependent_member_access_z |
| // CHECK: [[TYPE_METADATA_ARRAY:%.*]] = bitcast %swift.type* {{%.*}} to i64* |
| // CHECK: [[Z_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[TYPE_METADATA_ARRAY]], i64 17 |
| // CHECK: [[Z_OFFSET:%.*]] = load i64, i64* [[Z_OFFSET_ADDR]], align 8 |
| // CHECK: [[CLASS_BYTE_ARRAY:%.*]] = bitcast [[ROOTGENERIC]]* {{%.*}} to i8* |
| // CHECK: [[Z_ADDR:%.*]] = getelementptr inbounds i8, i8* [[CLASS_BYTE_ARRAY]], i64 [[Z_OFFSET]] |
| // CHECK: bitcast i8* [[Z_ADDR]] to %Ts5UInt8V* |
| sil @RootGeneric_concrete_fragile_dependent_member_access_z : $<F> RootGeneric<F> -> UInt8 { |
| entry(%c : $RootGeneric<F>): |
| %p = ref_element_addr %c : $RootGeneric<F>, #RootGeneric.z |
| %z = load_borrow %p : $*UInt8 |
| return %z : $UInt8 |
| } |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc i8 @RootGeneric_subst_concrete_fragile_dependent_member_access_z |
| // CHECK: [[Z_ADDR:%.*]] = getelementptr inbounds {{.*}}, {{.*}}* %0, i32 0, i32 4 |
| // CHECK: [[T0:%.*]] = getelementptr inbounds %Ts5UInt8V, %Ts5UInt8V* [[Z_ADDR]], i32 0, i32 0 |
| // CHECK: load i8, i8* [[T0]], align |
| sil @RootGeneric_subst_concrete_fragile_dependent_member_access_z : $RootGeneric<Int> -> UInt8 { |
| entry(%c : $RootGeneric<Int>): |
| %p = ref_element_addr %c : $RootGeneric<Int>, #RootGeneric.z |
| %z = load_borrow %p : $*UInt8 |
| return %z : $UInt8 |
| } |
| |
| /* TODO: Instantiate types for fragile generic instances so we can do |
| * fixed-layout access |
| sil @RootGeneric_concrete_fragile_fixed_member_access : $RootGeneric<Int32> -> (UInt8, Int32, UInt8) { |
| entry(%c : $RootGeneric<Int32>): |
| %p = ref_element_addr %c : $RootGeneric<Int32>, #RootGeneric.x |
| %x = load_borrow %p : $*UInt8 |
| %q = ref_element_addr %c : $RootGeneric<Int32>, #RootGeneric.y |
| %y = load_borrow %q : $*Int32 |
| %r = ref_element_addr %c : $RootGeneric<Int32>, #RootGeneric.z |
| %z = load_borrow %r : $*UInt8 |
| %t = tuple (%x : $UInt8, %y : $Int32, %z : $UInt8) |
| return %t : $(UInt8, Int32, UInt8) |
| } |
| */ |
| |
| // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} { |
| // CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2) |
| |
| // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMr" |
| // CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} { |
| // -- initialize the dependent field offsets |
| // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}}) |
| // CHECK: } |
| |
| // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} { |
| // CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2) |
| |
| // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMr" |
| // CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} { |
| // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}}) |
| // CHECK: } |
| |
| // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes015GenericInheritsC0CMi"(%swift.type_descriptor*, i8**, i8**) {{.*}} { |
| // Bind the generic parameters. |
| // CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type** |
| // CHECK: %A = load %swift.type*, %swift.type** [[T0]] |
| // CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1 |
| // CHECK: %B = load %swift.type*, %swift.type** [[T1]] |
| // Construct the class. |
| // CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** %2) |
| // Put the generic arguments in their correct positions. |
| // CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** |
| // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 18 |
| // CHECK: [[T0:%.*]] = bitcast %swift.type* %A to i8* |
| // CHECK: store i8* [[T0]], i8** [[A_ADDR]], align 8 |
| // CHECK: [[B_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 19 |
| // CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8* |
| // CHECK: store i8* [[T0]], i8** [[B_ADDR]], align 8 |
| // CHECK: ret %swift.type* [[METADATA]] |
| |
| // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes015GenericInheritsC0CMr" |
| // CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8*, i8**) {{.*}} { |
| // CHECK: [[SUPER:%.*]] ={{( tail)?}} call %swift.type* @"$S15generic_classes11RootGenericCMa"(%swift.type* %A) |
| // CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type** |
| // CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1 |
| // CHECK: store %swift.type* [[SUPER]], %swift.type** [[T1]], |
| // Initialize our own dependent field offsets. |
| // CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i64* |
| // CHECK: [[OFFSETS:%.*]] = getelementptr inbounds i64, i64* [[METADATA_ARRAY]], i64 23 |
| // CHECK: [[FIELDS_ADDR:%.*]] = getelementptr inbounds [1 x i8**], [1 x i8**]* %classFields, i32 0, i32 0 |
| // CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8*** |
| // CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1 |
| // CHECK: [[VWT:%.*]] = load i8**, i8*** [[T1]], align 8 |
| // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9 |
| // CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[FIELDS_ADDR]], i32 0 |
| // CHECK: store i8** [[T0]], i8*** [[T1]], align 8 |
| // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 1, i8*** [[FIELDS_ADDR]], i64* [[OFFSETS]]) |
| // CHECK: ret %swift.type* null |
| // CHECK: } |
| |
| // OSIZE: define hidden %swift.type* @"$S15generic_classes11RootGenericCMa"(%swift.type*) [[ATTRS:#[0-9]+]] { |
| // OSIZE: [[ATTRS]] = {{{.*}}noinline |