authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-18 01:54:27-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-18 01:54:27-05:00
log0d2f2b79eaf844e6bcdb41fe61c7e1655df9b1a0
tree2072c39406d37f55f4505acd95e23edef42daa11
parent69cf0ea56877a6f9bae51a35cffde371bf142567

IR: basic support for implicit casting to const pointer


3 files changed, 43 insertions(+), 2 deletions(-)

src/codegen.cpp+3-1
...@@ -1677,6 +1677,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru...@@ -1677,6 +1677,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru
1677 if (handle_is_ptr(instruction->value->type_entry)) {1677 if (handle_is_ptr(instruction->value->type_entry)) {
1678 return value;1678 return value;
1679 } else {1679 } else {
1680 assert(instruction->tmp_ptr);
1680 LLVMBuildStore(g->builder, value, instruction->tmp_ptr);1681 LLVMBuildStore(g->builder, value, instruction->tmp_ptr);
1681 return instruction->tmp_ptr;1682 return instruction->tmp_ptr;
1682 }1683 }
...@@ -2843,6 +2844,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2843,6 +2844,7 @@ static void do_code_gen(CodeGen *g) {
2843 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {2844 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {
2844 IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);2845 IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
2845 LLVMValueRef *slot;2846 LLVMValueRef *slot;
2847 TypeTableEntry *slot_type = instruction->type_entry;
2846 if (instruction->id == IrInstructionIdCast) {2848 if (instruction->id == IrInstructionIdCast) {
2847 IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;2849 IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;
2848 slot = &cast_instruction->tmp_ptr;2850 slot = &cast_instruction->tmp_ptr;
...@@ -2876,7 +2878,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2876,7 +2878,7 @@ static void do_code_gen(CodeGen *g) {
2876 } else {2878 } else {
2877 zig_unreachable();2879 zig_unreachable();
2878 }2880 }
2879 *slot = LLVMBuildAlloca(g->builder, instruction->type_entry->type_ref, "");2881 *slot = LLVMBuildAlloca(g->builder, slot_type->type_ref, "");
2880 }2882 }
28812883
2882 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);2884 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);
src/ir.cpp+39
...@@ -4230,6 +4230,13 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -4230,6 +4230,13 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
4230 return ImplicitCastMatchResultYes;4230 return ImplicitCastMatchResultYes;
4231 }4231 }
42324232
4233 // implicitly take a const pointer to something
4234 {
4235 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
4236 if (types_match_const_cast_only(expected_type, const_ptr_actual)) {
4237 return ImplicitCastMatchResultYes;
4238 }
4239 }
42334240
4234 return ImplicitCastMatchResultNo;4241 return ImplicitCastMatchResultNo;
4235}4242}
...@@ -4721,6 +4728,30 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so...@@ -4721,6 +4728,30 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
4721 return result;4728 return result;
4722}4729}
47234730
4731static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) {
4732 if (instr_is_comptime(value)) {
4733 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
4734 if (!val)
4735 return ira->codegen->invalid_instruction;
4736
4737 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec,
4738 source_instr->scope, source_instr->source_node);
4739 const_instruction->base.type_entry = wanted_type;
4740 const_instruction->base.static_value.special = ConstValSpecialStatic;
4741 const_instruction->base.static_value.depends_on_compile_var = val->depends_on_compile_var;
4742 const_instruction->base.static_value.data.x_ptr.base_ptr = val;
4743 const_instruction->base.static_value.data.x_ptr.index = SIZE_MAX;
4744 return &const_instruction->base;
4745 }
4746
4747 if (value->id == IrInstructionIdLoadPtr) {
4748 IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value;
4749 return load_ptr_inst->ptr;
4750 } else {
4751 zig_panic("TODO more ways to cast to const pointer");
4752 }
4753}
4754
4724static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) {4755static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) {
4725 assert(wanted_type->id == TypeTableEntryIdMaybe);4756 assert(wanted_type->id == TypeTableEntryIdMaybe);
4726 assert(instr_is_comptime(value));4757 assert(instr_is_comptime(value));
...@@ -4974,6 +5005,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -4974,6 +5005,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
4974 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);5005 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
4975 }5006 }
49765007
5008 // explicit cast from something to const pointer of it
5009 {
5010 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
5011 if (types_match_const_cast_only(wanted_type, const_ptr_actual)) {
5012 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
5013 }
5014 }
5015
4977 add_node_error(ira->codegen, source_instr->source_node,5016 add_node_error(ira->codegen, source_instr->source_node,
4978 buf_sprintf("invalid cast from type '%s' to '%s'",5017 buf_sprintf("invalid cast from type '%s' to '%s'",
4979 buf_ptr(&actual_type->name),5018 buf_ptr(&actual_type->name),
std/io.zig+1-1
...@@ -82,7 +82,7 @@ pub struct OutStream {...@@ -82,7 +82,7 @@ pub struct OutStream {
8282
83 pub fn write(self: &OutStream, bytes: []const u8) -> %usize {83 pub fn write(self: &OutStream, bytes: []const u8) -> %usize {
84 var src_bytes_left = bytes.len;84 var src_bytes_left = bytes.len;
85 var src_index: @typeOf(bytes.len) = 0;85 var src_index: usize = 0;
86 const dest_space_left = self.buffer.len - self.index;86 const dest_space_left = self.buffer.len - self.index;
8787
88 while (src_bytes_left > 0) {88 while (src_bytes_left > 0) {