Merge remote-tracking branch 'offical/master'

This commit is contained in:
2024-05-07 18:03:37 -04:00
11 changed files with 149 additions and 46 deletions
+2 -1
View File
@@ -2,7 +2,6 @@
set -eu
: ${CPPFLAGS=}
: ${CXX=clang++}
: ${CXXFLAGS=}
: ${LDFLAGS=}
: ${LLVM_CONFIG=}
@@ -44,6 +43,8 @@ if [ -z "$LLVM_CONFIG" ]; then
fi
fi
: ${CXX=$($LLVM_CONFIG --bindir)/clang++}
LLVM_VERSION="$($LLVM_CONFIG --version)"
LLVM_VERSION_MAJOR="$(echo $LLVM_VERSION | awk -F. '{print $1}')"
LLVM_VERSION_MINOR="$(echo $LLVM_VERSION | awk -F. '{print $2}')"
+1 -1
View File
@@ -2314,7 +2314,7 @@ futex :: proc {
*/
epoll_create :: proc(size: i32 = 1) -> (Fd, Errno) {
when ODIN_ARCH != .arm64 {
ret := syscall(SYS_epoll_create)
ret := syscall(SYS_epoll_create, i32(1))
return errno_unwrap(ret, Fd)
} else {
ret := syscall(SYS_epoll_create1, i32(0))
+2 -2
View File
@@ -25,7 +25,7 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
when ODIN_OS != .Darwin {
// We need to give the thread a moment to start up before we enable cancellation.
can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) == 0
can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0
}
sync.lock(&t.mutex)
@@ -40,7 +40,7 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
// Enable thread's cancelability.
if can_set_thread_cancel_state {
unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil)
unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil)
unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
}
}
+3
View File
@@ -2023,6 +2023,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
Selection sel = lookup_field(type, field_name, false);
if (sel.entity == nullptr) {
ERROR_BLOCK();
gbString type_str = type_to_string_shorthand(type);
error(ce->args[0],
"'%s' has no field named '%.*s'", type_str, LIT(field_name));
@@ -2096,6 +2097,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
Selection sel = lookup_field(type, field_name, false);
if (sel.entity == nullptr) {
ERROR_BLOCK();
gbString type_str = type_to_string_shorthand(type);
error(ce->args[0],
"'%s' has no field named '%.*s'", type_str, LIT(field_name));
@@ -5837,6 +5839,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
Selection sel = lookup_field(type, field_name, false);
if (sel.entity == nullptr) {
ERROR_BLOCK();
gbString type_str = type_to_string(bt);
error(ce->args[0],
"'%s' has no field named '%.*s'", type_str, LIT(field_name));
+8 -2
View File
@@ -102,6 +102,7 @@ gb_internal Type * check_init_variable (CheckerContext *c, Entity *
gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type, i64 max_bit_size=0);
gb_internal void add_map_key_type_dependencies(CheckerContext *ctx, Type *key);
gb_internal Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type);
gb_internal Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem);
gb_internal Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem);
@@ -1409,11 +1410,16 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T
poly->Struct.soa_kind != StructSoa_None) {
bool ok = is_polymorphic_type_assignable(c, poly->Struct.soa_elem, source->Struct.soa_elem, true, modify_type);
if (ok) switch (source->Struct.soa_kind) {
case StructSoa_Fixed:
case StructSoa_None:
default:
GB_PANIC("Unhandled SOA Kind");
break;
case StructSoa_Fixed:
if (modify_type) {
Type *type = make_soa_struct_fixed(c, nullptr, poly->Struct.node, poly->Struct.soa_elem, poly->Struct.soa_count, nullptr);
gb_memmove(poly, type, gb_size_of(*type));
}
break;
case StructSoa_Slice:
if (modify_type) {
Type *type = make_soa_struct_slice(c, nullptr, poly->Struct.node, poly->Struct.soa_elem);
+28 -4
View File
@@ -381,6 +381,7 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
Type *type = nullptr;
bool is_type_param = false;
bool is_type_polymorphic_type = false;
Type *specialization = nullptr;
if (type_expr == nullptr && default_value == nullptr) {
error(param, "Expected a type for this parameter");
continue;
@@ -393,7 +394,6 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
}
if (type_expr->kind == Ast_TypeidType) {
is_type_param = true;
Type *specialization = nullptr;
if (type_expr->TypeidType.specialization != nullptr) {
Ast *s = type_expr->TypeidType.specialization;
specialization = check_type(ctx, s);
@@ -471,6 +471,15 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
if (is_type_polymorphic(base_type(operand.type))) {
*is_polymorphic_ = true;
can_check_fields = false;
} else if (specialization &&
!check_type_specialization_to(ctx, specialization, operand.type, false, /*modify_type*/true)) {
if (!ctx->no_polymorphic_errors) {
gbString t = type_to_string(operand.type);
gbString s = type_to_string(specialization);
error(operand.expr, "Cannot convert type '%s' to the specialization '%s'", t, s);
gb_string_free(s);
gb_string_free(t);
}
}
e = alloc_entity_type_name(scope, token, operand.type);
e->TypeName.is_type_alias = true;
@@ -797,11 +806,11 @@ gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *nam
enum_type->Enum.scope = ctx->scope;
Type *base_type = t_int;
if (et->base_type != nullptr) {
if (unparen_expr(et->base_type) != nullptr) {
base_type = check_type(ctx, et->base_type);
}
if (base_type == nullptr || !is_type_integer(base_type)) {
if (base_type == nullptr || base_type == t_invalid || !is_type_integer(base_type)) {
error(node, "Base type for enumeration must be an integer");
return;
}
@@ -1080,6 +1089,8 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
array_add(&tags, tag);
add_entity_use(ctx, field, e);
total_bit_size += bit_size_u8;
}
}
@@ -1094,7 +1105,7 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type,
if (total_bit_size > maximum_bit_size) {
gbString s = type_to_string(backing_type);
error(node, "The numbers required %llu exceeds the backing type's (%s) bit size %llu",
error(node, "The total bit size of a bit_field's fields (%llu) must fit into its backing type's (%s) bit size of %llu",
cast(unsigned long long)total_bit_size,
s,
cast(unsigned long long)maximum_bit_size);
@@ -1428,6 +1439,10 @@ gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *special
bool can_convert = check_cast_internal(ctx, &o, specialization);
return can_convert;
} else if (t->kind == Type_Struct) {
if (t->Struct.polymorphic_parent == nullptr &&
t == s) {
return true;
}
if (t->Struct.polymorphic_parent == specialization) {
return true;
}
@@ -1477,6 +1492,10 @@ gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *special
return true;
}
} else if (t->kind == Type_Union) {
if (t->Union.polymorphic_parent == nullptr &&
t == s) {
return true;
}
if (t->Union.polymorphic_parent == specialization) {
return true;
}
@@ -3263,6 +3282,11 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T
case_end;
case_ast_node(pe, ParenExpr, e);
if (pe->expr == nullptr) {
error(e, "Expected an expression or type within the parentheses");
*type = t_invalid;
return true;
}
*type = check_type_expr(ctx, pe->expr, named_type);
set_base_type(named_type, *type);
return true;
+58 -34
View File
@@ -12,7 +12,7 @@ struct ErrorValue {
};
struct ErrorCollector {
TokenPos prev;
// TokenPos prev; // no point collecting because of the mulithreaded nature
std::atomic<i64> count;
std::atomic<i64> warning_count;
std::atomic<bool> in_block;
@@ -383,14 +383,13 @@ gb_internal void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va
}
push_error_value(pos, ErrorValue_Error);
// NOTE(bill): Duplicate error, skip it
if (pos.line == 0) {
error_out_empty();
error_out_coloured("Error: ", TerminalStyle_Normal, TerminalColour_Red);
error_out_va(fmt, va);
error_out("\n");
} else if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
} else {
// global_error_collector.prev = pos;
if (json_errors()) {
error_out_empty();
} else {
@@ -402,10 +401,6 @@ gb_internal void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va
error_out_va(fmt, va);
error_out("\n");
show_error_on_line(pos, end);
} else {
global_error_collector.curr_error_value = {};
global_error_collector.curr_error_value_set.store(false);
global_error_collector.count.fetch_sub(1);
}
try_pop_error_value();
mutex_unlock(&global_error_collector.mutex);
@@ -422,14 +417,13 @@ gb_internal void warning_va(TokenPos const &pos, TokenPos end, char const *fmt,
push_error_value(pos, ErrorValue_Warning);
if (!global_ignore_warnings()) {
// NOTE(bill): Duplicate error, skip it
if (pos.line == 0) {
error_out_empty();
error_out_coloured("Warning: ", TerminalStyle_Normal, TerminalColour_Yellow);
error_out_va(fmt, va);
error_out("\n");
} else if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
} else {
// global_error_collector.prev = pos;
if (json_errors()) {
error_out_empty();
} else {
@@ -460,13 +454,12 @@ gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_li
push_error_value(pos, ErrorValue_Error);
// NOTE(bill): Duplicate error, skip it
if (pos.line == 0) {
error_out_empty();
error_out_coloured("Error: ", TerminalStyle_Normal, TerminalColour_Red);
error_out_va(fmt, va);
} else if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
} else {
// global_error_collector.prev = pos;
if (json_errors()) {
error_out_empty();
} else {
@@ -493,9 +486,13 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
push_error_value(pos, ErrorValue_Warning);
// NOTE(bill): Duplicate error, skip it
if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
if (pos.line == 0) {
error_out_empty();
error_out_coloured("Syntax Error: ", TerminalStyle_Normal, TerminalColour_Red);
error_out_va(fmt, va);
error_out("\n");
} else {
// global_error_collector.prev = pos;
if (json_errors()) {
error_out_empty();
} else {
@@ -505,11 +502,6 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
error_out_va(fmt, va);
error_out("\n");
show_error_on_line(pos, end);
} else if (pos.line == 0) {
error_out_empty();
error_out_coloured("Syntax Error: ", TerminalStyle_Normal, TerminalColour_Red);
error_out_va(fmt, va);
error_out("\n");
}
try_pop_error_value();
@@ -526,14 +518,13 @@ gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end,
push_error_value(pos, ErrorValue_Warning);
// NOTE(bill): Duplicate error, skip it
if (pos.line == 0) {
error_out_empty();
error_out_coloured("Syntax_Error: ", TerminalStyle_Normal, TerminalColour_Red);
error_out_va(fmt, va);
error_out("\n");
} else if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
} else {
// global_error_collector.prev = pos;
if (json_errors()) {
error_out_empty();
} else {
@@ -564,9 +555,13 @@ gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const
push_error_value(pos, ErrorValue_Warning);
if (!global_ignore_warnings()) {
// NOTE(bill): Duplicate error, skip it
if (global_error_collector.prev != pos) {
global_error_collector.prev = pos;
if (pos.line == 0) {
error_out_empty();
error_out_coloured("Syntax Warning: ", TerminalStyle_Normal, TerminalColour_Yellow);
error_out_va(fmt, va);
error_out("\n");
} else {
// global_error_collector.prev = pos;
if (json_errors()) {
error_out_empty();
} else {
@@ -576,11 +571,6 @@ gb_internal void syntax_warning_va(TokenPos const &pos, TokenPos end, char const
error_out_va(fmt, va);
error_out("\n");
// show_error_on_line(pos, end);
} else if (pos.line == 0) {
error_out_empty();
error_out_coloured("Syntax Warning: ", TerminalStyle_Normal, TerminalColour_Yellow);
error_out_va(fmt, va);
error_out("\n");
}
}
@@ -705,9 +695,42 @@ gb_internal void print_all_errors(void) {
GB_ASSERT(any_errors() || any_warnings());
array_sort(global_error_collector.error_values, error_value_cmp);
{ // NOTE(bill): merge neighbouring errors
isize default_lines_to_skip = 1;
if (show_error_line()) {
// NOTE(bill): this will always be 2 extra lines
default_lines_to_skip += 2;
}
ErrorValue *prev_ev = nullptr;
for (isize i = 0; i < global_error_collector.error_values.count; /**/) {
ErrorValue &ev = global_error_collector.error_values[i];
if (prev_ev && prev_ev->pos == ev.pos) {
String_Iterator it = {{ev.msg.data, ev.msg.count}, 0};
for (isize lines_to_skip = default_lines_to_skip; lines_to_skip > 0; lines_to_skip -= 1) {
String line = string_split_iterator(&it, '\n');
if (line.len == 0) {
break;
}
}
if (it.str.len-it.pos > 0) {
array_add_elems(&prev_ev->msg, it.str.text+it.pos, it.str.len-it.pos);
}
array_free(&ev.msg);
array_ordered_remove(&global_error_collector.error_values, i);
} else {
prev_ev = &ev;
i += 1;
}
}
}
gbString res = gb_string_make(heap_allocator(), "");
defer (gb_string_free(res));
@@ -715,6 +738,7 @@ gb_internal void print_all_errors(void) {
res = gb_string_append_fmt(res, "{\n");
res = gb_string_append_fmt(res, "\t\"error_count\": %td,\n", global_error_collector.error_values.count);
res = gb_string_append_fmt(res, "\t\"errors\": [\n");
for_array(i, global_error_collector.error_values) {
ErrorValue ev = global_error_collector.error_values[i];
+5 -1
View File
@@ -581,6 +581,10 @@ gb_internal LLVMTypeRef llvm_array_type(LLVMTypeRef ElementType, uint64_t Elemen
#endif
}
gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value);
gb_internal u64 lb_get_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name);
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
#define LB_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime"
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
@@ -719,4 +723,4 @@ gb_global char const *llvm_linkage_strings[] = {
"linker private weak linkage"
};
#define ODIN_METADATA_REQUIRE "odin-metadata-require", 21
#define ODIN_METADATA_IS_PACKED str_lit("odin-is-packed")
+6
View File
@@ -1107,6 +1107,12 @@ gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) {
GB_ASSERT(is_type_pointer(value.type));
Type *t = type_deref(value.type);
LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, "");
u64 is_packed = lb_get_metadata_custom_u64(p->module, value.value, ODIN_METADATA_IS_PACKED);
if (is_packed != 0) {
LLVMSetAlignment(v, 1);
}
return lbValue{v, t};
}
+32 -1
View File
@@ -57,6 +57,29 @@ gb_internal lbValue lb_correct_endianness(lbProcedure *p, lbValue value) {
return value;
}
gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value) {
unsigned md_id = LLVMGetMDKindIDInContext(m->ctx, cast(char const *)name.text, cast(unsigned)name.len);
LLVMMetadataRef md = LLVMValueAsMetadata(LLVMConstInt(lb_type(m, t_u64), value, false));
LLVMValueRef node = LLVMMetadataAsValue(m->ctx, LLVMMDNodeInContext2(m->ctx, &md, 1));
LLVMSetMetadata(v_ref, md_id, node);
}
gb_internal u64 lb_get_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name) {
unsigned md_id = LLVMGetMDKindIDInContext(m->ctx, cast(char const *)name.text, cast(unsigned)name.len);
LLVMValueRef v_md = LLVMGetMetadata(v_ref, md_id);
if (v_md == nullptr) {
return 0;
}
unsigned node_count = LLVMGetMDNodeNumOperands(v_md);
if (node_count == 0) {
return 0;
}
GB_ASSERT(node_count == 1);
LLVMValueRef value = nullptr;
LLVMGetMDNodeOperands(v_md, &value);
return LLVMConstIntGetZExtValue(value);
}
gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, usize len, unsigned alignment, bool is_volatile) {
return lb_mem_zero_ptr_internal(p, ptr, LLVMConstInt(lb_type(p->module, t_uint), len, false), alignment, is_volatile);
}
@@ -1148,7 +1171,15 @@ gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
return lb_emit_struct_ep_internal(p, s, index, result_type);
lbValue gep = lb_emit_struct_ep_internal(p, s, index, result_type);
Type *bt = base_type(t);
if (bt->kind == Type_Struct && bt->Struct.is_packed) {
lb_set_metadata_custom_u64(p->module, gep.value, ODIN_METADATA_IS_PACKED, 1);
GB_ASSERT(lb_get_metadata_custom_u64(p->module, gep.value, ODIN_METADATA_IS_PACKED) == 1);
}
return gep;
}
gb_internal lbValue lb_emit_tuple_ev(lbProcedure *p, lbValue value, i32 index) {
+4
View File
@@ -3499,6 +3499,10 @@ gb_internal Ast *parse_type(AstFile *f) {
Token token = advance_token(f);
syntax_error(token, "Expected a type");
return ast_bad_expr(f, token, f->curr_token);
} else if (type->kind == Ast_ParenExpr &&
unparen_expr(type) == nullptr) {
syntax_error(type, "Expected a type within the parentheses");
return ast_bad_expr(f, type->ParenExpr.open, type->ParenExpr.close);
}
return type;
}