mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
codegen: fix global nested field_ptr
This commit is contained in:
parent
3a30b82741
commit
f894ec264b
109
src/codegen.zig
109
src/codegen.zig
@ -374,66 +374,7 @@ pub fn generateSymbol(
|
||||
|
||||
return Result.ok;
|
||||
},
|
||||
.field_ptr => {
|
||||
const field_ptr = typed_value.val.castTag(.field_ptr).?.data;
|
||||
const container_ptr = field_ptr.container_ptr;
|
||||
|
||||
switch (container_ptr.tag()) {
|
||||
.decl_ref => {
|
||||
const decl_index = container_ptr.castTag(.decl_ref).?.data;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const addend = blk: {
|
||||
switch (decl.ty.zigTypeTag()) {
|
||||
.Struct => {
|
||||
const addend = decl.ty.structFieldOffset(field_ptr.field_index, target);
|
||||
break :blk @intCast(u32, addend);
|
||||
},
|
||||
.Pointer => {
|
||||
assert(decl.ty.isSlice());
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const addend = switch (field_ptr.field_index) {
|
||||
0 => 0,
|
||||
1 => decl.ty.slicePtrFieldType(&buf).abiSize(target),
|
||||
else => unreachable,
|
||||
};
|
||||
break :blk @intCast(u32, addend);
|
||||
},
|
||||
else => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement generateSymbol for pointer type value: '{s}'",
|
||||
.{@tagName(typed_value.val.tag())},
|
||||
),
|
||||
},
|
||||
}
|
||||
};
|
||||
return lowerDeclRef(bin_file, src_loc, typed_value, decl_index, code, debug_output, .{
|
||||
.parent_atom_index = reloc_info.parent_atom_index,
|
||||
.addend = (reloc_info.addend orelse 0) + addend,
|
||||
});
|
||||
},
|
||||
.field_ptr => {
|
||||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
.ty = typed_value.ty,
|
||||
.val = container_ptr,
|
||||
}, code, debug_output, reloc_info)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
return Result.ok;
|
||||
},
|
||||
else => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement generateSymbol for pointer type value: '{s}'",
|
||||
.{@tagName(typed_value.val.tag())},
|
||||
),
|
||||
},
|
||||
}
|
||||
},
|
||||
.elem_ptr => return lowerParentPtr(
|
||||
.field_ptr, .elem_ptr => return lowerParentPtr(
|
||||
bin_file,
|
||||
src_loc,
|
||||
typed_value,
|
||||
@ -846,16 +787,12 @@ pub fn generateSymbol(
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
else => |t| {
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement generateSymbol for type '{s}'",
|
||||
.{@tagName(t)},
|
||||
),
|
||||
};
|
||||
},
|
||||
else => |t| return Result{ .fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement generateSymbol for type '{s}'",
|
||||
.{@tagName(t)},
|
||||
) },
|
||||
}
|
||||
}
|
||||
|
||||
@ -871,6 +808,38 @@ fn lowerParentPtr(
|
||||
const target = bin_file.options.target;
|
||||
|
||||
switch (parent_ptr.tag()) {
|
||||
.field_ptr => {
|
||||
const field_ptr = parent_ptr.castTag(.field_ptr).?.data;
|
||||
return lowerParentPtr(
|
||||
bin_file,
|
||||
src_loc,
|
||||
typed_value,
|
||||
field_ptr.container_ptr,
|
||||
code,
|
||||
debug_output,
|
||||
reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag()) {
|
||||
.Pointer => offset: {
|
||||
assert(field_ptr.container_ty.isSlice());
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
break :offset switch (field_ptr.field_index) {
|
||||
0 => 0,
|
||||
1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(target),
|
||||
else => unreachable,
|
||||
};
|
||||
},
|
||||
.Struct, .Union => field_ptr.container_ty.structFieldOffset(
|
||||
field_ptr.field_index,
|
||||
target,
|
||||
),
|
||||
else => return Result{ .fail = try ErrorMsg.create(
|
||||
bin_file.allocator,
|
||||
src_loc,
|
||||
"TODO implement lowerParentPtr for field_ptr with a container of type {}",
|
||||
.{field_ptr.container_ty.fmt(bin_file.options.module.?)},
|
||||
) },
|
||||
})),
|
||||
);
|
||||
},
|
||||
.elem_ptr => {
|
||||
const elem_ptr = parent_ptr.castTag(.elem_ptr).?.data;
|
||||
return lowerParentPtr(
|
||||
|
||||
@ -448,7 +448,6 @@ const Foo1 = union(enum) {
|
||||
var glbl: Foo1 = undefined;
|
||||
|
||||
test "global union with single field is correctly initialized" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user