diff options
| author | gingerBill <bill@gingerbill.org> | 2024-07-01 12:13:35 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-07-01 12:13:35 +0100 |
| commit | 544959326b467b6587a04d6211ea142de932109c (patch) | |
| tree | f00aa354b20732a8ab90d745a043e66ed6362bf3 /src/check_builtin.cpp | |
| parent | 942f3f52207e32f68a9342ba2693f3b37199937b (diff) | |
Add `intrinsics.type_struct_has_implicit_padding` #3844
Diffstat (limited to 'src/check_builtin.cpp')
| -rw-r--r-- | src/check_builtin.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index c1422e80e..7a1a8b9ee 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -5839,6 +5839,31 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As operand->mode = Addressing_Constant; operand->type = t_untyped_integer; break; + case BuiltinProc_type_struct_has_implicit_padding: + operand->value = exact_value_bool(false); + if (operand->mode != Addressing_Type) { + error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name)); + } else if (!is_type_struct(operand->type) && !is_type_soa_struct(operand->type)) { + error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name)); + } else { + Type *bt = base_type(operand->type); + if (bt->Struct.is_packed) { + operand->value = exact_value_bool(false); + } else if (bt->Struct.fields.count != 0) { + i64 size = type_size_of(bt); + Type *field_type = nullptr; + i64 last_offset = type_offset_of(bt, bt->Struct.fields.count-1, &field_type); + if (last_offset+type_size_of(field_type) < size) { + operand->value = exact_value_bool(true); + } else { + i64 packed_size = type_size_of_struct_pretend_is_packed(bt); + operand->value = exact_value_bool(packed_size < size); + } + } + } + operand->mode = Addressing_Constant; + operand->type = t_untyped_bool; + break; case BuiltinProc_type_proc_parameter_count: operand->value = exact_value_i64(0); |