diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-11-19 20:29:08 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-11-21 20:43:41 -0500 |
| commit | 47f06be36943f808aa9798c19172363afe6ae35c (patch) | |
| tree | 79ede48ae2cbbbbe2e2489b2733df4e907bfe968 /src/codegen.cpp | |
| parent | 21f344b3b903b41fd4793faa82a4ac26ad2544aa (diff) | |
| download | zig-47f06be36943f808aa9798c19172363afe6ae35c.tar.gz zig-47f06be36943f808aa9798c19172363afe6ae35c.zip | |
string literals are now null terminated
this also deletes C string literals from the language, and then makes
the std lib changes and compiler changes necessary to get the behavior
tests and std lib tests passing again.
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 61 |
1 files changed, 38 insertions, 23 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 5def04575e..4fc3b968c1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -949,7 +949,7 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { if (!val->global_refs->llvm_global) { Buf *buf_msg = panic_msg_buf(msg_id); - ConstExprValue *array_val = create_const_str_lit(g, buf_msg); + ConstExprValue *array_val = create_const_str_lit(g, buf_msg)->data.x_ptr.data.ref.pointee; init_const_slice(g, val, array_val, 0, buf_len(buf_msg), true); render_const_val(g, val, ""); @@ -2784,14 +2784,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, IrInstruction *op1 = bin_op_instruction->op1; IrInstruction *op2 = bin_op_instruction->op2; - assert(op1->value.type == op2->value.type || op_id == IrBinOpBitShiftLeftLossy || - op_id == IrBinOpBitShiftLeftExact || op_id == IrBinOpBitShiftRightLossy || - op_id == IrBinOpBitShiftRightExact || - (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) || - (op1->value.type->id == ZigTypeIdPointer && - (op_id == IrBinOpAdd || op_id == IrBinOpSub) && - op1->value.type->data.pointer.ptr_len != PtrLenSingle) - ); ZigType *operand_type = op1->value.type; ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; @@ -2848,7 +2840,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, AddSubMulMul; if (scalar_type->id == ZigTypeIdPointer) { - assert(scalar_type->data.pointer.ptr_len != PtrLenSingle); LLVMValueRef subscript_value; if (operand_type->id == ZigTypeIdVector) zig_panic("TODO: Implement vector operations on pointers."); @@ -3077,7 +3068,14 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, case CastOpNumLitToConcrete: zig_unreachable(); case CastOpNoop: - return expr_val; + if (actual_type->id == ZigTypeIdPointer && wanted_type->id == ZigTypeIdPointer && + actual_type->data.pointer.child_type->id == ZigTypeIdArray && + wanted_type->data.pointer.child_type->id == ZigTypeIdArray) + { + return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); + } else { + return expr_val; + } case CastOpIntToFloat: assert(actual_type->id == ZigTypeIdInt); if (actual_type->data.integral.is_signed) { @@ -3709,8 +3707,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI array_type = array_type->data.pointer.child_type; } if (safety_check_on) { - LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, - array_type->data.array.len, false); + uint64_t extra_len_from_null = array_type->data.array.is_null_terminated ? 1 : 0; + uint64_t full_len = array_type->data.array.len + extra_len_from_null; + LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, full_len, false); add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end); } if (array_ptr_type->data.pointer.host_int_bytes != 0) { @@ -6637,11 +6636,20 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con ConstExprValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val; assert(array_const_val->type->id == ZigTypeIdArray); if (!type_has_bits(array_const_val->type)) { - // make this a null pointer - ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), - get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + if (array_const_val->type->data.array.is_null_terminated) { + ConstExprValue *pointee = get_null_value(array_const_val->type->data.array.child_type); + render_const_val(g, pointee, ""); + render_const_val_global(g, pointee, ""); + const_val->global_refs->llvm_value = LLVMConstBitCast(pointee->global_refs->llvm_global, + get_llvm_type(g, const_val->type)); + return const_val->global_refs->llvm_value; + } else { + // make this a null pointer + ZigType *usize = g->builtin_types.entry_usize; + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + get_llvm_type(g, const_val->type)); + return const_val->global_refs->llvm_value; + } } size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index); @@ -6955,7 +6963,9 @@ check: switch (const_val->special) { case ConstArraySpecialUndef: return LLVMGetUndef(get_llvm_type(g, type_entry)); case ConstArraySpecialNone: { - LLVMValueRef *values = allocate<LLVMValueRef>(len); + uint64_t extra_len_from_null = type_entry->data.array.is_null_terminated ? 1 : 0; + uint64_t full_len = len + extra_len_from_null; + LLVMValueRef *values = allocate<LLVMValueRef>(full_len); LLVMTypeRef element_type_ref = get_llvm_type(g, type_entry->data.array.child_type); bool make_unnamed_struct = false; for (uint64_t i = 0; i < len; i += 1) { @@ -6964,15 +6974,19 @@ check: switch (const_val->special) { values[i] = val; make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, elem_value->type, val); } + if (type_entry->data.array.is_null_terminated) { + values[len] = LLVMConstNull(element_type_ref); + } if (make_unnamed_struct) { - return LLVMConstStruct(values, len, true); + return LLVMConstStruct(values, full_len, true); } else { - return LLVMConstArray(element_type_ref, values, (unsigned)len); + return LLVMConstArray(element_type_ref, values, (unsigned)full_len); } } case ConstArraySpecialBuf: { Buf *buf = const_val->data.x_array.data.s_buf; - return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true); + return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), + !type_entry->data.array.is_null_terminated); } } zig_unreachable(); @@ -9092,7 +9106,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { this_val->data.x_struct.fields = alloc_const_vals_ptrs(2); ConstExprValue *name_field = this_val->data.x_struct.fields[0]; - ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name); + ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true); ConstExprValue *fn_field = this_val->data.x_struct.fields[1]; @@ -10415,6 +10429,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget g->external_prototypes.init(8); g->string_literals_table.init(16); g->type_info_cache.init(32); + g->one_possible_values.init(32); g->is_test_build = is_test_build; g->is_single_threaded = false; buf_resize(&g->global_asm, 0); |
