Browse Source

Merge branch 'master' into map-dev

gingerBill 2 years ago
parent
commit
2b83f27f06
4 changed files with 36 additions and 26 deletions
  1. 17 17
      core/container/small_array/small_array.odin
  2. 7 0
      src/check_builtin.cpp
  3. 9 9
      src/llvm_backend_proc.cpp
  4. 3 0
      src/types.cpp

+ 17 - 17
core/container/small_array/small_array.odin

@@ -8,40 +8,40 @@ Small_Array :: struct($N: int, $T: typeid) where N >= 0 {
 }
 
 
-len :: proc(a: $A/Small_Array) -> int {
+len :: proc "contextless" (a: $A/Small_Array) -> int {
 	return a.len
 }
 
-cap :: proc(a: $A/Small_Array) -> int {
+cap :: proc "contextless" (a: $A/Small_Array) -> int {
 	return builtin.len(a.data)
 }
 
-space :: proc(a: $A/Small_Array) -> int {
+space :: proc "contextless" (a: $A/Small_Array) -> int {
 	return builtin.len(a.data) - a.len
 }
 
-slice :: proc(a: ^$A/Small_Array($N, $T)) -> []T {
+slice :: proc "contextless" (a: ^$A/Small_Array($N, $T)) -> []T {
 	return a.data[:a.len]
 }
 
 
-get :: proc(a: $A/Small_Array($N, $T), index: int) -> T {
+get :: proc "contextless" (a: $A/Small_Array($N, $T), index: int) -> T {
 	return a.data[index]
 }
-get_ptr :: proc(a: ^$A/Small_Array($N, $T), index: int) -> ^T {
+get_ptr :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int) -> ^T {
 	return &a.data[index]
 }
 
-set :: proc(a: ^$A/Small_Array($N, $T), index: int, item: T) {
+set :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int, item: T) {
 	a.data[index] = item
 }
 
-resize :: proc(a: ^$A/Small_Array, length: int) {
+resize :: proc "contextless" (a: ^$A/Small_Array, length: int) {
 	a.len = min(length, builtin.len(a.data))
 }
 
 
-push_back :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
+push_back :: proc "contextless" (a: ^$A/Small_Array($N, $T), item: T) -> bool {
 	if a.len < cap(a^) {
 		a.data[a.len] = item
 		a.len += 1
@@ -50,7 +50,7 @@ push_back :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
 	return false
 }
 
-push_front :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
+push_front :: proc "contextless" (a: ^$A/Small_Array($N, $T), item: T) -> bool {
 	if a.len < cap(a^) {
 		a.len += 1
 		data := slice(a)
@@ -61,14 +61,14 @@ push_front :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool {
 	return false
 }
 
-pop_back :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
+pop_back :: proc "odin" (a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
 	assert(condition=(N > 0 && a.len > 0), loc=loc)
 	item := a.data[a.len-1]
 	a.len -= 1
 	return item
 }
 
-pop_front :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
+pop_front :: proc "odin" (a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
 	assert(condition=(N > 0 && a.len > 0), loc=loc)
 	item := a.data[0]
 	s := slice(a)
@@ -77,7 +77,7 @@ pop_front :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T {
 	return item
 }
 
-pop_back_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
+pop_back_safe :: proc "contextless" (a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
 	if N > 0 && a.len > 0 {
 		item = a.data[a.len-1]
 		a.len -= 1
@@ -86,7 +86,7 @@ pop_back_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
 	return
 }
 
-pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
+pop_front_safe :: proc "contextless" (a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
 	if N > 0 && a.len > 0 {
 		item = a.data[0]
 		s := slice(a)
@@ -97,16 +97,16 @@ pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) {
 	return
 }
 
-consume :: proc(a: ^$A/Small_Array($N, $T), count: int, loc := #caller_location) {
+consume :: proc "odin" (a: ^$A/Small_Array($N, $T), count: int, loc := #caller_location) {
 	assert(condition=a.len >= count, loc=loc)
 	a.len -= count
 }
 
-clear :: proc(a: ^$A/Small_Array($N, $T)) {
+clear :: proc "contextless" (a: ^$A/Small_Array($N, $T)) {
 	resize(a, 0)
 }
 
-push_back_elems :: proc(a: ^$A/Small_Array($N, $T), items: ..T) {
+push_back_elems :: proc "contextless" (a: ^$A/Small_Array($N, $T), items: ..T) {
 	n := copy(a.data[a.len:], items[:])
 	a.len += n
 }

+ 7 - 0
src/check_builtin.cpp

@@ -4182,6 +4182,13 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 				return false;
 			}
 
+			Type *elem = type_deref(ptr0.type);
+			if (type_size_of(elem) == 0) {
+				gbString str = type_to_string(ptr0.type);
+				error(ptr0.expr, "Expected a pointer to a non-zero sized element for '%.*s', got %s", LIT(builtin_name), str);
+				gb_string_free(str);
+				return false
+			}
 		}
 		break;
 

+ 9 - 9
src/llvm_backend_proc.cpp

@@ -2125,17 +2125,17 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 		}
 	case BuiltinProc_ptr_sub:
 		{
-			lbValue ptr0 = lb_build_expr(p, ce->args[0]);
-			lbValue ptr1 = lb_build_expr(p, ce->args[1]);
+			Type *elem0 = type_deref(type_of_expr(ce->args[0]));
+			Type *elem1 = type_deref(type_of_expr(ce->args[1]));
+			GB_ASSERT(are_types_identical(elem0, elem1));
+			Type *elem = elem0;
 
-			LLVMTypeRef type_int = lb_type(p->module, t_int);
-			LLVMValueRef diff = LLVMBuildPtrDiff2(p->builder, lb_type(p->module, ptr0.type), ptr0.value, ptr1.value, "");
-			diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
+			lbValue ptr0 = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr);
+			lbValue ptr1 = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_uintptr);
 
-			lbValue res = {};
-			res.type = t_int;
-			res.value = diff;
-			return res;
+			lbValue diff = lb_emit_arith(p, Token_Sub, ptr0, ptr1, t_uintptr);
+			diff = lb_emit_conv(p, diff, t_int);
+			return lb_emit_arith(p, Token_Quo, diff, lb_const_int(p->module, t_int, type_size_of(elem)), t_int);
 		}
 
 

+ 3 - 0
src/types.cpp

@@ -1260,6 +1260,9 @@ bool is_type_typed(Type *t) {
 }
 bool is_type_untyped(Type *t) {
 	t = base_type(t);
+	if (t == nullptr) {
+		return false;
+	}
 	if (t->kind == Type_Basic) {
 		return (t->Basic.flags & BasicFlag_Untyped) != 0;
 	}