mirror of
https://github.com/ziglang/zig.git
synced 2026-01-09 08:55:36 +00:00
This commit makes it possible to obtain pointers to `extern` variables at comptime. - `ir_get_var_ptr` employs several checks to determine if the given variable is eligible for obtaining its pointer at comptime. This commit alters these checks to consider `extern` variables, which have runtime values, as eligible. - After this change, it's now possible for `render_const_val` to be called for `extern` variables. This commit modifies `render_const_val` to suppress the value generation for `extern` variables. - `do_code_gen` now creates `ZigValue::llvm_global` of `extern` variables before iterating through module-level variables so that other module-level variables can refer to them. This solution is incomplete since there are several cases still failing: - `global_var.array[n..m]` - `&global_var.array[i]` - `&global_var.inner_struct.value` - `&global_array[i]` Closes #5349
121 lines
4.4 KiB
Zig
121 lines
4.4 KiB
Zig
const std = @import("std");
|
|
const eql = std.mem.eql;
|
|
|
|
// These are defined in `obj.zig`
|
|
extern var global_var: usize;
|
|
extern const global_const: usize;
|
|
|
|
const TheStruct = @import("./types.zig").TheStruct;
|
|
extern var global_var_struct: TheStruct;
|
|
extern const global_const_struct: TheStruct;
|
|
|
|
const TheUnion = @import("./types.zig").TheUnion;
|
|
extern var global_var_union: TheUnion;
|
|
extern const global_const_union: TheUnion;
|
|
|
|
extern var global_var_array: [4]u32;
|
|
extern const global_const_array: [4]u32;
|
|
|
|
// Take the pointers to external entities as constant values
|
|
const p_global_var = &global_var;
|
|
const p_global_const = &global_const;
|
|
|
|
test "access the external integers" {
|
|
std.testing.expect(p_global_var.* == 2);
|
|
std.testing.expect(p_global_const.* == 422);
|
|
}
|
|
|
|
const p_global_var_struct = &global_var_struct;
|
|
const p_global_const_struct = &global_const_struct;
|
|
|
|
const p_global_var_struct_val = &global_var_struct.value;
|
|
const p_global_const_struct_val = &global_const_struct.value;
|
|
|
|
const p_global_var_struct_array = &global_var_struct.array;
|
|
const p_global_const_struct_array = &global_const_struct.array;
|
|
|
|
const p_global_var_struct_array2 = global_var_struct.array[1..3];
|
|
const p_global_const_struct_array2 = global_const_struct.array[1..3];
|
|
|
|
const p_global_var_struct_array3 = &global_var_struct.array[1];
|
|
const p_global_const_struct_array3 = &global_const_struct.array[1];
|
|
|
|
test "access the external integers in a struct through comptime ptrs" {
|
|
std.testing.expect(p_global_var_struct.value == 2);
|
|
std.testing.expect(p_global_const_struct.value == 422);
|
|
|
|
std.testing.expect(p_global_var_struct_val.* == 2);
|
|
std.testing.expect(p_global_const_struct_val.* == 422);
|
|
}
|
|
|
|
test "access the external arrays in a struct through comptime ptrs" {
|
|
// TODO
|
|
// std.testing.expect(eql(u32, &p_global_var_struct.array, &[_]u32{1, 2, 3, 4}));
|
|
// std.testing.expect(eql(u32, &p_global_const_struct.array, &[_]u32{5, 6, 7, 8}));
|
|
|
|
// TODO
|
|
// std.testing.expect(eql(u32, p_global_var_struct_array, &[_]u32{1, 2, 3, 4}));
|
|
// std.testing.expect(eql(u32, p_global_const_struct_array, &[_]u32{5, 6, 7, 8}));
|
|
|
|
// TODO
|
|
// std.testing.expect(eql(u32, p_global_var_struct_array2, &[_]u32{2, 3}));
|
|
// std.testing.expect(eql(u32, p_global_const_struct_array2, &[_]u32{6, 7}));
|
|
|
|
// TODO
|
|
// std.testing.expect(p_global_var_struct_array3.* == 2);
|
|
// std.testing.expect(p_global_const_struct_array3.* == 6);
|
|
}
|
|
|
|
test "access the external integers with indirection through comptime ptrs" {
|
|
std.testing.expect(p_global_var_struct.p_value.* == 3);
|
|
std.testing.expect(p_global_const_struct.p_value.* == 423);
|
|
}
|
|
|
|
const p_global_var_struct_inner_val = &global_var_struct.inner.value;
|
|
const p_global_const_struct_inner_val = &global_const_struct.inner.value;
|
|
|
|
test "access the external integers in a nested struct through comptime ptrs" {
|
|
// TODO
|
|
// std.testing.expect(p_global_var_struct_inner_val.* == 4);
|
|
// std.testing.expect(p_global_const_struct_inner_val.* == 424);
|
|
}
|
|
|
|
const p_global_var_union = &global_var_union;
|
|
const p_global_const_union = &global_const_union;
|
|
|
|
const p_global_var_union_val = &global_var_union.U32;
|
|
const p_global_const_union_val = &global_const_union.U32;
|
|
|
|
test "access the external integers in a union through comptime ptrs" {
|
|
std.testing.expect(p_global_var_union.U32 == 10);
|
|
std.testing.expect(p_global_const_union.U32 == 20);
|
|
|
|
// TODO
|
|
// std.testing.expect(p_global_var_union_val.* == 10);
|
|
// std.testing.expect(p_global_const_union_val.* == 20);
|
|
}
|
|
|
|
const p_global_var_array = &global_var_array;
|
|
const p_global_const_array = &global_const_array;
|
|
|
|
const p_global_var_array2 = global_var_array[1..3];
|
|
const p_global_const_array2 = global_const_array[1..3];
|
|
|
|
const p_global_var_array3 = &global_var_array[1];
|
|
const p_global_const_array3 = &global_const_array[1];
|
|
|
|
test "access the external arrays through comptime ptrs" {
|
|
std.testing.expect(eql(u32, &global_var_array, &[_]u32{1, 2, 3, 4}));
|
|
std.testing.expect(eql(u32, &global_const_array, &[_]u32{5, 6, 7, 8}));
|
|
|
|
std.testing.expect(eql(u32, p_global_var_array, &[_]u32{1, 2, 3, 4}));
|
|
std.testing.expect(eql(u32, p_global_const_array, &[_]u32{5, 6, 7, 8}));
|
|
|
|
std.testing.expect(eql(u32, p_global_var_array2, &[_]u32{2, 3}));
|
|
std.testing.expect(eql(u32, p_global_const_array2, &[_]u32{6, 7}));
|
|
|
|
// TODO
|
|
// std.testing.expect(p_global_var_array3.* == 2);
|
|
// std.testing.expect(p_global_const_array3.* == 6);
|
|
}
|