aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-23 00:34:47 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-23 00:34:59 -0700
commita922d5d42a3ba9bbded0740e1eb3246e7b57ad2a (patch)
treef62821f2a88dd807ca28362379cd4b1e01974275 /src/analyze.cpp
parent1543043bf5b5633de485dccee88872a3d4f6c454 (diff)
downloadzig-a922d5d42a3ba9bbded0740e1eb3246e7b57ad2a.tar.gz
zig-a922d5d42a3ba9bbded0740e1eb3246e7b57ad2a.zip
implement literal error values
See #23
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp34
1 files changed, 29 insertions, 5 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 1137915519..8f19dbd777 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -233,11 +233,10 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
entry->data.error.child_type = child_type;
if (child_type->size_in_bits == 0) {
- TypeTableEntry *tag_type = get_smallest_unsigned_int_type(g, g->next_error_index);
- entry->type_ref = tag_type->type_ref;
- entry->size_in_bits = tag_type->size_in_bits;
- entry->align_in_bits = tag_type->align_in_bits;
- entry->di_type = tag_type->di_type;
+ entry->type_ref = g->err_tag_type->type_ref;
+ entry->size_in_bits = g->err_tag_type->size_in_bits;
+ entry->align_in_bits = g->err_tag_type->align_in_bits;
+ entry->di_type = g->err_tag_type->di_type;
} else {
zig_panic("TODO get_error_type non-void");
@@ -2869,6 +2868,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
const_val->data.x_maybe = other_val;
const_val->ok = true;
break;
+ case CastOpErrToInt:
+ bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_err->value);
+ const_val->ok = true;
+ break;
}
}
@@ -2975,6 +2978,24 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
}
}
+ // explicit cast from %void to integer type which can fit it
+ if (actual_type->id == TypeTableEntryIdError &&
+ actual_type->data.error.child_type->size_in_bits == 0 &&
+ wanted_type->id == TypeTableEntryIdInt)
+ {
+ BigNum bn;
+ bignum_init_unsigned(&bn, g->next_error_index);
+ if (bignum_fits_in_bits(&bn, wanted_type->size_in_bits, wanted_type->data.integral.is_signed)) {
+ node->data.fn_call_expr.cast_op = CastOpErrToInt;
+ eval_const_expr_implicit_cast(g, node, expr_node);
+ return wanted_type;
+ } else {
+ add_node_error(g, node,
+ buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));
+ return g->builtin_types.entry_invalid;
+ }
+ }
+
add_node_error(g, node,
buf_sprintf("invalid cast from type '%s' to '%s'",
buf_ptr(&actual_type->name),
@@ -4353,6 +4374,9 @@ void semantic_analyze(CodeGen *g) {
}
}
}
+
+ g->err_tag_type = get_smallest_unsigned_int_type(g, g->next_error_index);
+
{
auto it = g->import_table.entry_iterator();
for (;;) {