mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Don't emit placeholders for field offsets and vtable entries, since they were always null. Instead, calculate the final size of class metadata at runtime using the size of the superclass metadata and the number of immediate members, and only copy this prefix from the template to the instantiated metadata, zero-filling the rest. For this to work with non-generic resilient classes and non-generic subclasses of generic classes, we need a new runtime entry point to relocate non-generic class metadata, calculating its size at runtime using the same strategy.
369 lines
17 KiB
Plaintext
369 lines
17 KiB
Plaintext
// RUN: %target-swift-frontend %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
|
|
// RUN: %target-swift-frontend -Osize %s -emit-ir | %FileCheck %s --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 [32 x i8] c"15generic_classes11RootGenericC\00"
|
|
// CHECK: [[ROOTGENERIC_FIELDS:@.*]] = private constant [7 x i8] c"x\00y\00z\00\00"
|
|
|
|
// CHECK-LABEL: @_T015generic_classes11RootGenericCMn =
|
|
// CHECK-SAME: hidden constant <{ {{.*}} %swift.method_descriptor }> <{
|
|
// -- name
|
|
// CHECK-SAME: [32 x i8]* [[ROOTGENERIC_NAME]]
|
|
// -- num fields
|
|
// CHECK-SAME: i32 3,
|
|
// -- field offset vector offset
|
|
// CHECK-SAME: i32 15,
|
|
// -- field names
|
|
// CHECK-SAME: [7 x i8]* [[ROOTGENERIC_FIELDS]]
|
|
// -- kind 0 (class)
|
|
// CHECK-SAME: i32 0,
|
|
// -- generic parameter vector offset
|
|
// CHECK-SAME: i32 10,
|
|
// -- generic parameter count, primary count
|
|
// CHECK-SAME: i32 1, i32 1,
|
|
// -- nesting depth
|
|
// CHECK-SAME: i16 1,
|
|
// -- flags -- has vtable
|
|
// CHECK-SAME: i16 4,
|
|
// -- generic parameters at depth 0
|
|
// CHECK-SAME: i32 1,
|
|
// -- vtable offset
|
|
// CHECK-SAME: i32 11,
|
|
// -- vtable size
|
|
// CHECK-SAME: i32 4
|
|
// CHECK-SAME: }
|
|
|
|
// CHECK-LABEL: @_T015generic_classes11RootGenericCMP = internal global
|
|
// -- template fill function
|
|
// CHECK-SAME: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_RootGeneric
|
|
// -- nominal type descriptor
|
|
// CHECK-SAME: @_T015generic_classes11RootGenericCMn
|
|
// -- ivar destroyer
|
|
// CHECK-SAME: i8* null
|
|
// CHECK-SAME: }>
|
|
|
|
// -- Check that offset vars are emitted for fixed-layout generics
|
|
// <rdar://problem/15081049>
|
|
// CHECK: @_T015generic_classes22RootGenericFixedLayoutC1xs5UInt8VvpWvd = hidden constant i64 16, align 8
|
|
// CHECK: @_T015generic_classes22RootGenericFixedLayoutC1ySayxGvpWvd = hidden constant i64 24, align 8
|
|
// CHECK: @_T015generic_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 [35 x i8] c"15generic_classes14RootNonGenericC\00"
|
|
// CHECK: @_T015generic_classes14RootNonGenericCMn = hidden constant <{ {{.*}} i32 }> <{
|
|
// -- name
|
|
// CHECK-SAME: [35 x i8]* [[ROOTNONGENERIC_NAME]]
|
|
// -- num fields
|
|
// CHECK-SAME: i32 3,
|
|
// -- -- field offset vector offset
|
|
// CHECK-SAME: i32 11,
|
|
// -- field names
|
|
// CHECK-SAME: [7 x i8]* [[ROOTGENERIC_FIELDS]]
|
|
// -- no generic metadata pattern, kind 0
|
|
// CHECK-SAME: i32 0,
|
|
// -- 0 = no generic parameter vector
|
|
// CHECK-SAME: i32 0,
|
|
// -- number of generic params, primary params
|
|
// CHECK-SAME: i32 0, i32 0
|
|
// CHECK-SAME: }>
|
|
|
|
// CHECK: @_T015generic_classes14RootNonGenericCMf = internal global <{ {{.*}} }> <{
|
|
// CHECK-SAME: void (%T15generic_classes14RootNonGenericC*)* @_T015generic_classes14RootNonGenericCfD,
|
|
// CHECK-SAME: i8** @_T0BoWV,
|
|
// CHECK-SAME-native: i64 0,
|
|
// CHECK-SAME-native: %swift.type* null,
|
|
// CHECK-SAME-native: %swift.opaque* null,
|
|
// CHECK-SAME-objc: i64 ptrtoint (%objc_class* @_T015generic_classes14RootNonGenericCMm to i64),
|
|
// CHECK-SAME-objc: %objc_class* @"OBJC_CLASS_$_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: {{.*}}* @_T015generic_classes14RootNonGenericCMn
|
|
// CHECK-SAME: }>
|
|
|
|
// CHECK: @_T015generic_classes015GenericInheritsC0CMP = internal global
|
|
// -- template fill function
|
|
// CHECK-SAME: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_GenericInheritsGeneric
|
|
// -- nominal type descriptor
|
|
// CHECK-SAME: @_T015generic_classes015GenericInheritsC0CMn,
|
|
// -- ivar destroyer
|
|
// CHECK-SAME: i8* null
|
|
// CHECK-SAME: }
|
|
|
|
// CHECK: @_T015generic_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 @_T015generic_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 @_T015generic_classes22RootGenericFixedLayoutCfD : $@convention(method) <T> (RootGenericFixedLayout<T>) -> ()
|
|
|
|
class RootNonGeneric {
|
|
var x : UInt8
|
|
var y : Int
|
|
var z : UInt8
|
|
|
|
init()
|
|
}
|
|
sil_vtable RootNonGeneric {}
|
|
sil @_T015generic_classes14RootNonGenericCfD : $@convention(method) (RootNonGeneric) -> ()
|
|
|
|
class GenericInheritsGeneric<A, B> : RootGeneric<A> {
|
|
var w : B
|
|
|
|
func zippity()
|
|
func doo()
|
|
func dah()
|
|
|
|
override init()
|
|
}
|
|
sil @_T015generic_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 @_T015generic_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 @_T015generic_classes024RecursiveGenericInheritsD0CfD : $@convention(method) <T, U> (RecursiveGenericInheritsGeneric<T, U>) -> ()
|
|
|
|
|
|
// CHECK: define{{( protected)?}} swiftcc [[ROOTGENERIC]]* @RootGeneric_fragile_dependent_alloc
|
|
// CHECK: [[METADATA:%.*]] = call %swift.type* @_T015generic_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_rt_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: define{{( protected)?}} private %swift.type* @create_generic_metadata_RootGeneric(%swift.type_pattern*, i8**) {{.*}} {
|
|
// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, {{.*}}, i64 8)
|
|
// -- initialize the dependent field offsets
|
|
// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
|
|
// CHECK: }
|
|
|
|
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_RootGenericFixedLayout(%swift.type_pattern*, i8**) {{.*}} {
|
|
// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, {{.*}}, i64 5)
|
|
// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
|
|
// CHECK: }
|
|
|
|
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_GenericInheritsGeneric(%swift.type_pattern*, 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 superclass.
|
|
// CHECK: [[SUPER:%.*]] = call %swift.type* @_T015generic_classes11RootGenericCMa(%swift.type* %A)
|
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
|
|
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[T0]], i64 6)
|
|
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
|
|
// Put the generic arguments in their correct positions.
|
|
// CHECK: [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i32 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:%.*]], i32 19
|
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8*
|
|
// CHECK: store i8* [[T0]], i8** [[B_ADDR]], align 8
|
|
// Set up the isa.
|
|
// CHECK-objc: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
|
|
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 0
|
|
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to %objc_class**
|
|
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -26
|
|
// CHECK-objc: [[METACLASS:%.*]] = bitcast i8** [[T0]] to %objc_class*
|
|
// CHECK-objc: store %objc_class* [[METACLASS]], %objc_class** [[T1]], align 8
|
|
// Set up the instance rodata pointer.
|
|
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 4
|
|
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to i64*
|
|
// CHECK-objc: [[RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -21
|
|
// CHECK-objc: [[T2:%.*]] = ptrtoint i8** [[RODATA]] to i64
|
|
// CHECK-objc: [[T3:%.*]] = or i64 [[T2]], 1
|
|
// CHECK-objc: store i64 [[T3]], i64* [[T1]], align 8
|
|
// Set up the class rodata pointer.
|
|
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -22
|
|
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to i64*
|
|
// CHECK-objc: [[META_RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -12
|
|
// CHECK-objc: [[T2:%.*]] = ptrtoint i8** [[META_RODATA]] to i64
|
|
// CHECK-objc: store i64 [[T2]], i64* [[T1]], align 8
|
|
// 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* [[METADATA]]
|
|
// CHECK: }
|
|
|
|
// OSIZE: define hidden %swift.type* @_T015generic_classes11RootGenericCMa(%swift.type*) [[ATTRS:#[0-9]+]] {
|
|
// OSIZE: [[ATTRS]] = {{{.*}}noinline
|