Allow using on bit fields

This commit is contained in:
Ginger Bill
2017-06-04 11:53:33 +01:00
parent 029a6095d9
commit ebe5beaafd
3 changed files with 86 additions and 54 deletions

View File

@@ -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);

View File

@@ -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);