diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-06-04 11:53:33 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-06-04 11:53:33 +0100 |
| commit | ebe5beaafd90bccaee2ece8510e61d2cbf7a81c2 (patch) | |
| tree | 0efe4ee84413bcde4260496c5ddac6cd47acd5bf /src | |
| parent | 029a6095d952e0319608aed8859508caf1101112 (diff) | |
Allow using on bit fields
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.c | 9 | ||||
| -rw-r--r-- | src/ir.c | 16 |
2 files changed, 18 insertions, 7 deletions
diff --git a/src/check_expr.c b/src/check_expr.c index d5a26a193..866a5f1a4 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -452,7 +452,7 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls, if (is_using) { Type *t = base_type(type_deref(type)); - if (!is_type_struct(t) && !is_type_raw_union(t) && + if (!is_type_struct(t) && !is_type_raw_union(t) && !is_type_bit_field(t) && f->names.count >= 1 && f->names.e[0]->kind == AstNode_Ident) { Token name_token = f->names.e[0]->Ident; @@ -477,7 +477,9 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls, error(name_token, "Previous `using` for an index expression `%.*s`", LIT(name_token.string)); } } else { - error(name_token, "`using` on a field `%.*s` must be a `struct` or `raw_union`", LIT(name_token.string)); + gbString type_str = type_to_string(type); + error(name_token, "`using` cannot be applied to the field `%.*s` of type `%s`", LIT(name_token.string), type_str); + gb_string_free(type_str); continue; } } @@ -2258,7 +2260,8 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { if (o->mode != Addressing_Variable || check_is_expr_vector_index(c, o->expr) || - check_is_vector_elem(c, o->expr)) { + check_is_vector_elem(c, o->expr) || + is_type_bit_field_value(o->type)) { if (ast_node_expect(node, AstNode_UnaryExpr)) { ast_node(ue, UnaryExpr, node); gbString str = expr_to_string(ue->expr); @@ -4836,10 +4836,18 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { if (sel.entity->type->kind == Type_BitFieldValue) { irAddr addr = ir_build_addr(proc, se->expr); Type *bft = type_deref(ir_addr_type(addr)); - GB_ASSERT(is_type_bit_field(bft)); - GB_ASSERT(sel.index.count == 1); - i32 index = sel.index.e[0]; - return ir_addr_bit_field(addr.addr, index); + if (sel.index.count == 1) { + GB_ASSERT(is_type_bit_field(bft)); + i32 index = sel.index.e[0]; + return ir_addr_bit_field(addr.addr, index); + } else { + Selection s = sel; + s.index.count--; + i32 index = s.index.e[s.index.count-1]; + irValue *a = addr.addr; + a = ir_emit_deep_field_gep(proc, a, s); + return ir_addr_bit_field(a, index); + } } else { irValue *a = ir_build_addr(proc, se->expr).addr; a = ir_emit_deep_field_gep(proc, a, sel); |