// 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.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 // // 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 { 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) (RootGeneric) -> () sil @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_ : $@convention(method) (@guaranteed RootGeneric) -> () sil @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_ : $@convention(method) (@guaranteed RootGeneric) -> () sil @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_ : $@convention(method) (@guaranteed RootGeneric) -> () 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 { var x : UInt8 var y : [T] var z : UInt8 init() } sil_vtable RootGenericFixedLayout {} sil @_T015generic_classes22RootGenericFixedLayoutCfD : $@convention(method) (RootGenericFixedLayout) -> () class RootNonGeneric { var x : UInt8 var y : Int var z : UInt8 init() } sil_vtable RootNonGeneric {} sil @_T015generic_classes14RootNonGenericCfD : $@convention(method) (RootNonGeneric) -> () class GenericInheritsGeneric : RootGeneric { var w : B func zippity() func doo() func dah() override init() } sil @_T015generic_classes015GenericInheritsC0CfD : $@convention(method) (GenericInheritsGeneric) -> () sil @_TFC15generic_classes22GenericInheritsGeneric7zippityU___fGS0_Q_Q0__FT_T_ : $@convention(method) (@guaranteed GenericInheritsGeneric) -> () sil @_TFC15generic_classes22GenericInheritsGeneric3dooU___fGS0_Q_Q0__FT_T_ : $@convention(method) (@guaranteed GenericInheritsGeneric) -> () sil @_TFC15generic_classes22GenericInheritsGeneric3dahU___fGS0_Q_Q0__FT_T_ : $@convention(method) (@guaranteed GenericInheritsGeneric) -> () 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 : RootNonGeneric { var w : UInt8 override init() } sil_vtable GenericInheritsNonGeneric {} sil @_T015generic_classes018GenericInheritsNonC0CfD : $@convention(method) (GenericInheritsNonGeneric) -> () // rdar://18067671 class RecursiveGenericInheritsGeneric : RootGeneric { var w : B var r : RecursiveGenericInheritsGeneric? func zippity() func doo() func dah() override init() } sil_vtable RecursiveGenericInheritsGeneric {} sil @_T015generic_classes024RecursiveGenericInheritsD0CfD : $@convention(method) (RecursiveGenericInheritsGeneric) -> () // 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 : $ () -> RootGeneric { entry: %x = alloc_ref $RootGeneric return %x : $RootGeneric } // 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 : $ RootGeneric -> UInt8 { entry(%c : $RootGeneric): %p = ref_element_addr %c : $RootGeneric, #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 : $ (RootGeneric) -> @out F { entry(%z : $*F, %c : $RootGeneric): %p = ref_element_addr %c : $RootGeneric, #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) -> @out Int { entry(%z : $*Int, %c : $RootGeneric): %p = ref_element_addr %c : $RootGeneric, #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 : $ RootGeneric -> UInt8 { entry(%c : $RootGeneric): %p = ref_element_addr %c : $RootGeneric, #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 -> UInt8 { entry(%c : $RootGeneric): %p = ref_element_addr %c : $RootGeneric, #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 -> (UInt8, Int32, UInt8) { entry(%c : $RootGeneric): %p = ref_element_addr %c : $RootGeneric, #RootGeneric.x %x = load_borrow %p : $*UInt8 %q = ref_element_addr %c : $RootGeneric, #RootGeneric.y %y = load_borrow %q : $*Int32 %r = ref_element_addr %c : $RootGeneric, #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