diff options
| author | gingerBill <bill@gingerbill.org> | 2021-08-21 23:10:21 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-08-21 23:10:21 +0100 |
| commit | 6a77fc4cdd35b2ecd1c32f7c5f2e249d6e225d91 (patch) | |
| tree | da479dcee4640fa3a21b440478644f7c67206bfc /src/llvm_backend_expr.cpp | |
| parent | 01a888fcedbdcfa4bd86de6e3346104cad8faa8a (diff) | |
Add multi-pointer types `[^]T`
Diffstat (limited to 'src/llvm_backend_expr.cpp')
| -rw-r--r-- | src/llvm_backend_expr.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index c598fbf62..27517f7a3 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1274,6 +1274,25 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), ""); return res; } + if (is_type_multi_pointer(src) && is_type_pointer(dst)) { + lbValue res = {}; + res.type = t; + res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), ""); + return res; + } + if (is_type_pointer(src) && is_type_multi_pointer(dst)) { + lbValue res = {}; + res.type = t; + res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), ""); + return res; + } + if (is_type_multi_pointer(src) && is_type_multi_pointer(dst)) { + lbValue res = {}; + res.type = t; + res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), ""); + return res; + } + @@ -2838,6 +2857,21 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { return lb_addr(v); } + case Type_MultiPointer: { + lbValue multi_ptr = {}; + multi_ptr = lb_build_expr(p, ie->expr); + if (deref) { + multi_ptr = lb_emit_load(p, multi_ptr); + } + lbValue index = lb_build_expr(p, ie->index); + lbValue v = {}; + + LLVMValueRef indices[1] = {index.value}; + v.value = LLVMBuildGEP(p->builder, multi_ptr.value, indices, 1, ""); + v.type = t; + return lb_addr(v); + } + case Type_RelativeSlice: { lbAddr slice_addr = {}; if (deref) { @@ -2952,6 +2986,27 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { return slice; } + case Type_MultiPointer: { + lbAddr res = lb_add_local_generated(p, type_of_expr(expr), false); + if (se->high == nullptr) { + lbValue offset = base; + LLVMValueRef indices[1] = {low.value}; + offset.value = LLVMBuildGEP(p->builder, offset.value, indices, 1, ""); + lb_addr_store(p, res, offset); + } else { + lb_emit_multi_pointer_slice_bounds_check(p, se->open, low, high); + + LLVMValueRef indices[1] = {low.value}; + LLVMValueRef ptr = LLVMBuildGEP(p->builder, base.value, indices, 1, ""); + LLVMValueRef len = LLVMBuildSub(p->builder, high.value, low.value, ""); + // TODO(bill): bounds_check for negative length + LLVMValueRef gep0 = lb_emit_struct_ep(p, res.addr, 0).value; + LLVMValueRef gep1 = lb_emit_struct_ep(p, res.addr, 1).value; + LLVMBuildStore(p->builder, ptr, gep0); + LLVMBuildStore(p->builder, len, gep1); + } + return res; + } case Type_Array: { Type *slice_type = alloc_type_slice(type->Array.elem); |