Skip to content

Commit 7990152

Browse files
committed
Support sentinel in @type
1 parent fecd540 commit 7990152

File tree

8 files changed

+142
-55
lines changed

8 files changed

+142
-55
lines changed

src/all_types.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -2023,12 +2023,14 @@ struct CodeGen {
20232023
ZigValue x_null;
20242024
ZigValue x_unreachable;
20252025
ZigValue zero_byte;
2026+
ZigValue optional_zero_byte;
20262027

20272028
ZigValue *for_undefined();
20282029
ZigValue *for_void();
20292030
ZigValue *for_null();
20302031
ZigValue *for_unreachable();
20312032
ZigValue *for_zero_byte();
2033+
ZigValue *for_optional_zero_byte();
20322034
} intern;
20332035

20342036
ZigType *align_amt_type;

src/analyze.cpp

+24-14
Original file line numberDiff line numberDiff line change
@@ -533,9 +533,10 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
533533

534534
TypeId type_id = {};
535535
ZigType **parent_pointer = nullptr;
536+
ZigValue *sentinel_unwrapped = get_sentinel_value(sentinel);
536537
if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||
537538
allow_zero || vector_index != VECTOR_INDEX_NONE || inferred_struct_field != nullptr ||
538-
sentinel != nullptr)
539+
sentinel_unwrapped != nullptr)
539540
{
540541
type_id.id = ZigTypeIdPointer;
541542
type_id.data.pointer.codegen = g;
@@ -577,13 +578,13 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
577578
buf_appendf(&entry->name, "[*");
578579
break;
579580
case PtrLenC:
580-
assert(sentinel == nullptr);
581+
assert(sentinel_unwrapped == nullptr);
581582
buf_appendf(&entry->name, "[*c]");
582583
break;
583584
}
584-
if (sentinel != nullptr) {
585+
if (sentinel_unwrapped != nullptr) {
585586
buf_appendf(&entry->name, ":");
586-
render_const_value(g, &entry->name, sentinel);
587+
render_const_value(g, &entry->name, sentinel_unwrapped);
587588
}
588589
switch (ptr_len) {
589590
case PtrLenSingle:
@@ -775,20 +776,22 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi
775776
assert(type_is_resolved(child_type, ResolveStatusSizeKnown));
776777

777778
ZigType *entry = new_type_table_entry(ZigTypeIdArray);
779+
ZigValue *sentinel_unwrapped = get_sentinel_value(sentinel);
778780

779781
buf_resize(&entry->name, 0);
780782
buf_appendf(&entry->name, "[%" ZIG_PRI_u64, array_size);
781-
if (sentinel != nullptr) {
783+
if (sentinel_unwrapped != nullptr) {
784+
assert(sentinel_unwrapped->type == child_type);
782785
buf_appendf(&entry->name, ":");
783-
render_const_value(g, &entry->name, sentinel);
786+
render_const_value(g, &entry->name, sentinel_unwrapped);
784787
}
785788
buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
786789

787790
size_t full_array_size;
788791
if (array_size == 0) {
789792
full_array_size = 0;
790793
} else {
791-
full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
794+
full_array_size = array_size + ((sentinel_unwrapped != nullptr) ? 1 : 0);
792795
}
793796

794797
entry->size_in_bits = child_type->size_in_bits * full_array_size;
@@ -816,9 +819,12 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
816819

817820
buf_resize(&entry->name, 0);
818821
buf_appendf(&entry->name, "[");
819-
if (ptr_type->data.pointer.sentinel != nullptr) {
820-
buf_appendf(&entry->name, ":");
821-
render_const_value(g, &entry->name, ptr_type->data.pointer.sentinel);
822+
{
823+
ZigValue *sentinel = get_sentinel_value(ptr_type->data.pointer.sentinel);
824+
if (sentinel != nullptr) {
825+
buf_appendf(&entry->name, ":");
826+
render_const_value(g, &entry->name, sentinel);
827+
}
822828
}
823829
buf_appendf(&entry->name, "]");
824830
append_ptr_type_attrs(&entry->name, ptr_type);
@@ -5660,7 +5666,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
56605666
// first we build the underlying array
56615667
ZigValue *array_val = create_const_vals(1);
56625668
array_val->special = ConstValSpecialStatic;
5663-
array_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), g->intern.for_zero_byte());
5669+
array_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), g->intern.for_optional_zero_byte());
56645670
array_val->data.x_array.special = ConstArraySpecialBuf;
56655671
array_val->data.x_array.data.s_buf = str;
56665672

