aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend_expr.cpp')
-rw-r--r--src/llvm_backend_expr.cpp32
1 files changed, 32 insertions, 0 deletions
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