Add field tags to bit_field

This commit is contained in:
gingerBill
2024-02-22 19:41:48 +00:00
parent 3f193d7446
commit 54515af8cc
7 changed files with 63 additions and 19 deletions

View File

@@ -187,6 +187,7 @@ Type_Info_Bit_Field :: struct {
types: []^Type_Info,
bit_sizes: []uintptr,
bit_offsets: []uintptr,
tags: []string,
}
Type_Info_Flag :: enum u8 {

View File

@@ -2297,6 +2297,23 @@ fmt_bit_field :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Bit
return
}
handle_bit_field_tag :: proc(data: rawptr, info: reflect.Type_Info_Bit_Field, idx: int, verb: ^rune) -> (do_continue: bool) {
tag := info.tags[idx]
if vt, ok := reflect.struct_tag_lookup(reflect.Struct_Tag(tag), "fmt"); ok {
value := strings.trim_space(string(vt))
switch value {
case "": return false
case "-": return true
}
r, w := utf8.decode_rune_in_string(value)
value = value[w:]
if value == "" || value[0] == ',' {
verb^ = r
}
}
return false
}
io.write_string(fi.writer, "bit_field{", &fi.n)
hash := fi.hash; defer fi.hash = hash
@@ -2318,7 +2335,11 @@ fmt_bit_field :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Bit
field_count := -1
for name, i in info.names {
_ = i
field_verb := verb
if handle_bit_field_tag(v.data, info, i, &field_verb) {
continue
}
field_count += 1
if !do_trailing_comma && field_count > 0 {
@@ -2343,7 +2364,7 @@ fmt_bit_field :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Bit
value = (value ~ m) - m
}
fmt_value(fi, any{&value, type.id}, verb)
fmt_value(fi, any{&value, type.id}, field_verb)
if do_trailing_comma { io.write_string(fi.writer, ",\n", &fi.n) }
}

View File