@@ -7067,11 +7073,13 @@ uint32_t type_id_hash(TypeId x) {
70677073
(((uint32_t)x.data.pointer.bit_offset_in_host) ^ (uint32_t)2639019452) +
70687074
(((uint32_t)x.data.pointer.vector_index) ^ (uint32_t)0x19199716) +
70697075
(((uint32_t)x.data.pointer.host_int_bytes) ^ (uint32_t)529908881) *
7070-
(x.data.pointer.sentinel ? hash_const_val(x.data.pointer.sentinel) : (uint32_t)2955491856);
7076+
(get_sentinel_value(x.data.pointer.sentinel) ?
7077+
hash_const_val(get_sentinel_value(x.data.pointer.sentinel)) : (uint32_t)2955491856);
70717078
case ZigTypeIdArray:
70727079
return hash_ptr(x.data.array.child_type) *
70737080
((uint32_t)x.data.array.size ^ (uint32_t)2122979968) *
7074-
(x.data.array.sentinel ? hash_const_val(x.data.array.sentinel) : (uint32_t)1927201585);
7081+
(get_sentinel_value(x.data.array.sentinel) ?
7082+
hash_const_val(get_sentinel_value(x.data.array.sentinel)) : (uint32_t)1927201585);
70757083
case ZigTypeIdInt:
70767084
return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +
70777085
(((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557);
@@ -8687,7 +8695,9 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
86878695

86888696
ZigType *elem_type = type->data.array.child_type;
86898697

8690-
uint64_t extra_len_from_sentinel = (type->data.array.sentinel != nullptr) ? 1 : 0;
8698+
// TODO: should this size be 1 or sizeof sentinel?
8699+
ZigValue *sentinel = get_sentinel_value(type->data.array.sentinel);
8700+
uint64_t extra_len_from_sentinel = (sentinel != nullptr) ? 1 : 0;
86918701
uint64_t full_len = type->data.array.len + extra_len_from_sentinel;
86928702
// TODO https://github.com/ziglang/zig/issues/1424
86938703
type->llvm_type = LLVMArrayType(get_llvm_type(g, elem_type), (unsigned)full_len);

src/codegen.cpp

+26-8
Original file line numberDiff line numberDiff line change
@@ -3707,7 +3707,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
37073707
array_type = array_type->data.pointer.child_type;
37083708
}
37093709
if (safety_check_on) {
3710-
uint64_t extra_len_from_sentinel = (array_type->data.array.sentinel != nullptr) ? 1 : 0;
3710+
ZigValue *sentinel = get_sentinel_value(array_type->data.array.sentinel);
3711+
// TODO: should this size be 1 or the size of the child element?
3712+
uint64_t extra_len_from_sentinel = (sentinel != nullptr) ? 1 : 0;
37113713
uint64_t full_len = array_type->data.array.len + extra_len_from_sentinel;
37123714
LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, full_len, false);
37133715
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);
@@ -3769,7 +3771,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
37693771
assert(len_index != SIZE_MAX);
37703772
LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
37713773
LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");
3772-
LLVMIntPredicate upper_op = (ptr_type->data.pointer.sentinel != nullptr) ? LLVMIntULE : LLVMIntULT;
3774+
LLVMIntPredicate upper_op = (get_sentinel_value(ptr_type->data.pointer.sentinel) != nullptr) ?
3775+
LLVMIntULE : LLVMIntULT;
37733776
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, upper_op, len);
37743777
}
37753778

