// RUN: %empty-directory(%t) // RUN: %{python} %utils/chex.py < %s > %t/generic_structs_future.sil // RUN: %target-swift-frontend -disable-type-layout -prespecialize-generic-metadata -target %module-target-future %t/generic_structs_future.sil -emit-ir | %FileCheck %t/generic_structs_future.sil // REQUIRES: OS=macosx || OS=ios || OS=tvos || OS=watchos || OS=linux-gnu // REQUIRES: CPU=x86_64 import Builtin // -- Generic structs with fixed layout should have no completion function // and emit the field offset vector as part of the pattern. // CHECK: [[PATTERN:@.*]] = internal constant [4 x i32] [i32 0, i32 1, i32 8, i32 0] // CHECK-LABEL: @"$s22generic_structs_future18FixedLayoutGenericVMP" = internal constant <{ {{.*}} }> <{ // -- instantiation function // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$s22generic_structs_future18FixedLayoutGenericVMi" // -- completion function // CHECK-SAME: i32 0, // -- pattern flags // CHECK-SAME: , // -- vwtable pointer // CHECK-SAME: @"$s22generic_structs_future18FixedLayoutGenericVWV" // -- extra data pattern // CHECK-SAME: [4 x i32]* [[PATTERN]] // CHECK-SAME: i16 1, // CHECK-SAME: i16 2 }> // -- Generic structs with dynamic layout contain the vwtable pattern as part // of the metadata pattern, and no independent vwtable symbol // CHECK: @"$s22generic_structs_future13SingleDynamicVWV" = internal constant // CHECK-SAME: i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @"$s22generic_structs_future13SingleDynamicVwCP" to i8*), // -- ... // -- placeholder for size, stride, flags // CHECK-SAME: i64 0, // CHECK-SAME: i64 0, // CHECK-SAME: i32 4194304, // CHECK-SAME: i32 0 } // FIXME: Strings should be unnamed_addr. rdar://problem/22674524 // CHECK: [[SINGLEDYNAMIC_NAME:@.*]] = private constant [14 x i8] c"SingleDynamic\00" // CHECK: @"$s22generic_structs_future13SingleDynamicVMn" = hidden constant // -- flags: struct, unique, generic // CHECK-SAME: // -- name // CHECK-SAME: [14 x i8]* [[SINGLEDYNAMIC_NAME]] // -- field count // CHECK-SAME: i32 1, // -- field offset vector offset // CHECK-SAME: i32 3, // -- generic instantiation info // CHECK-SAME: [{{[0-9]+}} x i8*]* @"$s22generic_structs_future13SingleDynamicVMI" // CHECK-SAME: @"$s22generic_structs_future13SingleDynamicVMP" // -- generic params, requirements, key args, extra args // CHECK-SAME: i16 1, i16 0, i16 1, i16 0 // -- generic parameters // CHECK-SAME: // CHECK-SAME: }> // CHECK: @"$s22generic_structs_future13SingleDynamicVMP" = internal constant <{ {{.*}} }> <{ // -- instantiation function // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**, i8*)* @"$s22generic_structs_future13SingleDynamicVMi" // -- vwtable pointer // CHECK-SAME: @"$s22generic_structs_future13SingleDynamicVWV" // -- Nominal type descriptor for generic struct with protocol requirements // FIXME: Strings should be unnamed_addr. rdar://problem/22674524 // CHECK: [[DYNAMICWITHREQUIREMENTS_NAME:@.*]] = private constant [24 x i8] c"DynamicWithRequirements\00" // CHECK: @"$s22generic_structs_future23DynamicWithRequirementsVMn" = hidden constant <{ {{.*}} i32 }> <{ // -- flags: struct, unique, generic // CHECK-SAME: // -- name // CHECK-SAME: [24 x i8]* [[DYNAMICWITHREQUIREMENTS_NAME]] // -- field count // CHECK-SAME: i32 2, // -- field offset vector offset // CHECK-SAME: i32 6, // -- generic params, requirements, key args, extra args // CHECK-SAME: i16 2, i16 2, i16 4, i16 0, // -- generic parameters // CHECK-SAME: , , // -- generic requirement // -- protocol requirement with key arg // CHECK-SAME: i32 128 // -- param 0 // CHECK-SAME: i32 0 // -- protocol Req1 // CHECK-SAME: @"$s22generic_structs_future4Req1Mp" // -- protocol requirement with key arg // CHECK-SAME: i32 128 // -- param 1 // CHECK-SAME: i32 2 // -- protocol Req2 // CHECK-SAME: @"$s22generic_structs_future4Req2Mp" // CHECK-SAME: }> // CHECK: @"$s22generic_structs_future23DynamicWithRequirementsVMP" = internal constant <{ {{.*}} }> <{ // -- Fixed-layout struct metadata contains fixed field offsets // CHECK: @"$s22generic_structs_future6IntishVMf" = internal constant <{ {{.*}} i32, [4 x i8], i64 }> <{ // CHECK-SAME: i32 0 // CHECK-SAME: }> // CHECK: @"$s22generic_structs_future7CharethVMf" = internal constant <{ {{.*}} i32, [4 x i8], i64 }> <{ // CHECK-SAME: i32 0 // CHECK-SAME: }> // CHECK: @"$s22generic_structs_future8StringlyVMf" = internal constant <{ {{.*}} i32, i32, i32, [4 x i8], i64 }> <{ // CHECK-SAME: i32 0, i32 8, i32 16, [4 x i8] zeroinitializer // CHECK-SAME: }> struct FixedLayoutGeneric { var x: Byteful var y: Byteful var z: Intish } struct SingleDynamic { var x : T } protocol Req1 { associatedtype Assoc1 } protocol Req2 {} struct DynamicWithRequirements { var x : T var y : U } struct Intish { var value : Builtin.Int64 } struct Chareth { var value : Builtin.Int21 } struct Byteful { var value : Builtin.Int8 } struct Stringly { var owner : Builtin.NativeObject var base : Builtin.RawPointer var size : Builtin.Int64 } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i32 } @concrete_instances(i64 %0, i32 %1) {{.*}} { // CHECK: entry: // CHECK: %2 = trunc i32 %1 to i21 // CHECK: %3 = zext i21 %2 to i32 // CHECK: %4 = insertvalue { i64, i32 } undef, i64 %0, 0 // CHECK: %5 = insertvalue { i64, i32 } %4, i32 %3, 1 // CHECK: ret { i64, i32 } %5 // CHECK: } sil @concrete_instances : $(SingleDynamic, SingleDynamic) -> (Intish, Chareth) { entry(%0 : $SingleDynamic, %1 : $SingleDynamic): %a = struct_extract %0 : $SingleDynamic, #SingleDynamic.x %b = struct_extract %1 : $SingleDynamic, #SingleDynamic.x %c = tuple (%a : $Intish, %b : $Chareth) return %c : $(Intish, Chareth) } struct ComplexDynamic { var a, a2 : Byteful var b : U var c : SingleDynamic var d : Chareth } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @explode_complex_dynamic sil @explode_complex_dynamic : $ (@in ComplexDynamic, @inout Byteful, @inout A, @inout B, @inout Chareth) -> () { entry(%0 : $*ComplexDynamic, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Chareth): %a = struct_element_addr %0 : $*ComplexDynamic, #ComplexDynamic.a2 // CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i32* // CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, i32* [[METADATA]], i64 10 // CHECK: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_ADDR]], align 8 // CHECK: [[BYTES:%.*]] = bitcast %T22generic_structs_future14ComplexDynamicV* %0 to i8* // CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i32 [[FIELD_OFFSET]] // CHECK: bitcast i8* [[BYTE_OFFSET]] to %swift.opaque* %b = struct_element_addr %0 : $*ComplexDynamic, #ComplexDynamic.b // CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i32* // CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, i32* [[METADATA]], i64 11 // CHECK: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_ADDR]], align 8 // CHECK: [[BYTES:%.*]] = bitcast %T22generic_structs_future14ComplexDynamicV* %0 to i8* // CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i32 [[FIELD_OFFSET]] // CHECK: bitcast i8* [[BYTE_OFFSET]] to %T22generic_structs_future13SingleDynamicV %5 = struct_element_addr %0 : $*ComplexDynamic, #ComplexDynamic.c %c = struct_element_addr %5 : $*SingleDynamic, #SingleDynamic.x // CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i32* // CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, i32* [[METADATA]], i64 12 // CHECK: [[FIELD_OFFSET:%.*]] = load i32, i32* [[FIELD_OFFSET_ADDR]], align 8 // CHECK: [[BYTES:%.*]] = bitcast %T22generic_structs_future14ComplexDynamicV* %0 to i8* // CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i32 [[FIELD_OFFSET]] // CHECK: bitcast i8* [[BYTE_OFFSET]] to %T22generic_structs_future7CharethV %d = struct_element_addr %0 : $*ComplexDynamic, #ComplexDynamic.d copy_addr %a to %1 : $*Byteful copy_addr %b to %2 : $*A copy_addr %c to %3 : $*B copy_addr %d to %4 : $*Chareth %v = tuple () return %v : $() } // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$s22generic_structs_future13SingleDynamicVMi"(%swift.type_descriptor* %0, i8** %1, i8* %2) // CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type** // CHECK: %T = load %swift.type*, %swift.type** [[T0]], align 8 // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_descriptor* %0, i8** %1, i8* %2, i64 24) // CHECK-NEXT: ret %swift.type* [[METADATA]] // CHECK: } // CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$s22generic_structs_future13SingleDynamicVMr" // CHECK-SAME: (%swift.type* [[METADATA:%.*]], i8* %0, i8** %1) {{.*}} { // Lay out fields. // CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i32* // CHECK: [[T1:%.*]] = getelementptr inbounds i32, i32* [[T0]], i64 6 // CHECK: [[T2:%.*]] = getelementptr inbounds i8**, i8*** [[TYPES:%.*]], i32 0 // CHECK: call void @swift_initStructMetadata(%swift.type* [[METADATA]], i64 0, i64 1, i8*** [[TYPES]], i32* [[T1]]) // CHECK: ret %swift.metadata_response // CHECK: } // Check that we directly delegate buffer witnesses to a single dynamic field: // initializeBufferWithCopyOfBuffer // CHECK-LABEL: define internal %swift.opaque* @"$s22generic_structs_future13SingleDynamicVwCP"([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic") {{.*}} { // CHECK: %T = load %swift.type*, // CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8*** // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1 // CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** [[T1]] // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** %T.valueWitnesses, // CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[T1]] to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* // CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %T) // CHECK-NEXT: [[T1:%.*]] = bitcast %swift.opaque* [[T0]] to {{.*}} // CHECK-NEXT: [[T2:%.*]] = bitcast {{.*}} [[T1]] to %swift.opaque* // CHECK-NEXT: ret %swift.opaque* [[T2]] protocol HasAssociatedType { associatedtype Assoc } protocol ParentHasAssociatedType : HasAssociatedType { associatedtype Assoc : HasAssociatedType } struct GenericLayoutWithAssocType { var x: T.Assoc var y: T.Assoc.Assoc } // CHECK-LABEL: define internal %swift.type* @"$s22generic_structs_future26GenericLayoutWithAssocTypeVMi"( // CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type** // CHECK: %T = load %swift.type*, %swift.type** [[T0]], align 8 // CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1 // CHECK: [[T2:%.*]] = bitcast %swift.type** [[T1]] to i8*** // CHECK: %T.ParentHasAssociatedType = load i8**, i8*** [[T2]], // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s22generic_structs_future26GenericLayoutWithAssocTypeVMr"( // CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState(i64 0, %swift.type* %T) // CHECK: [[T_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 // CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 1 // CHECK: [[T0:%.*]] = load i8*, i8** [[T0_GEP]] // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i8** // CHECK: [[T4:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, i8** %T.HasAssociatedType, %swift.type* %T, %swift.protocol_requirement* @"$s22generic_structs_future17HasAssociatedTypeTL", %swift.protocol_requirement* @"$s5Assoc22generic_structs_future17HasAssociatedTypePTl") // CHECK: %T.Assoc = extractvalue %swift.metadata_response [[T4]], 0 // CHECK: %T.Assoc.HasAssociatedType = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %T.ParentHasAssociatedType, %swift.type* %T, %swift.type* %T.Assoc, // CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, i8** %T.Assoc.HasAssociatedType, %swift.type* %T.Assoc, %swift.protocol_requirement* @"$s22generic_structs_future17HasAssociatedTypeTL", %swift.protocol_requirement* @"$s5Assoc22generic_structs_future17HasAssociatedTypePTl") // CHECK: %T.Assoc.Assoc = extractvalue %swift.metadata_response [[T2]], 0