@@ -959,6 +959,7 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
auto fields = array_make<Entity *>(permanent_allocator(), 0, bf->fields.count);
auto bit_sizes = array_make<u8> (permanent_allocator(), 0, bf->fields.count);
auto tags = array_make<String> (permanent_allocator(), 0, bf->fields.count);
u64 maximum_bit_size = 8 * type_size_of(backing_type);
u64 total_bit_size = 0;
@@ -1054,6 +1055,14 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
add_entity(ctx, ctx->scope, nullptr, e);
array_add(&fields, e);
array_add(&bit_sizes, bit_size_u8);
String tag = f->tag.string;
if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) {
error(f->tag, "Invalid string literal");
tag = {};
}
array_add(&tags, tag);
add_entity_use(ctx, field, e);
}
}
@@ -1080,6 +1089,7 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
bit_field_type->BitField.fields = slice_from_array(fields);
bit_field_type->BitField.bit_sizes = slice_from_array(bit_sizes);
bit_field_type->BitField.bit_offsets = bit_offsets;
bit_field_type->BitField.tags = tags.data;
}
gb_internal bool is_type_valid_bit_set_range(Type *t) {

View File

@@ -1792,19 +1792,21 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup
case Type_BitField:
{
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_bit_field_ptr);
LLVMValueRef vals[5] = {};
LLVMValueRef vals[6] = {};
vals[0] = lb_type_info(m, t->BitField.backing_type).value;
isize count = t->BitField.fields.count;
if (count > 0) {
i64 names_offset = 0;
i64 types_offset = 0;
i64 bit_sizes_offset = 0;
i64 names_offset = 0;
i64 types_offset = 0;
i64 bit_sizes_offset = 0;
i64 bit_offsets_offset = 0;
i64 tags_offset = 0;
lbValue memory_names = lb_type_info_member_names_offset (m, count, &names_offset);
lbValue memory_types = lb_type_info_member_types_offset (m, count, &types_offset);
lbValue memory_bit_sizes = lb_type_info_member_offsets_offset(m, count, &bit_sizes_offset);
lbValue memory_bit_offsets = lb_type_info_member_offsets_offset(m, count, &bit_offsets_offset);
lbValue memory_tags = lb_type_info_member_tags_offset (m, count, &tags_offset);
u64 bit_offset = 0;
for (isize source_index = 0; source_index < count; source_index++) {
@@ -1813,8 +1815,8 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup
lbValue index = lb_const_int(m, t_int, source_index);
if (f->token.string.len > 0) {
lbValue name = lb_emit_ptr_offset(p, memory_names, index);
lb_emit_store(p, name, lb_const_string(m, f->token.string));
lbValue name_ptr = lb_emit_ptr_offset(p, memory_names, index);
lb_emit_store(p, name_ptr, lb_const_string(m, f->token.string));
}
lbValue type_ptr = lb_emit_ptr_offset(p, memory_types, index);
lbValue bit_size_ptr = lb_emit_ptr_offset(p, memory_bit_sizes, index);
@@ -1824,21 +1826,23 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup
lb_emit_store(p, bit_size_ptr, lb_const_int(m, t_uintptr, bit_size));
lb_emit_store(p, bit_offset_ptr, lb_const_int(m, t_uintptr, bit_offset));
// lb_global_type_info_member_types_values [types_offset +source_index] = get_type_info_ptr(m, f->type);
// lb_global_type_info_member_offsets_values[bit_sizes_offset +source_index] = lb_const_int(m, t_uintptr, bit_size).value;
// lb_global_type_info_member_offsets_values[bit_offsets_offset+source_index] = lb_const_int(m, t_uintptr, bit_offset).value;
// if (f->token.string.len > 0) {
// lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string(m, f->token.string).value;
// }
if (t->BitField.tags) {
String tag = t->BitField.tags[source_index];
if (tag.len > 0) {
lbValue tag_ptr = lb_emit_ptr_offset(p, memory_tags, index);
lb_emit_store(p, tag_ptr, lb_const_string(m, tag));
}
}
bit_offset += bit_size;
}
lbValue cv = lb_const_int(m, t_int, count);
vals[1] = llvm_const_slice(m, memory_names, cv);
vals[2] = llvm_const_slice(m, memory_types, cv);
vals[3] = llvm_const_slice(m, memory_bit_sizes, cv);
vals[1] = llvm_const_slice(m, memory_names, cv);
vals[2] = llvm_const_slice(m, memory_types, cv);
vals[3] = llvm_const_slice(m, memory_bit_sizes, cv);
vals[4] = llvm_const_slice(m, memory_bit_offsets, cv);
vals[5] = llvm_const_slice(m, memory_tags, cv);
}
for (isize i = 0; i < gb_count_of(vals); i++) {

View File

@@ -1054,12 +1054,13 @@ gb_internal Ast *ast_field(AstFile *f, Array<Ast *> const &names, Ast *type, Ast
return result;
}
gb_internal Ast *ast_bit_field_field(AstFile *f, Ast *name, Ast *type, Ast *bit_size,
gb_internal Ast *ast_bit_field_field(AstFile *f, Ast *name, Ast *type, Ast *bit_size, Token tag,
CommentGroup *docs, CommentGroup *comment) {
Ast *result = alloc_ast_node(f, Ast_BitFieldField);
result->BitFieldField.name = name;
result->BitFieldField.type = type;
result->BitFieldField.bit_size = bit_size;
result->BitFieldField.tag = tag;
result->BitFieldField.docs = docs;
result->BitFieldField.comment = comment;
return result;
@@ -2611,7 +2612,12 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
expect_token(f, Token_Or);
Ast *bit_size = parse_expr(f, true);
Ast *bf_field = ast_bit_field_field(f, name, type, bit_size, docs, comment);
Token tag = {};
if (f->curr_token.kind == Token_String) {
tag = expect_token(f, Token_String);
}
Ast *bf_field = ast_bit_field_field(f, name, type, bit_size, tag, docs, comment);
array_add(&fields, bf_field);
if (!allow_field_separator(f)) {

View File

@@ -655,6 +655,7 @@ AST_KIND(_DeclEnd, "", bool) \
Ast * name; \
Ast * type; \
Ast * bit_size; \
Token tag; \
CommentGroup *docs; \
CommentGroup *comment; \
}) \

View File

@@ -286,6 +286,7 @@ struct TypeProc {
Scope * scope; \
Type * backing_type; \
Slice<Entity *> fields; \
String * tags; /*count == fields.count*/ \
Slice<u8> bit_sizes; \
Slice<i64> bit_offsets; \
Ast * node; \