@@ -6635,8 +6638,8 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
66356638
ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;
66366639
assert(array_const_val->type->id == ZigTypeIdArray);
66376640
if (!type_has_bits(array_const_val->type)) {
6638-
if (array_const_val->type->data.array.sentinel != nullptr) {
6639-
ZigValue *pointee = array_const_val->type->data.array.sentinel;
6641+
ZigValue *pointee = get_sentinel_value(array_const_val->type->data.array.sentinel);
6642+
if (pointee != nullptr) {
66406643
render_const_val(g, pointee, "");
66416644
render_const_val_global(g, pointee, "");
66426645
const_val->llvm_value = LLVMConstBitCast(pointee->llvm_global,
@@ -6957,7 +6960,9 @@ check: switch (const_val->special) {
69576960
case ConstArraySpecialUndef:
69586961
return LLVMGetUndef(get_llvm_type(g, type_entry));
69596962
case ConstArraySpecialNone: {
6960-
uint64_t extra_len_from_sentinel = (type_entry->data.array.sentinel != nullptr) ? 1 : 0;
6963+
ZigValue *sentinel = get_sentinel_value(type_entry->data.array.sentinel);
6964+
// TODO: is this supposed to be 1 or sizeof(sentinel)?
6965+
uint64_t extra_len_from_sentinel = (sentinel != nullptr) ? 1 : 0;
69616966
uint64_t full_len = len + extra_len_from_sentinel;
69626967
LLVMValueRef *values = allocate<LLVMValueRef>(full_len);
69636968
LLVMTypeRef element_type_ref = get_llvm_type(g, type_entry->data.array.child_type);
@@ -6968,8 +6973,8 @@ check: switch (const_val->special) {
69686973
values[i] = val;
69696974
make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, elem_value->type, val);
69706975
}
6971-
if (type_entry->data.array.sentinel != nullptr) {
6972-
values[len] = gen_const_val(g, type_entry->data.array.sentinel, "");
6976+
if (sentinel != nullptr) {
6977+
values[len] = gen_const_val(g, sentinel, "");
69736978
}
69746979
if (make_unnamed_struct) {
69756980
return LLVMConstStruct(values, full_len, true);
@@ -6980,7 +6985,7 @@ check: switch (const_val->special) {
69806985
case ConstArraySpecialBuf: {
69816986
Buf *buf = const_val->data.x_array.data.s_buf;
69826987
return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf),
6983-
type_entry->data.array.sentinel == nullptr);
6988+
get_sentinel_value(type_entry->data.array.sentinel) == nullptr);
69846989
}
69856990
}
69866991
zig_unreachable();
@@ -8023,6 +8028,12 @@ static void define_intern_values(CodeGen *g) {
80238028
value.special = ConstValSpecialStatic;
80248029
bigint_init_unsigned(&value.data.x_bigint, 0);
80258030
}
8031+
{
8032+
auto& value = g->intern.optional_zero_byte;
8033+
value.type = get_optional_type(g, g->builtin_types.entry_u8);
8034+
value.special = ConstValSpecialStatic;
8035+
value.data.x_optional = &g->intern.zero_byte;
8036+
}
80268037
}
80278038

80288039
static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) {
@@ -10618,3 +10629,10 @@ ZigValue *CodeGen::Intern::for_zero_byte() {
1061810629
#endif
1061910630
return &this->zero_byte;
1062010631
}
10632+
10633+
ZigValue *CodeGen::Intern::for_optional_zero_byte() {
10634+
#ifdef ZIG_ENABLE_MEM_PROFILE
10635+
memprof_intern_count.optional_zero_byte += 1;
10636+
#endif
10637+
return &this->optional_zero_byte;
10638+
}

0 commit comments

Comments
 (0)