@@ -1518,26 +1518,8 @@ pub const DeclGen = struct {
15181518 const llvm_int = llvm_usize .constInt (tv .val .toUnsignedInt (), .False );
15191519 return llvm_int .constIntToPtr (try dg .llvmType (tv .ty ));
15201520 },
1521- .field_ptr , .opt_payload_ptr , .eu_payload_ptr = > {
1522- const parent = try dg .lowerParentPtr (tv .val , tv .ty );
1523- return parent .llvm_ptr .constBitCast (try dg .llvmType (tv .ty ));
1524- },
1525- .elem_ptr = > {
1526- const elem_ptr = tv .val .castTag (.elem_ptr ).? .data ;
1527- const parent = try dg .lowerParentPtr (elem_ptr .array_ptr , tv .ty );
1528- const llvm_usize = try dg .llvmType (Type .usize );
1529- if (parent .llvm_ptr .typeOf ().getElementType ().getTypeKind () == .Array ) {
1530- const indices : [2 ]* const llvm.Value = .{
1531- llvm_usize .constInt (0 , .False ),
1532- llvm_usize .constInt (elem_ptr .index , .False ),
1533- };
1534- return parent .llvm_ptr .constInBoundsGEP (& indices , indices .len );
1535- } else {
1536- const indices : [1 ]* const llvm.Value = .{
1537- llvm_usize .constInt (elem_ptr .index , .False ),
1538- };
1539- return parent .llvm_ptr .constInBoundsGEP (& indices , indices .len );
1540- }
1521+ .field_ptr , .opt_payload_ptr , .eu_payload_ptr , .elem_ptr = > {
1522+ return dg .lowerParentPtr (tv .val , tv .ty .childType ());
15411523 },
15421524 .null_value , .zero = > {
15431525 const llvm_type = try dg .llvmType (tv .ty );
@@ -2786,167 +2768,150 @@ pub const DeclGen = struct {
27862768 llvm_ptr : * const llvm.Value ,
27872769 };
27882770
2789- fn lowerParentPtrDecl (dg : * DeclGen , ptr_val : Value , decl : * Module.Decl ) Error ! ParentPtr {
2771+ fn lowerParentPtrDecl (dg : * DeclGen , ptr_val : Value , decl : * Module.Decl , ptr_child_ty : Type ) Error ! * const llvm.Value {
27902772 decl .markAlive ();
27912773 var ptr_ty_payload : Type.Payload.ElemType = .{
27922774 .base = .{ .tag = .single_mut_pointer },
27932775 .data = decl .ty ,
27942776 };
27952777 const ptr_ty = Type .initPayload (& ptr_ty_payload .base );
27962778 const llvm_ptr = try dg .lowerDeclRefValue (.{ .ty = ptr_ty , .val = ptr_val }, decl );
2797- return ParentPtr {
2798- .llvm_ptr = llvm_ptr ,
2799- .ty = decl .ty ,
2800- };
2779+
2780+ if (ptr_child_ty .eql (decl .ty )) {
2781+ return llvm_ptr ;
2782+ } else {
2783+ return llvm_ptr .constBitCast ((try dg .llvmType (ptr_child_ty )).pointerType (0 ));
2784+ }
28012785 }
28022786
2803- fn lowerParentPtr (dg : * DeclGen , ptr_val : Value , base_ty : Type ) Error ! ParentPtr {
2804- switch (ptr_val .tag ()) {
2787+ fn lowerParentPtr (dg : * DeclGen , ptr_val : Value , ptr_child_ty : Type ) Error ! * const llvm.Value {
2788+ var bitcast_needed : bool = undefined ;
2789+ const llvm_ptr = switch (ptr_val .tag ()) {
28052790 .decl_ref_mut = > {
28062791 const decl = ptr_val .castTag (.decl_ref_mut ).? .data .decl ;
2807- return dg .lowerParentPtrDecl (ptr_val , decl );
2792+ return dg .lowerParentPtrDecl (ptr_val , decl , ptr_child_ty );
28082793 },
28092794 .decl_ref = > {
28102795 const decl = ptr_val .castTag (.decl_ref ).? .data ;
2811- return dg .lowerParentPtrDecl (ptr_val , decl );
2796+ return dg .lowerParentPtrDecl (ptr_val , decl , ptr_child_ty );
28122797 },
28132798 .variable = > {
28142799 const decl = ptr_val .castTag (.variable ).? .data .owner_decl ;
2815- return dg .lowerParentPtrDecl (ptr_val , decl );
2800+ return dg .lowerParentPtrDecl (ptr_val , decl , ptr_child_ty );
28162801 },
28172802 .int_i64 = > {
28182803 const int = ptr_val .castTag (.int_i64 ).? .data ;
28192804 const llvm_usize = try dg .llvmType (Type .usize );
28202805 const llvm_int = llvm_usize .constInt (@bitCast (u64 , int ), .False );
2821- return ParentPtr {
2822- .llvm_ptr = llvm_int .constIntToPtr (try dg .llvmType (base_ty )),
2823- .ty = base_ty ,
2824- };
2806+ return llvm_int .constIntToPtr ((try dg .llvmType (ptr_child_ty )).pointerType (0 ));
28252807 },
28262808 .int_u64 = > {
28272809 const int = ptr_val .castTag (.int_u64 ).? .data ;
28282810 const llvm_usize = try dg .llvmType (Type .usize );
28292811 const llvm_int = llvm_usize .constInt (int , .False );
2830- return ParentPtr {
2831- .llvm_ptr = llvm_int .constIntToPtr (try dg .llvmType (base_ty )),
2832- .ty = base_ty ,
2833- };
2812+ return llvm_int .constIntToPtr ((try dg .llvmType (ptr_child_ty )).pointerType (0 ));
28342813 },
2835- .field_ptr = > {
2814+ .field_ptr = > blk : {
28362815 const field_ptr = ptr_val .castTag (.field_ptr ).? .data ;
2837- const parent = try dg .lowerParentPtr (field_ptr .container_ptr , base_ty );
2816+ const parent_llvm_ptr = try dg .lowerParentPtr (field_ptr .container_ptr , field_ptr .container_ty );
2817+ const parent_ty = field_ptr .container_ty ;
2818+
28382819 const field_index = @intCast (u32 , field_ptr .field_index );
28392820 const llvm_u32 = dg .context .intType (32 );
28402821 const target = dg .module .getTarget ();
2841- switch (parent . ty .zigTypeTag ()) {
2822+ switch (parent_ty .zigTypeTag ()) {
28422823 .Union = > {
2843- const fields = parent . ty . unionFields () ;
2844- const layout = parent . ty . unionGetLayout ( target );
2845- const field_ty = fields . values ()[ field_index ]. ty ;
2824+ bitcast_needed = true ;
2825+
2826+ const layout = parent_ty . unionGetLayout ( target ) ;
28462827 if (layout .payload_size == 0 ) {
28472828 // In this case a pointer to the union and a pointer to any
28482829 // (void) payload is the same.
2849- return ParentPtr {
2850- .llvm_ptr = parent .llvm_ptr ,
2851- .ty = field_ty ,
2852- };
2853- }
2854- if (layout .tag_size == 0 ) {
2855- const indices : [2 ]* const llvm.Value = .{
2856- llvm_u32 .constInt (0 , .False ),
2857- llvm_u32 .constInt (0 , .False ),
2858- };
2859- return ParentPtr {
2860- .llvm_ptr = parent .llvm_ptr .constInBoundsGEP (& indices , indices .len ),
2861- .ty = field_ty ,
2862- };
2830+ break :blk parent_llvm_ptr ;
28632831 }
2864- const llvm_pl_index = @boolToInt (layout .tag_align >= layout .payload_align );
2832+ const llvm_pl_index = if (layout .tag_size == 0 )
2833+ 0
2834+ else
2835+ @boolToInt (layout .tag_align >= layout .payload_align );
28652836 const indices : [2 ]* const llvm.Value = .{
28662837 llvm_u32 .constInt (0 , .False ),
28672838 llvm_u32 .constInt (llvm_pl_index , .False ),
28682839 };
2869- return ParentPtr {
2870- .llvm_ptr = parent .llvm_ptr .constInBoundsGEP (& indices , indices .len ),
2871- .ty = field_ty ,
2872- };
2840+ break :blk parent_llvm_ptr .constInBoundsGEP (& indices , indices .len );
28732841 },
28742842 .Struct = > {
2843+ const field_ty = parent_ty .structFieldType (field_index );
2844+ bitcast_needed = ! field_ty .eql (ptr_child_ty );
2845+
28752846 var ty_buf : Type.Payload.Pointer = undefined ;
2876- const llvm_field_index = llvmFieldIndex (parent . ty , field_index , target , & ty_buf ).? ;
2847+ const llvm_field_index = llvmFieldIndex (parent_ty , field_index , target , & ty_buf ).? ;
28772848 const indices : [2 ]* const llvm.Value = .{
28782849 llvm_u32 .constInt (0 , .False ),
28792850 llvm_u32 .constInt (llvm_field_index , .False ),
28802851 };
2881- return ParentPtr {
2882- .llvm_ptr = parent .llvm_ptr .constInBoundsGEP (& indices , indices .len ),
2883- .ty = parent .ty .structFieldType (field_index ),
2884- };
2852+ break :blk parent_llvm_ptr .constInBoundsGEP (& indices , indices .len );
28852853 },
28862854 else = > unreachable ,
28872855 }
28882856 },
2889- .elem_ptr = > {
2857+ .elem_ptr = > blk : {
28902858 const elem_ptr = ptr_val .castTag (.elem_ptr ).? .data ;
2891- const parent = try dg .lowerParentPtr (elem_ptr .array_ptr , base_ty );
2859+ const parent_llvm_ptr = try dg .lowerParentPtr (elem_ptr .array_ptr , elem_ptr .elem_ty );
2860+ bitcast_needed = ! elem_ptr .elem_ty .eql (ptr_child_ty );
2861+
28922862 const llvm_usize = try dg .llvmType (Type .usize );
2893- const indices : [2 ]* const llvm.Value = .{
2894- llvm_usize .constInt (0 , .False ),
2863+ const indices : [1 ]* const llvm.Value = .{
28952864 llvm_usize .constInt (elem_ptr .index , .False ),
28962865 };
2897- return ParentPtr {
2898- .llvm_ptr = parent .llvm_ptr .constInBoundsGEP (& indices , indices .len ),
2899- .ty = parent .ty .childType (),
2900- };
2866+ break :blk parent_llvm_ptr .constInBoundsGEP (& indices , indices .len );
29012867 },
2902- .opt_payload_ptr = > {
2868+ .opt_payload_ptr = > blk : {
29032869 const opt_payload_ptr = ptr_val .castTag (.opt_payload_ptr ).? .data ;
2904- const parent = try dg .lowerParentPtr (opt_payload_ptr , base_ty );
2870+ const parent_llvm_ptr = try dg .lowerParentPtr (opt_payload_ptr . container_ptr , opt_payload_ptr . container_ty );
29052871 var buf : Type.Payload.ElemType = undefined ;
2906- const payload_ty = parent .ty .optionalChild (& buf );
2907- if (! payload_ty .hasRuntimeBitsIgnoreComptime () or parent .ty .isPtrLikeOptional ()) {
2872+
2873+ const payload_ty = opt_payload_ptr .container_ty .optionalChild (& buf );
2874+ bitcast_needed = ! payload_ty .eql (ptr_child_ty );
2875+
2876+ if (! payload_ty .hasRuntimeBitsIgnoreComptime () or payload_ty .isPtrLikeOptional ()) {
29082877 // In this case, we represent pointer to optional the same as pointer
29092878 // to the payload.
2910- return ParentPtr {
2911- .llvm_ptr = parent .llvm_ptr ,
2912- .ty = payload_ty ,
2913- };
2879+ break :blk parent_llvm_ptr ;
29142880 }
29152881
29162882 const llvm_u32 = dg .context .intType (32 );
29172883 const indices : [2 ]* const llvm.Value = .{
29182884 llvm_u32 .constInt (0 , .False ),
29192885 llvm_u32 .constInt (0 , .False ),
29202886 };
2921- return ParentPtr {
2922- .llvm_ptr = parent .llvm_ptr .constInBoundsGEP (& indices , indices .len ),
2923- .ty = payload_ty ,
2924- };
2887+ break :blk parent_llvm_ptr .constInBoundsGEP (& indices , indices .len );
29252888 },
2926- .eu_payload_ptr = > {
2889+ .eu_payload_ptr = > blk : {
29272890 const eu_payload_ptr = ptr_val .castTag (.eu_payload_ptr ).? .data ;
2928- const parent = try dg .lowerParentPtr (eu_payload_ptr , base_ty );
2929- const payload_ty = parent .ty .errorUnionPayload ();
2891+ const parent_llvm_ptr = try dg .lowerParentPtr (eu_payload_ptr .container_ptr , eu_payload_ptr .container_ty );
2892+
2893+ const payload_ty = eu_payload_ptr .container_ty .errorUnionPayload ();
2894+ bitcast_needed = ! payload_ty .eql (ptr_child_ty );
2895+
29302896 if (! payload_ty .hasRuntimeBitsIgnoreComptime ()) {
29312897 // In this case, we represent pointer to error union the same as pointer
29322898 // to the payload.
2933- return ParentPtr {
2934- .llvm_ptr = parent .llvm_ptr ,
2935- .ty = payload_ty ,
2936- };
2899+ break :blk parent_llvm_ptr ;
29372900 }
29382901
29392902 const llvm_u32 = dg .context .intType (32 );
29402903 const indices : [2 ]* const llvm.Value = .{
29412904 llvm_u32 .constInt (0 , .False ),
29422905 llvm_u32 .constInt (1 , .False ),
29432906 };
2944- return ParentPtr {
2945- .llvm_ptr = parent .llvm_ptr .constInBoundsGEP (& indices , indices .len ),
2946- .ty = payload_ty ,
2947- };
2907+ break :blk parent_llvm_ptr .constInBoundsGEP (& indices , indices .len );
29482908 },
29492909 else = > unreachable ,
2910+ };
2911+ if (bitcast_needed ) {
2912+ return llvm_ptr .constBitCast ((try dg .llvmType (ptr_child_ty )).pointerType (0 ));
2913+ } else {
2914+ return llvm_ptr ;
29502915 }
29512916 }
29522917
0 commit comments