aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-02-22 18:41:15 +0000
committergingerBill <bill@gingerbill.org>2024-02-22 18:41:15 +0000
commitafcc2889ecf532e03878825d7eb713674d1e7af7 (patch)
tree705466b6ec6ca09847a7491036ab5b83d17d806a /src/check_expr.cpp
parent5f001f6d5138d61fbb4900c951e2ccb12894d5ed (diff)
Support compound literals for `bit_field`
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp49
1 files changed, 44 insertions, 5 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 792e5b43c..d5890b191 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -8440,6 +8440,11 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
StringMap<String> fields_visited_through_raw_union = {};
defer (string_map_destroy(&fields_visited_through_raw_union));
+ String assignment_str = str_lit("structure literal");
+ if (bt->kind == Type_BitField) {
+ assignment_str = str_lit("bit_field literal");
+ }
+
for (Ast *elem : elems) {
if (elem->kind != Ast_FieldValue) {
error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed");
@@ -8461,17 +8466,26 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
continue;
}
- Entity *field = bt->Struct.fields[sel.index[0]];
+ Entity *field = nullptr;
+ if (bt->kind == Type_Struct) {
+ field = bt->Struct.fields[sel.index[0]];
+ } else if (bt->kind == Type_BitField) {
+ field = bt->BitField.fields[sel.index[0]];
+ } else {
+ GB_PANIC("Unknown type");
+ }
+
+
add_entity_use(c, fv->field, field);
if (string_set_update(&fields_visited, name)) {
if (sel.index.count > 1) {
if (String *found = string_map_get(&fields_visited_through_raw_union, sel.entity->token.string)) {
error(fv->field, "Field '%.*s' is already initialized due to a previously assigned struct #raw_union field '%.*s'", LIT(sel.entity->token.string), LIT(*found));
} else {
- error(fv->field, "Duplicate or reused field '%.*s' in structure literal", LIT(sel.entity->token.string));
+ error(fv->field, "Duplicate or reused field '%.*s' in %.*s", LIT(sel.entity->token.string), LIT(assignment_str));
}
} else {
- error(fv->field, "Duplicate field '%.*s' in structure literal", LIT(field->token.string));
+ error(fv->field, "Duplicate field '%.*s' in %.*s", LIT(field->token.string), LIT(assignment_str));
}
continue;
} else if (String *found = string_map_get(&fields_visited_through_raw_union, sel.entity->token.string)) {
@@ -8479,11 +8493,13 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
continue;
}
if (sel.indirect) {
- error(fv->field, "Cannot assign to the %d-nested anonymous indirect field '%.*s' in a structure literal", cast(int)sel.index.count-1, LIT(name));
+ error(fv->field, "Cannot assign to the %d-nested anonymous indirect field '%.*s' in a %.*s", cast(int)sel.index.count-1, LIT(name), LIT(assignment_str));
continue;
}
if (sel.index.count > 1) {
+ GB_ASSERT(bt->kind == Type_Struct);
+
if (is_constant) {
Type *ft = type;
for (i32 index : sel.index) {
@@ -8544,7 +8560,15 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
is_constant = check_is_operand_compound_lit_constant(c, &o);
}
- check_assignment(c, &o, field->type, str_lit("structure literal"));
+ u8 prev_bit_field_bit_size = c->bit_field_bit_size;
+ if (field->kind == Entity_Variable && field->Variable.bit_field_bit_size) {
+ // HACK NOTE(bill): This is a bit of a hack, but it will work fine for this use case
+ c->bit_field_bit_size = field->Variable.bit_field_bit_size;
+ }
+
+ check_assignment(c, &o, field->type, assignment_str);
+
+ c->bit_field_bit_size = prev_bit_field_bit_size;
}
}
@@ -9346,6 +9370,21 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *
}
break;
}
+ case Type_BitField: {
+ if (cl->elems.count == 0) {
+ break; // NOTE(bill): No need to init
+ }
+ is_constant = false;
+ if (cl->elems[0]->kind != Ast_FieldValue) {
+ gbString type_str = type_to_string(type);
+ error(node, "%s ('bit_field') compound literals are only allowed to contain 'field = value' elements", type_str);
+ gb_string_free(type_str);
+ } else {
+ check_compound_literal_field_values(c, cl->elems, o, type, is_constant);
+ }
+ break;
+ }
+
default: {
if (cl->elems.count == 0) {