Browse Source

Fix `lb_emit_ptr_offset`

gingerBill 3 years ago
parent
commit
8e7c7eeeba
3 changed files with 8 additions and 11 deletions
  1. 1 9
      src/llvm_backend_proc.cpp
  2. 1 1
      src/llvm_backend_utility.cpp
  3. 6 1
      src/types.cpp

+ 1 - 9
src/llvm_backend_proc.cpp

@@ -2077,15 +2077,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 			lbValue ptr = lb_build_expr(p, ce->args[0]);
 			lbValue ptr = lb_build_expr(p, ce->args[0]);
 			lbValue len = lb_build_expr(p, ce->args[1]);
 			lbValue len = lb_build_expr(p, ce->args[1]);
 			len = lb_emit_conv(p, len, t_int);
 			len = lb_emit_conv(p, len, t_int);
-
-			LLVMValueRef indices[1] = {
-				len.value,
-			};
-
-			lbValue res = {};
-			res.type = tv.type;
-			res.value = LLVMBuildGEP2(p->builder, lb_type(p->module, type_deref(tv.type)), ptr.value, indices, gb_count_of(indices), "");
-			return res;
+			return lb_emit_ptr_offset(p, ptr, len);
 		}
 		}
 	case BuiltinProc_ptr_sub:
 	case BuiltinProc_ptr_sub:
 		{
 		{

+ 1 - 1
src/llvm_backend_utility.cpp

@@ -1285,7 +1285,7 @@ lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
 	LLVMValueRef indices[1] = {index.value};
 	LLVMValueRef indices[1] = {index.value};
 	lbValue res = {};
 	lbValue res = {};
 	res.type = ptr.type;
 	res.type = ptr.type;
-	LLVMTypeRef type = lb_type(p->module, type_deref(ptr.type));
+	LLVMTypeRef type = lb_type(p->module, type_deref(res.type, true));
 
 
 	if (lb_is_const(ptr) && lb_is_const(index)) {
 	if (lb_is_const(ptr) && lb_is_const(index)) {
 		res.value = LLVMConstGEP2(type, ptr.value, indices, 1);
 		res.value = LLVMConstGEP2(type, ptr.value, indices, 1);

+ 6 - 1
src/types.cpp

@@ -1115,7 +1115,7 @@ Type *alloc_type_simd_vector(i64 count, Type *elem, Type *generic_count=nullptr)
 ////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////
 
 
 
 
-Type *type_deref(Type *t) {
+Type *type_deref(Type *t, bool allow_multi_pointer=false) {
 	if (t != nullptr) {
 	if (t != nullptr) {
 		Type *bt = base_type(t);
 		Type *bt = base_type(t);
 		if (bt == nullptr) {
 		if (bt == nullptr) {
@@ -1132,6 +1132,11 @@ Type *type_deref(Type *t) {
 				GB_ASSERT(elem->kind == Type_Struct && elem->Struct.soa_kind != StructSoa_None);
 				GB_ASSERT(elem->kind == Type_Struct && elem->Struct.soa_kind != StructSoa_None);
 				return elem->Struct.soa_elem;
 				return elem->Struct.soa_elem;
 			}
 			}
+		case Type_MultiPointer:
+			if (allow_multi_pointer) {
+				return bt->MultiPointer.elem;
+			}
+			break;
 		}
 		}
 	}
 	}
 	return t;
 	return t;