mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-31 05:20:09 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
+2
-2
@@ -532,9 +532,9 @@ gb_internal void report_os_info() {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t major, minor, patch;
|
||||
uint32_t major, minor, patch = 0;
|
||||
|
||||
if (sscanf(cast(const char *)sw_vers, "%u.%u.%u", &major, &minor, &patch) != 3) {
|
||||
if (sscanf(cast(const char *)sw_vers, "%u.%u.%u", &major, &minor, &patch) < 1) {
|
||||
gb_printf("macOS Unknown\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3502,9 +3502,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
case ExactValue_Integer:
|
||||
mp_abs(&operand->value.value_integer, &operand->value.value_integer);
|
||||
break;
|
||||
case ExactValue_Float:
|
||||
operand->value.value_float = gb_abs(operand->value.value_float);
|
||||
case ExactValue_Float: {
|
||||
u64 abs = bit_cast<u64>(operand->value.value_float);
|
||||
abs &= 0x7FFFFFFFFFFFFFFF;
|
||||
operand->value.value_float = bit_cast<f64>(abs);
|
||||
break;
|
||||
}
|
||||
case ExactValue_Complex: {
|
||||
f64 r = operand->value.value_complex->real;
|
||||
f64 i = operand->value.value_complex->imag;
|
||||
@@ -5558,6 +5561,9 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
// NOTE(bill): Is this even correct?
|
||||
new_type->Union.node = operand->expr;
|
||||
new_type->Union.scope = bt->Union.scope;
|
||||
if (bt->Union.kind == UnionType_no_nil) {
|
||||
new_type->Union.kind = UnionType_no_nil;
|
||||
}
|
||||
|
||||
operand->type = new_type;
|
||||
}
|
||||
|
||||
@@ -857,6 +857,7 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
|
||||
} else {
|
||||
String name = ident->Ident.token.string;
|
||||
Entity *found = scope_lookup(ctx->scope, name);
|
||||
|
||||
if (found == nullptr) {
|
||||
if (is_blank_ident(name)) {
|
||||
// NOTE(bill): link against nothing
|
||||
|
||||
+5
-2
@@ -3649,7 +3649,8 @@ gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type
|
||||
gb_string_free(oper_str);
|
||||
gb_string_free(to_type);
|
||||
} else if (is_type_integer(src_t) && is_type_integer(dst_t) &&
|
||||
types_have_same_internal_endian(src_t, dst_t)) {
|
||||
types_have_same_internal_endian(src_t, dst_t) &&
|
||||
type_endian_kind_of(src_t) == type_endian_kind_of(dst_t)) {
|
||||
gbString oper_type = type_to_string(src_t);
|
||||
gbString to_type = type_to_string(dst_t);
|
||||
error(o->expr, "Use of 'transmute' where 'cast' would be preferred since both are integers of the same endianness, from '%s' to '%s'", oper_type, to_type);
|
||||
@@ -10377,7 +10378,7 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no
|
||||
add_type_info_type(c, o->type);
|
||||
o->type = type_hint;
|
||||
o->mode = Addressing_OptionalOk;
|
||||
return kind;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10442,6 +10443,8 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no
|
||||
}
|
||||
}
|
||||
|
||||
end:;
|
||||
|
||||
if ((c->state_flags & StateFlag_no_type_assert) == 0) {
|
||||
add_package_dependency(c, "runtime", "type_assertion_check");
|
||||
add_package_dependency(c, "runtime", "type_assertion_check2");
|
||||
|
||||
+17
-3
@@ -5016,6 +5016,9 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) {
|
||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||
}
|
||||
return true;
|
||||
} else if (name == "export") {
|
||||
ac->is_export = true;
|
||||
return true;
|
||||
} else if (name == "force" || name == "require") {
|
||||
if (value != nullptr) {
|
||||
error(elem, "Expected no parameter for '%.*s'", LIT(name));
|
||||
@@ -5181,14 +5184,21 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||
GB_ASSERT(fl->library_name.pos.line != 0);
|
||||
fl->library_name.string = library_name;
|
||||
|
||||
AttributeContext ac = {};
|
||||
check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac);
|
||||
|
||||
Scope *scope = parent_scope;
|
||||
if (ac.is_export) {
|
||||
scope = parent_scope->parent;
|
||||
}
|
||||
|
||||
Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid,
|
||||
fl->fullpaths, library_name);
|
||||
e->LibraryName.decl = decl;
|
||||
add_entity_flags_from_file(ctx, e, parent_scope);
|
||||
add_entity(ctx, parent_scope, nullptr, e);
|
||||
add_entity(ctx, scope, nullptr, e);
|
||||
|
||||
|
||||
AttributeContext ac = {};
|
||||
check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac);
|
||||
if (ac.require_declaration) {
|
||||
mpsc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e);
|
||||
add_entity_use(ctx, nullptr, e);
|
||||
@@ -6309,6 +6319,10 @@ gb_internal void check_deferred_procedures(Checker *c) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dst_params == nullptr) {
|
||||
error(src->token, "Deferred procedure must have parameters for %s", attribute);
|
||||
continue;
|
||||
}
|
||||
GB_ASSERT(dst_params->kind == Type_Tuple);
|
||||
|
||||
Type *tsrc = alloc_type_tuple();
|
||||
|
||||
+12
-1
@@ -5837,9 +5837,20 @@ gb_inline isize gb_printf_err_va(char const *fmt, va_list va) {
|
||||
}
|
||||
|
||||
gb_inline isize gb_fprintf_va(struct gbFile *f, char const *fmt, va_list va) {
|
||||
gb_local_persist char buf[4096];
|
||||
char buf[4096];
|
||||
isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va);
|
||||
char *new_buf = NULL;
|
||||
isize n = gb_size_of(buf);
|
||||
while (len < 0) {
|
||||
n <<= 1;
|
||||
gb_free(gb_heap_allocator(), new_buf);
|
||||
new_buf = gb_alloc_array(gb_heap_allocator(), char, n);;
|
||||
len = gb_snprintf_va(new_buf, n, fmt, va);
|
||||
}
|
||||
gb_file_write(f, buf, len-1); // NOTE(bill): prevent extra whitespace
|
||||
if (new_buf != NULL) {
|
||||
gb_free(gb_heap_allocator(), new_buf);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,11 +169,17 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) {
|
||||
other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname);
|
||||
if (other_global) {
|
||||
LLVMSetLinkage(other_global, LLVMWeakAnyLinkage);
|
||||
if (!ec.e->Variable.is_export) {
|
||||
LLVMSetVisibility(other_global, LLVMHiddenVisibility);
|
||||
}
|
||||
}
|
||||
} else if (ec.e->kind == Entity_Procedure) {
|
||||
other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname);
|
||||
if (other_global) {
|
||||
LLVMSetLinkage(other_global, LLVMWeakAnyLinkage);
|
||||
if (!ec.e->Procedure.is_export) {
|
||||
LLVMSetVisibility(other_global, LLVMHiddenVisibility);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3364,9 +3364,7 @@ gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
|
||||
auto args = array_make<lbValue>(permanent_allocator(), arg_count);
|
||||
args[0] = ok;
|
||||
|
||||
args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id));
|
||||
args[2] = lb_const_int(p->module, t_i32, pos.line);
|
||||
args[3] = lb_const_int(p->module, t_i32, pos.column);
|
||||
lb_set_file_line_col(p, array_slice(args, 1, args.count), pos);
|
||||
|
||||
if (!build_context.no_rtti) {
|
||||
args[4] = lb_typeid(p->module, src_type);
|
||||
@@ -3393,9 +3391,7 @@ gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 6);
|
||||
args[0] = ok;
|
||||
|
||||
args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id));
|
||||
args[2] = lb_const_int(p->module, t_i32, pos.line);
|
||||
args[3] = lb_const_int(p->module, t_i32, pos.column);
|
||||
lb_set_file_line_col(p, array_slice(args, 1, args.count), pos);
|
||||
|
||||
args[4] = any_id;
|
||||
args[5] = id;
|
||||
|
||||
@@ -15,7 +15,6 @@ gb_global isize lb_global_type_info_member_offsets_index = 0;
|
||||
gb_global isize lb_global_type_info_member_usings_index = 0;
|
||||
gb_global isize lb_global_type_info_member_tags_index = 0;
|
||||
|
||||
|
||||
gb_internal void lb_init_module(lbModule *m, Checker *c) {
|
||||
m->info = &c->info;
|
||||
|
||||
@@ -540,6 +539,22 @@ gb_internal lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) {
|
||||
return lb_addr_get_ptr(p, addr);
|
||||
}
|
||||
|
||||
gb_internal void lb_set_file_line_col(lbProcedure *p, Array<lbValue> arr, TokenPos pos) {
|
||||
String file = get_file_path_string(pos.file_id);
|
||||
i32 line = pos.line;
|
||||
i32 col = pos.column;
|
||||
|
||||
if (build_context.obfuscate_source_code_locations) {
|
||||
file = obfuscate_string(file, "F");
|
||||
line = obfuscate_i32(line);
|
||||
col = obfuscate_i32(col);
|
||||
}
|
||||
|
||||
arr[0] = lb_find_or_add_entity_string(p->module, file);
|
||||
arr[1] = lb_const_int(p->module, t_i32, line);
|
||||
arr[2] = lb_const_int(p->module, t_i32, col);
|
||||
}
|
||||
|
||||
gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue len) {
|
||||
if (build_context.no_bounds_check) {
|
||||
return;
|
||||
@@ -553,14 +568,8 @@ gb_internal void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index
|
||||
index = lb_emit_conv(p, index, t_int);
|
||||
len = lb_emit_conv(p, len, t_int);
|
||||
|
||||
lbValue file = lb_find_or_add_entity_string(p->module, get_file_path_string(token.pos.file_id));
|
||||
lbValue line = lb_const_int(p->module, t_i32, token.pos.line);
|
||||
lbValue column = lb_const_int(p->module, t_i32, token.pos.column);
|
||||
|
||||
auto args = array_make<lbValue>(temporary_allocator(), 5);
|
||||
args[0] = file;
|
||||
args[1] = line;
|
||||
args[2] = column;
|
||||
lb_set_file_line_col(p, args, token.pos);
|
||||
args[3] = index;
|
||||
args[4] = len;
|
||||
|
||||
@@ -582,14 +591,8 @@ gb_internal void lb_emit_matrix_bounds_check(lbProcedure *p, Token token, lbValu
|
||||
row_count = lb_emit_conv(p, row_count, t_int);
|
||||
column_count = lb_emit_conv(p, column_count, t_int);
|
||||
|
||||
lbValue file = lb_find_or_add_entity_string(p->module, get_file_path_string(token.pos.file_id));
|
||||
lbValue line = lb_const_int(p->module, t_i32, token.pos.line);
|
||||
lbValue column = lb_const_int(p->module, t_i32, token.pos.column);
|
||||
|
||||
auto args = array_make<lbValue>(temporary_allocator(), 7);
|
||||
args[0] = file;
|
||||
args[1] = line;
|
||||
args[2] = column;
|
||||
lb_set_file_line_col(p, args, token.pos);
|
||||
args[3] = row_index;
|
||||
args[4] = column_index;
|
||||
args[5] = row_count;
|
||||
@@ -610,14 +613,8 @@ gb_internal void lb_emit_multi_pointer_slice_bounds_check(lbProcedure *p, Token
|
||||
low = lb_emit_conv(p, low, t_int);
|
||||
high = lb_emit_conv(p, high, t_int);
|
||||
|
||||
lbValue file = lb_find_or_add_entity_string(p->module, get_file_path_string(token.pos.file_id));
|
||||
lbValue line = lb_const_int(p->module, t_i32, token.pos.line);
|
||||
lbValue column = lb_const_int(p->module, t_i32, token.pos.column);
|
||||
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 5);
|
||||
args[0] = file;
|
||||
args[1] = line;
|
||||
args[2] = column;
|
||||
lb_set_file_line_col(p, args, token.pos);
|
||||
args[3] = low;
|
||||
args[4] = high;
|
||||
|
||||
@@ -632,16 +629,11 @@ gb_internal void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue
|
||||
return;
|
||||
}
|
||||
|
||||
lbValue file = lb_find_or_add_entity_string(p->module, get_file_path_string(token.pos.file_id));
|
||||
lbValue line = lb_const_int(p->module, t_i32, token.pos.line);
|
||||
lbValue column = lb_const_int(p->module, t_i32, token.pos.column);
|
||||
high = lb_emit_conv(p, high, t_int);
|
||||
|
||||
if (!lower_value_used) {
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 5);
|
||||
args[0] = file;
|
||||
args[1] = line;
|
||||
args[2] = column;
|
||||
lb_set_file_line_col(p, args, token.pos);
|
||||
args[3] = high;
|
||||
args[4] = len;
|
||||
|
||||
@@ -651,9 +643,7 @@ gb_internal void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue
|
||||
low = lb_emit_conv(p, low, t_int);
|
||||
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 6);
|
||||
args[0] = file;
|
||||
args[1] = line;
|
||||
args[2] = column;
|
||||
lb_set_file_line_col(p, args, token.pos);
|
||||
args[3] = low;
|
||||
args[4] = high;
|
||||
args[5] = len;
|
||||
|
||||
@@ -2174,7 +2174,32 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
case 128: return lb_emit_runtime_call(p, "abs_complex128", args);
|
||||
}
|
||||
GB_PANIC("Unknown complex type");
|
||||
} else if (is_type_float(t)) {
|
||||
bool little = is_type_endian_little(t) || (is_type_endian_platform(t) && build_context.endian_kind == TargetEndian_Little);
|
||||
Type *t_unsigned = nullptr;
|
||||
lbValue mask = {0};
|
||||
switch (type_size_of(t)) {
|
||||
case 2:
|
||||
t_unsigned = t_u16;
|
||||
mask = lb_const_int(p->module, t_unsigned, little ? 0x7FFF : 0xFF7F);
|
||||
break;
|
||||
case 4:
|
||||
t_unsigned = t_u32;
|
||||
mask = lb_const_int(p->module, t_unsigned, little ? 0x7FFFFFFF : 0xFFFFFF7F);
|
||||
break;
|
||||
case 8:
|
||||
t_unsigned = t_u64;
|
||||
mask = lb_const_int(p->module, t_unsigned, little ? 0x7FFFFFFFFFFFFFFF : 0xFFFFFFFFFFFFFF7F);
|
||||
break;
|
||||
default:
|
||||
GB_PANIC("abs: unhandled float size");
|
||||
}
|
||||
|
||||
lbValue as_unsigned = lb_emit_transmute(p, x, t_unsigned);
|
||||
lbValue abs = lb_emit_arith(p, Token_And, as_unsigned, mask, t_unsigned);
|
||||
return lb_emit_transmute(p, abs, t);
|
||||
}
|
||||
|
||||
lbValue zero = lb_const_nil(p->module, t);
|
||||
lbValue cond = lb_emit_comp(p, Token_Lt, x, zero);
|
||||
lbValue neg = lb_emit_unary_arith(p, Token_Sub, x, t);
|
||||
|
||||
@@ -771,9 +771,7 @@ gb_internal lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type
|
||||
auto args = array_make<lbValue>(permanent_allocator(), arg_count);
|
||||
args[0] = ok;
|
||||
|
||||
args[1] = lb_const_string(m, get_file_path_string(pos.file_id));
|
||||
args[2] = lb_const_int(m, t_i32, pos.line);
|
||||
args[3] = lb_const_int(m, t_i32, pos.column);
|
||||
lb_set_file_line_col(p, array_slice(args, 1, args.count), pos);
|
||||
|
||||
if (!build_context.no_rtti) {
|
||||
args[4] = lb_typeid(m, src_type);
|
||||
@@ -847,9 +845,7 @@ gb_internal lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *ty
|
||||
auto args = array_make<lbValue>(permanent_allocator(), arg_count);
|
||||
args[0] = ok;
|
||||
|
||||
args[1] = lb_const_string(m, get_file_path_string(pos.file_id));
|
||||
args[2] = lb_const_int(m, t_i32, pos.line);
|
||||
args[3] = lb_const_int(m, t_i32, pos.column);
|
||||
lb_set_file_line_col(p, array_slice(args, 1, args.count), pos);
|
||||
|
||||
if (!build_context.no_rtti) {
|
||||
args[4] = any_typeid;
|
||||
|
||||
@@ -1801,6 +1801,27 @@ gb_internal bool is_type_union_maybe_pointer_original_alignment(Type *t) {
|
||||
}
|
||||
|
||||
|
||||
enum TypeEndianKind {
|
||||
TypeEndian_Platform,
|
||||
TypeEndian_Little,
|
||||
TypeEndian_Big,
|
||||
};
|
||||
|
||||
gb_internal TypeEndianKind type_endian_kind_of(Type *t) {
|
||||
t = core_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
if (t->Basic.flags & BasicFlag_EndianLittle) {
|
||||
return TypeEndian_Little;
|
||||
}
|
||||
if (t->Basic.flags & BasicFlag_EndianBig) {
|
||||
return TypeEndian_Big;
|
||||
}
|
||||
} else if (t->kind == Type_BitSet) {
|
||||
return type_endian_kind_of(bit_set_to_int(t));
|
||||
}
|
||||
return TypeEndian_Platform;
|
||||
}
|
||||
|
||||
|
||||
gb_internal bool is_type_endian_big(Type *t) {
|
||||
t = core_type(t);
|
||||
|
||||
Reference in New Issue
Block a user