From afcc2889ecf532e03878825d7eb713674d1e7af7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Feb 2024 18:41:15 +0000 Subject: Support compound literals for `bit_field` --- src/llvm_backend_expr.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 7b31ca989..7e000c9e8 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -4235,6 +4235,38 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { switch (bt->kind) { default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break; + case Type_BitField: + for (Ast *elem : cl->elems) { + ast_node(fv, FieldValue, elem); + String name = fv->field->Ident.token.string; + Selection sel = lookup_field(bt, name, false); + GB_ASSERT(sel.is_bit_field); + GB_ASSERT(!sel.indirect); + GB_ASSERT(sel.index.count == 1); + GB_ASSERT(sel.entity != nullptr); + + i64 index = sel.index[0]; + i64 bit_offset = 0; + i64 bit_size = -1; + for_array(i, bt->BitField.fields) { + Entity *f = bt->BitField.fields[i]; + if (f == sel.entity) { + bit_offset = bt->BitField.bit_offsets[i]; + bit_size = bt->BitField.bit_sizes[i]; + break; + } + } + GB_ASSERT(bit_size > 0); + + Type *field_type = sel.entity->type; + lbValue field_expr = lb_build_expr(p, fv->value); + field_expr = lb_emit_conv(p, field_expr, field_type); + + lbAddr field_addr = lb_addr_bit_field(v.addr, field_type, index, bit_offset, bit_size); + lb_addr_store(p, field_addr, field_expr); + } + return v; + case Type_Struct: { // TODO(bill): "constant" '#raw_union's are not initialized constantly at the moment. // NOTE(bill): This is due to the layout of the unions when printed to LLVM-IR -- cgit v1.2.3