diff options
| author | gingerBill <bill@gingerbill.org> | 2023-09-27 11:38:11 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-09-27 11:38:11 +0100 |
| commit | acc29fbcebf4459b1c98c54d9cc565d363a4196a (patch) | |
| tree | 91b4692e0a8c9c3958ed44347ded5a2f40ee157d /src | |
| parent | 94d68c1f225c3699d905388baee15e42ec6e49a0 (diff) | |
| parent | fc93ea7aa370d25aab61dab43e885f50978dff50 (diff) | |
Merge branch 'master' into llvm-17
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_builtin.cpp | 2 | ||||
| -rw-r--r-- | src/check_expr.cpp | 16 | ||||
| -rw-r--r-- | src/check_stmt.cpp | 2 | ||||
| -rw-r--r-- | src/check_type.cpp | 3 | ||||
| -rw-r--r-- | src/checker.cpp | 3 | ||||
| -rw-r--r-- | src/error.cpp | 37 | ||||
| -rw-r--r-- | src/llvm_backend_expr.cpp | 23 | ||||
| -rw-r--r-- | src/parser.cpp | 60 | ||||
| -rw-r--r-- | src/types.cpp | 42 |
9 files changed, 149 insertions, 39 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 2e65c5750..851665cb2 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -2120,7 +2120,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As return false; } Type *t = o.type; - if (t == nullptr || t == t_invalid || is_type_asm_proc(o.type) || is_type_polymorphic(operand->type)) { + if (t == nullptr || t == t_invalid || is_type_asm_proc(t) || is_type_polymorphic(t)) { error(ce->args[0], "Invalid argument for '%.*s'", LIT(builtin_name)); return false; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 700412a86..968b6ec1e 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2462,8 +2462,9 @@ gb_internal void add_comparison_procedures_for_fields(CheckerContext *c, Type *t add_package_dependency(c, "runtime", "quaternion256_ne"); break; case Basic_cstring: - add_package_dependency(c, "runtime", "cstring_to_string"); - /*fallthrough*/ + add_package_dependency(c, "runtime", "cstring_eq"); + add_package_dependency(c, "runtime", "cstring_ne"); + break; case Basic_string: add_package_dependency(c, "runtime", "string_eq"); add_package_dependency(c, "runtime", "string_ne"); @@ -2621,7 +2622,16 @@ gb_internal void check_comparison(CheckerContext *c, Ast *node, Operand *x, Oper if (!is_type_untyped(x->type)) size = gb_max(size, type_size_of(x->type)); if (!is_type_untyped(y->type)) size = gb_max(size, type_size_of(y->type)); - if (is_type_string(x->type) || is_type_string(y->type)) { + if (is_type_cstring(x->type) && is_type_cstring(y->type)) { + switch (op) { + case Token_CmpEq: add_package_dependency(c, "runtime", "cstring_eq"); break; + case Token_NotEq: add_package_dependency(c, "runtime", "cstring_ne"); break; + case Token_Lt: add_package_dependency(c, "runtime", "cstring_lt"); break; + case Token_Gt: add_package_dependency(c, "runtime", "cstring_gt"); break; + case Token_LtEq: add_package_dependency(c, "runtime", "cstring_le"); break; + case Token_GtEq: add_package_dependency(c, "runtime", "cstring_gt"); break; + } + } else if (is_type_string(x->type) || is_type_string(y->type)) { switch (op) { case Token_CmpEq: add_package_dependency(c, "runtime", "string_eq"); break; case Token_NotEq: add_package_dependency(c, "runtime", "string_ne"); break; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cb1aa86ab..3f1b9611c 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1893,7 +1893,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f } if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) { - error(e->token, "@(thread_local) is not supported for this target platform"); + // error(e->token, "@(thread_local) is not supported for this target platform"); } diff --git a/src/check_type.cpp b/src/check_type.cpp index 5e7e76d66..a43c296a6 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -613,6 +613,9 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast * scope_reserve(ctx->scope, min_field_count); + rw_mutex_lock(&struct_type->Struct.fields_mutex); + defer (rw_mutex_unlock(&struct_type->Struct.fields_mutex)); + if (st->is_raw_union && min_field_count > 1) { struct_type->Struct.is_raw_union = true; context = str_lit("struct #raw_union"); diff --git a/src/checker.cpp b/src/checker.cpp index 984a00a90..7182b6559 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2029,6 +2029,9 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { break; + case Type_Generic: + break; + default: GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind); break; diff --git a/src/error.cpp b/src/error.cpp index 6a039006b..e63682829 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -356,7 +356,9 @@ gb_internal void error_out_coloured(char const *str, TerminalStyle style, Termin gb_internal void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { global_error_collector.count.fetch_add(1); - + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { + gb_exit(1); + } mutex_lock(&global_error_collector.mutex); // NOTE(bill): Duplicate error, skip it if (pos.line == 0) { @@ -372,11 +374,10 @@ 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.count.fetch_sub(1); } mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { - gb_exit(1); - } } gb_internal void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { @@ -410,8 +411,11 @@ gb_internal void error_line_va(char const *fmt, va_list va) { } gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) { - mutex_lock(&global_error_collector.mutex); global_error_collector.count.fetch_add(1); + if (global_error_collector.count.load() > MAX_ERROR_COLLECTOR_COUNT()) { + gb_exit(1); + } + mutex_lock(&global_error_collector.mutex); // NOTE(bill): Duplicate error, skip it if (pos.line == 0) { error_out_coloured("Error: ", TerminalStyle_Normal, TerminalColour_Red); @@ -425,15 +429,15 @@ gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_li error_out_va(fmt, va); } mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count.load() > MAX_ERROR_COLLECTOR_COUNT()) { - gb_exit(1); - } } gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + global_error_collector.count.fetch_add(1); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { + gb_exit(1); + } mutex_lock(&global_error_collector.mutex); - global_error_collector.count++; // NOTE(bill): Duplicate error, skip it if (global_error_collector.prev != pos) { global_error_collector.prev = pos; @@ -447,16 +451,14 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const * error_out_va(fmt, va); error_out("\n"); } - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { - gb_exit(1); - } } gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { global_error_collector.count.fetch_add(1); - + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { + gb_exit(1); + } mutex_lock(&global_error_collector.mutex); // NOTE(bill): Duplicate error, skip it if (pos.line == 0) { @@ -474,9 +476,6 @@ gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end, show_error_on_line(pos, end); } mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { - gb_exit(1); - } } @@ -578,7 +577,3 @@ gb_internal void compiler_error(char const *fmt, ...) { GB_DEBUG_TRAP(); gb_exit(1); } - - - - diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index e8569eba9..d6e8843fa 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2414,7 +2414,28 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left } if (is_type_string(a)) { - if (is_type_cstring(a)) { + if (is_type_cstring(a) && is_type_cstring(b)) { + left = lb_emit_conv(p, left, t_cstring); + right = lb_emit_conv(p, right, t_cstring); + char const *runtime_procedure = nullptr; + switch (op_kind) { + case Token_CmpEq: runtime_procedure = "cstring_eq"; break; + case Token_NotEq: runtime_procedure = "cstring_ne"; break; + case Token_Lt: runtime_procedure = "cstring_lt"; break; + case Token_Gt: runtime_procedure = "cstring_gt"; break; + case Token_LtEq: runtime_procedure = "cstring_le"; break; + case Token_GtEq: runtime_procedure = "cstring_gt"; break; + } + GB_ASSERT(runtime_procedure != nullptr); + + auto args = array_make<lbValue>(permanent_allocator(), 2); + args[0] = left; + args[1] = right; + return lb_emit_runtime_call(p, runtime_procedure, args); + } + + + if (is_type_cstring(a) ^ is_type_cstring(b)) { left = lb_emit_conv(p, left, t_string); right = lb_emit_conv(p, right, t_string); } diff --git a/src/parser.cpp b/src/parser.cpp index cdf3c239c..a4bf949b9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1361,6 +1361,22 @@ gb_internal Token peek_token(AstFile *f) { return {}; } +gb_internal Token peek_token_n(AstFile *f, isize n) { + Token found = {}; + for (isize i = f->curr_token_index+1; i < f->tokens.count; i++) { + Token tok = f->tokens[i]; + if (tok.kind == Token_Comment) { + continue; + } + found = tok; + if (n-- == 0) { + return found; + } + } + return {}; +} + + gb_internal bool skip_possible_newline(AstFile *f) { if (token_is_newline(f->curr_token)) { advance_token(f); @@ -2206,6 +2222,10 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { Ast *tag = ast_basic_directive(f, token, name); Ast *original_expr = parse_expr(f, lhs); Ast *expr = unparen_expr(original_expr); + if (expr == nullptr) { + syntax_error(name, "Expected a compound literal after #%.*s", LIT(name.string)); + return ast_bad_expr(f, token, name); + } switch (expr->kind) { case Ast_ArrayType: syntax_error(expr, "#partial has been replaced with #sparse for non-contiguous enumerated array types"); @@ -3419,6 +3439,18 @@ gb_internal Ast *parse_simple_stmt(AstFile *f, u32 flags) { case Token_Colon: expect_token_after(f, Token_Colon, "identifier list"); if ((flags&StmtAllowFlag_Label) && lhs.count == 1) { + bool is_partial = false; + Token partial_token = {}; + if (f->curr_token.kind == Token_Hash) { + // NOTE(bill): This is purely for error messages + Token name = peek_token_n(f, 0); + if (name.kind == Token_Ident && name.string == "partial" && + peek_token_n(f, 1).kind == Token_switch) { + partial_token = expect_token(f, Token_Hash); + expect_token(f, Token_Ident); + is_partial = true; + } + } switch (f->curr_token.kind) { case Token_OpenBrace: // block statement case Token_if: @@ -3440,6 +3472,19 @@ gb_internal Ast *parse_simple_stmt(AstFile *f, u32 flags) { break; } #undef _SET_LABEL + + if (is_partial) { + switch (stmt->kind) { + case Ast_SwitchStmt: + stmt->SwitchStmt.partial = true; + break; + case Ast_TypeSwitchStmt: + stmt->TypeSwitchStmt.partial = true; + break; + } + syntax_error(partial_token, "Incorrect use of directive, use '#partial %.*s: switch'", LIT(ast_token(name).string)); + } + return stmt; } break; } @@ -3984,7 +4029,9 @@ gb_internal Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_fl if (f->curr_token.kind != Token_Eq) { type = parse_var_type(f, allow_ellipsis, allow_typeid_token); Ast *tt = unparen_expr(type); - if (is_signature && !any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) { + if (is_signature && !any_polymorphic_names && + tt != nullptr && + tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) { syntax_error(type, "Specialization of typeid is not allowed without polymorphic names"); } } @@ -5941,6 +5988,16 @@ gb_internal ParseFileError process_imported_file(Parser *p, ImportedFile importe } } + { + String name = file->fullpath; + name = remove_directory_from_path(name); + name = remove_extension_from_path(name); + + if (string_starts_with(name, str_lit("_"))) { + syntax_error(pos, "Files cannot start with '_', got '%.*s'", LIT(file->fullpath)); + } + } + if (build_context.command_kind == Command_test) { String name = file->fullpath; name = remove_extension_from_path(name); @@ -5951,6 +6008,7 @@ gb_internal ParseFileError process_imported_file(Parser *p, ImportedFile importe } } + if (parse_file(p, file)) { MUTEX_GUARD_BLOCK(&pkg->files_mutex) { array_add(&pkg->files, file); diff --git a/src/types.cpp b/src/types.cpp index 22deca1dc..f3062365f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -143,7 +143,8 @@ struct TypeStruct { Type * soa_elem; i32 soa_count; StructSoaKind soa_kind; - BlockingMutex mutex; // for settings offsets + RwMutex fields_mutex; + BlockingMutex offset_mutex; // for settings offsets bool is_polymorphic; bool are_offsets_set : 1; @@ -2645,10 +2646,14 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple return are_types_identical(x->Slice.elem, y->Slice.elem); case Type_BitSet: - return are_types_identical(x->BitSet.elem, y->BitSet.elem) && - are_types_identical(x->BitSet.underlying, y->BitSet.underlying) && - x->BitSet.lower == y->BitSet.lower && - x->BitSet.upper == y->BitSet.upper; + if (are_types_identical(x->BitSet.elem, y->BitSet.elem) && + are_types_identical(x->BitSet.underlying, y->BitSet.underlying)) { + if (is_type_enum(x->BitSet.elem)) { + return true; + } + return x->BitSet.lower == y->BitSet.lower && x->BitSet.upper == y->BitSet.upper; + } + return false; case Type_Enum: @@ -2951,7 +2956,11 @@ gb_internal Selection lookup_field_from_index(Type *type, i64 index) { gbAllocator a = permanent_allocator(); isize max_count = 0; switch (type->kind) { - case Type_Struct: max_count = type->Struct.fields.count; break; + case Type_Struct: + rw_mutex_shared_lock(&type->Struct.fields_mutex); + max_count = type->Struct.fields.count; + rw_mutex_shared_unlock(&type->Struct.fields_mutex); + break; case Type_Tuple: max_count = type->Tuple.variables.count; break; } @@ -2960,7 +2969,9 @@ gb_internal Selection lookup_field_from_index(Type *type, i64 index) { } switch (type->kind) { - case Type_Struct: + case Type_Struct: { + rw_mutex_shared_lock(&type->Struct.fields_mutex); + defer (rw_mutex_shared_unlock(&type->Struct.fields_mutex)); for (isize i = 0; i < max_count; i++) { Entity *f = type->Struct.fields[i]; if (f->kind == Entity_Variable) { @@ -2971,7 +2982,8 @@ gb_internal Selection lookup_field_from_index(Type *type, i64 index) { } } } - break; + } break; + case Type_Tuple: for (isize i = 0; i < max_count; i++) { Entity *f = type->Tuple.variables[i]; @@ -3024,7 +3036,10 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } } if (type->kind == Type_Struct) { - for_array(i, type->Struct.fields) { + rw_mutex_shared_lock(&type->Struct.fields_mutex); + isize field_count = type->Struct.fields.count; + rw_mutex_shared_unlock(&type->Struct.fields_mutex); + if (field_count != 0) for_array(i, type->Struct.fields) { Entity *f = type->Struct.fields[i]; if (f->flags&EntityFlag_Using) { sel = lookup_field_with_selection(f->type, field_name, is_type, sel, allow_blank_ident); @@ -3052,7 +3067,9 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } if (type->kind == Type_Struct) { + rw_mutex_shared_lock(&type->Struct.fields_mutex); Scope *s = type->Struct.scope; + rw_mutex_shared_unlock(&type->Struct.fields_mutex); if (s != nullptr) { Entity *found = scope_lookup_current(s, field_name); if (found != nullptr && found->kind != Entity_Variable) { @@ -3100,7 +3117,10 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } } - for_array(i, type->Struct.fields) { + rw_mutex_shared_lock(&type->Struct.fields_mutex); + isize field_count = type->Struct.fields.count; + rw_mutex_shared_unlock(&type->Struct.fields_mutex); + if (field_count != 0) for_array(i, type->Struct.fields) { Entity *f = type->Struct.fields[i]; if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) { continue; @@ -3680,7 +3700,7 @@ gb_internal i64 *type_set_offsets_of(Slice<Entity *> const &fields, bool is_pack gb_internal bool type_set_offsets(Type *t) { t = base_type(t); if (t->kind == Type_Struct) { - MUTEX_GUARD(&t->Struct.mutex); + MUTEX_GUARD(&t->Struct.offset_mutex); if (!t->Struct.are_offsets_set) { t->Struct.are_offsets_being_processed = true; t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union); |