diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-01-16 12:42:46 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-01-16 12:42:46 -0500 |
| commit | 4cbeb87e83135e0a1ecbfb90170761ad6e5adb7a (patch) | |
| tree | b95b6e7a7723280c7f9ae7be17ff748f4f2cfaa0 /src | |
| parent | c7591736b4ae3aed90f6980b4cb23a4dab21d925 (diff) | |
| download | zig-4cbeb87e83135e0a1ecbfb90170761ad6e5adb7a.tar.gz zig-4cbeb87e83135e0a1ecbfb90170761ad6e5adb7a.zip | |
fix handling of const values for 2d arrays
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 5 | ||||
| -rw-r--r-- | src/codegen.cpp | 33 | ||||
| -rw-r--r-- | src/ir.cpp | 9 |
3 files changed, 36 insertions, 11 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index bd322d114c..e9c2118f68 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -81,6 +81,11 @@ struct ConstArrayValue { // This will be the same as `len` from the type, but we duplicate the information // in the constant value so that pointers pointing to arrays can see this size. size_t size; + // If the data for this array is supposed to be contained in a different constant + // value, we link to the parent here. This way getting a pointer to this constant + // value can return a pointer into the parent data structure. + ConstExprValue *parent_array; + size_t parent_array_index; }; enum ConstPtrSpecial { diff --git a/src/codegen.cpp b/src/codegen.cpp index ebaa1b4c07..35039b9418 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2412,6 +2412,25 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) { } } +static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) { + ConstExprValue *parent_array = array_const_val->data.x_array.parent_array; + LLVMValueRef base_ptr; + if (parent_array) { + size_t parent_array_index = array_const_val->data.x_array.parent_array_index; + base_ptr = gen_const_ptr_array_recursive(g, parent_array, parent_array_index); + } else { + render_const_val(g, array_const_val); + render_const_val_global(g, array_const_val); + base_ptr = array_const_val->llvm_global; + } + TypeTableEntry *usize = g->builtin_types.entry_usize; + LLVMValueRef indices[] = { + LLVMConstNull(usize->type_ref), + LLVMConstInt(usize->type_ref, index, false), + }; + return LLVMConstInBoundsGEP(base_ptr, indices, 2); +} + static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { TypeTableEntry *canon_type = get_underlying_type(const_val->type); assert(!canon_type->zero_bits); @@ -2554,7 +2573,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { render_const_val_global(g, const_val); size_t index = const_val->data.x_ptr.index; ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr; - TypeTableEntry *usize = g->builtin_types.entry_usize; if (base_ptr) { if (index == SIZE_MAX) { render_const_val(g, base_ptr); @@ -2568,25 +2586,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { assert(array_const_val->type->id == TypeTableEntryIdArray); if (array_const_val->type->zero_bits) { // make this a null pointer - TypeTableEntry *usize_type = g->builtin_types.entry_usize; - const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref), + TypeTableEntry *usize = g->builtin_types.entry_usize; + const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), const_val->type->type_ref); render_const_val_global(g, const_val); return const_val->llvm_value; } - render_const_val(g, array_const_val); - render_const_val_global(g, array_const_val); - LLVMValueRef indices[] = { - LLVMConstNull(usize->type_ref), - LLVMConstInt(usize->type_ref, index, false), - }; - LLVMValueRef uncasted_ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2); + LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, index); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); const_val->llvm_value = ptr_val; render_const_val_global(g, const_val); return ptr_val; } } else { + TypeTableEntry *usize = g->builtin_types.entry_usize; const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref); render_const_val_global(g, const_val); return const_val->llvm_value; diff --git a/src/ir.cpp b/src/ir.cpp index 60c5f8b85c..98d56de989 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8314,7 +8314,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc return ira->codegen->builtin_types.entry_invalid; bool safety_check_on = elem_ptr_instruction->safety_check_on; - if (casted_elem_index->value.special != ConstValSpecialRuntime) { + if (instr_is_comptime(casted_elem_index)) { uint64_t index = casted_elem_index->value.data.x_bignum.data.x_uint; if (array_type->id == TypeTableEntryIdArray) { uint64_t array_len = array_type->data.array.len; @@ -9923,6 +9923,13 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira if (const_val.special == ConstValSpecialStatic) { ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, const_val.depends_on_compile_var); *out_val = const_val; + for (size_t i = 0; i < elem_count; i += 1) { + ConstExprValue *elem_val = &out_val->data.x_array.elements[i]; + if (elem_val->type->id == TypeTableEntryIdArray) { + elem_val->data.x_array.parent_array = out_val; + elem_val->data.x_array.parent_array_index = i; + } + } return fixed_size_array_type; } |
