Merge remote-tracking branch 'offical/master'

This commit is contained in:
ed
2025-01-30 14:36:46 -05:00
126 changed files with 2481 additions and 1004 deletions
+4 -1
View File
@@ -251,7 +251,10 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
exp *= 10;
exp += v;
}
big_int_exp_u64(dst, &b, exp, success);
BigInt tmp = {};
mp_init(&tmp);
big_int_exp_u64(&tmp, &b, exp, success);
big_int_mul_eq(dst, &tmp);
}
if (is_negative) {
+26 -4
View File
@@ -472,6 +472,7 @@ struct BuildContext {
bool ignore_microsoft_magic;
bool linker_map_file;
bool use_single_module;
bool use_separate_modules;
bool module_per_file;
bool cached;
@@ -1719,13 +1720,15 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
bc->optimization_level = gb_clamp(bc->optimization_level, -1, 3);
#if defined(GB_SYSTEM_WINDOWS)
if (bc->optimization_level <= 0) {
if (!is_arch_wasm()) {
bc->use_separate_modules = true;
}
}
#endif
if (build_context.use_single_module) {
bc->use_separate_modules = false;
}
// TODO: Static map calls are bugged on `amd64sysv` abi.
@@ -2124,6 +2127,7 @@ gb_internal bool init_build_paths(String init_filename) {
}
}
bool no_crt_checks_failed = false;
if (build_context.no_crt && !build_context.ODIN_DEFAULT_TO_NIL_ALLOCATOR && !build_context.ODIN_DEFAULT_TO_PANIC_ALLOCATOR) {
switch (build_context.metrics.os) {
case TargetOs_linux:
@@ -2133,11 +2137,29 @@ gb_internal bool init_build_paths(String init_filename) {
case TargetOs_openbsd:
case TargetOs_netbsd:
case TargetOs_haiku:
gb_printf_err("-no-crt on unix systems requires either -default-to-nil-allocator or -default-to-panic-allocator to also be present because the default allocator requires crt\n");
return false;
gb_printf_err("-no-crt on Unix systems requires either -default-to-nil-allocator or -default-to-panic-allocator to also be present, because the default allocator requires CRT\n");
no_crt_checks_failed = true;
}
}
if (build_context.no_crt && !build_context.no_thread_local) {
switch (build_context.metrics.os) {
case TargetOs_linux:
case TargetOs_darwin:
case TargetOs_essence:
case TargetOs_freebsd:
case TargetOs_openbsd:
case TargetOs_netbsd:
case TargetOs_haiku:
gb_printf_err("-no-crt on Unix systems requires the -no-thread-local flag to also be present, because the TLS is inaccessible without CRT\n");
no_crt_checks_failed = true;
}
}
if (no_crt_checks_failed) {
return false;
}
return true;
}
+1 -1
View File
@@ -60,7 +60,7 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o
error(operand->expr, "Cannot assign a type '%s' to variable '%.*s'", t, LIT(e->token.string));
}
if (e->type == nullptr) {
error_line("\tThe type of the variable '%.*s' cannot be inferred as a type does not have a default type\n", LIT(e->token.string));
error_line("\tThe type of the variable '%.*s' cannot be inferred as a type and does not have a default type\n", LIT(e->token.string));
}
e->type = operand->type;
return nullptr;
+5 -5
View File
@@ -1044,7 +1044,7 @@ gb_internal AstPackage *get_package_of_type(Type *type) {
}
// NOTE(bill): 'content_name' is for debugging and error messages
// NOTE(bill): 'context_name' is for debugging and error messages
gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *type, String context_name) {
check_not_tuple(c, operand);
if (operand->mode == Addressing_Invalid) {
@@ -1973,10 +1973,10 @@ gb_internal bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
case Token_Quo:
case Token_QuoEq:
if (is_type_matrix(main_type)) {
error(op, "Operator '%.*s' is only allowed with matrix types", LIT(op.string));
error(op, "Operator '%.*s' is not allowed with matrix types", LIT(op.string));
return false;
} else if (is_type_simd_vector(main_type) && is_type_integer(type)) {
error(op, "Operator '%.*s' is only allowed with #simd types with integer elements", LIT(op.string));
error(op, "Operator '%.*s' is not allowed with #simd types with integer elements", LIT(op.string));
return false;
}
/*fallthrough*/
@@ -2023,14 +2023,14 @@ gb_internal bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
case Token_ModEq:
case Token_ModModEq:
if (is_type_matrix(main_type)) {
error(op, "Operator '%.*s' is only allowed with matrix types", LIT(op.string));
error(op, "Operator '%.*s' is not allowed with matrix types", LIT(op.string));
return false;
}
if (!is_type_integer(type)) {
error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string));
return false;
} else if (is_type_simd_vector(main_type)) {
error(op, "Operator '%.*s' is only allowed with #simd types with integer elements", LIT(op.string));
error(op, "Operator '%.*s' is not allowed with #simd types with integer elements", LIT(op.string));
return false;
}
break;
+2 -1
View File
@@ -685,7 +685,8 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *
ST_ALIGN(min_field_align);
ST_ALIGN(max_field_align);
ST_ALIGN(align);
if (struct_type->Struct.custom_align < struct_type->Struct.custom_min_field_align) {
if (struct_type->Struct.custom_align != 0 &&
struct_type->Struct.custom_align < struct_type->Struct.custom_min_field_align) {
error(st->align, "#align(%lld) is defined to be less than #min_field_align(%lld)",
cast(long long)struct_type->Struct.custom_align,
cast(long long)struct_type->Struct.custom_min_field_align);
+18 -3
View File
@@ -749,9 +749,15 @@ gb_internal void check_scope_usage_internal(Checker *c, Scope *scope, u64 vet_fl
// TODO(bill): When is a good size warn?
// Is >256 KiB good enough?
if (sz > 1ll<<18) {
gbString type_str = type_to_string(e->type);
warning(e->token, "Declaration of '%.*s' may cause a stack overflow due to its type '%s' having a size of %lld bytes", LIT(e->token.string), type_str, cast(long long)sz);
gb_string_free(type_str);
bool is_ref = false;
if((e->flags & EntityFlag_ForValue) != 0) {
is_ref = type_deref(e->Variable.for_loop_parent_type) != NULL;
}
if(!is_ref) {
gbString type_str = type_to_string(e->type);
warning(e->token, "Declaration of '%.*s' may cause a stack overflow due to its type '%s' having a size of %lld bytes", LIT(e->token.string), type_str, cast(long long)sz);
gb_string_free(type_str);
}
}
}
}
@@ -5034,6 +5040,12 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) {
ac->extra_linker_flags = ev.value_string;
}
return true;
} else if (name == "ignore_duplicates") {
if (value != nullptr) {
error(elem, "Expected no parameter for '%.*s'", LIT(name));
}
ac->ignore_duplicates = true;
return true;
}
return false;
}
@@ -5184,6 +5196,9 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
if (ac.foreign_import_priority_index != 0) {
e->LibraryName.priority_index = ac.foreign_import_priority_index;
}
if (ac.ignore_duplicates) {
e->LibraryName.ignore_duplicates = true;
}
String extra_linker_flags = string_trim_whitespace(ac.extra_linker_flags);
if (extra_linker_flags.len != 0) {
e->LibraryName.extra_linker_flags = extra_linker_flags;
+1
View File
@@ -140,6 +140,7 @@ struct AttributeContext {
bool instrumentation_enter : 1;
bool instrumentation_exit : 1;
bool rodata : 1;
bool ignore_duplicates : 1;
u32 optimization_mode; // ProcedureOptimizationMode
i64 foreign_import_priority_index;
String extra_linker_flags;
+1
View File
@@ -274,6 +274,7 @@ struct Entity {
Slice<String> paths;
String name;
i64 priority_index;
bool ignore_duplicates;
String extra_linker_flags;
} LibraryName;
i32 Nil;
+32 -1
View File
@@ -449,6 +449,26 @@ gb_internal i32 linker_stage(LinkerData *gen) {
if (extra_linker_flags.len != 0) {
lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags));
}
if (build_context.metrics.os == TargetOs_darwin) {
// Print frameworks first
for (String lib : e->LibraryName.paths) {
lib = string_trim_whitespace(lib);
if (lib.len == 0) {
continue;
}
if (string_ends_with(lib, str_lit(".framework"))) {
if (string_set_update(&min_libs_set, lib)) {
continue;
}
String lib_name = lib;
lib_name = remove_extension_from_path(lib_name);
lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name));
}
}
}
for (String lib : e->LibraryName.paths) {
lib = string_trim_whitespace(lib);
if (lib.len == 0) {
@@ -536,7 +556,18 @@ gb_internal i32 linker_stage(LinkerData *gen) {
}
array_add(&gen->output_object_paths, obj_file);
} else {
if (string_set_update(&min_libs_set, lib) && build_context.min_link_libs) {
bool short_circuit = false;
if (string_ends_with(lib, str_lit(".framework"))) {
short_circuit = true;
} else if (string_ends_with(lib, str_lit(".dylib"))) {
short_circuit = true;
} else if (string_ends_with(lib, str_lit(".so"))) {
short_circuit = true;
} else if (e->LibraryName.ignore_duplicates) {
short_circuit = true;
}
if (string_set_update(&min_libs_set, lib) && (build_context.min_link_libs || short_circuit)) {
continue;
}
+2 -2
View File
@@ -1147,14 +1147,14 @@ gb_internal void lb_finalize_objc_names(lbProcedure *p) {
String name = entry.key;
args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args);
lb_addr_store(p, entry.value, ptr);
lb_addr_store(p, entry.value.local_module_addr, ptr);
}
for (auto const &entry : m->objc_selectors) {
String name = entry.key;
args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args);
lb_addr_store(p, entry.value, ptr);
lb_addr_store(p, entry.value.local_module_addr, ptr);
}
lb_end_procedure_body(p);
+7 -2
View File
@@ -143,6 +143,11 @@ struct lbPadType {
LLVMTypeRef type;
};
struct lbObjcRef {
Entity * entity;
lbAddr local_module_addr;
};
struct lbModule {
LLVMModuleRef mod;
LLVMContextRef ctx;
@@ -196,8 +201,8 @@ struct lbModule {
RecursiveMutex debug_values_mutex;
PtrMap<void *, LLVMMetadataRef> debug_values;
StringMap<lbAddr> objc_classes;
StringMap<lbAddr> objc_selectors;
StringMap<lbObjcRef> objc_classes;
StringMap<lbObjcRef> objc_selectors;
PtrMap<Type *, lbAddr> map_cell_info_map; // address of runtime.Map_Info
PtrMap<Type *, lbAddr> map_info_map; // address of runtime.Map_Cell_Info
+11 -10
View File
@@ -4294,6 +4294,17 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) {
gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
ast_node(se, SliceExpr, expr);
lbAddr addr = lb_build_addr(p, se->expr);
lbValue base = lb_addr_load(p, addr);
Type *type = base_type(base.type);
if (is_type_pointer(type)) {
type = base_type(type_deref(type));
addr = lb_addr(base);
base = lb_addr_load(p, addr);
}
lbValue low = lb_const_int(p->module, t_int, 0);
lbValue high = {};
@@ -4306,16 +4317,6 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) {
bool no_indices = se->low == nullptr && se->high == nullptr;
lbAddr addr = lb_build_addr(p, se->expr);
lbValue base = lb_addr_load(p, addr);
Type *type = base_type(base.type);
if (is_type_pointer(type)) {
type = base_type(type_deref(type));
addr = lb_addr(base);
base = lb_addr_load(p, addr);
}
switch (type->kind) {
case Type_Slice: {
Type *slice_type = type;
+53 -47
View File
@@ -2093,23 +2093,34 @@ gb_internal void lb_set_wasm_export_attributes(LLVMValueRef value, String export
gb_internal lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) {
lbAddr *found = string_map_get(&p->module->objc_selectors, name);
lbObjcRef *found = string_map_get(&p->module->objc_selectors, name);
if (found) {
return *found;
} else {
lbModule *default_module = &p->module->gen->default_module;
Entity *e = nullptr;
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e);
lbValue ptr = lb_find_value_from_entity(p->module, e);
lbAddr local_addr = lb_addr(ptr);
string_map_set(&default_module->objc_selectors, name, default_addr);
if (default_module != p->module) {
string_map_set(&p->module->objc_selectors, name, local_addr);
}
return local_addr;
return found->local_module_addr;
}
lbModule *default_module = &p->module->gen->default_module;
Entity *entity = {};
if (default_module != p->module) {
found = string_map_get(&default_module->objc_selectors, name);
if (found) {
entity = found->entity;
}
}
if (!entity) {
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &entity);
string_map_set(&default_module->objc_selectors, name, lbObjcRef{entity, default_addr});
}
lbValue ptr = lb_find_value_from_entity(p->module, entity);
lbAddr local_addr = lb_addr(ptr);
if (default_module != p->module) {
string_map_set(&p->module->objc_selectors, name, lbObjcRef{entity, local_addr});
}
return local_addr;
}
gb_internal lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) {
@@ -2139,23 +2150,34 @@ gb_internal lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr)
}
gb_internal lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) {
lbAddr *found = string_map_get(&p->module->objc_classes, name);
lbObjcRef *found = string_map_get(&p->module->objc_classes, name);
if (found) {
return *found;
} else {
lbModule *default_module = &p->module->gen->default_module;
Entity *e = nullptr;
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e);
lbValue ptr = lb_find_value_from_entity(p->module, e);
lbAddr local_addr = lb_addr(ptr);
string_map_set(&default_module->objc_classes, name, default_addr);
if (default_module != p->module) {
string_map_set(&p->module->objc_classes, name, local_addr);
}
return local_addr;
return found->local_module_addr;
}
lbModule *default_module = &p->module->gen->default_module;
Entity *entity = {};
if (default_module != p->module) {
found = string_map_get(&default_module->objc_classes, name);
if (found) {
entity = found->entity;
}
}
if (!entity) {
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &entity);
string_map_set(&default_module->objc_classes, name, lbObjcRef{entity, default_addr});
}
lbValue ptr = lb_find_value_from_entity(p->module, entity);
lbAddr local_addr = lb_addr(ptr);
if (default_module != p->module) {
string_map_set(&p->module->objc_classes, name, lbObjcRef{entity, local_addr});
}
return local_addr;
}
gb_internal lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) {
@@ -2196,23 +2218,7 @@ gb_internal lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) {
GB_ASSERT(e->kind == Entity_TypeName);
String name = e->TypeName.objc_class_name;
lbAddr *found = string_map_get(&p->module->objc_classes, name);
if (found) {
return lb_addr_load(p, *found);
} else {
lbModule *default_module = &p->module->gen->default_module;
Entity *e = nullptr;
lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &e);
lbValue ptr = lb_find_value_from_entity(p->module, e);
lbAddr local_addr = lb_addr(ptr);
string_map_set(&default_module->objc_classes, name, default_addr);
if (default_module != p->module) {
string_map_set(&p->module->objc_classes, name, local_addr);
}
return lb_addr_load(p, local_addr);
}
return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name));
}
return lb_build_expr(p, expr);
+27 -3
View File
@@ -331,6 +331,7 @@ enum BuildFlagKind {
BuildFlag_UseRADLink,
BuildFlag_Linker,
BuildFlag_UseSeparateModules,
BuildFlag_UseSingleModule,
BuildFlag_NoThreadedChecker,
BuildFlag_ShowDebugMessages,
@@ -545,6 +546,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_UseRADLink, str_lit("radlink"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_Linker, str_lit("linker"), BuildFlagParam_String, Command__does_build);
add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_UseSingleModule, str_lit("use-single-module"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_NoThreadedChecker, str_lit("no-threaded-checker"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_ShowDebugMessages, str_lit("show-debug-messages"), BuildFlagParam_None, Command_all);
@@ -1240,8 +1242,19 @@ gb_internal bool parse_build_flags(Array<String> args) {
case BuildFlag_UseSeparateModules:
if (build_context.use_single_module) {
gb_printf_err("-use-separate-modules cannot be used with -use-single-module\n");
bad_flags = true;
}
build_context.use_separate_modules = true;
break;
case BuildFlag_UseSingleModule:
if (build_context.use_separate_modules) {
gb_printf_err("-use-single-module cannot be used with -use-separate-modules\n");
bad_flags = true;
}
build_context.use_single_module = true;
break;
case BuildFlag_NoThreadedChecker:
build_context.no_threaded_checker = true;
break;
@@ -1801,7 +1814,10 @@ gb_internal void check_defines(BuildContext *bc, Checker *c) {
if (!found) {
ERROR_BLOCK();
warning(nullptr, "given -define:%.*s is unused in the project", LIT(name));
error_line("\tSuggestion: use the -show-defineables flag for an overview of the possible defines\n");
if (!global_ignore_warnings()) {
error_line("\tSuggestion: use the -show-defineables flag for an overview of the possible defines\n");
}
}
}
}
@@ -2331,6 +2347,10 @@ gb_internal void print_show_help(String const arg0, String command, String optio
print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing.");
}
if (print_flag("-default-to-panic-allocator")) {
print_usage_line(2, "Sets the default allocator to be the panic_allocator, an allocator which calls panic() on any allocation attempt.");
}
if (print_flag("-define:<name>=<value>")) {
print_usage_line(2, "Defines a scalar boolean, integer or string as global constant.");
print_usage_line(2, "Example: -define:SPAM=123");
@@ -2710,8 +2730,12 @@ gb_internal void print_show_help(String const arg0, String command, String optio
if (run_or_build) {
if (print_flag("-use-separate-modules")) {
print_usage_line(2, "The backend generates multiple build units which are then linked together.");
print_usage_line(2, "Normally, a single build unit is generated for a standard project.");
print_usage_line(2, "This is the default behaviour on Windows for '-o:none' and '-o:minimal' builds.");
print_usage_line(2, "This is the default behaviour for '-o:none' and '-o:minimal' builds.");
print_usage_line(2, "Normally, a single build unit is generated for a standard project for '-o:speed' or '-o:size'.");
}
if (print_flag("-use-single-module")) {
print_usage_line(2, "The backend generates only a single build unit.");
print_usage_line(2, "This is the default behaviour for '-o:speed' or '-o:size'.");
}
}
+3 -1
View File
@@ -4773,7 +4773,9 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha
case Type_BitSet:
str = gb_string_appendc(str, "bit_set[");
if (is_type_enum(type->BitSet.elem)) {
if (type->BitSet.elem == nullptr) {
str = gb_string_appendc(str, "<unresolved>");
} else if (is_type_enum(type->BitSet.elem)) {
str = write_type_to_string(str, type->BitSet.elem);
} else {
str = gb_string_append_fmt(str, "%lld", type->BitSet.lower);