mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-22 23:47:51 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
+23
-3
@@ -696,6 +696,12 @@ enum TimingsExportFormat : i32 {
|
||||
TimingsExportCSV = 2,
|
||||
};
|
||||
|
||||
enum DependenciesExportFormat : i32 {
|
||||
DependenciesExportUnspecified = 0,
|
||||
DependenciesExportMake = 1,
|
||||
DependenciesExportJson = 2,
|
||||
};
|
||||
|
||||
enum ErrorPosStyle {
|
||||
ErrorPosStyle_Default, // path(line:column) msg
|
||||
ErrorPosStyle_Unix, // path:line:column: msg
|
||||
@@ -833,6 +839,8 @@ struct BuildContext {
|
||||
bool show_timings;
|
||||
TimingsExportFormat export_timings_format;
|
||||
String export_timings_file;
|
||||
DependenciesExportFormat export_dependencies_format;
|
||||
String export_dependencies_file;
|
||||
bool show_unused;
|
||||
bool show_unused_with_location;
|
||||
bool show_more_timings;
|
||||
@@ -893,7 +901,6 @@ struct BuildContext {
|
||||
u32 cmd_doc_flags;
|
||||
Array<String> extra_packages;
|
||||
|
||||
StringSet test_names;
|
||||
bool test_all_packages;
|
||||
|
||||
gbAffinity affinity;
|
||||
@@ -1032,6 +1039,13 @@ gb_global TargetMetrics target_netbsd_amd64 = {
|
||||
str_lit("x86_64-unknown-netbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_netbsd_arm64 = {
|
||||
TargetOs_netbsd,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
str_lit("aarch64-unknown-netbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_haiku_amd64 = {
|
||||
TargetOs_haiku,
|
||||
TargetArch_amd64,
|
||||
@@ -1147,8 +1161,10 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("freebsd_amd64"), &target_freebsd_amd64 },
|
||||
{ str_lit("freebsd_arm64"), &target_freebsd_arm64 },
|
||||
|
||||
{ str_lit("openbsd_amd64"), &target_openbsd_amd64 },
|
||||
{ str_lit("netbsd_amd64"), &target_netbsd_amd64 },
|
||||
{ str_lit("netbsd_arm64"), &target_netbsd_arm64 },
|
||||
|
||||
{ str_lit("openbsd_amd64"), &target_openbsd_amd64 },
|
||||
{ str_lit("haiku_amd64"), &target_haiku_amd64 },
|
||||
|
||||
{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
|
||||
@@ -1909,7 +1925,11 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
#elif defined(GB_SYSTEM_OPENBSD)
|
||||
metrics = &target_openbsd_amd64;
|
||||
#elif defined(GB_SYSTEM_NETBSD)
|
||||
metrics = &target_netbsd_amd64;
|
||||
#if defined(GB_CPU_ARM)
|
||||
metrics = &target_netbsd_arm64;
|
||||
#else
|
||||
metrics = &target_netbsd_amd64;
|
||||
#endif
|
||||
#elif defined(GB_SYSTEM_HAIKU)
|
||||
metrics = &target_haiku_amd64;
|
||||
#elif defined(GB_CPU_ARM)
|
||||
|
||||
+72
-24
@@ -1079,7 +1079,7 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &original_string, bool err_on_not_found, LoadFileCache **cache_) {
|
||||
gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &original_string, bool err_on_not_found, LoadFileCache **cache_, LoadFileTier tier) {
|
||||
ast_node(ce, CallExpr, call);
|
||||
ast_node(bd, BasicDirective, ce->proc);
|
||||
String builtin_name = bd->name.string;
|
||||
@@ -1105,12 +1105,16 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String
|
||||
|
||||
gbFileError file_error = gbFileError_None;
|
||||
String data = {};
|
||||
bool exists = false;
|
||||
LoadFileTier cache_tier = LoadFileTier_Invalid;
|
||||
|
||||
LoadFileCache **cache_ptr = string_map_get(&c->info->load_file_cache, path);
|
||||
LoadFileCache *cache = cache_ptr ? *cache_ptr : nullptr;
|
||||
if (cache) {
|
||||
file_error = cache->file_error;
|
||||
data = cache->data;
|
||||
exists = cache->exists;
|
||||
cache_tier = cache->tier;
|
||||
}
|
||||
defer ({
|
||||
if (cache == nullptr) {
|
||||
@@ -1118,60 +1122,78 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String
|
||||
new_cache->path = path;
|
||||
new_cache->data = data;
|
||||
new_cache->file_error = file_error;
|
||||
new_cache->exists = exists;
|
||||
new_cache->tier = cache_tier;
|
||||
string_map_init(&new_cache->hashes, 32);
|
||||
string_map_set(&c->info->load_file_cache, path, new_cache);
|
||||
if (cache_) *cache_ = new_cache;
|
||||
} else {
|
||||
cache->data = data;
|
||||
cache->file_error = file_error;
|
||||
cache->exists = exists;
|
||||
cache->tier = cache_tier;
|
||||
if (cache_) *cache_ = cache;
|
||||
}
|
||||
});
|
||||
|
||||
TEMPORARY_ALLOCATOR_GUARD();
|
||||
char *c_str = alloc_cstring(temporary_allocator(), path);
|
||||
if (tier > cache_tier) {
|
||||
cache_tier = tier;
|
||||
|
||||
gbFile f = {};
|
||||
if (cache == nullptr) {
|
||||
TEMPORARY_ALLOCATOR_GUARD();
|
||||
char *c_str = alloc_cstring(temporary_allocator(), path);
|
||||
|
||||
gbFile f = {};
|
||||
file_error = gb_file_open(&f, c_str);
|
||||
defer (gb_file_close(&f));
|
||||
|
||||
if (file_error == gbFileError_None) {
|
||||
exists = true;
|
||||
|
||||
switch(tier) {
|
||||
case LoadFileTier_Exists:
|
||||
// Nothing to do.
|
||||
break;
|
||||
case LoadFileTier_Contents: {
|
||||
isize file_size = cast(isize)gb_file_size(&f);
|
||||
if (file_size > 0) {
|
||||
u8 *ptr = cast(u8 *)gb_alloc(permanent_allocator(), file_size+1);
|
||||
gb_file_read_at(&f, ptr, file_size, 0);
|
||||
ptr[file_size] = '\0';
|
||||
data.text = ptr;
|
||||
data.len = file_size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GB_PANIC("Unhandled LoadFileTier");
|
||||
};
|
||||
}
|
||||
}
|
||||
defer (gb_file_close(&f));
|
||||
|
||||
switch (file_error) {
|
||||
default:
|
||||
case gbFileError_Invalid:
|
||||
if (err_on_not_found) {
|
||||
error(ce->proc, "Failed to `#%.*s` file: %s; invalid file or cannot be found", LIT(builtin_name), c_str);
|
||||
error(ce->proc, "Failed to `#%.*s` file: %.*s; invalid file or cannot be found", LIT(builtin_name), LIT(path));
|
||||
}
|
||||
call->state_flags |= StateFlag_DirectiveWasFalse;
|
||||
return false;
|
||||
case gbFileError_NotExists:
|
||||
if (err_on_not_found) {
|
||||
error(ce->proc, "Failed to `#%.*s` file: %s; file cannot be found", LIT(builtin_name), c_str);
|
||||
error(ce->proc, "Failed to `#%.*s` file: %.*s; file cannot be found", LIT(builtin_name), LIT(path));
|
||||
}
|
||||
call->state_flags |= StateFlag_DirectiveWasFalse;
|
||||
return false;
|
||||
case gbFileError_Permission:
|
||||
if (err_on_not_found) {
|
||||
error(ce->proc, "Failed to `#%.*s` file: %s; file permissions problem", LIT(builtin_name), c_str);
|
||||
error(ce->proc, "Failed to `#%.*s` file: %.*s; file permissions problem", LIT(builtin_name), LIT(path));
|
||||
}
|
||||
call->state_flags |= StateFlag_DirectiveWasFalse;
|
||||
return false;
|
||||
case gbFileError_None:
|
||||
// Okay
|
||||
break;
|
||||
}
|
||||
|
||||
if (cache == nullptr) {
|
||||
isize file_size = cast(isize)gb_file_size(&f);
|
||||
if (file_size > 0) {
|
||||
u8 *ptr = cast(u8 *)gb_alloc(permanent_allocator(), file_size+1);
|
||||
gb_file_read_at(&f, ptr, file_size, 0);
|
||||
ptr[file_size] = '\0';
|
||||
data.text = ptr;
|
||||
data.len = file_size;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1263,7 +1285,7 @@ gb_internal LoadDirectiveResult check_load_directive(CheckerContext *c, Operand
|
||||
operand->mode = Addressing_Constant;
|
||||
|
||||
LoadFileCache *cache = nullptr;
|
||||
if (cache_load_file_directive(c, call, o.value.value_string, err_on_not_found, &cache)) {
|
||||
if (cache_load_file_directive(c, call, o.value.value_string, err_on_not_found, &cache, LoadFileTier_Contents)) {
|
||||
operand->value = exact_value_string(cache->data);
|
||||
return LoadDirective_Success;
|
||||
}
|
||||
@@ -1345,6 +1367,8 @@ gb_internal LoadDirectiveResult check_load_directory_directive(CheckerContext *c
|
||||
map_set(&c->info->load_directory_map, call, new_cache);
|
||||
} else {
|
||||
cache->file_error = file_error;
|
||||
|
||||
map_set(&c->info->load_directory_map, call, cache);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1389,7 +1413,7 @@ gb_internal LoadDirectiveResult check_load_directory_directive(CheckerContext *c
|
||||
|
||||
for (FileInfo fi : list) {
|
||||
LoadFileCache *cache = nullptr;
|
||||
if (cache_load_file_directive(c, call, fi.fullpath, err_on_not_found, &cache)) {
|
||||
if (cache_load_file_directive(c, call, fi.fullpath, err_on_not_found, &cache, LoadFileTier_Contents)) {
|
||||
array_add(&file_caches, cache);
|
||||
} else {
|
||||
result = LoadDirective_Error;
|
||||
@@ -1488,6 +1512,30 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o
|
||||
|
||||
operand->type = t_source_code_location;
|
||||
operand->mode = Addressing_Value;
|
||||
} else if (name == "exists") {
|
||||
if (ce->args.count != 1) {
|
||||
error(ce->close, "'#exists' expects 1 argument, got %td", ce->args.count);
|
||||
return false;
|
||||
}
|
||||
|
||||
Operand o = {};
|
||||
check_expr(c, &o, ce->args[0]);
|
||||
if (o.mode != Addressing_Constant || !is_type_string(o.type)) {
|
||||
error(ce->args[0], "'#exists' expected a constant string argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
operand->type = t_untyped_bool;
|
||||
operand->mode = Addressing_Constant;
|
||||
|
||||
String original_string = o.value.value_string;
|
||||
LoadFileCache *cache = nullptr;
|
||||
if (cache_load_file_directive(c, call, original_string, /* err_on_not_found=*/ false, &cache, LoadFileTier_Exists)) {
|
||||
operand->value = exact_value_bool(cache->exists);
|
||||
} else {
|
||||
operand->value = exact_value_bool(false);
|
||||
}
|
||||
|
||||
} else if (name == "load") {
|
||||
return check_load_directive(c, operand, call, type_hint, true) == LoadDirective_Success;
|
||||
} else if (name == "load_directory") {
|
||||
@@ -1540,7 +1588,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o
|
||||
String hash_kind = o_hash.value.value_string;
|
||||
|
||||
LoadFileCache *cache = nullptr;
|
||||
if (cache_load_file_directive(c, call, original_string, true, &cache)) {
|
||||
if (cache_load_file_directive(c, call, original_string, true, &cache, LoadFileTier_Contents)) {
|
||||
MUTEX_GUARD(&c->info->load_file_mutex);
|
||||
// TODO(bill): make these procedures fast :P
|
||||
u64 hash_value = 0;
|
||||
|
||||
+22
-1
@@ -125,6 +125,8 @@ gb_internal Entity *find_polymorphic_record_entity(GenTypesData *found_gen_types
|
||||
|
||||
gb_internal bool complete_soa_type(Checker *checker, Type *t, bool wait_to_finish);
|
||||
|
||||
gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y);
|
||||
|
||||
enum LoadDirectiveResult {
|
||||
LoadDirective_Success = 0,
|
||||
LoadDirective_Error = 1,
|
||||
@@ -2252,6 +2254,17 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i
|
||||
gb_internal bool check_integer_exceed_suggestion(CheckerContext *c, Operand *o, Type *type, i64 max_bit_size=0) {
|
||||
if (is_type_integer(type) && o->value.kind == ExactValue_Integer) {
|
||||
gbString b = type_to_string(type);
|
||||
defer (gb_string_free(b));
|
||||
|
||||
if (is_type_enum(o->type)) {
|
||||
if (check_is_castable_to(c, o, type)) {
|
||||
gbString ot = type_to_string(o->type);
|
||||
error_line("\tSuggestion: Try casting the '%s' expression to '%s'", ot, b);
|
||||
gb_string_free(ot);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
i64 sz = type_size_of(type);
|
||||
i64 bit_size = 8*sz;
|
||||
@@ -2301,7 +2314,6 @@ gb_internal bool check_integer_exceed_suggestion(CheckerContext *c, Operand *o,
|
||||
}
|
||||
}
|
||||
|
||||
gb_string_free(b);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -7408,6 +7420,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
||||
String name = bd->name.string;
|
||||
if (
|
||||
name == "location" ||
|
||||
name == "exists" ||
|
||||
name == "assert" ||
|
||||
name == "panic" ||
|
||||
name == "region" ||
|
||||
@@ -8331,6 +8344,7 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A
|
||||
name == "assert" ||
|
||||
name == "defined" ||
|
||||
name == "config" ||
|
||||
name == "exists" ||
|
||||
name == "load" ||
|
||||
name == "load_hash" ||
|
||||
name == "load_directory" ||
|
||||
@@ -8854,6 +8868,10 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
|
||||
case Type_Array:
|
||||
ft = bt->Array.elem;
|
||||
break;
|
||||
case Type_BitField:
|
||||
is_constant = false;
|
||||
ft = bt->BitField.fields[index]->type;
|
||||
break;
|
||||
default:
|
||||
GB_PANIC("invalid type: %s", type_to_string(ft));
|
||||
break;
|
||||
@@ -8880,6 +8898,9 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
|
||||
case Type_Array:
|
||||
nested_ft = bt->Array.elem;
|
||||
break;
|
||||
case Type_BitField:
|
||||
nested_ft = bt->BitField.fields[index]->type;
|
||||
break;
|
||||
default:
|
||||
GB_PANIC("invalid type %s", type_to_string(nested_ft));
|
||||
break;
|
||||
|
||||
@@ -5852,35 +5852,6 @@ gb_internal void remove_neighbouring_duplicate_entires_from_sorted_array(Array<E
|
||||
gb_internal void check_test_procedures(Checker *c) {
|
||||
array_sort(c->info.testing_procedures, init_procedures_cmp);
|
||||
remove_neighbouring_duplicate_entires_from_sorted_array(&c->info.testing_procedures);
|
||||
|
||||
if (build_context.test_names.entries.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
AstPackage *pkg = c->info.init_package;
|
||||
Scope *s = pkg->scope;
|
||||
|
||||
for (String const &name : build_context.test_names) {
|
||||
Entity *e = scope_lookup(s, name);
|
||||
if (e == nullptr) {
|
||||
Token tok = {};
|
||||
if (pkg->files.count != 0) {
|
||||
tok = pkg->files[0]->tokens[0];
|
||||
}
|
||||
error(tok, "Unable to find the test '%.*s' in 'package %.*s' ", LIT(name), LIT(pkg->name));
|
||||
}
|
||||
}
|
||||
|
||||
for (isize i = 0; i < c->info.testing_procedures.count; /**/) {
|
||||
Entity *e = c->info.testing_procedures[i];
|
||||
String name = e->token.string;
|
||||
if (!string_set_exists(&build_context.test_names, name)) {
|
||||
array_ordered_remove(&c->info.testing_procedures, i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -336,7 +336,16 @@ struct ObjcMsgData {
|
||||
ObjcMsgKind kind;
|
||||
Type *proc_type;
|
||||
};
|
||||
|
||||
enum LoadFileTier {
|
||||
LoadFileTier_Invalid,
|
||||
LoadFileTier_Exists,
|
||||
LoadFileTier_Contents,
|
||||
};
|
||||
|
||||
struct LoadFileCache {
|
||||
LoadFileTier tier;
|
||||
bool exists;
|
||||
String path;
|
||||
gbFileError file_error;
|
||||
String data;
|
||||
|
||||
@@ -256,6 +256,7 @@ extern "C" {
|
||||
|
||||
#if defined(GB_SYSTEM_NETBSD)
|
||||
#include <stdio.h>
|
||||
#include <lwp.h>
|
||||
#define lseek64 lseek
|
||||
#endif
|
||||
|
||||
@@ -3027,6 +3028,8 @@ gb_inline u32 gb_thread_current_id(void) {
|
||||
thread_id = find_thread(NULL);
|
||||
#elif defined(GB_SYSTEM_FREEBSD)
|
||||
thread_id = pthread_getthreadid_np();
|
||||
#elif defined(GB_SYSTEM_NETBSD)
|
||||
thread_id = (u32)_lwp_self();
|
||||
#else
|
||||
#error Unsupported architecture for gb_thread_current_id()
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,15 @@ gb_internal LLVMMetadataRef lb_debug_end_location_from_ast(lbProcedure *p, Ast *
|
||||
return lb_debug_location_from_token_pos(p, ast_end_token(node).pos);
|
||||
}
|
||||
|
||||
gb_internal void lb_debug_file_line(lbModule *m, Ast *node, LLVMMetadataRef *file, unsigned *line) {
|
||||
if (*file == nullptr) {
|
||||
if (node) {
|
||||
*file = lb_get_llvm_metadata(m, node->file());
|
||||
*line = cast(unsigned)ast_token(node).pos.line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
|
||||
i64 size = type_size_of(type); // Check size
|
||||
gb_unused(size);
|
||||
@@ -117,6 +126,8 @@ gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &nam
|
||||
gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
|
||||
GB_ASSERT(bt->kind == Type_Struct);
|
||||
|
||||
lb_debug_file_line(m, bt->Struct.node, &file, &line);
|
||||
|
||||
unsigned tag = DW_TAG_structure_type;
|
||||
if (is_type_raw_union(bt)) {
|
||||
tag = DW_TAG_union_type;
|
||||
@@ -336,6 +347,8 @@ gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name,
|
||||
Type *bt = base_type(type);
|
||||
GB_ASSERT(bt->kind == Type_Union);
|
||||
|
||||
lb_debug_file_line(m, bt->Union.node, &file, &line);
|
||||
|
||||
u64 size_in_bits = 8*type_size_of(bt);
|
||||
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
|
||||
|
||||
@@ -415,6 +428,8 @@ gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name
|
||||
Type *bt = base_type(type);
|
||||
GB_ASSERT(bt->kind == Type_BitSet);
|
||||
|
||||
lb_debug_file_line(m, bt->BitSet.node, &file, &line);
|
||||
|
||||
u64 size_in_bits = 8*type_size_of(bt);
|
||||
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
|
||||
|
||||
@@ -494,6 +509,8 @@ gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name,
|
||||
Type *bt = base_type(type);
|
||||
GB_ASSERT(bt->kind == Type_Enum);
|
||||
|
||||
lb_debug_file_line(m, bt->Enum.node, &file, &line);
|
||||
|
||||
u64 size_in_bits = 8*type_size_of(bt);
|
||||
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
|
||||
|
||||
|
||||
@@ -4533,10 +4533,26 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
|
||||
if (lb_is_nested_possibly_constant(type, sel, elem)) {
|
||||
continue;
|
||||
}
|
||||
lbValue dst = lb_emit_deep_field_gep(p, comp_lit_ptr, sel);
|
||||
field_expr = lb_build_expr(p, elem);
|
||||
field_expr = lb_emit_conv(p, field_expr, sel.entity->type);
|
||||
lb_emit_store(p, dst, field_expr);
|
||||
if (sel.is_bit_field) {
|
||||
Selection sub_sel = trim_selection(sel);
|
||||
lbValue trimmed_dst = lb_emit_deep_field_gep(p, comp_lit_ptr, sub_sel);
|
||||
Type *bf = base_type(type_deref(trimmed_dst.type));
|
||||
if (is_type_pointer(bf)) {
|
||||
trimmed_dst = lb_emit_load(p, trimmed_dst);
|
||||
bf = base_type(type_deref(trimmed_dst.type));
|
||||
}
|
||||
GB_ASSERT(bf->kind == Type_BitField);
|
||||
|
||||
isize idx = sel.index[sel.index.count-1];
|
||||
lbAddr dst = lb_addr_bit_field(trimmed_dst, bf->BitField.fields[idx]->type, bf->BitField.bit_offsets[idx], bf->BitField.bit_sizes[idx]);
|
||||
lb_addr_store(p, dst, field_expr);
|
||||
|
||||
} else {
|
||||
lbValue dst = lb_emit_deep_field_gep(p, comp_lit_ptr, sel);
|
||||
lb_emit_store(p, dst, field_expr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,15 +1097,7 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> c
|
||||
ptr = lb_address_from_load_or_generate_local(p, x);
|
||||
}
|
||||
} else {
|
||||
if (LLVMIsConstant(x.value)) {
|
||||
// NOTE(bill): if the value is already constant, then just it as a global variable
|
||||
// and pass it by pointer
|
||||
lbAddr addr = lb_add_global_generated(p->module, original_type, x);
|
||||
lb_make_global_private_const(addr);
|
||||
ptr = addr.addr;
|
||||
} else {
|
||||
ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
|
||||
}
|
||||
ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
|
||||
}
|
||||
array_add(&processed_args, ptr);
|
||||
}
|
||||
|
||||
+130
-25
@@ -234,6 +234,8 @@ enum BuildFlagKind {
|
||||
BuildFlag_ShowMoreTimings,
|
||||
BuildFlag_ExportTimings,
|
||||
BuildFlag_ExportTimingsFile,
|
||||
BuildFlag_ExportDependencies,
|
||||
BuildFlag_ExportDependenciesFile,
|
||||
BuildFlag_ShowSystemCalls,
|
||||
BuildFlag_ThreadCount,
|
||||
BuildFlag_KeepTempFiles,
|
||||
@@ -276,8 +278,6 @@ enum BuildFlagKind {
|
||||
BuildFlag_RelocMode,
|
||||
BuildFlag_DisableRedZone,
|
||||
|
||||
BuildFlag_TestName,
|
||||
|
||||
BuildFlag_DisallowDo,
|
||||
BuildFlag_DefaultToNilAllocator,
|
||||
BuildFlag_DefaultToPanicAllocator,
|
||||
@@ -320,7 +320,6 @@ enum BuildFlagKind {
|
||||
BuildFlag_Subsystem,
|
||||
#endif
|
||||
|
||||
|
||||
BuildFlag_COUNT,
|
||||
};
|
||||
|
||||
@@ -427,6 +426,8 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_ExportTimingsFile, str_lit("export-timings-file"), BuildFlagParam_String, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_ExportDependencies, str_lit("export-dependencies"), BuildFlagParam_String, Command__does_build);
|
||||
add_flag(&build_flags, BuildFlag_ExportDependenciesFile, str_lit("export-dependencies-file"), BuildFlagParam_String, Command__does_build);
|
||||
add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None, Command_check);
|
||||
add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None, Command_check);
|
||||
add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None, Command_all);
|
||||
@@ -471,8 +472,6 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build);
|
||||
add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_DefaultToPanicAllocator, str_lit("default-to-panic-allocator"),BuildFlagParam_None, Command__does_check);
|
||||
@@ -753,6 +752,36 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
|
||||
break;
|
||||
}
|
||||
case BuildFlag_ExportDependencies: {
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
|
||||
if (value.value_string == "make") {
|
||||
build_context.export_dependencies_format = DependenciesExportMake;
|
||||
} else if (value.value_string == "json") {
|
||||
build_context.export_dependencies_format = DependenciesExportJson;
|
||||
} else {
|
||||
gb_printf_err("Invalid export format for -export-dependencies:<string>, got %.*s\n", LIT(value.value_string));
|
||||
gb_printf_err("Valid export formats:\n");
|
||||
gb_printf_err("\tmake\n");
|
||||
gb_printf_err("\tjson\n");
|
||||
bad_flags = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BuildFlag_ExportDependenciesFile: {
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
|
||||
String export_path = string_trim_whitespace(value.value_string);
|
||||
if (is_build_flag_path_valid(export_path)) {
|
||||
build_context.export_dependencies_file = path_to_full_path(heap_allocator(), export_path);
|
||||
} else {
|
||||
gb_printf_err("Invalid -export-dependencies path, got %.*s\n", LIT(export_path));
|
||||
bad_flags = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BuildFlag_ShowSystemCalls: {
|
||||
GB_ASSERT(value.kind == ExactValue_Invalid);
|
||||
build_context.show_system_calls = true;
|
||||
@@ -1119,21 +1148,6 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
case BuildFlag_DisableRedZone:
|
||||
build_context.disable_red_zone = true;
|
||||
break;
|
||||
case BuildFlag_TestName: {
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
{
|
||||
String name = value.value_string;
|
||||
if (!string_is_valid_identifier(name)) {
|
||||
gb_printf_err("Test name '%.*s' must be a valid identifier\n", LIT(name));
|
||||
bad_flags = true;
|
||||
break;
|
||||
}
|
||||
string_set_add(&build_context.test_names, name);
|
||||
|
||||
// NOTE(bill): Allow for multiple -test-name
|
||||
continue;
|
||||
}
|
||||
}
|
||||
case BuildFlag_DisallowDo:
|
||||
build_context.disallow_do = true;
|
||||
break;
|
||||
@@ -1635,6 +1649,74 @@ gb_internal void show_timings(Checker *c, Timings *t) {
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void export_dependencies(Parser *p) {
|
||||
GB_ASSERT(build_context.export_dependencies_format != DependenciesExportUnspecified);
|
||||
|
||||
if (build_context.export_dependencies_file.len <= 0) {
|
||||
gb_printf_err("No dependency file specified with `-export-dependencies-file`\n");
|
||||
exit_with_errors();
|
||||
return;
|
||||
}
|
||||
|
||||
gbFile f = {};
|
||||
char * fileName = (char *)build_context.export_dependencies_file.text;
|
||||
gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, fileName);
|
||||
if (err != gbFileError_None) {
|
||||
gb_printf_err("Failed to export dependencies to: %s\n", fileName);
|
||||
exit_with_errors();
|
||||
return;
|
||||
}
|
||||
defer (gb_file_close(&f));
|
||||
|
||||
if (build_context.export_dependencies_format == DependenciesExportMake) {
|
||||
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
|
||||
defer (gb_free(heap_allocator(), exe_name.text));
|
||||
|
||||
gb_fprintf(&f, "%.*s:", LIT(exe_name));
|
||||
|
||||
isize current_line_length = exe_name.len + 1;
|
||||
|
||||
for(AstPackage *pkg : p->packages) {
|
||||
for(AstFile *file : pkg->files) {
|
||||
/* Arbitrary line break value. Maybe make this better? */
|
||||
if (current_line_length >= 80-2) {
|
||||
gb_file_write(&f, " \\\n ", 4);
|
||||
current_line_length = 1;
|
||||
}
|
||||
|
||||
gb_file_write(&f, " ", 1);
|
||||
current_line_length++;
|
||||
|
||||
for (isize k = 0; k < file->fullpath.len; k++) {
|
||||
char part = file->fullpath.text[k];
|
||||
if (part == ' ') {
|
||||
gb_file_write(&f, "\\", 1);
|
||||
current_line_length++;
|
||||
}
|
||||
gb_file_write(&f, &part, 1);
|
||||
current_line_length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gb_fprintf(&f, "\n");
|
||||
} else if (build_context.export_dependencies_format == DependenciesExportJson) {
|
||||
gb_fprintf(&f, "{\n");
|
||||
|
||||
gb_fprintf(&f, "\t\"source_files\": [\n");
|
||||
|
||||
for(AstPackage *pkg : p->packages) {
|
||||
for(AstFile *file : pkg->files) {
|
||||
gb_fprintf(&f, "\t\t\"%.*s\",\n", LIT(file->fullpath));
|
||||
}
|
||||
}
|
||||
|
||||
gb_fprintf(&f, "\t],\n");
|
||||
|
||||
gb_fprintf(&f, "}\n");
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void remove_temp_files(lbGenerator *gen) {
|
||||
if (build_context.keep_temp_files) return;
|
||||
|
||||
@@ -1790,6 +1872,18 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(2, "Example: -export-timings-file:timings.json");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-export-dependencies:<format>");
|
||||
print_usage_line(2, "Exports dependencies to one of a few formats. Requires `-export-dependencies-file`.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-export-dependencies:make Exports in Makefile format");
|
||||
print_usage_line(3, "-export-dependencies:json Exports in JSON format");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-export-dependencies-file:<filename>");
|
||||
print_usage_line(2, "Specifies the filename for `-export-dependencies`.");
|
||||
print_usage_line(2, "Example: -export-dependencies-file:dependencies.d");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-thread-count:<integer>");
|
||||
print_usage_line(2, "Overrides the number of threads the compiler will use to compile with.");
|
||||
print_usage_line(2, "Example: -thread-count:2");
|
||||
@@ -1962,10 +2056,6 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
}
|
||||
|
||||
if (test_only) {
|
||||
print_usage_line(1, "-test-name:<string>");
|
||||
print_usage_line(2, "Runs specific test only by name.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-all-packages");
|
||||
print_usage_line(2, "Tests all packages imported into the given initial package.");
|
||||
print_usage_line(0, "");
|
||||
@@ -2489,7 +2579,6 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
TIME_SECTION("init args");
|
||||
map_init(&build_context.defined_values);
|
||||
build_context.extra_packages.allocator = heap_allocator();
|
||||
string_set_init(&build_context.test_names);
|
||||
|
||||
Array<String> args = setup_args(arg_count, arg_ptr);
|
||||
|
||||
@@ -2657,6 +2746,10 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
gb_printf_err("Expected either a directory or a .odin file, got '%.*s'\n", LIT(init_filename));
|
||||
return 1;
|
||||
}
|
||||
if (!gb_file_exists(cast(const char*)init_filename.text)) {
|
||||
gb_printf_err("The file '%.*s' was not found.\n", LIT(init_filename));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2881,6 +2974,10 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
if (build_context.show_timings) {
|
||||
show_timings(checker, &global_timings);
|
||||
}
|
||||
|
||||
if (build_context.export_dependencies_format != DependenciesExportUnspecified) {
|
||||
export_dependencies(parser);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
@@ -2903,6 +3000,10 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
if (build_context.show_timings) {
|
||||
show_timings(checker, &global_timings);
|
||||
}
|
||||
|
||||
if (build_context.export_dependencies_format != DependenciesExportUnspecified) {
|
||||
export_dependencies(parser);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
@@ -2916,6 +3017,10 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
show_timings(checker, &global_timings);
|
||||
}
|
||||
|
||||
if (build_context.export_dependencies_format != DependenciesExportUnspecified) {
|
||||
export_dependencies(parser);
|
||||
}
|
||||
|
||||
if (run_output) {
|
||||
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
|
||||
defer (gb_free(heap_allocator(), exe_name.text));
|
||||
|
||||
@@ -494,6 +494,8 @@ gb_internal u32 thread_current_id(void) {
|
||||
thread_id = find_thread(NULL);
|
||||
#elif defined(GB_SYSTEM_FREEBSD)
|
||||
thread_id = pthread_getthreadid_np();
|
||||
#elif defined(GB_SYSTEM_NETBSD)
|
||||
thread_id = (u32)_lwp_self();
|
||||
#else
|
||||
#error Unsupported architecture for thread_current_id()
|
||||
#endif
|
||||
|
||||
@@ -457,6 +457,15 @@ gb_internal Selection sub_selection(Selection const &sel, isize offset) {
|
||||
return res;
|
||||
}
|
||||
|
||||
gb_internal Selection trim_selection(Selection const &sel) {
|
||||
Selection res = {};
|
||||
res.index.data = sel.index.data;
|
||||
res.index.count = gb_max(sel.index.count - 1, 0);
|
||||
res.index.capacity = res.index.count;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
gb_global Type basic_types[] = {
|
||||
{Type_Basic, {Basic_Invalid, 0, 0, STR_LIT("invalid type")}},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user