aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-04-02 18:19:59 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-04-02 18:19:59 -0400
commit8fd0fddce5d44344dd7914ae86a4d976b99f9cc3 (patch)
tree69d6a1b6e32e8c8a622eb149c0e60f33f426996d /src/codegen.cpp
parent0594487a2e98e18a18c0c6bdb2532c5e36fc6ea7 (diff)
downloadzig-8fd0fddce5d44344dd7914ae86a4d976b99f9cc3.tar.gz
zig-8fd0fddce5d44344dd7914ae86a4d976b99f9cc3.zip
zig build system progress
* In-progress os.ChildProcess.spawn implementation. See #204 * Add explicit cast from integer to error. Closes #294 * fix casting from error to integer * fix compiler crash when initializing variable to undefined with no type
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp74
1 files changed, 66 insertions, 8 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index cbc0d4c0b0..ed4b0e0df2 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -570,6 +570,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
return buf_create_from_str("attempt to unwrap error");
case PanicMsgIdUnreachable:
return buf_create_from_str("reached unreachable code");
+ case PanicMsgIdInvalidErrorCode:
+ return buf_create_from_str("invalid error code");
}
zig_unreachable();
}
@@ -1227,14 +1229,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
zig_unreachable();
case CastOpNoop:
return expr_val;
- case CastOpErrToInt:
- assert(actual_type->id == TypeTableEntryIdErrorUnion);
- if (!type_has_bits(actual_type->data.error.child_type)) {
- return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
- g->err_tag_type, wanted_type, expr_val);
- } else {
- zig_panic("TODO");
- }
case CastOpResizeSlice:
{
assert(cast_instruction->tmp_ptr);
@@ -1402,6 +1396,66 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
instruction->target->value.type, wanted_int_type, target_val);
}
+static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
+ TypeTableEntry *wanted_type = instruction->base.value.type;
+ assert(wanted_type->id == TypeTableEntryIdPureError);
+
+ TypeTableEntry *actual_type = instruction->target->value.type;
+ assert(actual_type->id == TypeTableEntryIdInt);
+ assert(!actual_type->data.integral.is_signed);
+
+ LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
+
+ if (ir_want_debug_safety(g, &instruction->base)) {
+ LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
+ LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
+ LLVMValueRef ok_bit;
+ uint64_t biggest_possible_err_val = max_unsigned_val(actual_type);
+ if (biggest_possible_err_val < g->error_decls.length) {
+ ok_bit = neq_zero_bit;
+ } else {
+ LLVMValueRef error_value_count = LLVMConstInt(actual_type->type_ref, g->error_decls.length, false);
+ LLVMValueRef in_bounds_bit = LLVMBuildICmp(g->builder, LLVMIntULT, target_val, error_value_count, "");
+ ok_bit = LLVMBuildAnd(g->builder, neq_zero_bit, in_bounds_bit, "");
+ }
+
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrOk");
+ LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrFail");
+
+ LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, fail_block);
+ gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);
+
+ LLVMPositionBuilderAtEnd(g->builder, ok_block);
+ }
+
+ return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);
+}
+
+static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) {
+ TypeTableEntry *wanted_type = instruction->base.value.type;
+ assert(wanted_type->id == TypeTableEntryIdInt);
+ assert(!wanted_type->data.integral.is_signed);
+
+ TypeTableEntry *actual_type = instruction->target->value.type;
+ LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
+
+ if (actual_type->id == TypeTableEntryIdPureError) {
+ return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
+ g->err_tag_type, wanted_type, target_val);
+ } else if (actual_type->id == TypeTableEntryIdErrorUnion) {
+ if (!type_has_bits(actual_type->data.error.child_type)) {
+ return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
+ g->err_tag_type, wanted_type, target_val);
+ } else {
+ zig_panic("TODO");
+ }
+ } else {
+ zig_unreachable();
+ }
+}
+
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
IrInstructionUnreachable *unreachable_instruction)
{
@@ -2786,6 +2840,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_int_to_ptr(g, executable, (IrInstructionIntToPtr *)instruction);
case IrInstructionIdIntToEnum:
return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction);
+ case IrInstructionIdIntToErr:
+ return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);
+ case IrInstructionIdErrToInt:
+ return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);
case IrInstructionIdContainerInitList:
return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
case IrInstructionIdPanic: