mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-23 07:57:52 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
+1
-1
@@ -251,7 +251,7 @@ gb_internal void report_ram_info() {
|
||||
int result = sysinfo(&info);
|
||||
|
||||
if (result == 0x0) {
|
||||
gb_printf("%lu MiB\n", info.totalram * info.mem_unit / gb_megabytes(1));
|
||||
gb_printf("%lu MiB\n", (unsigned long)(info.totalram * info.mem_unit / gb_megabytes(1)));
|
||||
} else {
|
||||
gb_printf("Unknown.\n");
|
||||
}
|
||||
|
||||
+11
-9
@@ -978,7 +978,7 @@ gb_global TargetMetrics target_linux_arm32 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_arm32,
|
||||
4, 4, 4, 8,
|
||||
str_lit("arm-linux-gnu"),
|
||||
str_lit("arm-unknown-linux-gnueabihf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_darwin_amd64 = {
|
||||
@@ -1906,6 +1906,16 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
#else
|
||||
metrics = &target_linux_amd64;
|
||||
#endif
|
||||
#elif defined(GB_CPU_ARM)
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#error "Build Error: Unsupported architecture"
|
||||
#elif defined(GB_SYSTEM_OSX)
|
||||
#error "Build Error: Unsupported architecture"
|
||||
#elif defined(GB_SYSTEM_FREEBSD)
|
||||
#error "Build Error: Unsupported architecture"
|
||||
#else
|
||||
metrics = &target_linux_arm32;
|
||||
#endif
|
||||
#else
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
metrics = &target_windows_i386;
|
||||
@@ -2052,14 +2062,6 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
|
||||
if (bc->metrics.os == TargetOs_freestanding) {
|
||||
bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR = !bc->ODIN_DEFAULT_TO_PANIC_ALLOCATOR;
|
||||
} else if (is_arch_wasm()) {
|
||||
if (bc->metrics.os == TargetOs_js || bc->metrics.os == TargetOs_wasi) {
|
||||
// TODO(bill): Should these even have a default "heap-like" allocator?
|
||||
}
|
||||
|
||||
if (!bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR && !bc->ODIN_DEFAULT_TO_PANIC_ALLOCATOR) {
|
||||
bc->ODIN_DEFAULT_TO_PANIC_ALLOCATOR = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+35
-1
@@ -1092,7 +1092,13 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String
|
||||
|
||||
BlockingMutex *ignore_mutex = nullptr;
|
||||
bool ok = determine_path_from_string(ignore_mutex, call, base_dir, original_string, &path);
|
||||
gb_unused(ok);
|
||||
if (!ok) {
|
||||
if (err_on_not_found) {
|
||||
error(ce->proc, "Failed to `#%.*s` file: %.*s; invalid file or cannot be found", LIT(builtin_name), LIT(original_string));
|
||||
}
|
||||
call->state_flags |= StateFlag_DirectiveWasFalse;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MUTEX_GUARD(&c->info->load_file_mutex);
|
||||
@@ -5235,6 +5241,34 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
operand->type = t_untyped_bool;
|
||||
break;
|
||||
|
||||
|
||||
case BuiltinProc_type_is_matrix_row_major:
|
||||
case BuiltinProc_type_is_matrix_column_major:
|
||||
{
|
||||
Operand op = {};
|
||||
Type *bt = check_type(c, ce->args[0]);
|
||||
Type *type = base_type(bt);
|
||||
if (type == nullptr || type == t_invalid) {
|
||||
error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
if (type->kind != Type_Matrix) {
|
||||
gbString s = type_to_string(bt);
|
||||
error(ce->args[0], "Expected a matrix type for '%.*s', got '%s'", LIT(builtin_name), s);
|
||||
gb_string_free(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id == BuiltinProc_type_is_matrix_row_major) {
|
||||
operand->value = exact_value_bool(bt->Matrix.is_row_major == true);
|
||||
} else {
|
||||
operand->value = exact_value_bool(bt->Matrix.is_row_major == false);
|
||||
}
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->type = t_untyped_bool;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_type_has_field:
|
||||
{
|
||||
Operand op = {};
|
||||
|
||||
+55
-6
@@ -1179,15 +1179,59 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
|
||||
LIT(context_name));
|
||||
check_assignment_error_suggestion(c, operand, type);
|
||||
|
||||
Type *src = base_type(operand->type);
|
||||
Type *dst = base_type(type);
|
||||
if (context_name == "procedure argument") {
|
||||
Type *src = base_type(operand->type);
|
||||
Type *dst = base_type(type);
|
||||
if (is_type_slice(src) && are_types_identical(src->Slice.elem, dst)) {
|
||||
gbString a = expr_to_string(operand->expr);
|
||||
error_line("\tSuggestion: Did you mean to pass the slice into the variadic parameter with ..%s?\n\n", a);
|
||||
gb_string_free(a);
|
||||
}
|
||||
}
|
||||
if (src->kind == dst->kind && src->kind == Type_Proc) {
|
||||
Type *x = src;
|
||||
Type *y = dst;
|
||||
bool same_inputs = are_types_identical_internal(x->Proc.params, y->Proc.params, false);
|
||||
bool same_outputs = are_types_identical_internal(x->Proc.results, y->Proc.results, false);
|
||||
if (same_inputs && same_outputs &&
|
||||
x->Proc.calling_convention != y->Proc.calling_convention) {
|
||||
gbString s_expected = type_to_string(y);
|
||||
gbString s_got = type_to_string(x);
|
||||
|
||||
error_line("\tNote: The calling conventions differ between the procedure signature types\n");
|
||||
error_line("\t Expected \"%s\", got \"%s\"\n",
|
||||
proc_calling_convention_strings[y->Proc.calling_convention],
|
||||
proc_calling_convention_strings[x->Proc.calling_convention]);
|
||||
error_line("\t Expected: %s\n", s_expected);
|
||||
error_line("\t Got: %s\n", s_got);
|
||||
gb_string_free(s_got);
|
||||
gb_string_free(s_expected);
|
||||
} else if (same_inputs && !same_outputs) {
|
||||
gbString s_expected = type_to_string(y->Proc.results);
|
||||
gbString s_got = type_to_string(x->Proc.results);
|
||||
error_line("\tNote: The return types differ between the procedure signature types\n");
|
||||
error_line("\t Expected: %s\n", s_expected);
|
||||
error_line("\t Got: %s\n", s_got);
|
||||
gb_string_free(s_got);
|
||||
gb_string_free(s_expected);
|
||||
} else if (!same_inputs && same_outputs) {
|
||||
gbString s_expected = type_to_string(y->Proc.params);
|
||||
gbString s_got = type_to_string(x->Proc.params);
|
||||
error_line("\tNote: The input parameter types differ between the procedure signature types\n");
|
||||
error_line("\t Expected: %s\n", s_expected);
|
||||
error_line("\t Got: %s\n", s_got);
|
||||
gb_string_free(s_got);
|
||||
gb_string_free(s_expected);
|
||||
} else {
|
||||
gbString s_expected = type_to_string(y);
|
||||
gbString s_got = type_to_string(x);
|
||||
error_line("\tNote: The signature type do not match whatsoever\n");
|
||||
error_line("\t Expected: %s\n", s_expected);
|
||||
error_line("\t Got: %s\n", s_got);
|
||||
gb_string_free(s_got);
|
||||
gb_string_free(s_expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1761,7 +1805,7 @@ gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *nam
|
||||
|
||||
case Entity_ImportName:
|
||||
if (!allow_import_name) {
|
||||
error(n, "Use of import '%.*s' not in selector", LIT(name));
|
||||
error(n, "Use of import name '%.*s' not in the form of 'x.y'", LIT(name));
|
||||
}
|
||||
return e;
|
||||
case Entity_LibraryName:
|
||||
@@ -7757,13 +7801,18 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64
|
||||
return true;
|
||||
|
||||
case Type_Matrix:
|
||||
*max_count = t->Matrix.column_count;
|
||||
if (indirection) {
|
||||
o->mode = Addressing_Variable;
|
||||
} else if (o->mode != Addressing_Variable) {
|
||||
o->mode = Addressing_Value;
|
||||
}
|
||||
o->type = alloc_type_array(t->Matrix.elem, t->Matrix.row_count);
|
||||
if (t->Matrix.is_row_major) {
|
||||
*max_count = t->Matrix.row_count;
|
||||
o->type = alloc_type_array(t->Matrix.elem, t->Matrix.column_count);
|
||||
} else {
|
||||
*max_count = t->Matrix.column_count;
|
||||
o->type = alloc_type_array(t->Matrix.elem, t->Matrix.row_count);
|
||||
}
|
||||
return true;
|
||||
|
||||
case Type_Slice:
|
||||
@@ -10159,7 +10208,7 @@ gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node,
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = node;
|
||||
return kind;
|
||||
} else if (ok) {
|
||||
} else if (ok && !is_type_matrix(t)) {
|
||||
ExactValue value = type_and_value_of_expr(ie->expr).value;
|
||||
o->mode = Addressing_Constant;
|
||||
bool success = false;
|
||||
|
||||
+7
-2
@@ -565,7 +565,11 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
|
||||
} else {
|
||||
error(lhs->expr, "Cannot assign to '%s' which is a procedure parameter", str);
|
||||
}
|
||||
error_line("\tSuggestion: Did you mean to pass '%.*s' by pointer?\n", LIT(e->token.string));
|
||||
if (is_type_pointer(e->type)) {
|
||||
error_line("\tSuggestion: Did you mean to shadow it? '%.*s := %.*s'?\n", LIT(e->token.string), LIT(e->token.string));
|
||||
} else {
|
||||
error_line("\tSuggestion: Did you mean to pass '%.*s' by pointer?\n", LIT(e->token.string));
|
||||
}
|
||||
show_error_on_line(e->token.pos, token_pos_end(e->token));
|
||||
} else {
|
||||
ERROR_BLOCK();
|
||||
@@ -1663,6 +1667,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
bool is_ptr = type_deref(operand.type);
|
||||
Type *t = base_type(type_deref(operand.type));
|
||||
|
||||
switch (t->kind) {
|
||||
@@ -1707,7 +1712,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
break;
|
||||
|
||||
case Type_Array:
|
||||
is_possibly_addressable = operand.mode == Addressing_Variable;
|
||||
is_possibly_addressable = operand.mode == Addressing_Variable || is_ptr;
|
||||
array_add(&vals, t->Array.elem);
|
||||
array_add(&vals, t_int);
|
||||
break;
|
||||
|
||||
+1
-1
@@ -1595,7 +1595,7 @@ gb_internal bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
|
||||
return is_expr_from_a_parameter(ctx, lhs);
|
||||
} else if (expr->kind == Ast_Ident) {
|
||||
Operand x= {};
|
||||
Entity *e = check_ident(ctx, &x, expr, nullptr, nullptr, false);
|
||||
Entity *e = check_ident(ctx, &x, expr, nullptr, nullptr, true);
|
||||
if (e->flags & EntityFlag_Param) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2645,6 +2645,10 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||
str_lit("memmove"),
|
||||
);
|
||||
|
||||
FORCE_ADD_RUNTIME_ENTITIES(build_context.metrics.arch == TargetArch_arm32,
|
||||
str_lit("aeabi_d2h")
|
||||
);
|
||||
|
||||
FORCE_ADD_RUNTIME_ENTITIES(is_arch_wasm() && !build_context.tilde_backend,
|
||||
// // Extended data type internal procedures
|
||||
// str_lit("umodti3"),
|
||||
|
||||
@@ -256,6 +256,9 @@ BuiltinProc__type_simple_boolean_begin,
|
||||
|
||||
BuiltinProc__type_simple_boolean_end,
|
||||
|
||||
BuiltinProc_type_is_matrix_row_major,
|
||||
BuiltinProc_type_is_matrix_column_major,
|
||||
|
||||
BuiltinProc_type_has_field,
|
||||
BuiltinProc_type_field_type,
|
||||
|
||||
@@ -567,6 +570,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("type_has_nil"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("type_is_matrix_row_major"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("type_is_matrix_column_major"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("type_has_field"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("type_field_type"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
|
||||
+4
-3
@@ -6261,11 +6261,12 @@ gb_no_inline isize gb_snprintf_va(char *text, isize max_len, char const *fmt, va
|
||||
#elif defined(__aarch64__)
|
||||
gb_inline u64 gb_rdtsc(void) {
|
||||
int64_t virtual_timer_value;
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
|
||||
return virtual_timer_value;
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
|
||||
return virtual_timer_value;
|
||||
}
|
||||
#else
|
||||
#error "gb_rdtsc not supported"
|
||||
#warning "gb_rdtsc not supported"
|
||||
gb_inline u64 gb_rdtsc(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
|
||||
@@ -2384,9 +2384,10 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
|
||||
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);
|
||||
ptr0 = lb_emit_conv(p, ptr0, t_int);
|
||||
ptr1 = lb_emit_conv(p, ptr1, t_int);
|
||||
|
||||
lbValue diff = lb_emit_arith(p, Token_Sub, ptr0, ptr1, t_uintptr);
|
||||
diff = lb_emit_conv(p, diff, t_int);
|
||||
lbValue diff = lb_emit_arith(p, Token_Sub, ptr0, ptr1, t_int);
|
||||
return lb_emit_arith(p, Token_Quo, diff, lb_const_int(p->module, t_int, type_size_of(elem)), t_int);
|
||||
}
|
||||
|
||||
@@ -2903,7 +2904,6 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
break;
|
||||
case TargetArch_arm32:
|
||||
{
|
||||
// TODO(bill): Check this is correct
|
||||
GB_ASSERT(arg_count <= 7);
|
||||
|
||||
char asm_string[] = "svc #0";
|
||||
@@ -2911,13 +2911,14 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
constraints = gb_string_appendc(constraints, ",{");
|
||||
static char const *regs[] = {
|
||||
"r8",
|
||||
"r7",
|
||||
"r0",
|
||||
"r1",
|
||||
"r2",
|
||||
"r3",
|
||||
"r4",
|
||||
"r5",
|
||||
"r6",
|
||||
};
|
||||
constraints = gb_string_appendc(constraints, regs[i]);
|
||||
constraints = gb_string_appendc(constraints, "}");
|
||||
|
||||
@@ -2223,8 +2223,8 @@ gb_internal LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &
|
||||
GB_ASSERT(value.kind == ExactValue_Integer);
|
||||
i64 v = exact_value_to_i64(value);
|
||||
switch (v) {
|
||||
case OdinAtomicMemoryOrder_relaxed: return LLVMAtomicOrderingUnordered;
|
||||
case OdinAtomicMemoryOrder_consume: return LLVMAtomicOrderingMonotonic;
|
||||
case OdinAtomicMemoryOrder_relaxed: return LLVMAtomicOrderingMonotonic;
|
||||
case OdinAtomicMemoryOrder_consume: return LLVMAtomicOrderingAcquire;
|
||||
case OdinAtomicMemoryOrder_acquire: return LLVMAtomicOrderingAcquire;
|
||||
case OdinAtomicMemoryOrder_release: return LLVMAtomicOrderingRelease;
|
||||
case OdinAtomicMemoryOrder_acq_rel: return LLVMAtomicOrderingAcquireRelease;
|
||||
|
||||
+8
-2
@@ -3499,8 +3499,14 @@ gb_internal Array<Ast *> parse_ident_list(AstFile *f, bool allow_poly_names) {
|
||||
gb_internal Ast *parse_type(AstFile *f) {
|
||||
Ast *type = parse_type_or_ident(f);
|
||||
if (type == nullptr) {
|
||||
Token token = advance_token(f);
|
||||
syntax_error(token, "Expected a type");
|
||||
Token prev_token = f->curr_token;
|
||||
Token token = {};
|
||||
if (f->curr_token.kind == Token_OpenBrace) {
|
||||
token = f->curr_token;
|
||||
} else {
|
||||
token = advance_token(f);
|
||||
}
|
||||
syntax_error(token, "Expected a type, got '%.*s'", LIT(prev_token.string));
|
||||
return ast_bad_expr(f, token, f->curr_token);
|
||||
} else if (type->kind == Ast_ParenExpr &&
|
||||
unparen_expr(type) == nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user