gingerBill 1 year ago
parent
commit
cbabcb0907
3 changed files with 34 additions and 2 deletions
  1. 7 0
      src/check_expr.cpp
  2. 18 2
      src/llvm_backend_expr.cpp
  3. 9 0
      src/types.cpp

+ 7 - 0
src/check_expr.cpp

@@ -8866,6 +8866,10 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
 					case Type_Array:
 					case Type_Array:
 						ft = bt->Array.elem;
 						ft = bt->Array.elem;
 						break;
 						break;
+					case Type_BitField:
+						is_constant = false;
+						ft = bt->BitField.fields[index]->type;
+						break;
 					default:
 					default:
 						GB_PANIC("invalid type: %s", type_to_string(ft));
 						GB_PANIC("invalid type: %s", type_to_string(ft));
 						break;
 						break;
@@ -8892,6 +8896,9 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
 				case Type_Array:
 				case Type_Array:
 					nested_ft = bt->Array.elem;
 					nested_ft = bt->Array.elem;
 					break;
 					break;
+				case Type_BitField:
+					nested_ft = bt->BitField.fields[index]->type;
+					break;
 				default:
 				default:
 					GB_PANIC("invalid type %s", type_to_string(nested_ft));
 					GB_PANIC("invalid type %s", type_to_string(nested_ft));
 					break;
 					break;

+ 18 - 2
src/llvm_backend_expr.cpp

@@ -4533,10 +4533,26 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
 						if (lb_is_nested_possibly_constant(type, sel, elem)) {
 						if (lb_is_nested_possibly_constant(type, sel, elem)) {
 							continue;
 							continue;
 						}
 						}
-						lbValue dst = lb_emit_deep_field_gep(p, comp_lit_ptr, sel);
 						field_expr = lb_build_expr(p, elem);
 						field_expr = lb_build_expr(p, elem);
 						field_expr = lb_emit_conv(p, field_expr, sel.entity->type);
 						field_expr = lb_emit_conv(p, field_expr, sel.entity->type);
-						lb_emit_store(p, dst, field_expr);
+						if (sel.is_bit_field) {
+							Selection sub_sel = trim_selection(sel);
+							lbValue trimmed_dst = lb_emit_deep_field_gep(p, comp_lit_ptr, sub_sel);
+							Type *bf = base_type(type_deref(trimmed_dst.type));
+							if (is_type_pointer(bf)) {
+								trimmed_dst = lb_emit_load(p, trimmed_dst);
+								bf = base_type(type_deref(trimmed_dst.type));
+							}
+							GB_ASSERT(bf->kind == Type_BitField);
+
+							isize idx = sel.index[sel.index.count-1];
+							lbAddr dst = lb_addr_bit_field(trimmed_dst, bf->BitField.fields[idx]->type, bf->BitField.bit_offsets[idx], bf->BitField.bit_sizes[idx]);
+							lb_addr_store(p, dst, field_expr);
+
+						} else {
+							lbValue dst = lb_emit_deep_field_gep(p, comp_lit_ptr, sel);
+							lb_emit_store(p, dst, field_expr);
+						}
 						continue;
 						continue;
 					}
 					}
 
 

+ 9 - 0
src/types.cpp

@@ -457,6 +457,15 @@ gb_internal Selection sub_selection(Selection const &sel, isize offset) {
 	return res;
 	return res;
 }
 }
 
 
+gb_internal Selection trim_selection(Selection const &sel) {
+	Selection res = {};
+	res.index.data = sel.index.data;
+	res.index.count = gb_max(sel.index.count - 1, 0);
+	res.index.capacity = res.index.count;
+	return res;
+}
+
+
 gb_global Type basic_types[] = {
 gb_global Type basic_types[] = {
 	{Type_Basic, {Basic_Invalid,           0,                                          0, STR_LIT("invalid type")}},
 	{Type_Basic, {Basic_Invalid,           0,                                          0, STR_LIT("invalid type")}},