aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-06-04 11:53:33 +0100
committerGinger Bill <bill@gingerbill.org>2017-06-04 11:53:33 +0100
commitebe5beaafd90bccaee2ece8510e61d2cbf7a81c2 (patch)
tree0efe4ee84413bcde4260496c5ddac6cd47acd5bf /src
parent029a6095d952e0319608aed8859508caf1101112 (diff)
Allow using on bit fields
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c9
-rw-r--r--src/ir.c16
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);
diff --git a/src/ir.c b/src/ir.c
index 2002c7a4c..f2b75b88d 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -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);