mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-31 18:32:12 +00:00
Add field tags to bit_field
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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) }
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -655,6 +655,7 @@ AST_KIND(_DeclEnd, "", bool) \
|
||||
Ast * name; \
|
||||
Ast * type; \
|
||||
Ast * bit_size; \
|
||||
Token tag; \
|
||||
CommentGroup *docs; \
|
||||
CommentGroup *comment; \
|
||||
}) \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
Reference in New Issue
Block a user