From 34a048f7daaf93b16ae4121bf5238f9008f3465b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 9 Dec 2022 11:29:28 +0000 Subject: Replace compiler for loops for the hash-table types to simplify code usage --- src/check_decl.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 0e41dbbb5..18e5477d6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1499,8 +1499,8 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty if (t->kind == Type_Struct) { Scope *scope = t->Struct.scope; GB_ASSERT(scope != nullptr); - MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { - Entity *f = scope->elements.entries[i].value; + MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + Entity *f = entry.value; if (f->kind == Entity_Variable) { Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr); if (is_value) uvar->flags |= EntityFlag_Value; @@ -1599,12 +1599,12 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level - for_array(i, decl->deps.entries) { - Entity *e = decl->deps.entries[i].ptr; + for (auto const &entry : decl->deps) { + Entity *e = entry.ptr; ptr_set_add(&decl->parent->deps, e); } - for_array(i, decl->type_info_deps.entries) { - Type *t = decl->type_info_deps.entries[i].ptr; + for (auto const &entry : decl->type_info_deps) { + Type *t = entry.ptr; ptr_set_add(&decl->parent->type_info_deps, t); } -- cgit v1.2.3 From 690666537c8a27d3c418b38b3285899100c9a556 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 18 Dec 2022 21:46:27 +0000 Subject: Add `gb_internal` to checker --- src/check_builtin.cpp | 34 ++--- src/check_decl.cpp | 44 +++--- src/check_expr.cpp | 334 +++++++++++++++++++++--------------------- src/check_stmt.cpp | 46 +++--- src/check_type.cpp | 80 +++++----- src/checker.cpp | 393 +++++++++++++++++++++++++------------------------- src/types.cpp | 3 +- 7 files changed, 466 insertions(+), 468 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 533929200..859fbea28 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1,6 +1,6 @@ typedef bool (BuiltinTypeIsProc)(Type *t); -BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - BuiltinProc__type_simple_boolean_begin] = { +gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - BuiltinProc__type_simple_boolean_begin] = { nullptr, // BuiltinProc__type_simple_boolean_begin is_type_boolean, @@ -51,7 +51,7 @@ BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - }; -void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type) { +gb_internal void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type) { if (right_type == nullptr) { return; } @@ -62,7 +62,7 @@ void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, } } -void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { +gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { Type *left_type = nullptr; Type *right_type = nullptr; if (x->type->kind == Type_Tuple) { @@ -88,7 +88,7 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name } -void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) { +gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) { // TODO(bill): better error message gbString t = type_to_string(x.type); error(x.expr, "'%.*s' does not return a value, value is of type %s", LIT(name), t); @@ -118,7 +118,7 @@ void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Op } -void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { +gb_internal void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_) { Type *left_type = nullptr; Type *right_type = nullptr; if (x->type->kind == Type_Tuple) { @@ -144,7 +144,7 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na } -bool does_require_msgSend_stret(Type *return_type) { +gb_internal bool does_require_msgSend_stret(Type *return_type) { if (return_type == nullptr) { return false; } @@ -165,7 +165,7 @@ bool does_require_msgSend_stret(Type *return_type) { return false; } -ObjcMsgKind get_objc_proc_kind(Type *return_type) { +gb_internal ObjcMsgKind get_objc_proc_kind(Type *return_type) { if (return_type == nullptr) { return ObjcMsg_normal; } @@ -189,7 +189,7 @@ ObjcMsgKind get_objc_proc_kind(Type *return_type) { return ObjcMsg_normal; } -void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { +gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { ObjcMsgKind kind = get_objc_proc_kind(return_type); Scope *scope = create_scope(c->info, nullptr); @@ -230,7 +230,7 @@ void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Sliceproc); String builtin_name = bd->name.string; @@ -1170,7 +1170,7 @@ bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &origi } -bool is_valid_type_for_load(Type *type) { +gb_internal bool is_valid_type_for_load(Type *type) { if (type == t_invalid) { return false; } else if (is_type_string(type)) { @@ -1191,7 +1191,7 @@ bool is_valid_type_for_load(Type *type) { return false; } -LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) { +gb_internal LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) { ast_node(ce, CallExpr, call); ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -1256,7 +1256,7 @@ LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, As } -bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint) { +gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint) { ast_node(ce, CallExpr, call); ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -1581,7 +1581,7 @@ bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast return true; } -bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { +gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { ast_node(ce, CallExpr, call); if (ce->inlining != ProcInlining_none) { error(call, "Inlining operators are not allowed on built-in procedures"); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 18e5477d6..a976c1b73 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1,7 +1,7 @@ -void check_stmt (CheckerContext *ctx, Ast *node, u32 flags); +gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags); // NOTE(bill): 'content_name' is for debugging and error messages -Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) { +gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) { if (operand->mode == Addressing_Invalid || operand->type == t_invalid || e->type == t_invalid) { @@ -110,7 +110,7 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri return e->type; } -void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice const &inits, String context_name) { +gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice const &inits, String context_name) { if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) { return; } @@ -144,7 +144,7 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Sl } } -void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { +gb_internal void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { if (operand->mode == Addressing_Invalid || operand->type == t_invalid || e->type == t_invalid) { @@ -184,7 +184,7 @@ void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { } -bool is_type_distinct(Ast *node) { +gb_internal bool is_type_distinct(Ast *node) { for (;;) { if (node == nullptr) { return false; @@ -217,7 +217,7 @@ bool is_type_distinct(Ast *node) { return false; } -Ast *remove_type_alias_clutter(Ast *node) { +gb_internal Ast *remove_type_alias_clutter(Ast *node) { for (;;) { if (node == nullptr) { return nullptr; @@ -232,7 +232,7 @@ Ast *remove_type_alias_clutter(Ast *node) { } } -isize total_attribute_count(DeclInfo *decl) { +gb_internal isize total_attribute_count(DeclInfo *decl) { isize attribute_count = 0; for_array(i, decl->attributes) { Ast *attr = decl->attributes[i]; @@ -242,7 +242,7 @@ isize total_attribute_count(DeclInfo *decl) { return attribute_count; } -Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { +gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations // // X :: enum {A, B, C} @@ -288,7 +288,7 @@ Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named return et; } -void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) { +gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) { GB_ASSERT(e->type == nullptr); DeclInfo *decl = decl_info_of_entity(e); @@ -390,7 +390,7 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) } -void override_entity_in_scope(Entity *original_entity, Entity *new_entity) { +gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_entity) { // NOTE(bill): The original_entity's scope may not be same scope that it was inserted into // e.g. file entity inserted into its package scope String original_name = original_entity->token.string; @@ -433,7 +433,7 @@ void override_entity_in_scope(Entity *original_entity, Entity *new_entity) { -void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) { +gb_internal void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) { GB_ASSERT(e->type == nullptr); GB_ASSERT(e->kind == Entity_Constant); init = unparen_expr(init); @@ -609,12 +609,12 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, typedef bool TypeCheckSig(Type *t); -bool sig_compare(TypeCheckSig *a, Type *x, Type *y) { +gb_internal bool sig_compare(TypeCheckSig *a, Type *x, Type *y) { x = core_type(x); y = core_type(y); return (a(x) && a(y)); } -bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { +gb_internal bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { x = core_type(x); y = core_type(y); if (a == b) { @@ -623,7 +623,7 @@ bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { return ((a(x) && b(y)) || (b(x) && a(y))); } -bool signature_parameter_similar_enough(Type *x, Type *y) { +gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) { if (sig_compare(is_type_pointer, x, y)) { return true; } @@ -674,7 +674,7 @@ bool signature_parameter_similar_enough(Type *x, Type *y) { } -bool are_signatures_similar_enough(Type *a_, Type *b_) { +gb_internal bool are_signatures_similar_enough(Type *a_, Type *b_) { GB_ASSERT(a_->kind == Type_Proc); GB_ASSERT(b_->kind == Type_Proc); TypeProc *a = &a_->Proc; @@ -704,7 +704,7 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) { return true; } -Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) { +gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) { Ast *ident = nullptr; Entity **foreign_library = nullptr; @@ -747,7 +747,7 @@ Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) { return nullptr; } -String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) { +gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) { if (link_prefix.len > 0) { if (link_name.len > 0) { error(token, "'link_name' and 'link_prefix' cannot be used together"); @@ -764,7 +764,7 @@ String handle_link_name(CheckerContext *ctx, Token token, String link_name, Stri return link_name; } -void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { +gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { GB_ASSERT(e->type == nullptr); if (d->proc_lit->kind != Ast_ProcLit) { // TOOD(bill): Better error message @@ -1121,7 +1121,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } } -void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) { +gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) { GB_ASSERT(e->type == nullptr); GB_ASSERT(e->kind == Entity_Variable); @@ -1239,7 +1239,7 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed"); } -void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) { +gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) { GB_ASSERT(pg_entity->kind == Entity_ProcGroup); auto *pge = &pg_entity->ProcGroup; String proc_group_name = pg_entity->token.string; @@ -1367,7 +1367,7 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) } -void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) { +gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) { if (e->state == EntityState_Resolved) { return; } @@ -1437,7 +1437,7 @@ struct ProcUsingVar { }; -void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { +gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { if (body == nullptr) { return; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fbc4f8b63..3003e07b6 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -17,7 +17,7 @@ enum CallArgumentError { CallArgumentError_MAX, }; -char const *CallArgumentError_strings[CallArgumentError_MAX] = { +gb_global char const *CallArgumentError_strings[CallArgumentError_MAX] = { "None", "NoneProcedureType", "WrongTypes", @@ -57,7 +57,7 @@ struct ValidIndexAndScore { i64 score; }; -int valid_index_and_score_cmp(void const *a, void const *b) { +gb_internal int valid_index_and_score_cmp(void const *a, void const *b) { i64 si = (cast(ValidIndexAndScore const *)a)->score; i64 sj = (cast(ValidIndexAndScore const *)b)->score; return sj < si ? -1 : sj > si; @@ -70,56 +70,56 @@ typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType); -void check_expr (CheckerContext *c, Operand *operand, Ast *expression); -void check_multi_expr (CheckerContext *c, Operand *operand, Ast *expression); -void check_multi_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression); -void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint); -void check_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); -ExprKind check_expr_base (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); -void check_expr_with_type_hint (CheckerContext *c, Operand *o, Ast *e, Type *t); -Type * check_type (CheckerContext *c, Ast *expression); -Type * check_type_expr (CheckerContext *c, Ast *expression, Type *named_type); -Type * make_optional_ok_type (Type *value, bool typed=true); -Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint); -Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name); -Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure); -void check_not_tuple (CheckerContext *c, Operand *operand); -void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); -gbString expr_to_string (Ast *expression); -void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body); -void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); -bool check_is_terminating (Ast *node, String const &label); -bool check_has_break (Ast *stmt, String const &label, bool implicit); -void check_stmt (CheckerContext *c, Ast *node, u32 flags); -void check_stmt_list (CheckerContext *c, Slice const &stmts, u32 flags); -void check_init_constant (CheckerContext *c, Entity *e, Operand *operand); -bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value); -bool check_procedure_type (CheckerContext *c, Type *type, Ast *proc_type_node, Array *operands = nullptr); -void check_struct_type (CheckerContext *c, Type *struct_type, Ast *node, Array *poly_operands, - Type *named_type = nullptr, Type *original_type_for_poly = nullptr); -void check_union_type (CheckerContext *c, Type *union_type, Ast *node, Array *poly_operands, - Type *named_type = nullptr, Type *original_type_for_poly = nullptr); +gb_internal void check_expr (CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_multi_expr (CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_multi_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint); +gb_internal void check_expr_or_type (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); +gb_internal ExprKind check_expr_base (CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint); +gb_internal void check_expr_with_type_hint (CheckerContext *c, Operand *o, Ast *e, Type *t); +gb_internal Type * check_type (CheckerContext *c, Ast *expression); +gb_internal Type * check_type_expr (CheckerContext *c, Ast *expression, Type *named_type); +gb_internal Type * make_optional_ok_type (Type *value, bool typed=true); +gb_internal Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint); +gb_internal Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name); +gb_internal Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure); +gb_internal void check_not_tuple (CheckerContext *c, Operand *operand); +gb_internal void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); +gb_internal gbString expr_to_string (Ast *expression); +gb_internal void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body); +gb_internal void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); +gb_internal bool check_is_terminating (Ast *node, String const &label); +gb_internal bool check_has_break (Ast *stmt, String const &label, bool implicit); +gb_internal void check_stmt (CheckerContext *c, Ast *node, u32 flags); +gb_internal void check_stmt_list (CheckerContext *c, Slice const &stmts, u32 flags); +gb_internal void check_init_constant (CheckerContext *c, Entity *e, Operand *operand); +gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value); +gb_internal bool check_procedure_type (CheckerContext *c, Type *type, Ast *proc_type_node, Array *operands = nullptr); +gb_internal void check_struct_type (CheckerContext *c, Type *struct_type, Ast *node, Array *poly_operands, + Type *named_type = nullptr, Type *original_type_for_poly = nullptr); +gb_internal void check_union_type (CheckerContext *c, Type *union_type, Ast *node, Array *poly_operands, + Type *named_type = nullptr, Type *original_type_for_poly = nullptr); -CallArgumentData check_call_arguments (CheckerContext *c, Operand *operand, Type *proc_type, Ast *call); -Type * check_init_variable (CheckerContext *c, Entity *e, Operand *operand, String context_name); +gb_internal CallArgumentData check_call_arguments (CheckerContext *c, Operand *operand, Type *proc_type, Ast *call); +gb_internal Type * check_init_variable (CheckerContext *c, Entity *e, Operand *operand, String context_name); -void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type); -void add_map_key_type_dependencies(CheckerContext *ctx, Type *key); +gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type); +gb_internal void add_map_key_type_dependencies(CheckerContext *ctx, Type *key); -Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem); -Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem); +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); -bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint); +gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint); -void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_); +gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_); -void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type); -void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); -void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); -void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); +gb_internal void check_or_else_right_type(CheckerContext *c, Ast *expr, String const &name, Type *right_type); +gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); +gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); +gb_internal void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); -bool is_diverging_expr(Ast *expr); +gb_internal bool is_diverging_expr(Ast *expr); enum LoadDirectiveResult { @@ -128,7 +128,7 @@ enum LoadDirectiveResult { LoadDirective_NotFound = 2, }; -bool is_load_directive_call(Ast *call) { +gb_internal bool is_load_directive_call(Ast *call) { call = unparen_expr(call); if (call->kind != Ast_CallExpr) { return false; @@ -141,9 +141,9 @@ bool is_load_directive_call(Ast *call) { String name = bd->name.string; return name == "load"; } -LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found); +gb_internal LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found); -void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { +gb_internal void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { auto results = did_you_mean_results(d); if (results.count != 0) { error_line("\tSuggestion: Did you mean?\n"); @@ -155,7 +155,7 @@ void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { } } -void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) { +gb_internal void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) { if (e->kind != Entity_TypeName) { return; } @@ -189,7 +189,7 @@ void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_ } -void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") { +gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") { ERROR_BLOCK(); GB_ASSERT(e->kind == Entity_TypeName); GB_ASSERT(e->TypeName.objc_metadata != nullptr); @@ -211,7 +211,7 @@ void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, check_did_you_mean_print(&d, prefix); } -void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { +gb_internal void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); @@ -224,7 +224,7 @@ void check_did_you_mean_type(String const &name, Array const &fields, } -void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { +gb_internal void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); @@ -236,7 +236,7 @@ void check_did_you_mean_type(String const &name, Slice const &fields, check_did_you_mean_print(&d, prefix); } -void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { +gb_internal void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); @@ -249,7 +249,7 @@ void check_did_you_mean_scope(String const &name, Scope *scope, char const *pref check_did_you_mean_print(&d, prefix); } -Entity *entity_from_expr(Ast *expr) { +gb_internal Entity *entity_from_expr(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { case Ast_Ident: @@ -260,7 +260,7 @@ Entity *entity_from_expr(Ast *expr) { return nullptr; } -void error_operand_not_expression(Operand *o) { +gb_internal void error_operand_not_expression(Operand *o) { if (o->mode == Addressing_Type) { gbString err = expr_to_string(o->expr); error(o->expr, "'%s' is not an expression but a type", err); @@ -269,7 +269,7 @@ void error_operand_not_expression(Operand *o) { } } -void error_operand_no_value(Operand *o) { +gb_internal void error_operand_no_value(Operand *o) { if (o->mode == Addressing_NoValue) { gbString err = expr_to_string(o->expr); Ast *x = unparen_expr(o->expr); @@ -283,7 +283,7 @@ void error_operand_no_value(Operand *o) { } } -void add_map_get_dependencies(CheckerContext *c) { +gb_internal void add_map_get_dependencies(CheckerContext *c) { if (build_context.use_static_map_calls) { add_package_dependency(c, "runtime", "map_desired_position"); add_package_dependency(c, "runtime", "map_probe_distance"); @@ -292,7 +292,7 @@ void add_map_get_dependencies(CheckerContext *c) { } } -void add_map_set_dependencies(CheckerContext *c) { +gb_internal void add_map_set_dependencies(CheckerContext *c) { init_core_source_code_location(c->checker); if (t_map_set_proc == nullptr) { @@ -308,14 +308,14 @@ void add_map_set_dependencies(CheckerContext *c) { } } -void add_map_reserve_dependencies(CheckerContext *c) { +gb_internal void add_map_reserve_dependencies(CheckerContext *c) { init_core_source_code_location(c->checker); add_package_dependency(c, "runtime", "__dynamic_map_reserve"); } -void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reserve_size) { +gb_internal void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reserve_size) { Scope *s = c->scope; check_collect_entities(c, nodes); @@ -337,8 +337,8 @@ void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reser } } -bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_entity, Type *type, - Array *param_operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { +gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_entity, Type *type, + Array *param_operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { /////////////////////////////////////////////////////////////////////////////// // // // TODO CLEANUP(bill): This procedure is very messy and hacky. Clean this!!! // @@ -571,24 +571,24 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_ return true; } -bool check_polymorphic_procedure_assignment(CheckerContext *c, Operand *operand, Type *type, Ast *poly_def_node, PolyProcData *poly_proc_data) { +gb_internal bool check_polymorphic_procedure_assignment(CheckerContext *c, Operand *operand, Type *type, Ast *poly_def_node, PolyProcData *poly_proc_data) { if (operand->expr == nullptr) return false; Entity *base_entity = entity_of_node(operand->expr); if (base_entity == nullptr) return false; return find_or_generate_polymorphic_procedure(c, base_entity, type, nullptr, poly_def_node, poly_proc_data); } -bool find_or_generate_polymorphic_procedure_from_parameters(CheckerContext *c, Entity *base_entity, Array *operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { +gb_internal bool find_or_generate_polymorphic_procedure_from_parameters(CheckerContext *c, Entity *base_entity, Array *operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { return find_or_generate_polymorphic_procedure(c, base_entity, nullptr, operands, poly_def_node, poly_proc_data); } -bool check_type_specialization_to(CheckerContext *c, Type *specialization, Type *type, bool compound, bool modify_type); -bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type); -bool check_cast_internal(CheckerContext *c, Operand *x, Type *type); +gb_internal bool check_type_specialization_to(CheckerContext *c, Type *specialization, Type *type, bool compound, bool modify_type); +gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type); +gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type); #define MAXIMUM_TYPE_DISTANCE 10 -i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type) { +gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type) { if (c == nullptr) { GB_ASSERT(operand->mode == Addressing_Value); GB_ASSERT(is_type_typed(operand->type)); @@ -887,7 +887,7 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type } -i64 assign_score_function(i64 distance, bool is_variadic=false) { +gb_internal i64 assign_score_function(i64 distance, bool is_variadic=false) { // 3*x^2 + 1 > x^2 + x + 1 (for positive x) i64 const c = 3*MAXIMUM_TYPE_DISTANCE*MAXIMUM_TYPE_DISTANCE + 1; @@ -900,7 +900,7 @@ i64 assign_score_function(i64 distance, bool is_variadic=false) { } -bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type *type, i64 *score_, bool is_variadic=false) { +gb_internal bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type *type, i64 *score_, bool is_variadic=false) { i64 score = 0; i64 distance = check_distance_between_types(c, operand, type); bool ok = distance >= 0; @@ -912,19 +912,19 @@ bool check_is_assignable_to_with_score(CheckerContext *c, Operand *operand, Type } -bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type) { +gb_internal bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type) { i64 score = 0; return check_is_assignable_to_with_score(c, operand, type, &score); } -bool internal_check_is_assignable_to(Type *src, Type *dst) { +gb_internal bool internal_check_is_assignable_to(Type *src, Type *dst) { Operand x = {}; x.type = src; x.mode = Addressing_Value; return check_is_assignable_to(nullptr, &x, dst); } -AstPackage *get_package_of_type(Type *type) { +gb_internal AstPackage *get_package_of_type(Type *type) { for (;;) { if (type == nullptr) { return nullptr; @@ -962,7 +962,7 @@ AstPackage *get_package_of_type(Type *type) { // NOTE(bill): 'content_name' is for debugging and error messages -void check_assignment(CheckerContext *c, Operand *operand, Type *type, String context_name) { +gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *type, String context_name) { check_not_tuple(c, operand); if (operand->mode == Addressing_Invalid) { return; @@ -1110,7 +1110,7 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co } } -bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) { +gb_internal bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) { Type *gt = *gt_; GB_ASSERT(gt->kind == Type_Generic); @@ -1139,7 +1139,7 @@ bool polymorphic_assign_index(Type **gt_, i64 *dst_count, i64 source_count) { return false; } -bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type) { +gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, bool compound, bool modify_type) { Operand o = {Addressing_Value}; o.type = source; switch (poly->kind) { @@ -1439,7 +1439,7 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, return false; } -bool check_cycle(CheckerContext *c, Entity *curr, bool report) { +gb_internal bool check_cycle(CheckerContext *c, Entity *curr, bool report) { if (curr->state != EntityState_InProgress) { return false; } @@ -1461,7 +1461,7 @@ bool check_cycle(CheckerContext *c, Entity *curr, bool report) { return false; } -Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name) { +gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name) { GB_ASSERT(n->kind == Ast_Ident); o->mode = Addressing_Invalid; o->expr = n; @@ -1630,7 +1630,7 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ } -bool check_unary_op(CheckerContext *c, Operand *o, Token op) { +gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) { if (o->type == nullptr) { gbString str = expr_to_string(o->expr); error(o->expr, "Expression has no value '%s'", str); @@ -1672,7 +1672,7 @@ bool check_unary_op(CheckerContext *c, Operand *o, Token op) { return true; } -bool check_binary_op(CheckerContext *c, Operand *o, Token op) { +gb_internal bool check_binary_op(CheckerContext *c, Operand *o, Token op) { Type *main_type = o->type; // TODO(bill): Handle errors correctly @@ -1783,7 +1783,7 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { } -bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value) { +gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value) { if (in_value.kind == ExactValue_Invalid) { // NOTE(bill): There's already been an error return true; @@ -1998,7 +1998,7 @@ bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Typ } -void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type) { +gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); defer( @@ -2032,7 +2032,7 @@ void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type } } -void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { +gb_internal void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); defer( @@ -2074,7 +2074,7 @@ void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { } -bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { +gb_internal bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { GB_ASSERT(o->mode == Addressing_Constant); ExactValue out_value = o->value; if (is_type_constant_type(type) && check_representable_as_constant(ctx, o->value, type, &out_value)) { @@ -2112,7 +2112,7 @@ bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { } } -bool check_is_not_addressable(CheckerContext *c, Operand *o) { +gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) { if (o->mode == Addressing_OptionalOk) { Ast *expr = unselector_expr(o->expr); if (expr->kind != Ast_TypeAssertion) { @@ -2143,7 +2143,7 @@ bool check_is_not_addressable(CheckerContext *c, Operand *o) { return o->mode != Addressing_Variable && o->mode != Addressing_SoaVariable; } -void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { +gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { switch (op.kind) { case Token_And: { // Pointer address if (check_is_not_addressable(c, o)) { @@ -2270,7 +2270,7 @@ void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { o->mode = Addressing_Value; } -void add_comparison_procedures_for_fields(CheckerContext *c, Type *t) { +gb_internal void add_comparison_procedures_for_fields(CheckerContext *c, Type *t) { if (t == nullptr) { return; } @@ -2323,7 +2323,7 @@ void add_comparison_procedures_for_fields(CheckerContext *c, Type *t) { } -void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { +gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { if (x->mode == Addressing_Type && y->mode == Addressing_Type) { bool comp = are_types_identical(x->type, y->type); switch (op) { @@ -2516,7 +2516,7 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { } -void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *type_hint) { +gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *type_hint) { GB_ASSERT(node->kind == Ast_BinaryExpr); ast_node(be, BinaryExpr, node); @@ -2635,7 +2635,7 @@ void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *node, Type *typ -bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { +gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { if (check_is_assignable_to(c, operand, y)) { return true; } @@ -2851,7 +2851,7 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { return false; } -bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) { +gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) { bool is_const_expr = x->mode == Addressing_Constant; Type *bt = base_type(type); @@ -2886,7 +2886,7 @@ bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) { } -void check_cast(CheckerContext *c, Operand *x, Type *type) { +gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { if (!is_operand_value(*x)) { error(x->expr, "Only values can be casted"); x->mode = Addressing_Invalid; @@ -2930,7 +2930,7 @@ void check_cast(CheckerContext *c, Operand *x, Type *type) { x->type = type; } -bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { +gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { if (!is_operand_value(*o)) { error(o->expr, "'transmute' can only be applied to values"); o->mode = Addressing_Invalid; @@ -3043,7 +3043,7 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { return true; } -bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y) { +gb_internal bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y) { if (is_type_array(x->type) && !is_type_array(y->type)) { if (check_is_assignable_to(c, y, x->type)) { if (check_binary_op(c, x, op)) { @@ -3054,19 +3054,19 @@ bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y return false; } -bool is_ise_expr(Ast *node) { +gb_internal bool is_ise_expr(Ast *node) { node = unparen_expr(node); return node->kind == Ast_ImplicitSelectorExpr; } -bool can_use_other_type_as_type_hint(bool use_lhs_as_type_hint, Type *other_type) { +gb_internal bool can_use_other_type_as_type_hint(bool use_lhs_as_type_hint, Type *other_type) { if (use_lhs_as_type_hint) { // RHS in this case return other_type != nullptr && other_type != t_invalid && is_type_typed(other_type); } return false; } -Type *check_matrix_type_hint(Type *matrix, Type *type_hint) { +gb_internal Type *check_matrix_type_hint(Type *matrix, Type *type_hint) { Type *xt = base_type(matrix); if (type_hint != nullptr) { Type *th = base_type(type_hint); @@ -3086,7 +3086,7 @@ Type *check_matrix_type_hint(Type *matrix, Type *type_hint) { } -void check_binary_matrix(CheckerContext *c, Token const &op, Operand *x, Operand *y, Type *type_hint, bool use_lhs_as_type_hint) { +gb_internal void check_binary_matrix(CheckerContext *c, Token const &op, Operand *x, Operand *y, Type *type_hint, bool use_lhs_as_type_hint) { if (!check_binary_op(c, x, op)) { x->mode = Addressing_Invalid; return; @@ -3197,7 +3197,7 @@ matrix_error: } -void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint, bool use_lhs_as_type_hint=false) { +gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint, bool use_lhs_as_type_hint=false) { GB_ASSERT(node->kind == Ast_BinaryExpr); Operand y_ = {}, *y = &y_; @@ -3563,7 +3563,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint x->mode = Addressing_Value; } -Operand make_operand_from_node(Ast *node) { +gb_internal Operand make_operand_from_node(Ast *node) { GB_ASSERT(node != nullptr); Operand x = {}; x.expr = node; @@ -3574,7 +3574,7 @@ Operand make_operand_from_node(Ast *node) { } -void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) { +gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) { GB_ASSERT(e != nullptr); ExprInfo *old = check_get_expr_info(c, e); if (old == nullptr) { @@ -3689,7 +3689,7 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) add_type_and_value(c->info, e, old->mode, type, old->value); } -void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { +gb_internal void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { GB_ASSERT(e != nullptr); ExprInfo *found = check_get_expr_info(c, e); if (found) { @@ -3697,7 +3697,7 @@ void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { } } -void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type) { +gb_internal void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type) { gbString expr_str = expr_to_string(operand->expr); gbString type_str = type_to_string(target_type); gbString from_type_str = type_to_string(operand->type); @@ -3728,7 +3728,7 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ operand->mode = Addressing_Invalid; } -ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { +gb_internal ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { Type *t = core_type(type); if (is_type_boolean(t)) { // v = exact_value_to_boolean(v); @@ -3746,7 +3746,7 @@ ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { return v; } -void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { +gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { GB_ASSERT_NOT_NULL(target_type); if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Type || @@ -3995,7 +3995,7 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { operand->type = target_type; } -bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast *index_value, i64 max_count, i64 *value, Type *type_hint=nullptr) { +gb_internal bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast *index_value, i64 max_count, i64 *value, Type *type_hint=nullptr) { Operand operand = {Addressing_Invalid}; check_expr_with_type_hint(c, &operand, index_value, type_hint); if (operand.mode == Addressing_Invalid) { @@ -4121,7 +4121,7 @@ bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast return true; } -ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 index, bool *success_, bool *finish_) { +gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 index, bool *success_, bool *finish_) { if (value.kind == ExactValue_String) { GB_ASSERT(0 <= index && index < value.value_string.len); u8 val = value.value_string[index]; @@ -4269,7 +4269,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in -ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selection sel, bool *success_) { +gb_internal ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selection sel, bool *success_) { if (operand->mode != Addressing_Constant) { if (success_) *success_ = false; return empty_exact_value; @@ -4349,7 +4349,7 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti return empty_exact_value; } -Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { +gb_internal Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { Type *array_type = base_type(type_deref(original_type)); GB_ASSERT(array_type->kind == Type_Array || array_type->kind == Type_SimdVector); if (array_type->kind == Type_SimdVector) { @@ -4376,7 +4376,7 @@ Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize n } -bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool *allow_builtin) { +gb_internal bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool *allow_builtin) { bool is_declared = entity != nullptr; if (is_declared) { if (entity->kind == Entity_Builtin) { @@ -4391,7 +4391,7 @@ bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool * } // NOTE(bill, 2022-02-03): see `check_const_decl` for why it exists reasoning -Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool ident_only) { +gb_internal Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool ident_only) { if (node->kind == Ast_Ident) { String name = node->Ident.token.string; return scope_lookup(c->scope, name); @@ -4471,7 +4471,7 @@ Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool i } -Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *type_hint) { +gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *type_hint) { ast_node(se, SelectorExpr, node); bool check_op_expr = true; @@ -4865,7 +4865,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ return entity; } -bool is_type_normal_pointer(Type *ptr, Type **elem) { +gb_internal bool is_type_normal_pointer(Type *ptr, Type **elem) { ptr = base_type(ptr); if (is_type_pointer(ptr)) { if (is_type_rawptr(ptr)) { @@ -4877,7 +4877,7 @@ bool is_type_normal_pointer(Type *ptr, Type **elem) { return false; } -bool check_identifier_exists(Scope *s, Ast *node, bool nested = false, Scope **out_scope = nullptr) { +gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = false, Scope **out_scope = nullptr) { switch (node->kind) { case_ast_node(i, Ident, node); String name = i->token.string; @@ -4907,7 +4907,7 @@ bool check_identifier_exists(Scope *s, Ast *node, bool nested = false, Scope **o return false; } -isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) { +gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) { if (lhs != nullptr && c->decl != nullptr) { mutex_lock(&c->info->deps_mutex); @@ -4930,7 +4930,7 @@ isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs } -bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { +gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -5011,7 +5011,7 @@ bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, -bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { +gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -5104,7 +5104,7 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, } -bool is_expr_constant_zero(Ast *expr) { +gb_internal bool is_expr_constant_zero(Ast *expr) { GB_ASSERT(expr != nullptr); auto v = exact_value_to_integer(expr->tav.value); if (v.kind == ExactValue_Integer) { @@ -5113,7 +5113,7 @@ bool is_expr_constant_zero(Ast *expr) { return false; } -isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { +gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { GB_ASSERT(pt != nullptr); GB_ASSERT(pt->kind == Type_Proc); isize param_count = 0; @@ -5167,7 +5167,7 @@ isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_ } -CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { +gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { ast_node(ce, CallExpr, call); GB_ASSERT(is_type_proc(proc_type)); proc_type = base_type(proc_type); @@ -5406,7 +5406,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { return err; } -bool is_call_expr_field_value(AstCallExpr *ce) { +gb_internal bool is_call_expr_field_value(AstCallExpr *ce) { GB_ASSERT(ce != nullptr); if (ce->args.count == 0) { @@ -5415,7 +5415,7 @@ bool is_call_expr_field_value(AstCallExpr *ce) { return ce->args[0]->kind == Ast_FieldValue; } -isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { +gb_internal isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { isize param_count = pt->param_count; for (isize i = 0; i < param_count; i++) { Entity *e = pt->params->Tuple.variables[i]; @@ -5429,7 +5429,7 @@ isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { } return -1; } -isize lookup_procedure_result(TypeProc *pt, String result_name) { +gb_internal isize lookup_procedure_result(TypeProc *pt, String result_name) { isize result_count = pt->result_count; for (isize i = 0; i < result_count; i++) { Entity *e = pt->results->Tuple.variables[i]; @@ -5444,7 +5444,7 @@ isize lookup_procedure_result(TypeProc *pt, String result_name) { return -1; } -CALL_ARGUMENT_CHECKER(check_named_call_arguments) { +gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { ast_node(ce, CallExpr, call); GB_ASSERT(is_type_proc(proc_type)); proc_type = base_type(proc_type); @@ -5628,7 +5628,7 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { return err; } -Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_, bool *is_variadic) { +gb_internal Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_, bool *is_variadic) { Entity **lhs = nullptr; isize lhs_count = -1; @@ -5667,7 +5667,7 @@ Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize } -bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice *clauses, bool print_err) { +gb_internal bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice *clauses, bool print_err) { if (clauses != nullptr) { for (Ast *clause : *clauses) { Operand o = {}; @@ -5733,7 +5733,7 @@ bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, S } -CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Slice const &args) { +gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Slice const &args) { ast_node(ce, CallExpr, call); CallArgumentCheckerType *call_checker = check_call_arguments_internal; @@ -6262,7 +6262,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type } -isize lookup_polymorphic_record_parameter(Type *t, String parameter_name) { +gb_internal isize lookup_polymorphic_record_parameter(Type *t, String parameter_name) { if (!is_type_polymorphic_record(t)) { return -1; } @@ -6285,7 +6285,7 @@ isize lookup_polymorphic_record_parameter(Type *t, String parameter_name) { } -CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *operand, Ast *call) { +gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *operand, Ast *call) { ast_node(ce, CallExpr, call); Type *original_type = operand->type; @@ -6605,7 +6605,7 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper -ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { +gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { if (proc != nullptr && proc->kind == Ast_BasicDirective) { ast_node(bd, BasicDirective, proc); @@ -6880,7 +6880,7 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr } -void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { +gb_internal void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { check_expr_base(c, o, e, t); check_not_tuple(c, o); char const *err_str = nullptr; @@ -6905,7 +6905,7 @@ void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { } } -bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, Type *original_type) { +gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, Type *original_type) { switch (t->kind) { case Type_Basic: if (t->Basic.kind == Basic_string) { @@ -7018,7 +7018,7 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count, return false; } -bool ternary_compare_types(Type *x, Type *y) { +gb_internal bool ternary_compare_types(Type *x, Type *y) { if (is_type_untyped_undef(x) && type_has_undef(y)) { return true; } else if (is_type_untyped_nil(x) && type_has_nil(y)) { @@ -7032,7 +7032,7 @@ bool ternary_compare_types(Type *x, Type *y) { } -bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValue *inline_for_depth_, Type *type_hint=nullptr) { +gb_internal bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValue *inline_for_depth_, Type *type_hint=nullptr) { if (!is_ast_range(node)) { return false; } @@ -7124,7 +7124,7 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu return true; } -bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { +gb_internal bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { if (is_operand_nil(*o)) { return true; } @@ -7143,7 +7143,7 @@ bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) { } -bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, AstImplicitSelectorExpr *ise, Type *th) { +gb_internal bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, AstImplicitSelectorExpr *ise, Type *th) { if (is_type_enum(th)) { Type *enum_type = base_type(th); GB_ASSERT(enum_type->kind == Type_Enum); @@ -7182,7 +7182,7 @@ bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, AstImplicitSe return false; } -ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(ise, ImplicitSelectorExpr, node); o->type = t_invalid; @@ -7226,7 +7226,7 @@ ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, Ast *node, } -void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_) { +gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, Type **ok_type_) { switch (x->mode) { case Addressing_MapIndex: case Addressing_OptionalOk: @@ -7263,7 +7263,7 @@ void check_promote_optional_ok(CheckerContext *c, Operand *x, Type **val_type_, } -void check_matrix_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal void check_matrix_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(ie, MatrixIndexExpr, node); check_expr(c, o, ie->expr); @@ -7336,7 +7336,7 @@ struct TypeAndToken { typedef PtrMap SeenMap; -void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operand, bool use_expr = true) { +gb_internal void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operand, bool use_expr = true) { if (operand.mode != Addressing_Constant) { return; } @@ -7378,7 +7378,7 @@ void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operan } -void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Operand const &x, Operand const &lhs, Operand const &rhs) { +gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Operand const &x, Operand const &lhs, Operand const &rhs) { if (is_type_enum(x.type)) { // TODO(bill): Fix this logic so it's fast!!! @@ -7419,11 +7419,11 @@ void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Ope } } } -void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) { +gb_internal void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) { add_constant_switch_case(ctx, seen, x); } -ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(bd, BasicDirective, node); ExprKind kind = Expr_Expr; @@ -7477,7 +7477,7 @@ ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Ty return kind; } -ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; Operand cond = {Addressing_Invalid}; ast_node(te, TernaryIfExpr, node); @@ -7555,7 +7555,7 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t return kind; } -ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; Operand cond = {}; ast_node(te, TernaryWhenExpr, node); @@ -7582,7 +7582,7 @@ ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type return kind; } -ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(oe, OrElseExpr, node); String name = oe->token.string; @@ -7696,7 +7696,7 @@ ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type return Expr_Expr; } -ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(re, OrReturnExpr, node); String name = re->token.string; @@ -7775,7 +7775,7 @@ ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *ty return Expr_Expr; } -ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; ast_node(cl, CompoundLit, node); @@ -8739,7 +8739,7 @@ ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type * return kind; } -ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; ast_node(ta, TypeAssertion, node); check_expr(c, o, ta->expr); @@ -8868,7 +8868,7 @@ ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *ty return kind; } -ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ast_node(se, SelectorCallExpr, node); // IMPORTANT NOTE(bill, 2020-05-22): This is a complete hack to get a shorthand which is extremely useful for vtables // COM APIs is a great example of where this kind of thing is extremely useful @@ -9016,7 +9016,7 @@ ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type } -ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; ast_node(ie, IndexExpr, node); check_expr(c, o, ie->expr); @@ -9140,7 +9140,7 @@ ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_h return kind; } -ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Stmt; ast_node(se, SliceExpr, node); check_expr(c, o, se->expr); @@ -9328,7 +9328,7 @@ ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_h return kind; } -ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { u32 prev_state_flags = c->state_flags; defer (c->state_flags = prev_state_flags); if (node->state_flags != 0) { @@ -9755,7 +9755,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type -ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { +gb_internal ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = check_expr_base_internal(c, o, node, type_hint); if (o->type != nullptr && core_type(o->type) == nullptr) { o->type = t_invalid; @@ -9777,7 +9777,7 @@ ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hi } -void check_multi_expr_or_type(CheckerContext *c, Operand *o, Ast *e) { +gb_internal void check_multi_expr_or_type(CheckerContext *c, Operand *o, Ast *e) { check_expr_base(c, o, e, nullptr); switch (o->mode) { default: @@ -9789,7 +9789,7 @@ void check_multi_expr_or_type(CheckerContext *c, Operand *o, Ast *e) { o->mode = Addressing_Invalid; } -void check_multi_expr(CheckerContext *c, Operand *o, Ast *e) { +gb_internal void check_multi_expr(CheckerContext *c, Operand *o, Ast *e) { check_expr_base(c, o, e, nullptr); switch (o->mode) { default: @@ -9804,7 +9804,7 @@ void check_multi_expr(CheckerContext *c, Operand *o, Ast *e) { o->mode = Addressing_Invalid; } -void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { +gb_internal void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { check_expr_base(c, o, e, type_hint); switch (o->mode) { default: @@ -9819,7 +9819,7 @@ void check_multi_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type o->mode = Addressing_Invalid; } -void check_not_tuple(CheckerContext *c, Operand *o) { +gb_internal void check_not_tuple(CheckerContext *c, Operand *o) { if (o->mode == Addressing_Value) { // NOTE(bill): Tuples are not first class thus never named if (o->type->kind == Type_Tuple) { @@ -9832,13 +9832,13 @@ void check_not_tuple(CheckerContext *c, Operand *o) { } } -void check_expr(CheckerContext *c, Operand *o, Ast *e) { +gb_internal void check_expr(CheckerContext *c, Operand *o, Ast *e) { check_multi_expr(c, o, e); check_not_tuple(c, o); } -void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { +gb_internal void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { check_expr_base(c, o, e, type_hint); check_not_tuple(c, o); error_operand_no_value(o); @@ -9846,7 +9846,7 @@ void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) -bool is_exact_value_zero(ExactValue const &v) { +gb_internal bool is_exact_value_zero(ExactValue const &v) { switch (v.kind) { case ExactValue_Invalid: return true; @@ -9910,9 +9910,9 @@ bool is_exact_value_zero(ExactValue const &v) { -gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); +gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); -gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { +gb_internal gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); @@ -9922,7 +9922,7 @@ gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) return str; } -gbString string_append_string(gbString str, String string) { +gb_internal gbString string_append_string(gbString str, String string) { if (string.len > 0) { return gb_string_append_length(str, &string[0], string.len); } @@ -9930,13 +9930,13 @@ gbString string_append_string(gbString str, String string) { } -gbString string_append_token(gbString str, Token token) { +gb_internal gbString string_append_token(gbString str, Token token) { str = string_append_string(str, token.string); return str; } -gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { +gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { if (node == nullptr) return str; @@ -10501,9 +10501,9 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { return str; } -gbString expr_to_string(Ast *expression) { +gb_internal gbString expr_to_string(Ast *expression) { return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, false); } -gbString expr_to_string_shorthand(Ast *expression) { +gb_internal gbString expr_to_string_shorthand(Ast *expression) { return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, true); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 3fe6699ea..cae9c3537 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1,4 +1,4 @@ -bool is_diverging_expr(Ast *expr) { +gb_internal bool is_diverging_expr(Ast *expr) { expr = unparen_expr(expr); if (expr->kind != Ast_CallExpr) { return false; @@ -23,14 +23,14 @@ bool is_diverging_expr(Ast *expr) { t = base_type(t); return t != nullptr && t->kind == Type_Proc && t->Proc.diverging; } -bool is_diverging_stmt(Ast *stmt) { +gb_internal bool is_diverging_stmt(Ast *stmt) { if (stmt->kind != Ast_ExprStmt) { return false; } return is_diverging_expr(stmt->ExprStmt.expr); } -bool contains_deferred_call(Ast *node) { +gb_internal bool contains_deferred_call(Ast *node) { if (node->viral_state_flags & ViralStateFlag_ContainsDeferredProcedure) { return true; } @@ -61,7 +61,7 @@ bool contains_deferred_call(Ast *node) { return false; } -void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { +gb_internal void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { if (stmts.count == 0) { return; } @@ -137,7 +137,7 @@ void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) } } -bool check_is_terminating_list(Slice const &stmts, String const &label) { +gb_internal bool check_is_terminating_list(Slice const &stmts, String const &label) { // Iterate backwards for (isize n = stmts.count-1; n >= 0; n--) { Ast *stmt = stmts[n]; @@ -155,7 +155,7 @@ bool check_is_terminating_list(Slice const &stmts, String const &label) { return false; } -bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { +gb_internal bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { for_array(i, stmts) { Ast *stmt = stmts[i]; if (check_has_break(stmt, label, implicit)) { @@ -166,7 +166,7 @@ bool check_has_break_list(Slice const &stmts, String const &label, bool i } -bool check_has_break(Ast *stmt, String const &label, bool implicit) { +gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) { switch (stmt->kind) { case Ast_BranchStmt: if (stmt->BranchStmt.token.kind == Token_break) { @@ -225,7 +225,7 @@ bool check_has_break(Ast *stmt, String const &label, bool implicit) { // NOTE(bill): The last expression has to be a 'return' statement // TODO(bill): This is a mild hack and should be probably handled properly -bool check_is_terminating(Ast *node, String const &label) { +gb_internal bool check_is_terminating(Ast *node, String const &label) { switch (node->kind) { case_ast_node(rs, ReturnStmt, node); return true; @@ -327,7 +327,7 @@ bool check_is_terminating(Ast *node, String const &label) { -Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) { +gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) { if (rhs->mode == Addressing_Invalid) { return nullptr; } @@ -477,8 +477,8 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) } -void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags); -void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { +gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags); +gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { u32 prev_state_flags = ctx->state_flags; if (node->state_flags != 0) { @@ -510,7 +510,7 @@ void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { } -void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) { +gb_internal void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) { Operand operand = {Addressing_Invalid}; check_expr(ctx, &operand, ws->cond); if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) { @@ -539,7 +539,7 @@ void check_when_stmt(CheckerContext *ctx, AstWhenStmt *ws, u32 flags) { } } -void check_label(CheckerContext *ctx, Ast *label, Ast *parent) { +gb_internal void check_label(CheckerContext *ctx, Ast *label, Ast *parent) { if (label == nullptr) { return; } @@ -582,7 +582,7 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) { } // Returns 'true' for 'continue', 'false' for 'return' -bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) { +gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) { if (e == nullptr) { if (is_blank_ident(expr)) { error(us->token, "'using' in a statement is not allowed with the blank identifier '_'"); @@ -704,7 +704,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b return true; } -void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { +gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(irs, UnrollRangeStmt, node); check_open_scope(ctx, node); @@ -863,7 +863,7 @@ void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { check_close_scope(ctx); } -void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { +gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(ss, SwitchStmt, node); Operand x = {}; @@ -1092,7 +1092,7 @@ enum TypeSwitchKind { TypeSwitch_Any, }; -TypeSwitchKind check_valid_type_switch_type(Type *type) { +gb_internal TypeSwitchKind check_valid_type_switch_type(Type *type) { type = type_deref(type); if (is_type_union(type)) { return TypeSwitch_Union; @@ -1103,7 +1103,7 @@ TypeSwitchKind check_valid_type_switch_type(Type *type) { return TypeSwitch_Invalid; } -void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { +gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(ss, TypeSwitchStmt, node); Operand x = {}; @@ -1318,7 +1318,7 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { } } -void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { +gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { if (body->kind != Ast_BlockStmt) { return; } @@ -1377,7 +1377,7 @@ void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { } } -bool all_operands_valid(Array const &operands) { +gb_internal bool all_operands_valid(Array const &operands) { if (any_errors()) { for_array(i, operands) { if (operands[i].type == t_invalid) { @@ -1388,7 +1388,7 @@ bool all_operands_valid(Array const &operands) { return true; } -bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) { +gb_internal bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) { BuiltinProcId id = BuiltinProc_Invalid; Entity *e = entity_of_node(expr); if (e != nullptr && e->kind == Entity_Builtin) { @@ -1400,7 +1400,7 @@ bool check_stmt_internal_builtin_proc_id(Ast *expr, BuiltinProcId *id_) { return id != BuiltinProc_Invalid; } -bool check_expr_is_stack_variable(Ast *expr) { +gb_internal bool check_expr_is_stack_variable(Ast *expr) { /* expr = unparen_expr(expr); Entity *e = entity_of_node(expr); @@ -1419,7 +1419,7 @@ bool check_expr_is_stack_variable(Ast *expr) { return false; } -void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { +gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { u32 mod_flags = flags & (~Stmt_FallthroughAllowed); switch (node->kind) { case_ast_node(_, EmptyStmt, node); case_end; diff --git a/src/check_type.cpp b/src/check_type.cpp index 62ca19c57..4634e1fbe 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1,6 +1,6 @@ -ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location); +gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location); -void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) { +gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) { t = base_type(t); GB_ASSERT(t->kind == Type_Array); Entity *e = scope_lookup_current(ctx->scope, name); @@ -27,7 +27,7 @@ void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, } } -void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) { +gb_internal void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) { if (t == nullptr) { return; } @@ -81,7 +81,7 @@ void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field } } -bool does_field_type_allow_using(Type *t) { +gb_internal bool does_field_type_allow_using(Type *t) { t = base_type(t); if (is_type_struct(t)) { return true; @@ -91,8 +91,8 @@ bool does_field_type_allow_using(Type *t) { return false; } -void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields, String **tags, Slice const ¶ms, - isize init_field_capacity, Type *struct_type, String context) { +gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields, String **tags, Slice const ¶ms, + isize init_field_capacity, Type *struct_type, String context) { auto fields_array = array_make(heap_allocator(), 0, init_field_capacity); auto tags_array = array_make(heap_allocator(), 0, init_field_capacity); @@ -219,7 +219,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields } -bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { +gb_internal bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { GB_ASSERT(align_ != nullptr); Operand o = {}; check_expr(ctx, &o, node); @@ -256,7 +256,7 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { } -Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure) { +gb_internal Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure) { mutex_lock(&ctx->info->gen_types_mutex); defer (mutex_unlock(&ctx->info->gen_types_mutex)); @@ -320,7 +320,7 @@ Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, } -void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_type, Type *original_type) { +gb_internal void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_type, Type *original_type) { GB_ASSERT(is_type_named(named_type)); gbAllocator a = heap_allocator(); Scope *s = ctx->scope->parent; @@ -358,10 +358,10 @@ void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_t mutex_unlock(&ctx->info->gen_types_mutex); } -Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params, - bool *is_polymorphic_, - Ast *node, Array *poly_operands, - Type *named_type, Type *original_type_for_poly) { +gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params, + bool *is_polymorphic_, + Ast *node, Array *poly_operands, + Type *named_type, Type *original_type_for_poly) { Type *polymorphic_params_type = nullptr; bool can_check_fields = true; GB_ASSERT(is_polymorphic_ != nullptr); @@ -540,7 +540,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para return polymorphic_params_type; } -bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_type, Array *poly_operands, bool *is_polymorphic_) { +gb_internal bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_type, Array *poly_operands, bool *is_polymorphic_) { if (poly_operands == nullptr) { return false; } @@ -569,7 +569,7 @@ bool check_record_poly_operand_specialization(CheckerContext *ctx, Type *record_ } -void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { +gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { GB_ASSERT(is_type_struct(struct_type)); ast_node(st, StructType, node); @@ -626,7 +626,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array< } } } -void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { +gb_internal void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array *poly_operands, Type *named_type, Type *original_type_for_poly) { GB_ASSERT(is_type_union(union_type)); ast_node(ut, UnionType, node); @@ -709,7 +709,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, ArrayEnum.max_value_index = max_value_index; } -bool is_type_valid_bit_set_range(Type *t) { +gb_internal bool is_type_valid_bit_set_range(Type *t) { if (is_type_integer(t)) { return true; } @@ -861,7 +861,7 @@ bool is_type_valid_bit_set_range(Type *t) { return false; } -void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) { +gb_internal void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) { ast_node(bs, BitSetType, node); GB_ASSERT(type->kind == Type_BitSet); type->BitSet.node = node; @@ -1102,7 +1102,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no } -bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) { +gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) { if (type == nullptr || type == t_invalid) { return true; @@ -1229,7 +1229,7 @@ bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Typ } -Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand) { +gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand) { bool modify_type = !ctx->no_polymorphic_errors; bool show_error = modify_type && !ctx->hide_polymorphic_errors; if (!is_operand_value(operand)) { @@ -1256,7 +1256,7 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper return t_invalid; } -bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { +gb_internal bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { if (expr == nullptr) { return false; } @@ -1275,7 +1275,7 @@ bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { } -ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) { +gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) { ParameterValue param_value = {}; param_value.original_ast_expr = expr; if (expr == nullptr) { @@ -1370,7 +1370,7 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type * } -Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array *operands) { +gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array *operands) { if (_params == nullptr) { return nullptr; } @@ -1814,7 +1814,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is return tuple; } -Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { +gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { if (_results == nullptr) { return nullptr; } @@ -1928,7 +1928,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { // NOTE(bill): 'operands' is for generating non generic procedure type -bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array *operands) { +gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array *operands) { ast_node(pt, ProcType, proc_type_node); if (ctx->polymorphic_scope == nullptr && ctx->allow_polymorphic_types) { @@ -2084,7 +2084,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, } -i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { +gb_internal i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { if (e == nullptr) { return 0; } @@ -2169,7 +2169,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) { return 0; } -Type *make_optional_ok_type(Type *value, bool typed) { +gb_internal Type *make_optional_ok_type(Type *value, bool typed) { gbAllocator a = permanent_allocator(); Type *t = alloc_type_tuple(); slice_init(&t->Tuple.variables, a, 2); @@ -2185,7 +2185,7 @@ enum : i64 { MAP_CACHE_LINE_SIZE = 1 << MAP_CACHE_LINE_LOG2 }; GB_STATIC_ASSERT(MAP_CACHE_LINE_SIZE >= 64); -void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { +gb_internal void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { i64 elem_sz = type_size_of(type); i64 len = 1; @@ -2197,7 +2197,7 @@ void map_cell_size_and_len(Type *type, i64 *size_, i64 *len_) { if (len_) *len_ = len; } -void init_map_internal_types(Type *type) { +gb_internal void init_map_internal_types(Type *type) { GB_ASSERT(type->kind == Type_Map); GB_ASSERT(t_allocator != nullptr); if (type->Map.lookup_result_type != nullptr) return; @@ -2210,7 +2210,7 @@ void init_map_internal_types(Type *type) { type->Map.lookup_result_type = make_optional_ok_type(value); } -void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) { +gb_internal void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) { key = core_type(key); if (is_type_cstring(key)) { @@ -2249,7 +2249,7 @@ void add_map_key_type_dependencies(CheckerContext *ctx, Type *key) { } } -void check_map_type(CheckerContext *ctx, Type *type, Ast *node) { +gb_internal void check_map_type(CheckerContext *ctx, Type *type, Ast *node) { GB_ASSERT(type->kind == Type_Map); ast_node(mt, MapType, node); @@ -2282,7 +2282,7 @@ void check_map_type(CheckerContext *ctx, Type *type, Ast *node) { // error(node, "'map' types are not yet implemented"); } -void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) { +gb_internal void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) { ast_node(mt, MatrixType, node); Operand row = {}; @@ -2346,7 +2346,7 @@ type_assign:; -Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) { +gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) { Type *bt_elem = base_type(elem); bool is_polymorphic = is_type_polymorphic(elem); @@ -2501,20 +2501,20 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el } -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_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type) { return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, count, generic_type, StructSoa_Fixed); } -Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) { +gb_internal Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem) { return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Slice); } -Type *make_soa_struct_dynamic_array(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) { return make_soa_struct_internal(ctx, array_typ_expr, elem_expr, elem, -1, nullptr, StructSoa_Dynamic); } -bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_type) { +gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_type) { GB_ASSERT_NOT_NULL(type); if (e == nullptr) { *type = t_invalid; @@ -2997,7 +2997,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t return false; } -Type *check_type(CheckerContext *ctx, Ast *e) { +gb_internal Type *check_type(CheckerContext *ctx, Ast *e) { CheckerContext c = *ctx; c.type_path = new_checker_type_path(); defer (destroy_checker_type_path(c.type_path)); @@ -3005,7 +3005,7 @@ Type *check_type(CheckerContext *ctx, Ast *e) { return check_type_expr(&c, e, nullptr); } -Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) { +gb_internal Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) { Type *type = nullptr; bool ok = check_type_internal(ctx, e, &type, named_type); diff --git a/src/checker.cpp b/src/checker.cpp index d5222f615..e2c430dc2 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,12 +1,12 @@ #include "entity.cpp" #include "types.cpp" -void check_expr(CheckerContext *c, Operand *operand, Ast *expression); -void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr); -void add_comparison_procedures_for_fields(CheckerContext *c, Type *t); -Type *check_type(CheckerContext *ctx, Ast *e); +gb_internal void check_expr(CheckerContext *c, Operand *operand, Ast *expression); +gb_internal void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr); +gb_internal void add_comparison_procedures_for_fields(CheckerContext *c, Type *t); +gb_internal Type *check_type(CheckerContext *ctx, Ast *e); -bool is_operand_value(Operand o) { +gb_internal bool is_operand_value(Operand o) { switch (o.mode) { case Addressing_Value: case Addressing_Context: @@ -22,14 +22,14 @@ bool is_operand_value(Operand o) { } return false; } -bool is_operand_nil(Operand o) { +gb_internal bool is_operand_nil(Operand o) { return o.mode == Addressing_Value && o.type == t_untyped_nil; } -bool is_operand_undef(Operand o) { +gb_internal bool is_operand_undef(Operand o) { return o.mode == Addressing_Value && o.type == t_untyped_undef; } -bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { +gb_internal bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { if (build_context.disallow_rtti && type) { if (is_type_any(type)) { gbString t = type_to_string(type); @@ -41,12 +41,12 @@ bool check_rtti_type_disallowed(Token const &token, Type *type, char const *form return false; } -bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) { +gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) { GB_ASSERT(expr != nullptr); return check_rtti_type_disallowed(ast_token(expr), type, format); } -void scope_reset(Scope *scope) { +gb_internal void scope_reset(Scope *scope) { if (scope == nullptr) return; scope->head_child.store(nullptr, std::memory_order_relaxed); @@ -54,14 +54,14 @@ void scope_reset(Scope *scope) { ptr_set_clear(&scope->imported); } -void scope_reserve(Scope *scope, isize capacity) { +gb_internal void scope_reserve(Scope *scope, isize capacity) { isize cap = 2*capacity; if (cap > scope->elements.hashes.count) { string_map_rehash(&scope->elements, capacity); } } -i32 is_scope_an_ancestor(Scope *parent, Scope *child) { +gb_internal i32 is_scope_an_ancestor(Scope *parent, Scope *child) { i32 i = 0; while (child != nullptr) { if (parent == child) { @@ -73,35 +73,35 @@ i32 is_scope_an_ancestor(Scope *parent, Scope *child) { return -1; } -void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { +gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { if (s->hashes.data != nullptr) { ptr_set_destroy(s); } } -void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { +gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { if (s->hashes.data == nullptr) { ptr_set_init(s, heap_allocator()); } ptr_set_add(s, n); } -bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { +gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { return ptr_set_exists(s, n); } -void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) { +gb_internal void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) { ptr_set_remove(s, n); } -void entity_graph_node_destroy(EntityGraphNode *n, gbAllocator a) { +gb_internal void entity_graph_node_destroy(EntityGraphNode *n, gbAllocator a) { entity_graph_node_set_destroy(&n->pred); entity_graph_node_set_destroy(&n->succ); gb_free(a, n); } -int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { +gb_internal int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { EntityGraphNode *x = data[i]; EntityGraphNode *y = data[j]; u64 a = x->entity->order_in_src; @@ -115,7 +115,7 @@ int entity_graph_node_cmp(EntityGraphNode **data, isize i, isize j) { return +1; } -void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { +gb_internal void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { EntityGraphNode *x = data[i]; EntityGraphNode *y = data[j]; data[i] = y; @@ -126,42 +126,42 @@ void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j) { -void import_graph_node_set_destroy(ImportGraphNodeSet *s) { +gb_internal void import_graph_node_set_destroy(ImportGraphNodeSet *s) { if (s->hashes.data != nullptr) { ptr_set_destroy(s); } } -void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) { +gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) { if (s->hashes.data == nullptr) { ptr_set_init(s, heap_allocator()); } ptr_set_add(s, n); } -bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { +gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { return ptr_set_exists(s, n); } -void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { +gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { ptr_set_remove(s, n); } -ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) { +gb_internal ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) { ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode); n->pkg = pkg; n->scope = pkg->scope; return n; } -void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) { +gb_internal void import_graph_node_destroy(ImportGraphNode *n, gbAllocator a) { import_graph_node_set_destroy(&n->pred); import_graph_node_set_destroy(&n->succ); gb_free(a, n); } -int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) { +gb_internal int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) { ImportGraphNode *x = data[i]; ImportGraphNode *y = data[j]; GB_ASSERT(x != y); @@ -177,7 +177,7 @@ int import_graph_node_cmp(ImportGraphNode **data, isize i, isize j) { return 0; } -void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) { +gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) { ImportGraphNode *x = data[i]; ImportGraphNode *y = data[j]; data[i] = y; @@ -186,7 +186,7 @@ void import_graph_node_swap(ImportGraphNode **data, isize i, isize j) { y->index = i; } -GB_COMPARE_PROC(ast_node_cmp) { +gb_internal GB_COMPARE_PROC(ast_node_cmp) { Ast *x = *cast(Ast **)a; Ast *y = *cast(Ast **)b; Token i = ast_token(x); @@ -199,7 +199,7 @@ GB_COMPARE_PROC(ast_node_cmp) { -void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { +gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { d->parent = parent; d->scope = scope; ptr_set_init(&d->deps, heap_allocator()); @@ -207,18 +207,18 @@ void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { array_init (&d->labels, heap_allocator()); } -DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { +gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { DeclInfo *d = gb_alloc_item(permanent_allocator(), DeclInfo); init_decl_info(d, scope, parent); return d; } -void destroy_declaration_info(DeclInfo *d) { +gb_internal void destroy_declaration_info(DeclInfo *d) { ptr_set_destroy(&d->deps); array_free(&d->labels); } -bool decl_info_has_init(DeclInfo *d) { +gb_internal bool decl_info_has_init(DeclInfo *d) { if (d->init_expr != nullptr) { return true; } @@ -239,7 +239,7 @@ bool decl_info_has_init(DeclInfo *d) { -Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { +gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; string_map_init(&s->elements, heap_allocator(), init_elements_capacity); @@ -260,7 +260,7 @@ Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capaci return s; } -Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { +gb_internal Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { GB_ASSERT(f != nullptr); GB_ASSERT(f->pkg != nullptr); GB_ASSERT(f->pkg->scope != nullptr); @@ -276,7 +276,7 @@ Scope *create_scope_from_file(CheckerInfo *info, AstFile *f) { return s; } -Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { +gb_internal Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { GB_ASSERT(pkg != nullptr); isize total_pkg_decl_count = 0; @@ -307,7 +307,7 @@ Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { return s; } -void destroy_scope(Scope *scope) { +gb_internal void destroy_scope(Scope *scope) { for (auto const &entry : scope->elements) { Entity *e = entry.value; if (e->kind == Entity_Variable) { @@ -331,7 +331,7 @@ void destroy_scope(Scope *scope) { } -void add_scope(CheckerContext *c, Ast *node, Scope *scope) { +gb_internal void add_scope(CheckerContext *c, Ast *node, Scope *scope) { GB_ASSERT(node != nullptr); GB_ASSERT(scope != nullptr); scope->node = node; @@ -352,7 +352,7 @@ void add_scope(CheckerContext *c, Ast *node, Scope *scope) { } } -Scope *scope_of_node(Ast *node) { +gb_internal Scope *scope_of_node(Ast *node) { if (node == nullptr) { return nullptr; } @@ -375,7 +375,7 @@ Scope *scope_of_node(Ast *node) { } -void check_open_scope(CheckerContext *c, Ast *node) { +gb_internal void check_open_scope(CheckerContext *c, Ast *node) { node = unparen_expr(node); GB_ASSERT(node->kind == Ast_Invalid || is_ast_stmt(node) || @@ -397,12 +397,12 @@ void check_open_scope(CheckerContext *c, Ast *node) { c->state_flags |= StateFlag_bounds_check; } -void check_close_scope(CheckerContext *c) { +gb_internal void check_close_scope(CheckerContext *c) { c->scope = c->scope->parent; } -Entity *scope_lookup_current(Scope *s, String const &name) { +gb_internal Entity *scope_lookup_current(Scope *s, String const &name) { Entity **found = string_map_get(&s->elements, name); if (found) { return *found; @@ -410,7 +410,7 @@ Entity *scope_lookup_current(Scope *s, String const &name) { return nullptr; } -void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) { +gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) { if (scope != nullptr) { bool gone_thru_proc = false; bool gone_thru_package = false; @@ -455,7 +455,7 @@ void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entit if (scope_) *scope_ = nullptr; } -Entity *scope_lookup(Scope *s, String const &name) { +gb_internal Entity *scope_lookup(Scope *s, String const &name) { Entity *entity = nullptr; scope_lookup_parent(s, name, nullptr, &entity); return entity; @@ -463,7 +463,7 @@ Entity *scope_lookup(Scope *s, String const &name) { -Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { +gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { if (name == "") { return nullptr; } @@ -502,7 +502,7 @@ end:; return result; } -Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { +gb_internal Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { String name = entity->token.string; return scope_insert_with_name(s, name, entity, use_mutex); } @@ -528,14 +528,14 @@ struct VettedEntity { Entity *entity; Entity *other; }; -void init_vetted_entity(VettedEntity *ve, VettedEntityKind kind, Entity *entity, Entity *other=nullptr) { +gb_internal void init_vetted_entity(VettedEntity *ve, VettedEntityKind kind, Entity *entity, Entity *other=nullptr) { ve->kind = kind; ve->entity = entity; ve->other = other; } -GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { +gb_internal GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { Entity *x = (cast(VettedEntity *)a)->entity; Entity *y = (cast(VettedEntity *)b)->entity; GB_ASSERT(x != nullptr); @@ -544,7 +544,7 @@ GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { return token_pos_cmp(x->token.pos, y->token.pos); } -bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { +gb_internal bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { Ast *init = unparen_expr(expr); if (init == nullptr) { return false; @@ -568,7 +568,7 @@ bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { } -bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { +gb_internal bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { if (e->kind != Entity_Variable) { return false; } @@ -634,7 +634,7 @@ bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { return true; } -bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { +gb_internal bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { if ((e->flags&EntityFlag_Used) == 0) { switch (e->kind) { case Entity_Variable: @@ -652,7 +652,7 @@ bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) { return false; } -void check_scope_usage(Checker *c, Scope *scope) { +gb_internal void check_scope_usage(Checker *c, Scope *scope) { bool vet_unused = true; bool vet_shadowing = true; @@ -728,12 +728,12 @@ void check_scope_usage(Checker *c, Scope *scope) { } -void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { +gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { mutex_lock(&info->deps_mutex); ptr_set_add(&d->deps, e); mutex_unlock(&info->deps_mutex); } -void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { +gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { if (d == nullptr) { return; } @@ -746,7 +746,7 @@ void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool r } } -AstPackage *get_core_package(CheckerInfo *info, String name) { +gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { gbAllocator a = heap_allocator(); String path = get_fullpath_core(a, name); defer (gb_free(a, path.text)); @@ -764,7 +764,7 @@ AstPackage *get_core_package(CheckerInfo *info, String name) { } -void add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { +gb_internal void add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); @@ -774,7 +774,7 @@ void add_package_dependency(CheckerContext *c, char const *package_name, char co add_dependency(c->info, c->decl, e); } -void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { +gb_internal void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); @@ -787,7 +787,7 @@ void try_to_add_package_dependency(CheckerContext *c, char const *package_name, } -void add_declaration_dependency(CheckerContext *c, Entity *e) { +gb_internal void add_declaration_dependency(CheckerContext *c, Entity *e) { if (e == nullptr) { return; } @@ -797,7 +797,7 @@ void add_declaration_dependency(CheckerContext *c, Entity *e) { } -Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) { +gb_internal Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) { String name = entity->token.string; defer (entity->state = EntityState_Resolved); @@ -810,27 +810,27 @@ Entity *add_global_entity(Entity *entity, Scope *scope=builtin_pkg->scope) { return entity; } -void add_global_constant(char const *name, Type *type, ExactValue value) { +gb_internal void add_global_constant(char const *name, Type *type, ExactValue value) { Entity *entity = alloc_entity(Entity_Constant, nullptr, make_token_ident(name), type); entity->Constant.value = value; add_global_entity(entity); } -void add_global_string_constant(char const *name, String const &value) { +gb_internal void add_global_string_constant(char const *name, String const &value) { add_global_constant(name, t_untyped_string, exact_value_string(value)); } -void add_global_bool_constant(char const *name, bool value) { +gb_internal void add_global_bool_constant(char const *name, bool value) { add_global_constant(name, t_untyped_bool, exact_value_bool(value)); } -void add_global_type_entity(String name, Type *type) { +gb_internal void add_global_type_entity(String name, Type *type) { add_global_entity(alloc_entity_type_name(nullptr, make_token_ident(name), type)); } -AstPackage *create_builtin_package(char const *name) { +gb_internal AstPackage *create_builtin_package(char const *name) { gbAllocator a = permanent_allocator(); AstPackage *pkg = gb_alloc_item(a, AstPackage); pkg->name = make_string_c(name); @@ -847,7 +847,7 @@ struct GlobalEnumValue { i64 value; }; -Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) { +gb_internal Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) { Scope *scope = create_scope(nullptr, builtin_pkg->scope); Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); @@ -882,7 +882,7 @@ Slice add_global_enum_type(String const &type_name, GlobalEnumValue *v return slice_from_array(fields); } -void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { +gb_internal void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { for (Entity *field : fields) { GB_ASSERT(field->kind == Entity_Constant); if (value == exact_value_to_i64(field->Constant.value)) { @@ -893,7 +893,7 @@ void add_global_enum_constant(Slice const &fields, char const *name, i GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value); } -Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) { +gb_internal Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) { Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); Type *named_type = alloc_type_named(type_name, backing_type, e); e->type = named_type; @@ -905,7 +905,7 @@ Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_ } -void init_universal(void) { +gb_internal void init_universal(void) { BuildContext *bc = &build_context; builtin_pkg = create_builtin_package("builtin"); @@ -1122,7 +1122,7 @@ void init_universal(void) { -void init_checker_info(CheckerInfo *i) { +gb_internal void init_checker_info(CheckerInfo *i) { gbAllocator a = heap_allocator(); TIME_SECTION("checker info: general"); @@ -1180,7 +1180,7 @@ void init_checker_info(CheckerInfo *i) { string_map_init(&i->load_file_cache, a); } -void destroy_checker_info(CheckerInfo *i) { +gb_internal void destroy_checker_info(CheckerInfo *i) { array_free(&i->definitions); array_free(&i->entities); map_destroy(&i->global_untyped); @@ -1217,7 +1217,7 @@ void destroy_checker_info(CheckerInfo *i) { string_map_destroy(&i->load_file_cache); } -CheckerContext make_checker_context(Checker *c) { +gb_internal CheckerContext make_checker_context(Checker *c) { CheckerContext ctx = {}; ctx.checker = c; ctx.info = &c->info; @@ -1230,12 +1230,12 @@ CheckerContext make_checker_context(Checker *c) { ctx.poly_level = 0; return ctx; } -void destroy_checker_context(CheckerContext *ctx) { +gb_internal void destroy_checker_context(CheckerContext *ctx) { destroy_checker_type_path(ctx->type_path); destroy_checker_poly_path(ctx->poly_path); } -void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { +gb_internal void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { if (file != nullptr) { ctx->file = file; ctx->decl = file->pkg->decl_info; @@ -1243,7 +1243,7 @@ void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { ctx->pkg = file->pkg; } } -void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) { +gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) { if (ctx == nullptr) { return; } @@ -1258,7 +1258,7 @@ void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMa -void init_checker(Checker *c) { +gb_internal void init_checker(Checker *c) { gbAllocator a = heap_allocator(); TIME_SECTION("init checker info"); @@ -1278,7 +1278,7 @@ void init_checker(Checker *c) { c->builtin_ctx = make_checker_context(c); } -void destroy_checker(Checker *c) { +gb_internal void destroy_checker(Checker *c) { destroy_checker_info(&c->info); destroy_checker_context(&c->builtin_ctx); @@ -1290,7 +1290,7 @@ void destroy_checker(Checker *c) { } -TypeAndValue type_and_value_of_expr(Ast *expr) { +gb_internal TypeAndValue type_and_value_of_expr(Ast *expr) { TypeAndValue tav = {}; if (expr != nullptr) { tav = expr->tav; @@ -1298,7 +1298,7 @@ TypeAndValue type_and_value_of_expr(Ast *expr) { return tav; } -Type *type_of_expr(Ast *expr) { +gb_internal Type *type_of_expr(Ast *expr) { TypeAndValue tav = expr->tav; if (tav.mode != Addressing_Invalid) { return tav.type; @@ -1313,14 +1313,14 @@ Type *type_of_expr(Ast *expr) { return nullptr; } -Entity *implicit_entity_of_node(Ast *clause) { +gb_internal Entity *implicit_entity_of_node(Ast *clause) { if (clause != nullptr && clause->kind == Ast_CaseClause) { return clause->CaseClause.implicit_entity; } return nullptr; } -Entity *entity_of_node(Ast *expr) { +gb_internal Entity *entity_of_node(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { case_ast_node(ident, Ident, expr); @@ -1341,25 +1341,25 @@ Entity *entity_of_node(Ast *expr) { return nullptr; } -DeclInfo *decl_info_of_entity(Entity *e) { +gb_internal DeclInfo *decl_info_of_entity(Entity *e) { if (e != nullptr) { return e->decl_info; } return nullptr; } -DeclInfo *decl_info_of_ident(Ast *ident) { +gb_internal DeclInfo *decl_info_of_ident(Ast *ident) { return decl_info_of_entity(entity_of_node(ident)); } -AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { +gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { AstFile **found = string_map_get(&i->files, filename); if (found != nullptr) { return *found; } return nullptr; } -ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { +gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { if (c->untyped != nullptr) { ExprInfo **found = map_get(c->untyped, expr); if (found) { @@ -1377,7 +1377,7 @@ ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { } } -void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (c->untyped != nullptr) { map_set(c->untyped, expr, make_expr_info(mode, type, value, false)); } else { @@ -1387,7 +1387,7 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type } } -void check_remove_expr_info(CheckerContext *c, Ast *e) { +gb_internal void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, e); GB_ASSERT(map_get(c->untyped, e) == nullptr); @@ -1401,7 +1401,7 @@ void check_remove_expr_info(CheckerContext *c, Ast *e) { } -isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { +gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { type = default_type(type); if (type == t_llvm_bool) { type = t_bool; @@ -1436,7 +1436,7 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { } -void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (expr == nullptr) { return; } @@ -1453,7 +1453,7 @@ void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, check_set_expr_info(c, expr, mode, type, value); } -void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (expr == nullptr) { return; } @@ -1489,7 +1489,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty mutex_unlock(&i->type_and_value_mutex); } -void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { +gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { GB_ASSERT(identifier != nullptr); GB_ASSERT(identifier->kind == Ast_Ident); // if (is_blank_ident(identifier)) { @@ -1505,7 +1505,7 @@ void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { mpmc_enqueue(&i->definition_queue, entity); } -bool redeclaration_error(String name, Entity *prev, Entity *found) { +gb_internal bool redeclaration_error(String name, Entity *prev, Entity *found) { TokenPos pos = found->token.pos; Entity *up = found->using_parent; if (up != nullptr) { @@ -1548,7 +1548,7 @@ bool redeclaration_error(String name, Entity *prev, Entity *found) { return false; } -void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) { +gb_internal void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) { if (c->file != nullptr && (c->file->flags & AstFile_IsLazy) != 0 && scope->flags & ScopeFlag_File) { AstPackage *pkg = c->file->pkg; if (pkg->kind == Package_Init && e->kind == Entity_Procedure && e->token.string == "main") { @@ -1561,7 +1561,7 @@ void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope *scope) { } } -bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) { +gb_internal bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) { if (scope == nullptr) { return false; } @@ -1581,11 +1581,11 @@ bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Enti } return true; } -bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) { +gb_internal bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) { return add_entity_with_name(c, scope, identifier, entity, entity->token.string); } -void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) { +gb_internal void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) { if (entity == nullptr) { return; } @@ -1622,7 +1622,7 @@ void add_entity_use(CheckerContext *c, Ast *identifier, Entity *entity) { } -bool could_entity_be_lazy(Entity *e, DeclInfo *d) { +gb_internal bool could_entity_be_lazy(Entity *e, DeclInfo *d) { if ((e->flags & EntityFlag_Lazy) == 0) { return false; } @@ -1673,7 +1673,7 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return true; } -void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) { +gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) { if (identifier == nullptr) { // NOTE(bill): Should only happen on errors error(e->token, "Invalid variable declaration"); @@ -1738,16 +1738,15 @@ void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, Dec } -void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) { +gb_internal void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) { GB_ASSERT(clause != nullptr); GB_ASSERT(e != nullptr); GB_ASSERT(clause->kind == Ast_CaseClause); clause->CaseClause.implicit_entity = e; } -void add_type_info_type(CheckerContext *c, Type *t) { - void add_type_info_type_internal(CheckerContext *c, Type *t); - +gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t); +gb_internal void add_type_info_type(CheckerContext *c, Type *t) { if (build_context.disallow_rtti) { return; } @@ -1757,7 +1756,7 @@ void add_type_info_type(CheckerContext *c, Type *t) { mutex_unlock(&c->info->type_info_mutex); } -void add_type_info_type_internal(CheckerContext *c, Type *t) { +gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { if (t == nullptr) { return; } @@ -1982,7 +1981,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { gb_global bool global_procedure_body_in_worker_queue = false; -void check_procedure_later(CheckerContext *c, ProcInfo *info) { +gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); @@ -1994,7 +1993,7 @@ void check_procedure_later(CheckerContext *c, ProcInfo *info) { mpmc_enqueue(queue, info); } -void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { +gb_internal void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { ProcInfo *info = gb_alloc_item(permanent_allocator(), ProcInfo); info->file = file; info->token = token; @@ -2006,7 +2005,7 @@ void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclIn } -void add_min_dep_type_info(Checker *c, Type *t) { +gb_internal void add_min_dep_type_info(Checker *c, Type *t) { if (t == nullptr) { return; } @@ -2201,7 +2200,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { } -void add_dependency_to_set(Checker *c, Entity *entity) { +gb_internal void add_dependency_to_set(Checker *c, Entity *entity) { if (entity == nullptr) { return; } @@ -2254,7 +2253,7 @@ void add_dependency_to_set(Checker *c, Entity *entity) { } } -void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) { +gb_internal void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) { Entity *e = scope_lookup(scope, name); if (e == nullptr) { return; @@ -2266,7 +2265,7 @@ void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) { -void generate_minimum_dependency_set(Checker *c, Entity *start) { +gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { isize entity_count = c->info.entities.count; isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor @@ -2479,7 +2478,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { #undef FORCE_ADD_RUNTIME_ENTITIES } -bool is_entity_a_dependency(Entity *e) { +gb_internal bool is_entity_a_dependency(Entity *e) { if (e == nullptr) return false; switch (e->kind) { case Entity_Procedure: @@ -2493,7 +2492,7 @@ bool is_entity_a_dependency(Entity *e) { return false; } -Array generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) { +gb_internal Array generate_entity_dependency_graph(CheckerInfo *info, gbAllocator allocator) { PtrMap M = {}; map_init(&M, allocator, info->entities.count); defer (map_destroy(&M)); @@ -2612,10 +2611,10 @@ Array generate_entity_dependency_graph(CheckerInfo *info, gbA } -void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d); +gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d); -Entity *find_core_entity(Checker *c, String name) { +gb_internal Entity *find_core_entity(Checker *c, String name) { Entity *e = scope_lookup_current(c->info.runtime_package->scope, name); if (e == nullptr) { compiler_error("Could not find type declaration for '%.*s'\n" @@ -2625,7 +2624,7 @@ Entity *find_core_entity(Checker *c, String name) { return e; } -Type *find_core_type(Checker *c, String name) { +gb_internal Type *find_core_type(Checker *c, String name) { Entity *e = scope_lookup_current(c->info.runtime_package->scope, name); if (e == nullptr) { compiler_error("Could not find type declaration for '%.*s'\n" @@ -2640,7 +2639,7 @@ Type *find_core_type(Checker *c, String name) { } -Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { +gb_internal Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { AstPackage *package = get_core_package(info, pkg); Entity *e = scope_lookup_current(package->scope, name); if (e == nullptr) { @@ -2650,7 +2649,7 @@ Entity *find_entity_in_pkg(CheckerInfo *info, String const &pkg, String const &n return e; } -Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { +gb_internal Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) { AstPackage *package = get_core_package(info, pkg); Entity *e = scope_lookup_current(package->scope, name); if (e == nullptr) { @@ -2661,58 +2660,58 @@ Type *find_type_in_pkg(CheckerInfo *info, String const &pkg, String const &name) return e->type; } -CheckerTypePath *new_checker_type_path() { +gb_internal CheckerTypePath *new_checker_type_path() { gbAllocator a = heap_allocator(); auto *tp = gb_alloc_item(a, CheckerTypePath); array_init(tp, a, 0, 16); return tp; } -void destroy_checker_type_path(CheckerTypePath *tp) { +gb_internal void destroy_checker_type_path(CheckerTypePath *tp) { array_free(tp); gb_free(heap_allocator(), tp); } -void check_type_path_push(CheckerContext *c, Entity *e) { +gb_internal void check_type_path_push(CheckerContext *c, Entity *e) { GB_ASSERT(c->type_path != nullptr); GB_ASSERT(e != nullptr); array_add(c->type_path, e); } -Entity *check_type_path_pop(CheckerContext *c) { +gb_internal Entity *check_type_path_pop(CheckerContext *c) { GB_ASSERT(c->type_path != nullptr); return array_pop(c->type_path); } -CheckerPolyPath *new_checker_poly_path(void) { +gb_internal CheckerPolyPath *new_checker_poly_path(void) { gbAllocator a = heap_allocator(); auto *pp = gb_alloc_item(a, CheckerPolyPath); array_init(pp, a, 0, 16); return pp; } -void destroy_checker_poly_path(CheckerPolyPath *pp) { +gb_internal void destroy_checker_poly_path(CheckerPolyPath *pp) { array_free(pp); gb_free(heap_allocator(), pp); } -void check_poly_path_push(CheckerContext *c, Type *t) { +gb_internal void check_poly_path_push(CheckerContext *c, Type *t) { GB_ASSERT(c->poly_path != nullptr); GB_ASSERT(t != nullptr); GB_ASSERT(is_type_polymorphic(t)); array_add(c->poly_path, t); } -Type *check_poly_path_pop(CheckerContext *c) { +gb_internal Type *check_poly_path_pop(CheckerContext *c) { GB_ASSERT(c->poly_path != nullptr); return array_pop(c->poly_path); } -Array proc_group_entities(CheckerContext *c, Operand o) { +gb_internal Array proc_group_entities(CheckerContext *c, Operand o) { Array procs = {}; if (o.mode == Addressing_ProcGroup) { GB_ASSERT(o.proc_group != nullptr); @@ -2724,7 +2723,7 @@ Array proc_group_entities(CheckerContext *c, Operand o) { return procs; } -Array proc_group_entities_cloned(CheckerContext *c, Operand o) { +gb_internal Array proc_group_entities_cloned(CheckerContext *c, Operand o) { auto entities = proc_group_entities(c, o); if (entities.count == 0) { return {}; @@ -2735,7 +2734,7 @@ Array proc_group_entities_cloned(CheckerContext *c, Operand o) { -void init_core_type_info(Checker *c) { +gb_internal void init_core_type_info(Checker *c) { if (t_type_info != nullptr) { return; } @@ -2816,7 +2815,7 @@ void init_core_type_info(Checker *c) { t_type_info_soa_pointer_ptr = alloc_type_pointer(t_type_info_soa_pointer); } -void init_mem_allocator(Checker *c) { +gb_internal void init_mem_allocator(Checker *c) { if (t_allocator != nullptr) { return; } @@ -2825,7 +2824,7 @@ void init_mem_allocator(Checker *c) { t_allocator_error = find_core_type(c, str_lit("Allocator_Error")); } -void init_core_context(Checker *c) { +gb_internal void init_core_context(Checker *c) { if (t_context != nullptr) { return; } @@ -2833,7 +2832,7 @@ void init_core_context(Checker *c) { t_context_ptr = alloc_type_pointer(t_context); } -void init_core_source_code_location(Checker *c) { +gb_internal void init_core_source_code_location(Checker *c) { if (t_source_code_location != nullptr) { return; } @@ -2841,7 +2840,7 @@ void init_core_source_code_location(Checker *c) { t_source_code_location_ptr = alloc_type_pointer(t_source_code_location); } -void init_core_map_type(Checker *c) { +gb_internal void init_core_map_type(Checker *c) { if (t_map_info != nullptr) { return; } @@ -2855,7 +2854,7 @@ void init_core_map_type(Checker *c) { t_raw_map_ptr = alloc_type_pointer(t_raw_map); } -void init_preload(Checker *c) { +gb_internal void init_preload(Checker *c) { init_core_type_info(c); init_mem_allocator(c); init_core_context(c); @@ -2863,7 +2862,7 @@ void init_preload(Checker *c) { init_core_map_type(c); } -ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { +gb_internal ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { ExactValue ev = {}; if (value != nullptr) { Operand op = {}; @@ -2879,7 +2878,7 @@ ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { return ev; } -Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { +gb_internal Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { if (value != nullptr) { return check_type(c, value); } @@ -2890,7 +2889,7 @@ Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { #define ATTRIBUTE_USER_TAG_NAME "tag" -DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { ExactValue ev = check_decl_attribute_value(c, value); if (name == ATTRIBUTE_USER_TAG_NAME) { @@ -2945,7 +2944,7 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(proc_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3242,7 +3241,7 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(var_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3367,7 +3366,7 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(const_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(const_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3381,7 +3380,7 @@ DECL_ATTRIBUTE_PROC(const_decl_attribute) { return false; } -DECL_ATTRIBUTE_PROC(type_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(type_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -3412,7 +3411,7 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { -void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac) { +gb_internal void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac) { if (attributes.count == 0) return; String original_link_prefix = {}; @@ -3480,7 +3479,7 @@ void check_decl_attributes(CheckerContext *c, Array const &attributes, De } -isize get_total_value_count(Slice const &values) { +gb_internal isize get_total_value_count(Slice const &values) { isize count = 0; for_array(i, values) { Type *t = type_of_expr(values[i]); @@ -3498,7 +3497,7 @@ isize get_total_value_count(Slice const &values) { return count; } -bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) { +gb_internal bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) { isize lhs = vd->names.count; isize rhs = 0; if (is_global) { @@ -3541,7 +3540,7 @@ bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global) { return true; } -void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) { +gb_internal void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) { Operand operand = {Addressing_Invalid}; if (!ws->is_cond_determined) { check_expr(c, &operand, ws->cond); @@ -3577,7 +3576,7 @@ void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws) { } } -void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attributes) { +gb_internal void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attributes) { switch (e->kind) { case Entity_ProcGroup: case Entity_Procedure: @@ -3640,7 +3639,7 @@ void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array *attr } } -void check_collect_value_decl(CheckerContext *c, Ast *decl) { +gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -3891,7 +3890,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } } -void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { +gb_internal void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -3912,7 +3911,7 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { check_collect_entities(&c, block->stmts); } -bool correct_single_type_alias(CheckerContext *c, Entity *e) { +gb_internal bool correct_single_type_alias(CheckerContext *c, Entity *e) { if (e->kind == Entity_Constant) { DeclInfo *d = e->decl_info; if (d != nullptr && d->init_expr != nullptr) { @@ -3927,7 +3926,7 @@ bool correct_single_type_alias(CheckerContext *c, Entity *e) { return false; } -bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { +gb_internal bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { isize n = s->elements.entries.count; bool correction = false; for (isize i = n-1; i >= 0; i--) { @@ -3935,7 +3934,7 @@ bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { } return correction; } -bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { +gb_internal bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { isize n = s->elements.entries.count; bool correction = false; for (isize i = 0; i < n; i++) { @@ -3945,7 +3944,7 @@ bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { } -void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { +gb_internal void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { // NOTE(bill, 2022-02-04): This is used to solve the problem caused by type aliases // of type aliases being "confused" as constants // @@ -3966,7 +3965,7 @@ void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { // NOTE(bill): If file_scopes == nullptr, this will act like a local scope -void check_collect_entities(CheckerContext *c, Slice const &nodes) { +gb_internal void check_collect_entities(CheckerContext *c, Slice const &nodes) { AstFile *curr_file = nullptr; if ((c->scope->flags&ScopeFlag_File) != 0) { curr_file = c->scope->file; @@ -4050,13 +4049,13 @@ void check_collect_entities(CheckerContext *c, Slice const &nodes) { } } -CheckerContext *create_checker_context(Checker *c) { +gb_internal CheckerContext *create_checker_context(Checker *c) { CheckerContext *ctx = gb_alloc_item(permanent_allocator(), CheckerContext); *ctx = make_checker_context(c); return ctx; } -void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { +gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { GB_ASSERT(e != nullptr); GB_ASSERT(d != nullptr); @@ -4089,7 +4088,7 @@ void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { check_entity_decl(ctx, e, d, nullptr); } -void check_all_global_entities(Checker *c) { +gb_internal void check_all_global_entities(Checker *c) { // NOTE(bill): This must be single threaded // Don't bother trying for_array(i, c->info.entities) { @@ -4107,7 +4106,7 @@ void check_all_global_entities(Checker *c) { } -bool is_string_an_identifier(String s) { +gb_internal bool is_string_an_identifier(String s) { isize offset = 0; if (s.len < 1) { return false; @@ -4131,7 +4130,7 @@ bool is_string_an_identifier(String s) { return offset == s.len; } -String path_to_entity_name(String name, String fullpath, bool strip_extension=true) { +gb_internal String path_to_entity_name(String name, String fullpath, bool strip_extension=true) { if (name.len != 0) { return name; } @@ -4177,7 +4176,7 @@ String path_to_entity_name(String name, String fullpath, bool strip_extension=tr #if 1 -void add_import_dependency_node(Checker *c, Ast *decl, PtrMap *M) { +gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMap *M) { AstPackage *parent_pkg = decl->file()->pkg; switch (decl->kind) { @@ -4242,7 +4241,7 @@ void add_import_dependency_node(Checker *c, Ast *decl, PtrMap generate_import_dependency_graph(Checker *c) { +gb_internal Array generate_import_dependency_graph(Checker *c) { PtrMap M = {}; map_init(&M, heap_allocator(), 2*c->parser->packages.count); defer (map_destroy(&M)); @@ -4285,7 +4284,7 @@ struct ImportPathItem { Ast * decl; }; -Array find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet *visited) { +gb_internal Array find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet *visited) { Array empty_path = {}; if (ptr_set_update(visited, start)) { @@ -4335,7 +4334,7 @@ Array find_import_path(Checker *c, AstPackage *start, AstPackage } #endif -String get_invalid_import_name(String input) { +gb_internal String get_invalid_import_name(String input) { isize slash = 0; for (isize i = input.len-1; i >= 0; i--) { if (input[i] == '/' || input[i] == '\\') { @@ -4347,7 +4346,7 @@ String get_invalid_import_name(String input) { return input; } -void check_add_import_decl(CheckerContext *ctx, Ast *decl) { +gb_internal void check_add_import_decl(CheckerContext *ctx, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -4422,7 +4421,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { scope->flags |= ScopeFlag_HasBeenImported; } -DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { +gb_internal DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind != ExactValue_String) { @@ -4449,7 +4448,7 @@ DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { return false; } -void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { +gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { if (decl->state_flags & StateFlag_BeenHandled) return; decl->state_flags |= StateFlag_BeenHandled; @@ -4515,10 +4514,10 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { } // Returns true if a new package is present -bool collect_file_decls(CheckerContext *ctx, Slice const &decls); -bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws); +gb_internal bool collect_file_decls(CheckerContext *ctx, Slice const &decls); +gb_internal bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws); -bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { +gb_internal bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { Operand operand = {Addressing_Invalid}; if (!ws->is_cond_determined) { check_expr(ctx, &operand, ws->cond); @@ -4557,7 +4556,7 @@ bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { return false; } -bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { +gb_internal bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { Operand operand = {Addressing_Invalid}; if (!ws->is_cond_determined) { check_expr(ctx, &operand, ws->cond); @@ -4594,7 +4593,7 @@ bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { } -bool collect_file_decl(CheckerContext *ctx, Ast *decl) { +gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl) { GB_ASSERT(ctx->scope->flags&ScopeFlag_File); AstFile *curr_file = ctx->scope->file; @@ -4658,7 +4657,7 @@ bool collect_file_decl(CheckerContext *ctx, Ast *decl) { return false; } -bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { +gb_internal bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { GB_ASSERT(ctx->scope->flags&ScopeFlag_File); for_array(i, decls) { @@ -4671,7 +4670,7 @@ bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { return false; } -GB_COMPARE_PROC(sort_file_by_name) { +gb_internal GB_COMPARE_PROC(sort_file_by_name) { AstFile const *x = *cast(AstFile const **)a; AstFile const *y = *cast(AstFile const **)b; String x_name = filename_from_path(x->fullpath); @@ -4679,7 +4678,7 @@ GB_COMPARE_PROC(sort_file_by_name) { return string_compare(x_name, y_name); } -void check_create_file_scopes(Checker *c) { +gb_internal void check_create_file_scopes(Checker *c) { for_array(i, c->parser->packages) { AstPackage *pkg = c->parser->packages[i]; isize total_pkg_decl_count = 0; @@ -4705,7 +4704,7 @@ struct ThreadProcCheckerSection { }; -void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { +gb_internal void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { isize thread_count = gb_max(build_context.thread_count, 1); isize worker_count = thread_count-1; // NOTE(bill): The main thread will also be used for work if (!build_context.threaded_checker) { @@ -4744,7 +4743,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { } -WORKER_TASK_PROC(thread_proc_collect_entities) { +gb_internal WORKER_TASK_PROC(thread_proc_collect_entities) { auto *cs = cast(ThreadProcCheckerSection *)data; Checker *c = cs->checker; CheckerContext collect_entity_ctx = make_checker_context(c); @@ -4775,11 +4774,11 @@ WORKER_TASK_PROC(thread_proc_collect_entities) { } -void check_collect_entities_all(Checker *c) { +gb_internal void check_collect_entities_all(Checker *c) { check_with_workers(c, thread_proc_collect_entities, c->info.files.entries.count); } -void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { +gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedExprInfoMap *untyped) { if (pkg->files.count != 0) { AstPackageExportedEntity item = {}; while (mpmc_dequeue(&pkg->exported_entity_queue, &item)) { @@ -4793,7 +4792,7 @@ void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *pkg, UntypedE } } -WORKER_TASK_PROC(thread_proc_check_export_entities) { +gb_internal WORKER_TASK_PROC(thread_proc_check_export_entities) { auto cs = cast(ThreadProcCheckerSection *)data; Checker *c = cs->checker; @@ -4815,11 +4814,11 @@ WORKER_TASK_PROC(thread_proc_check_export_entities) { return 0; } -void check_export_entities(Checker *c) { +gb_internal void check_export_entities(Checker *c) { check_with_workers(c, thread_proc_check_export_entities, c->info.packages.entries.count); } -void check_import_entities(Checker *c) { +gb_internal void check_import_entities(Checker *c) { Array dep_graph = generate_import_dependency_graph(c); defer ({ for_array(i, dep_graph) { @@ -4961,9 +4960,9 @@ void check_import_entities(Checker *c) { } -Array find_entity_path(Entity *start, Entity *end, PtrSet *visited = nullptr); +gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet *visited = nullptr); -bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, Array *path_) { +gb_internal bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, Array *path_) { GB_ASSERT(path_ != nullptr); if (tuple == nullptr) { return false; @@ -4995,7 +4994,7 @@ bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet *visited, return false; } -Array find_entity_path(Entity *start, Entity *end, PtrSet *visited) { +gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet *visited) { PtrSet visited_ = {}; bool made_visited = false; if (visited == nullptr) { @@ -5047,7 +5046,7 @@ Array find_entity_path(Entity *start, Entity *end, PtrSet *v } -void calculate_global_init_order(Checker *c) { +gb_internal void calculate_global_init_order(Checker *c) { CheckerInfo *info = &c->info; TIME_SECTION("calculate_global_init_order: generate entity dependency graph"); @@ -5122,7 +5121,7 @@ void calculate_global_init_order(Checker *c) { } -bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) { +gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) { if (pi == nullptr) { return false; } @@ -5201,9 +5200,9 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *)); -bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped); +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped); -void check_unchecked_bodies(Checker *c) { +gb_internal void check_unchecked_bodies(Checker *c) { // NOTE(2021-02-26, bill): Sanity checker // This is a partial hack to make sure all procedure bodies have been checked // even ones which should not exist, due to the multithreaded nature of the parser @@ -5255,7 +5254,7 @@ void check_unchecked_bodies(Checker *c) { } -void check_test_procedures(Checker *c) { +gb_internal void check_test_procedures(Checker *c) { if (build_context.test_names.entries.count == 0) { return; } @@ -5290,7 +5289,7 @@ void check_test_procedures(Checker *c) { gb_global std::atomic total_bodies_checked; -bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) { +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) { GB_ASSERT(pi->decl != nullptr); if (pi->decl->parent && pi->decl->parent->entity) { Entity *parent = pi->decl->parent->entity; @@ -5318,7 +5317,7 @@ struct ThreadProcBodyData { ThreadProcBodyData *all_data; }; -WORKER_TASK_PROC(thread_proc_body) { +gb_internal WORKER_TASK_PROC(thread_proc_body) { ThreadProcBodyData *bd = cast(ThreadProcBodyData *)data; Checker *c = bd->checker; GB_ASSERT(c != nullptr); @@ -5338,7 +5337,7 @@ WORKER_TASK_PROC(thread_proc_body) { return 0; } -void check_procedure_bodies(Checker *c) { +gb_internal void check_procedure_bodies(Checker *c) { GB_ASSERT(c != nullptr); u32 thread_count = cast(u32)gb_max(build_context.thread_count, 1); @@ -5414,7 +5413,7 @@ void check_procedure_bodies(Checker *c) { global_procedure_body_in_worker_queue = false; } -void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { +gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { if (untyped == nullptr) { return; } @@ -5428,7 +5427,7 @@ void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { map_clear(untyped); } -void check_deferred_procedures(Checker *c) { +gb_internal void check_deferred_procedures(Checker *c) { for (Entity *src = nullptr; mpmc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { GB_ASSERT(src->kind == Entity_Procedure); @@ -5581,7 +5580,7 @@ void check_deferred_procedures(Checker *c) { } -void check_unique_package_names(Checker *c) { +gb_internal void check_unique_package_names(Checker *c) { StringMap pkgs = {}; // Key: package name string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count); defer (string_map_destroy(&pkgs)); @@ -5614,7 +5613,7 @@ void check_unique_package_names(Checker *c) { } } -void check_add_entities_from_queues(Checker *c) { +gb_internal void check_add_entities_from_queues(Checker *c) { isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.entities, cap); for (Entity *e; mpmc_dequeue(&c->info.entity_queue, &e); /**/) { @@ -5622,7 +5621,7 @@ void check_add_entities_from_queues(Checker *c) { } } -void check_add_definitions_from_queues(Checker *c) { +gb_internal void check_add_definitions_from_queues(Checker *c) { isize cap = c->info.definitions.count + c->info.definition_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.definitions, cap); for (Entity *e; mpmc_dequeue(&c->info.definition_queue, &e); /**/) { @@ -5630,12 +5629,12 @@ void check_add_definitions_from_queues(Checker *c) { } } -void check_merge_queues_into_arrays(Checker *c) { +gb_internal void check_merge_queues_into_arrays(Checker *c) { check_add_entities_from_queues(c); check_add_definitions_from_queues(c); } -GB_COMPARE_PROC(init_procedures_cmp) { +gb_internal GB_COMPARE_PROC(init_procedures_cmp) { int cmp = 0; Entity *x = *(Entity **)a; Entity *y = *(Entity **)b; @@ -5673,11 +5672,11 @@ GB_COMPARE_PROC(init_procedures_cmp) { } -void check_sort_init_procedures(Checker *c) { +gb_internal void check_sort_init_procedures(Checker *c) { gb_sort_array(c->info.init_procedures.data, c->info.init_procedures.count, init_procedures_cmp); } -void add_type_info_for_type_definitions(Checker *c) { +gb_internal void add_type_info_for_type_definitions(Checker *c) { for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; if (e->kind == Entity_TypeName && e->type != nullptr) { @@ -5689,7 +5688,7 @@ void add_type_info_for_type_definitions(Checker *c) { } } -void check_parsed_files(Checker *c) { +gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("map full filepaths to scope"); add_type_info_type(&c->builtin_ctx, t_invalid); diff --git a/src/types.cpp b/src/types.cpp index 2ab7374c2..c8e24f01d 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4029,9 +4029,8 @@ gb_internal bool has_type_got_objc_class_attribute(Type *t) { +gb_internal bool internal_check_is_assignable_to(Type *src, Type *dst); gb_internal bool is_type_objc_object(Type *t) { - bool internal_check_is_assignable_to(Type *src, Type *dst); - return internal_check_is_assignable_to(t, t_objc_object); } -- cgit v1.2.3 From c1f5be24e28c41efbbbe6d116d533b55d48bbf82 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 18 Dec 2022 22:49:10 +0000 Subject: Remove dead code in the compiler --- build.bat | 1 + src/build_settings.cpp | 6 +- src/check_decl.cpp | 10 - src/check_expr.cpp | 24 - src/check_stmt.cpp | 6 - src/checker.cpp | 140 ++---- src/checker.hpp | 8 - src/common.cpp | 9 + src/docs.cpp | 9 - src/entity.cpp | 8 - src/exact_value.cpp | 86 ++-- src/llvm_backend.cpp | 10 +- src/llvm_backend_debug.cpp | 6 - src/llvm_backend_general.cpp | 68 --- src/llvm_backend_opt.cpp | 20 +- src/llvm_backend_proc.cpp | 88 ++-- src/llvm_backend_stmt.cpp | 10 - src/llvm_backend_utility.cpp | 12 - src/main.cpp | 77 +--- src/parser.cpp | 36 -- src/parser.hpp | 5 - src/parser_pos.cpp | 2 - src/query_data.cpp | 1030 ------------------------------------------ src/range_cache.cpp | 18 +- src/string.cpp | 14 - src/string_map.cpp | 2 - src/threading.cpp | 50 +- src/types.cpp | 75 --- 28 files changed, 169 insertions(+), 1661 deletions(-) delete mode 100644 src/query_data.cpp (limited to 'src/check_decl.cpp') diff --git a/build.bat b/build.bat index 7391bd95f..d7a89fe20 100644 --- a/build.bat +++ b/build.bat @@ -62,6 +62,7 @@ if %release_mode% EQU 0 ( rem Debug set compiler_warnings= ^ -W4 -WX ^ -wd4100 -wd4101 -wd4127 -wd4146 ^ + -wd4505 ^ -wd4456 -wd4457 set compiler_includes= ^ diff --git a/src/build_settings.cpp b/src/build_settings.cpp index d66db8099..7d796d775 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -149,7 +149,6 @@ enum CommandKind : u32 { Command_run = 1<<0, Command_build = 1<<1, Command_check = 1<<3, - Command_query = 1<<4, Command_doc = 1<<5, Command_version = 1<<6, Command_test = 1<<7, @@ -157,7 +156,7 @@ enum CommandKind : u32 { Command_strip_semicolon = 1<<8, Command_bug_report = 1<<9, - Command__does_check = Command_run|Command_build|Command_check|Command_query|Command_doc|Command_test|Command_strip_semicolon, + Command__does_check = Command_run|Command_build|Command_check|Command_doc|Command_test|Command_strip_semicolon, Command__does_build = Command_run|Command_build|Command_test, Command_all = ~(u32)0, }; @@ -166,7 +165,6 @@ gb_global char const *odin_command_strings[32] = { "run", "build", "check", - "query", "doc", "version", "test", @@ -316,8 +314,6 @@ struct BuildContext { u32 cmd_doc_flags; Array extra_packages; - QueryDataSetSettings query_data_set_settings; - StringSet test_names; gbAffinity affinity; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index a976c1b73..d982a69fc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -232,16 +232,6 @@ gb_internal Ast *remove_type_alias_clutter(Ast *node) { } } -gb_internal isize total_attribute_count(DeclInfo *decl) { - isize attribute_count = 0; - for_array(i, decl->attributes) { - Ast *attr = decl->attributes[i]; - if (attr->kind != Ast_Attribute) continue; - attribute_count += attr->Attribute.elems.count; - } - return attribute_count; -} - gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations // diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 3003e07b6..ed1ddd1f1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5103,16 +5103,6 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize return optional_ok; } - -gb_internal bool is_expr_constant_zero(Ast *expr) { - GB_ASSERT(expr != nullptr); - auto v = exact_value_to_integer(expr->tav.value); - if (v.kind == ExactValue_Integer) { - return big_int_cmp_zero(&v.value_integer) == 0; - } - return false; -} - gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { GB_ASSERT(pt != nullptr); GB_ASSERT(pt->kind == Type_Proc); @@ -5429,20 +5419,6 @@ gb_internal isize lookup_procedure_parameter(TypeProc *pt, String parameter_name } return -1; } -gb_internal isize lookup_procedure_result(TypeProc *pt, String result_name) { - isize result_count = pt->result_count; - for (isize i = 0; i < result_count; i++) { - Entity *e = pt->results->Tuple.variables[i]; - String name = e->token.string; - if (is_blank_ident(name)) { - continue; - } - if (name == result_name) { - return i; - } - } - return -1; -} gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { ast_node(ce, CallExpr, call); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cae9c3537..73adbed8b 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1520,12 +1520,6 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) } case_end; - case_ast_node(ts, TagStmt, node); - // TODO(bill): Tag Statements - error(node, "Tag statements are not supported yet"); - check_stmt(ctx, ts->stmt, flags); - case_end; - case_ast_node(as, AssignStmt, node); switch (as->op.kind) { case Token_Eq: { diff --git a/src/checker.cpp b/src/checker.cpp index e2c430dc2..f130a965f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -61,18 +61,6 @@ gb_internal void scope_reserve(Scope *scope, isize capacity) { } } -gb_internal i32 is_scope_an_ancestor(Scope *parent, Scope *child) { - i32 i = 0; - while (child != nullptr) { - if (parent == child) { - return i; - } - child = child->parent; - i++; - } - return -1; -} - gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { if (s->hashes.data != nullptr) { ptr_set_destroy(s); @@ -86,9 +74,9 @@ gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNod ptr_set_add(s, n); } -gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { - return ptr_set_exists(s, n); -} +// gb_internal bool entity_graph_node_set_exists(EntityGraphNodeSet *s, EntityGraphNode *n) { +// return ptr_set_exists(s, n); +// } gb_internal void entity_graph_node_set_remove(EntityGraphNodeSet *s, EntityGraphNode *n) { ptr_set_remove(s, n); @@ -139,13 +127,13 @@ gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNod ptr_set_add(s, n); } -gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { - return ptr_set_exists(s, n); -} +// gb_internal bool import_graph_node_set_exists(ImportGraphNodeSet *s, ImportGraphNode *n) { +// return ptr_set_exists(s, n); +// } -gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { - ptr_set_remove(s, n); -} +// gb_internal void import_graph_node_set_remove(ImportGraphNodeSet *s, ImportGraphNode *n) { +// ptr_set_remove(s, n); +// } gb_internal ImportGraphNode *import_graph_node_create(gbAllocator a, AstPackage *pkg) { ImportGraphNode *n = gb_alloc_item(a, ImportGraphNode); @@ -186,15 +174,6 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j y->index = i; } -gb_internal GB_COMPARE_PROC(ast_node_cmp) { - Ast *x = *cast(Ast **)a; - Ast *y = *cast(Ast **)b; - Token i = ast_token(x); - Token j = ast_token(y); - return token_pos_cmp(i.pos, j.pos); -} - - @@ -213,27 +192,27 @@ gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { return d; } -gb_internal void destroy_declaration_info(DeclInfo *d) { - ptr_set_destroy(&d->deps); - array_free(&d->labels); -} +// gb_internal void destroy_declaration_info(DeclInfo *d) { +// ptr_set_destroy(&d->deps); +// array_free(&d->labels); +// } -gb_internal bool decl_info_has_init(DeclInfo *d) { - if (d->init_expr != nullptr) { - return true; - } - if (d->proc_lit != nullptr) { - switch (d->proc_lit->kind) { - case_ast_node(pl, ProcLit, d->proc_lit); - if (pl->body != nullptr) { - return true; - } - case_end; - } - } +// gb_internal bool decl_info_has_init(DeclInfo *d) { +// if (d->init_expr != nullptr) { +// return true; +// } +// if (d->proc_lit != nullptr) { +// switch (d->proc_lit->kind) { +// case_ast_node(pl, ProcLit, d->proc_lit); +// if (pl->body != nullptr) { +// return true; +// } +// case_end; +// } +// } - return false; -} +// return false; +// } @@ -528,11 +507,6 @@ struct VettedEntity { Entity *entity; Entity *other; }; -gb_internal void init_vetted_entity(VettedEntity *ve, VettedEntityKind kind, Entity *entity, Entity *other=nullptr) { - ve->kind = kind; - ve->entity = entity; - ve->other = other; -} gb_internal GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { @@ -1144,7 +1118,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { - i->allow_identifier_uses = build_context.query_data_set_settings.kind == QueryDataSet_GoToDefinitions; + i->allow_identifier_uses = false; if (i->allow_identifier_uses) { array_init(&i->identifier_uses, a); } @@ -1226,13 +1200,10 @@ gb_internal CheckerContext make_checker_context(Checker *c) { ctx.type_path = new_checker_type_path(); ctx.type_level = 0; - ctx.poly_path = new_checker_poly_path(); - ctx.poly_level = 0; return ctx; } gb_internal void destroy_checker_context(CheckerContext *ctx) { destroy_checker_type_path(ctx->type_path); - destroy_checker_poly_path(ctx->poly_path); } gb_internal void add_curr_ast_file(CheckerContext *ctx, AstFile *file) { @@ -1348,17 +1319,17 @@ gb_internal DeclInfo *decl_info_of_entity(Entity *e) { return nullptr; } -gb_internal DeclInfo *decl_info_of_ident(Ast *ident) { - return decl_info_of_entity(entity_of_node(ident)); -} +// gb_internal DeclInfo *decl_info_of_ident(Ast *ident) { +// return decl_info_of_entity(entity_of_node(ident)); +// } -gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { - AstFile **found = string_map_get(&i->files, filename); - if (found != nullptr) { - return *found; - } - return nullptr; -} +// gb_internal AstFile *ast_file_of_filename(CheckerInfo *i, String filename) { +// AstFile **found = string_map_get(&i->files, filename); +// if (found != nullptr) { +// return *found; +// } +// return nullptr; +// } gb_internal ExprInfo *check_get_expr_info(CheckerContext *c, Ast *expr) { if (c->untyped != nullptr) { ExprInfo **found = map_get(c->untyped, expr); @@ -2684,32 +2655,6 @@ gb_internal Entity *check_type_path_pop(CheckerContext *c) { } -gb_internal CheckerPolyPath *new_checker_poly_path(void) { - gbAllocator a = heap_allocator(); - auto *pp = gb_alloc_item(a, CheckerPolyPath); - array_init(pp, a, 0, 16); - return pp; -} - -gb_internal void destroy_checker_poly_path(CheckerPolyPath *pp) { - array_free(pp); - gb_free(heap_allocator(), pp); -} - - -gb_internal void check_poly_path_push(CheckerContext *c, Type *t) { - GB_ASSERT(c->poly_path != nullptr); - GB_ASSERT(t != nullptr); - GB_ASSERT(is_type_polymorphic(t)); - array_add(c->poly_path, t); -} - -gb_internal Type *check_poly_path_pop(CheckerContext *c) { - GB_ASSERT(c->poly_path != nullptr); - return array_pop(c->poly_path); -} - - gb_internal Array proc_group_entities(CheckerContext *c, Operand o) { Array procs = {}; @@ -2878,13 +2823,6 @@ gb_internal ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) return ev; } -gb_internal Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { - if (value != nullptr) { - return check_type(c, value); - } - return nullptr; -} - #define ATTRIBUTE_USER_TAG_NAME "tag" diff --git a/src/checker.hpp b/src/checker.hpp index e1efd5b89..58f6a027c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -397,8 +397,6 @@ struct CheckerContext { CheckerTypePath *type_path; isize type_level; // TODO(bill): Actually handle correctly - CheckerPolyPath *poly_path; - isize poly_level; // TODO(bill): Actually handle correctly UntypedExprInfoMap *untyped; @@ -489,12 +487,6 @@ gb_internal void destroy_checker_type_path(CheckerTypePath *tp); gb_internal void check_type_path_push(CheckerContext *c, Entity *e); gb_internal Entity *check_type_path_pop (CheckerContext *c); -gb_internal CheckerPolyPath *new_checker_poly_path(); -gb_internal void destroy_checker_poly_path(CheckerPolyPath *); - -gb_internal void check_poly_path_push(CheckerContext *c, Type *t); -gb_internal Type *check_poly_path_pop (CheckerContext *c); - gb_internal void init_core_context(Checker *c); gb_internal void init_mem_allocator(Checker *c); diff --git a/src/common.cpp b/src/common.cpp index 09203e633..3624446f1 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -50,6 +50,10 @@ gb_internal void debugf(char const *fmt, ...); #include "string.cpp" #include "range_cache.cpp" +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif gb_internal gb_inline bool is_power_of_two(i64 x) { if (x <= 0) { @@ -900,3 +904,8 @@ gb_internal Slice did_you_mean_results(DidYouMeanAnswers *d) } return slice_array(d->distances, 0, count); } + + +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif \ No newline at end of file diff --git a/src/docs.cpp b/src/docs.cpp index 33b1e8361..b1efa2b46 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -85,15 +85,6 @@ gb_internal void print_doc_line(i32 indent, char const *fmt, ...) { va_end(va); gb_printf("\n"); } -gb_internal void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { - while (indent --> 0) { - gb_printf("\t"); - } - va_list va; - va_start(va, fmt); - gb_printf_va(fmt, va); - va_end(va); -} gb_internal void print_doc_line_no_newline(i32 indent, String const &data) { while (indent --> 0) { gb_printf("\t"); diff --git a/src/entity.cpp b/src/entity.cpp index 6a3a69950..0605a293a 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -404,14 +404,6 @@ gb_internal Entity *alloc_entity_proc_group(Scope *scope, Token token, Type *typ return entity; } - -gb_internal Entity *alloc_entity_builtin(Scope *scope, Token token, Type *type, i32 id) { - Entity *entity = alloc_entity(Entity_Builtin, scope, token, type); - entity->Builtin.id = id; - entity->state = EntityState_Resolved; - return entity; -} - gb_internal Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type, String path, String name, Scope *import_scope) { Entity *entity = alloc_entity(Entity_ImportName, scope, token, type); diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 453909a15..f4c85505d 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -15,16 +15,6 @@ struct Quaternion256 { f64 imag, jmag, kmag, real; }; -gb_internal Quaternion256 quaternion256_inverse(Quaternion256 x) { - f64 invmag2 = 1.0 / (x.real*x.real + x.imag*x.imag + x.jmag*x.jmag + x.kmag*x.kmag); - x.real = +x.real * invmag2; - x.imag = -x.imag * invmag2; - x.jmag = -x.jmag * invmag2; - x.kmag = -x.kmag * invmag2; - return x; -} - - enum ExactValueKind { ExactValue_Invalid = 0, @@ -453,44 +443,44 @@ gb_internal ExactValue exact_value_kmag(ExactValue v) { return r; } -gb_internal ExactValue exact_value_make_imag(ExactValue v) { - switch (v.kind) { - case ExactValue_Integer: - return exact_value_complex(0, exact_value_to_float(v).value_float); - case ExactValue_Float: - return exact_value_complex(0, v.value_float); - default: - GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); - } - ExactValue r = {ExactValue_Invalid}; - return r; -} - -gb_internal ExactValue exact_value_make_jmag(ExactValue v) { - switch (v.kind) { - case ExactValue_Integer: - return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0); - case ExactValue_Float: - return exact_value_quaternion(0, 0, v.value_float, 0); - default: - GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); - } - ExactValue r = {ExactValue_Invalid}; - return r; -} - -gb_internal ExactValue exact_value_make_kmag(ExactValue v) { - switch (v.kind) { - case ExactValue_Integer: - return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float); - case ExactValue_Float: - return exact_value_quaternion(0, 0, 0, v.value_float); - default: - GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); - } - ExactValue r = {ExactValue_Invalid}; - return r; -} +// gb_internal ExactValue exact_value_make_imag(ExactValue v) { +// switch (v.kind) { +// case ExactValue_Integer: +// return exact_value_complex(0, exact_value_to_float(v).value_float); +// case ExactValue_Float: +// return exact_value_complex(0, v.value_float); +// default: +// GB_PANIC("Expected an integer or float type for 'exact_value_make_imag'"); +// } +// ExactValue r = {ExactValue_Invalid}; +// return r; +// } + +// gb_internal ExactValue exact_value_make_jmag(ExactValue v) { +// switch (v.kind) { +// case ExactValue_Integer: +// return exact_value_quaternion(0, 0, exact_value_to_float(v).value_float, 0); +// case ExactValue_Float: +// return exact_value_quaternion(0, 0, v.value_float, 0); +// default: +// GB_PANIC("Expected an integer or float type for 'exact_value_make_jmag'"); +// } +// ExactValue r = {ExactValue_Invalid}; +// return r; +// } + +// gb_internal ExactValue exact_value_make_kmag(ExactValue v) { +// switch (v.kind) { +// case ExactValue_Integer: +// return exact_value_quaternion(0, 0, 0, exact_value_to_float(v).value_float); +// case ExactValue_Float: +// return exact_value_quaternion(0, 0, 0, v.value_float); +// default: +// GB_PANIC("Expected an integer or float type for 'exact_value_make_kmag'"); +// } +// ExactValue r = {ExactValue_Invalid}; +// return r; +// } gb_internal i64 exact_value_to_i64(ExactValue v) { v = exact_value_to_integer(v); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ca4b3b683..c5bc96eb9 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -605,11 +605,11 @@ gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { return {p->value, p->type}; } -gb_internal void lb_debug_print(lbProcedure *p, String const &str) { - auto args = array_make(heap_allocator(), 1); - args[0] = lb_const_string(p->module, str); - lb_emit_runtime_call(p, "print_string", args); -} +// gb_internal void lb_debug_print(lbProcedure *p, String const &str) { +// auto args = array_make(heap_allocator(), 1); +// args[0] = lb_const_string(p->module, str); +// lb_emit_runtime_call(p, "print_string", args); +// } gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { GB_ASSERT(build_context.use_static_map_calls); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 849416579..55c4370a2 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -14,12 +14,6 @@ gb_internal void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef va } } -gb_internal LLVMMetadataRef lb_get_llvm_file_metadata_from_node(lbModule *m, Ast *node) { - if (node == nullptr) { - return nullptr; - } - return lb_get_llvm_metadata(m, node->file()); -} gb_internal LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) { GB_ASSERT_MSG(p->debug_info != nullptr, "missing debug information for %.*s", LIT(p->name)); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index f30038da8..e5aa95f10 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -272,12 +272,6 @@ gb_internal lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index) gb_internal LLVMValueRef llvm_zero(lbModule *m) { return LLVMConstInt(lb_type(m, t_int), 0, false); } -gb_internal LLVMValueRef llvm_zero32(lbModule *m) { - return LLVMConstInt(lb_type(m, t_i32), 0, false); -} -gb_internal LLVMValueRef llvm_one(lbModule *m) { - return LLVMConstInt(lb_type(m, t_i32), 1, false); -} gb_internal LLVMValueRef llvm_alloca(lbProcedure *p, LLVMTypeRef llvm_type, isize alignment, char const *name) { LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block); @@ -874,14 +868,6 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { lb_emit_store(p, addr.addr, value); } -gb_internal void lb_const_store(lbValue ptr, lbValue value) { - GB_ASSERT(lb_is_const(ptr)); - GB_ASSERT(lb_is_const(value)); - GB_ASSERT(is_type_pointer(ptr.type)); - LLVMSetInitializer(ptr.value, value.value); -} - - gb_internal bool lb_is_type_proc_recursive(Type *t) { for (;;) { if (t == nullptr) { @@ -1327,21 +1313,6 @@ gb_internal void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src)); } -gb_internal LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) { - switch (alignment) { - case 1: - return LLVMArrayType(lb_type(m, t_u8), 0); - case 2: - return LLVMArrayType(lb_type(m, t_u16), 0); - case 4: - return LLVMArrayType(lb_type(m, t_u32), 0); - case 8: - return LLVMArrayType(lb_type(m, t_u64), 0); - default: case 16: - return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0); - } -} - gb_internal String lb_mangle_name(lbModule *m, Entity *e) { String name = e->token.string; @@ -2202,9 +2173,6 @@ gb_internal void lb_add_member(lbModule *m, String const &name, lbValue val) { string_map_set(&m->members, name, val); } } -gb_internal void lb_add_member(lbModule *m, StringHashKey const &key, lbValue val) { - string_map_set(&m->members, key, val); -} gb_internal void lb_add_procedure_value(lbModule *m, lbProcedure *p) { if (p->entity != nullptr) { map_set(&m->procedure_values, p->value, p->entity); @@ -2493,42 +2461,6 @@ gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) return res; } -gb_internal lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) { - LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)}; - LLVMValueRef data = LLVMConstStringInContext(m->ctx, - cast(char const *)str.text, - cast(unsigned)str.len, - false); - - - char *name = nullptr; - { - isize max_len = 7+8+1; - name = gb_alloc_array(permanent_allocator(), char, max_len); - u32 id = m->gen->global_array_index.fetch_add(1); - isize len = gb_snprintf(name, max_len, "csbs$%x", id); - len -= 1; - } - LLVMTypeRef type = LLVMTypeOf(data); - LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name); - LLVMSetInitializer(global_data, data); - lb_make_global_private_const(global_data); - LLVMSetAlignment(global_data, 1); - - LLVMValueRef ptr = nullptr; - if (str.len != 0) { - ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2); - } else { - ptr = LLVMConstNull(lb_type(m, t_u8_ptr)); - } - LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true); - LLVMValueRef values[2] = {ptr, len}; - - lbValue res = {}; - res.value = llvm_const_named_struct(m, t_u8_slice, values, 2); - res.type = t_u8_slice; - return res; -} gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String const &str, Type *slice_type) { GB_ASSERT(is_type_slice(slice_type)); LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)}; diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 533264e62..fd6d94361 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -37,16 +37,16 @@ gb_internal void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i3 gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPassManagerRef mpm, i32 optimization_level); gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level); -gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) { - lbModule *m = cast(lbModule *)user_data; - if (m == nullptr) { - return false; - } - if (value == nullptr) { - return false; - } - return LLVMIsAAllocaInst(value) != nullptr; -} +// gb_internal LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data) { +// lbModule *m = cast(lbModule *)user_data; +// if (m == nullptr) { +// return false; +// } +// if (value == nullptr) { +// return false; +// } +// return LLVMIsAAllocaInst(value) != nullptr; +// } #if LLVM_VERSION_MAJOR < 12 diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 0789fb2c1..384d29ca7 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -383,46 +383,46 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name } -gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) { - lbParamPasskind kind = lbParamPass_Value; - - if (e != nullptr && !are_types_identical(abi_type, e->type)) { - if (is_type_pointer(abi_type)) { - GB_ASSERT(e->kind == Entity_Variable); - Type *av = core_type(type_deref(abi_type)); - if (are_types_identical(av, core_type(e->type))) { - kind = lbParamPass_Pointer; - if (e->flags&EntityFlag_Value) { - kind = lbParamPass_ConstRef; - } - } else { - kind = lbParamPass_BitCast; - } - } else if (is_type_integer(abi_type)) { - kind = lbParamPass_Integer; - } else if (abi_type == t_llvm_bool) { - kind = lbParamPass_Value; - } else if (is_type_boolean(abi_type)) { - kind = lbParamPass_Integer; - } else if (is_type_simd_vector(abi_type)) { - kind = lbParamPass_BitCast; - } else if (is_type_float(abi_type)) { - kind = lbParamPass_BitCast; - } else if (is_type_tuple(abi_type)) { - kind = lbParamPass_Tuple; - } else if (is_type_proc(abi_type)) { - kind = lbParamPass_Value; - } else { - GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type)); - } - } - - if (kind_) *kind_ = kind; - lbValue res = {}; - res.value = LLVMGetParam(p->value, cast(unsigned)index); - res.type = abi_type; - return res; -} +// gb_internal lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) { +// lbParamPasskind kind = lbParamPass_Value; + +// if (e != nullptr && !are_types_identical(abi_type, e->type)) { +// if (is_type_pointer(abi_type)) { +// GB_ASSERT(e->kind == Entity_Variable); +// Type *av = core_type(type_deref(abi_type)); +// if (are_types_identical(av, core_type(e->type))) { +// kind = lbParamPass_Pointer; +// if (e->flags&EntityFlag_Value) { +// kind = lbParamPass_ConstRef; +// } +// } else { +// kind = lbParamPass_BitCast; +// } +// } else if (is_type_integer(abi_type)) { +// kind = lbParamPass_Integer; +// } else if (abi_type == t_llvm_bool) { +// kind = lbParamPass_Value; +// } else if (is_type_boolean(abi_type)) { +// kind = lbParamPass_Integer; +// } else if (is_type_simd_vector(abi_type)) { +// kind = lbParamPass_BitCast; +// } else if (is_type_float(abi_type)) { +// kind = lbParamPass_BitCast; +// } else if (is_type_tuple(abi_type)) { +// kind = lbParamPass_Tuple; +// } else if (is_type_proc(abi_type)) { +// kind = lbParamPass_Value; +// } else { +// GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type)); +// } +// } + +// if (kind_) *kind_ = kind; +// lbValue res = {}; +// res.value = LLVMGetParam(p->value, cast(unsigned)index); +// res.type = abi_type; +// return res; +// } @@ -1165,14 +1165,6 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array c return result; } -gb_internal LLVMValueRef llvm_splat_float(i64 count, LLVMTypeRef type, f64 value) { - LLVMValueRef v = LLVMConstReal(type, value); - LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count); - for (i64 i = 0; i < count; i++) { - values[i] = v; - } - return LLVMConstVector(values, cast(unsigned)count); -} gb_internal LLVMValueRef llvm_splat_int(i64 count, LLVMTypeRef type, i64 value, bool is_signed=false) { LLVMValueRef v = LLVMConstInt(type, value, is_signed); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, count); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 66c422071..6400a8a9d 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -378,16 +378,6 @@ gb_internal lbValue lb_map_cell_index_static(lbProcedure *p, Type *type, lbValue return lb_emit_ptr_offset(p, elems_ptr, data_index); } -gb_internal void lb_map_kvh_data_static(lbProcedure *p, lbValue map_value, lbValue *ks_, lbValue *vs_, lbValue *hs_) { - lbValue capacity = lb_map_cap(p, map_value); - lbValue ks = lb_map_data_uintptr(p, map_value); - lbValue vs = {}; - lbValue hs = {}; - if (ks_) *ks_ = ks; - if (vs_) *vs_ = vs; - if (hs_) *hs_ = hs; -} - gb_internal lbValue lb_map_hash_is_valid(lbProcedure *p, lbValue hash) { // N :: size_of(uintptr)*8 - 1 // (hash != 0) & (hash>>N == 0) diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 94b900278..dbed32b82 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -599,14 +599,6 @@ gb_internal lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) } -gb_internal lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x) { - GB_ASSERT(is_type_bit_set(x.type)); - Type *underlying = bit_set_to_int(x.type); - lbValue card = lb_emit_count_ones(p, x, underlying); - return lb_emit_conv(p, card, t_int); -} - - gb_internal lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) { GB_ASSERT(is_type_tuple(type)); lbModule *m = p->module; @@ -1493,10 +1485,6 @@ gb_internal lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da) { GB_ASSERT(is_type_dynamic_array(da.type)); return lb_emit_struct_ev(p, da, 2); } -gb_internal lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) { - GB_ASSERT(is_type_dynamic_array(da.type)); - return lb_emit_struct_ev(p, da, 3); -} gb_internal lbValue lb_map_len(lbProcedure *p, lbValue value) { GB_ASSERT_MSG(is_type_map(value.type) || are_types_identical(value.type, t_raw_map), "%s", type_to_string(value.type)); diff --git a/src/main.cpp b/src/main.cpp index 614130bb6..c7250aa8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,14 @@ #include "common.cpp" #include "timings.cpp" #include "tokenizer.cpp" +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif #include "big_int.cpp" +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif #include "exact_value.cpp" #include "build_settings.cpp" @@ -58,7 +65,6 @@ gb_global Timings global_timings = {0}; #endif #endif -#include "query_data.cpp" #include "bug_report.cpp" // NOTE(bill): 'name' is used in debugging and profiling modes @@ -573,7 +579,6 @@ gb_internal void usage(String argv0) { print_usage_line(1, " one must contain the program's entry point, all must be in the same package."); print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); print_usage_line(1, "check parse, and type check a directory of .odin files"); - print_usage_line(1, "query parse, type check, and output a .json file containing information about the program"); print_usage_line(1, "strip-semicolon parse, type check, and remove unneeded semicolons from the entire program"); print_usage_line(1, "test build and runs procedures with the attribute @(test) in the initial package"); print_usage_line(1, "doc generate documentation on a directory of .odin files"); @@ -817,12 +822,6 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_UseStaticMapCalls, str_lit("use-static-map-calls"), BuildFlagParam_None, Command__does_check); - - add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); - - add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc); add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); add_flag(&build_flags, BuildFlag_DocFormat, str_lit("doc-format"), BuildFlagParam_None, Command_doc); @@ -1445,39 +1444,6 @@ gb_internal bool parse_build_flags(Array args) { build_context.strict_style_init_only = true; break; } - case BuildFlag_Compact: { - if (!build_context.query_data_set_settings.ok) { - gb_printf_err("Invalid use of -compact flag, only allowed with 'odin query'\n"); - bad_flags = true; - } else { - build_context.query_data_set_settings.compact = true; - } - break; - } - case BuildFlag_GlobalDefinitions: { - if (!build_context.query_data_set_settings.ok) { - gb_printf_err("Invalid use of -global-definitions flag, only allowed with 'odin query'\n"); - bad_flags = true; - } else if (build_context.query_data_set_settings.kind != QueryDataSet_Invalid) { - gb_printf_err("Invalid use of -global-definitions flag, a previous flag for 'odin query' was set\n"); - bad_flags = true; - } else { - build_context.query_data_set_settings.kind = QueryDataSet_GlobalDefinitions; - } - break; - } - case BuildFlag_GoToDefinitions: { - if (!build_context.query_data_set_settings.ok) { - gb_printf_err("Invalid use of -go-to-definitions flag, only allowed with 'odin query'\n"); - bad_flags = true; - } else if (build_context.query_data_set_settings.kind != QueryDataSet_Invalid) { - gb_printf_err("Invalid use of -global-definitions flag, a previous flag for 'odin query' was set\n"); - bad_flags = true; - } else { - build_context.query_data_set_settings.kind = QueryDataSet_GoToDefinitions; - } - break; - } case BuildFlag_Short: build_context.cmd_doc_flags |= CmdDocFlag_Short; break; @@ -1638,16 +1604,6 @@ gb_internal bool parse_build_flags(Array args) { gb_printf_err("`-export-timings:` requires `-show-timings` or `-show-more-timings` to be present\n"); bad_flags = true; } - - if (build_context.query_data_set_settings.ok) { - if (build_context.query_data_set_settings.kind == QueryDataSet_Invalid) { - gb_printf_err("'odin query' requires a flag determining the kind of query data set to be returned\n"); - gb_printf_err("\t-global-definitions : outputs a JSON file of global definitions\n"); - gb_printf_err("\t-go-to-definitions : outputs a OGTD binary file of go to definitions for identifiers within an Odin project\n"); - bad_flags = true; - } - } - return !bad_flags; } @@ -1931,8 +1887,6 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(3, "odin check filename.odin -file # Type check single-file package, must contain entry point."); } else if (command == "test") { print_usage_line(1, "test Build ands runs procedures with the attribute @(test) in the initial package"); - } else if (command == "query") { - print_usage_line(1, "query [experimental] Parse, type check, and output a .json file containing information about the program"); } else if (command == "doc") { print_usage_line(1, "doc generate documentation from a directory of .odin files"); print_usage_line(2, "Examples:"); @@ -2627,15 +2581,6 @@ int main(int arg_count, char const **arg_ptr) { build_context.command_kind = Command_strip_semicolon; build_context.no_output_files = true; init_filename = args[2]; - } else if (command == "query") { - if (args.count < 3) { - usage(args[0]); - return 1; - } - build_context.command_kind = Command_query; - build_context.no_output_files = true; - build_context.query_data_set_settings.ok = true; - init_filename = args[2]; } else if (command == "doc") { if (args.count < 3) { usage(args[0]); @@ -2824,12 +2769,8 @@ int main(int arg_count, char const **arg_ptr) { print_show_unused(checker); } - if (build_context.query_data_set_settings.ok) { - generate_and_print_query_data(checker, &global_timings); - } else { - if (build_context.show_timings) { - show_timings(checker, &global_timings); - } + if (build_context.show_timings) { + show_timings(checker, &global_timings); } if (global_error_collector.count != 0) { diff --git a/src/parser.cpp b/src/parser.cpp index 1606f5b47..2ccdac7fa 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -237,9 +237,6 @@ gb_internal Ast *clone_ast(Ast *node) { case Ast_ExprStmt: n->ExprStmt.expr = clone_ast(n->ExprStmt.expr); break; - case Ast_TagStmt: - n->TagStmt.stmt = clone_ast(n->TagStmt.stmt); - break; case Ast_AssignStmt: n->AssignStmt.lhs = clone_ast_array(n->AssignStmt.lhs); n->AssignStmt.rhs = clone_ast_array(n->AssignStmt.rhs); @@ -497,14 +494,6 @@ gb_internal Ast *ast_tag_expr(AstFile *f, Token token, Token name, Ast *expr) { return result; } -gb_internal Ast *ast_tag_stmt(AstFile *f, Token token, Token name, Ast *stmt) { - Ast *result = alloc_ast_node(f, Ast_TagStmt); - result->TagStmt.token = token; - result->TagStmt.name = name; - result->TagStmt.stmt = stmt; - return result; -} - gb_internal Ast *ast_unary_expr(AstFile *f, Token op, Ast *expr) { Ast *result = alloc_ast_node(f, Ast_UnaryExpr); result->UnaryExpr.op = op; @@ -1308,16 +1297,6 @@ gb_internal Token advance_token(AstFile *f) { return prev; } -gb_internal bool peek_token_kind(AstFile *f, TokenKind kind) { - for (isize i = f->curr_token_index+1; i < f->tokens.count; i++) { - Token tok = f->tokens[i]; - if (kind != Token_Comment && tok.kind == Token_Comment) { - continue; - } - return tok.kind == kind; - } - return false; -} gb_internal Token peek_token(AstFile *f) { for (isize i = f->curr_token_index+1; i < f->tokens.count; i++) { @@ -1440,17 +1419,6 @@ gb_internal Token expect_operator(AstFile *f) { return prev; } -gb_internal Token expect_keyword(AstFile *f) { - Token prev = f->curr_token; - if (!gb_is_between(prev.kind, Token__KeywordBegin+1, Token__KeywordEnd-1)) { - String p = token_to_string(prev); - syntax_error(f->curr_token, "Expected a keyword, got '%.*s'", - LIT(p)); - } - advance_token(f); - return prev; -} - gb_internal bool allow_token(AstFile *f, TokenKind kind) { Token prev = f->curr_token; if (prev.kind == kind) { @@ -1957,10 +1925,6 @@ gb_internal bool ast_on_same_line(Token const &x, Ast *yp) { return x.pos.line == y.pos.line; } -gb_internal bool ast_on_same_line(Ast *x, Ast *y) { - return ast_on_same_line(ast_token(x), y); -} - gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { Ast *expr = parse_unary_expr(f, false); Ast *e = strip_or_return_expr(expr); diff --git a/src/parser.hpp b/src/parser.hpp index a2d2c038e..f7b3e51ae 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -457,11 +457,6 @@ AST_KIND(_StmtBegin, "", bool) \ AST_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \ AST_KIND(EmptyStmt, "empty statement", struct { Token token; }) \ AST_KIND(ExprStmt, "expression statement", struct { Ast *expr; } ) \ - AST_KIND(TagStmt, "tag statement", struct { \ - Token token; \ - Token name; \ - Ast * stmt; \ - }) \ AST_KIND(AssignStmt, "assign statement", struct { \ Token op; \ Slice lhs, rhs; \ diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index 19a525e2e..fb7f0c9c2 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -53,7 +53,6 @@ gb_internal Token ast_token(Ast *node) { case Ast_BadStmt: return node->BadStmt.begin; case Ast_EmptyStmt: return node->EmptyStmt.token; case Ast_ExprStmt: return ast_token(node->ExprStmt.expr); - case Ast_TagStmt: return node->TagStmt.token; case Ast_AssignStmt: return node->AssignStmt.op; case Ast_BlockStmt: return node->BlockStmt.open; case Ast_IfStmt: return node->IfStmt.token; @@ -197,7 +196,6 @@ Token ast_end_token(Ast *node) { case Ast_BadStmt: return node->BadStmt.end; case Ast_EmptyStmt: return node->EmptyStmt.token; case Ast_ExprStmt: return ast_end_token(node->ExprStmt.expr); - case Ast_TagStmt: return ast_end_token(node->TagStmt.stmt); case Ast_AssignStmt: if (node->AssignStmt.rhs.count > 0) { return ast_end_token(node->AssignStmt.rhs[node->AssignStmt.rhs.count-1]); diff --git a/src/query_data.cpp b/src/query_data.cpp deleted file mode 100644 index 86487a058..000000000 --- a/src/query_data.cpp +++ /dev/null @@ -1,1030 +0,0 @@ -struct QueryValue; -struct QueryValuePair; - -gb_global gbAllocator query_value_allocator = {}; - -enum QueryKind { - Query_Invalid, - Query_String, - Query_Boolean, - Query_Integer, - Query_Float, - Query_Array, - Query_Map, -}; - -struct QueryValuePair { - String key; - QueryValue *value; -}; - - -struct QueryValue { - QueryKind kind; - bool packed; -}; - -struct QueryValueString : QueryValue { - QueryValueString(String const &v) { - kind = Query_String; - value = v; - packed = false; - } - String value; -}; - -struct QueryValueBoolean : QueryValue { - QueryValueBoolean(bool v) { - kind = Query_Boolean; - value = v; - packed = false; - } - bool value; -}; - -struct QueryValueInteger : QueryValue { - QueryValueInteger(i64 v) { - kind = Query_Integer; - value = v; - packed = false; - } - i64 value; -}; - -struct QueryValueFloat : QueryValue { - QueryValueFloat(f64 v) { - kind = Query_Float; - value = v; - packed = false; - } - f64 value; -}; - -struct QueryValueArray : QueryValue { - QueryValueArray() { - kind = Query_Array; - array_init(&value, query_value_allocator); - packed = false; - } - QueryValueArray(Array const &v) { - kind = Query_Array; - value = v; - packed = false; - } - Array value; - - void reserve(isize cap) { - array_reserve(&value, cap); - } - void add(QueryValue *v) { - array_add(&value, v); - } - void add(char const *v) { - add(make_string_c(cast(char *)v)); - } - void add(String const &v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueString); - *val = QueryValueString(v); - add(val); - } - void add(bool v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean); - *val = QueryValueBoolean(v); - add(val); - } - void add(i64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueInteger); - *val = QueryValueInteger(v); - add(val); - } - void add(f64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueFloat); - *val = QueryValueFloat(v); - add(val); - } -}; - -struct QueryValueMap : QueryValue { - QueryValueMap() { - kind = Query_Map; - array_init(&value, query_value_allocator); - packed = false; - } - QueryValueMap(Array const &v) { - kind = Query_Map; - value = v; - packed = false; - } - Array value; - - - void reserve(isize cap) { - array_reserve(&value, cap); - } - void add(char const *k, QueryValue *v) { - add(make_string_c(cast(char *)k), v); - } - void add(String const &k, QueryValue *v) { - QueryValuePair kv = {k, v}; - array_add(&value, kv); - } - - void add(char const *k, String const &v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueString); - *val = QueryValueString(v); - add(k, val); - } - void add(char const *k, char const *v) { - add(k, make_string_c(cast(char *)v)); - } - void add(char const *k, bool v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean); - *val = QueryValueBoolean(v); - add(k, val); - } - void add(char const *k, i64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueInteger); - *val = QueryValueInteger(v); - add(k, val); - } - void add(char const *k, f64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueFloat); - *val = QueryValueFloat(v); - add(k, val); - } - void add(String const &k, String const &v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueString); - *val = QueryValueString(v); - add(k, val); - } - void add(String const &k, char const *v) { - add(k, make_string_c(cast(char *)v)); - } - void add(String const &k, bool v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueBoolean); - *val = QueryValueBoolean(v); - add(k, val); - } - void add(String const &k, i64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueInteger); - *val = QueryValueInteger(v); - add(k, val); - } - void add(String const &k, f64 v) { - auto val = gb_alloc_item(query_value_allocator, QueryValueFloat); - *val = QueryValueFloat(v); - add(k, val); - } -}; - - -#define DEF_QUERY_PROC(TYPE, VALUETYPE, NAME) TYPE *NAME(VALUETYPE value) { \ - auto v = gb_alloc_item(query_value_allocator, TYPE); \ - *v = TYPE(value); \ - return v; \ -} -#define DEF_QUERY_PROC0(TYPE, NAME) TYPE *NAME() { \ - auto v = gb_alloc_item(query_value_allocator, TYPE); \ - *v = TYPE(); \ - return v; \ -} - -gb_internal DEF_QUERY_PROC(QueryValueString, String const &, query_value_string); -gb_internal DEF_QUERY_PROC(QueryValueBoolean, bool, query_value_boolean); -gb_internal DEF_QUERY_PROC(QueryValueInteger, i64, query_value_integer); -gb_internal DEF_QUERY_PROC(QueryValueFloat, f64, query_value_float); -gb_internal DEF_QUERY_PROC(QueryValueArray, Array const &, query_value_array); -gb_internal DEF_QUERY_PROC(QueryValueMap, Array const &, query_value_map); -gb_internal DEF_QUERY_PROC0(QueryValueArray, query_value_array); -gb_internal DEF_QUERY_PROC0(QueryValueMap, query_value_map); - -gb_internal isize qprintf(bool format, isize indent, char const *fmt, ...) { - if (format) while (indent --> 0) { - gb_printf("\t"); - } - va_list va; - va_start(va, fmt); - isize res = gb_printf_va(fmt, va); - va_end(va); - return res; -} - -gb_internal bool qv_valid_char(u8 c) { - if (c >= 0x80) { - return false; - } - - switch (c) { - case '\"': - case '\n': - case '\r': - case '\t': - case '\v': - case '\f': - return false; - } - - return true; -} - -gb_internal void print_query_data_as_json(QueryValue *value, bool format = true, isize indent = 0) { - if (value == nullptr) { - gb_printf("null"); - return; - } - switch (value->kind) { - case Query_String: { - auto v = cast(QueryValueString *)value; - String name = v->value; - isize extra = 0; - for (isize i = 0; i < name.len; i++) { - u8 c = name[i]; - if (!qv_valid_char(c)) { - extra += 5; - } - } - - if (extra == 0) { - gb_printf("\"%.*s\"", LIT(name)); - return; - } - - char const hex_table[] = "0123456789ABCDEF"; - isize buf_len = name.len + extra + 2 + 1; - - u8 *buf = gb_alloc_array(temporary_allocator(), u8, buf_len); - - isize j = 0; - - for (isize i = 0; i < name.len; i++) { - u8 c = name[i]; - if (qv_valid_char(c)) { - buf[j+0] = c; - j += 1; - } else if (c == '"') { - buf[j+0] = '\\'; - buf[j+1] = '\"'; - j += 2; - } else { - switch (c) { - case '\n': buf[j+0] = '\\'; buf[j+1] = 'n'; j += 2; break; - case '\r': buf[j+0] = '\\'; buf[j+1] = 'r'; j += 2; break; - case '\t': buf[j+0] = '\\'; buf[j+1] = 't'; j += 2; break; - case '\v': buf[j+0] = '\\'; buf[j+1] = 'v'; j += 2; break; - case '\f': - default: - buf[j+0] = '\\'; - buf[j+1] = hex_table[0]; - buf[j+2] = hex_table[0]; - buf[j+3] = hex_table[c >> 4]; - buf[j+4] = hex_table[c & 0x0f]; - j += 5; - break; - } - } - } - - gb_printf("\"%s\"", buf); - return; - } - case Query_Boolean: { - auto v = cast(QueryValueBoolean *)value; - if (v->value) { - gb_printf("true"); - } else { - gb_printf("false"); - } - return; - } - case Query_Integer: { - auto v = cast(QueryValueInteger *)value; - gb_printf("%lld", cast(long long)v->value); - return; - } - case Query_Float: { - auto v = cast(QueryValueFloat *)value; - gb_printf("%f", v->value); - return; - } - case Query_Array: { - auto v = cast(QueryValueArray *)value; - if (v->value.count > 0) { - bool ff = format && !v->packed; - gb_printf("["); - if (ff) gb_printf("\n"); - for_array(i, v->value) { - qprintf(ff, indent+1, ""); - print_query_data_as_json(v->value[i], ff, indent+1); - if (i < v->value.count-1) { - gb_printf(","); - if (!ff && format) { - gb_printf(" "); - } - } - if (ff) gb_printf("\n"); - } - qprintf(ff, indent, "]"); - } else { - gb_printf("[]"); - } - return; - } - case Query_Map: { - auto v = cast(QueryValueMap *)value; - if (v->value.count > 0) { - bool ff = format && !v->packed; - gb_printf("{"); - if (ff) gb_printf("\n"); - for_array(i, v->value) { - auto kv = v->value[i]; - qprintf(ff, indent+1, "\"%.*s\":", LIT(kv.key)); - if (format) gb_printf(" "); - print_query_data_as_json(kv.value, ff, indent+1); - if (i < v->value.count-1) { - gb_printf(","); - if (!ff && format) { - gb_printf(" "); - } - } - if (ff) gb_printf("\n"); - } - qprintf(ff, indent, "}"); - } else { - gb_printf("{}"); - } - return; - } - } -} - - - -gb_internal int query_data_package_compare(void const *a, void const *b) { - AstPackage *x = *cast(AstPackage *const *)a; - AstPackage *y = *cast(AstPackage *const *)b; - - if (x == y) { - return 0; - } - - if (x != nullptr && y != nullptr) { - return string_compare(x->name, y->name); - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - return 0; -} - -gb_internal int query_data_definition_compare(void const *a, void const *b) { - Entity *x = *cast(Entity *const *)a; - Entity *y = *cast(Entity *const *)b; - - if (x == y) { - return 0; - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - - if (x->pkg != y->pkg) { - i32 res = query_data_package_compare(&x->pkg, &y->pkg); - if (res != 0) { - return res; - } - } - - return string_compare(x->token.string, y->token.string); -} - -gb_internal int entity_name_compare(void const *a, void const *b) { - Entity *x = *cast(Entity *const *)a; - Entity *y = *cast(Entity *const *)b; - if (x == y) { - return 0; - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - return string_compare(x->token.string, y->token.string); -} - - -gb_internal void generate_and_print_query_data_global_definitions(Checker *c, Timings *timings); -gb_internal void generate_and_print_query_data_go_to_definitions(Checker *c); - -gb_internal void generate_and_print_query_data(Checker *c, Timings *timings) { - query_value_allocator = heap_allocator(); - switch (build_context.query_data_set_settings.kind) { - case QueryDataSet_GlobalDefinitions: - generate_and_print_query_data_global_definitions(c, timings); - return; - case QueryDataSet_GoToDefinitions: - generate_and_print_query_data_go_to_definitions(c); - return; - } -} - - -gb_internal void generate_and_print_query_data_global_definitions(Checker *c, Timings *timings) { - auto *root = query_value_map(); - - if (global_error_collector.errors.count > 0) { - auto *errors = query_value_array(); - root->add("errors", errors); - for_array(i, global_error_collector.errors) { - String err = string_trim_whitespace(global_error_collector.errors[i]); - errors->add(err); - } - - } - - { // Packages - auto *packages = query_value_array(); - root->add("packages", packages); - - auto sorted_packages = array_make(query_value_allocator, 0, c->info.packages.entries.count); - defer (array_free(&sorted_packages)); - - for (auto const &entry : c->info.packages) { - AstPackage *pkg = entry.value; - if (pkg != nullptr) { - array_add(&sorted_packages, pkg); - } - } - gb_sort_array(sorted_packages.data, sorted_packages.count, query_data_package_compare); - packages->reserve(sorted_packages.count); - - for_array(i, sorted_packages) { - AstPackage *pkg = sorted_packages[i]; - String name = pkg->name; - String fullpath = pkg->fullpath; - - auto *files = query_value_array(); - files->reserve(pkg->files.count); - for_array(j, pkg->files) { - AstFile *f = pkg->files[j]; - files->add(f->fullpath); - } - - auto *package = query_value_map(); - package->reserve(3); - packages->add(package); - - package->add("name", pkg->name); - package->add("fullpath", pkg->fullpath); - package->add("files", files); - } - } - - if (c->info.definitions.count > 0) { - auto *definitions = query_value_array(); - root->add("definitions", definitions); - - auto sorted_definitions = array_make(query_value_allocator, 0, c->info.definitions.count); - defer (array_free(&sorted_definitions)); - - for_array(i, c->info.definitions) { - Entity *e = c->info.definitions[i]; - String name = e->token.string; - if (is_blank_ident(name)) { - continue; - } - if ((e->scope->flags & (ScopeFlag_Pkg|ScopeFlag_File)) == 0) { - continue; - } - if (e->parent_proc_decl != nullptr) { - continue; - } - switch (e->kind) { - case Entity_Builtin: - case Entity_Nil: - case Entity_Label: - continue; - } - if (e->pkg == nullptr) { - continue; - } - if (e->token.pos.line == 0) { - continue; - } - if (e->kind == Entity_Procedure) { - Type *t = base_type(e->type); - if (t->kind != Type_Proc) { - continue; - } - if (t->Proc.is_poly_specialized) { - continue; - } - } - if (e->kind == Entity_TypeName) { - Type *t = base_type(e->type); - if (t->kind == Type_Struct) { - if (t->Struct.is_poly_specialized) { - continue; - } - } - if (t->kind == Type_Union) { - if (t->Union.is_poly_specialized) { - continue; - } - } - } - - array_add(&sorted_definitions, e); - } - - gb_sort_array(sorted_definitions.data, sorted_definitions.count, query_data_definition_compare); - definitions->reserve(sorted_definitions.count); - - for_array(i, sorted_definitions) { - Entity *e = sorted_definitions[i]; - String name = e->token.string; - - auto *def = query_value_map(); - def->reserve(16); - definitions->add(def); - - def->add("package", e->pkg->name); - def->add("name", name); - def->add("filepath", get_file_path_string(e->token.pos.file_id)); - def->add("line", cast(i64)e->token.pos.line); - def->add("column", cast(i64)e->token.pos.column); - def->add("file_offset", cast(i64)e->token.pos.offset); - - switch (e->kind) { - case Entity_Constant: def->add("kind", str_lit("constant")); break; - case Entity_Variable: def->add("kind", str_lit("variable")); break; - case Entity_TypeName: def->add("kind", str_lit("type name")); break; - case Entity_Procedure: def->add("kind", str_lit("procedure")); break; - case Entity_ProcGroup: def->add("kind", str_lit("procedure group")); break; - case Entity_ImportName: def->add("kind", str_lit("import name")); break; - case Entity_LibraryName: def->add("kind", str_lit("library name")); break; - default: GB_PANIC("Invalid entity kind to be added"); - } - - - if (e->type != nullptr && e->type != t_invalid) { - Type *t = e->type; - Type *bt = t; - - switch (e->kind) { - case Entity_TypeName: - if (!e->TypeName.is_type_alias) { - bt = base_type(t); - } - break; - } - - { - gbString str = type_to_string(t); - String type_str = make_string(cast(u8 *)str, gb_string_length(str)); - def->add("type", type_str); - } - if (t != bt) { - gbString str = type_to_string(bt); - String type_str = make_string(cast(u8 *)str, gb_string_length(str)); - def->add("base_type", type_str); - } - { - String type_kind = {}; - Type *bt = base_type(t); - switch (bt->kind) { - case Type_Pointer: type_kind = str_lit("pointer"); break; - case Type_Array: type_kind = str_lit("array"); break; - case Type_Slice: type_kind = str_lit("slice"); break; - case Type_DynamicArray: type_kind = str_lit("dynamic array"); break; - case Type_Map: type_kind = str_lit("map"); break; - case Type_Struct: type_kind = str_lit("struct"); break; - case Type_Union: type_kind = str_lit("union"); break; - case Type_Enum: type_kind = str_lit("enum"); break; - case Type_Proc: type_kind = str_lit("procedure"); break; - case Type_BitSet: type_kind = str_lit("bit set"); break; - case Type_SimdVector: type_kind = str_lit("simd vector"); break; - - case Type_Generic: - case Type_Tuple: - GB_PANIC("Invalid definition type"); - break; - } - if (type_kind.len > 0) { - def->add("type_kind", type_kind); - } - } - } - - if (e->kind == Entity_TypeName) { - def->add("size", type_size_of(e->type)); - def->add("align", type_align_of(e->type)); - - - if (is_type_struct(e->type)) { - auto *data = query_value_map(); - data->reserve(6); - - def->add("data", data); - - Type *t = base_type(e->type); - GB_ASSERT(t->kind == Type_Struct); - - if (t->Struct.is_polymorphic) { - data->add("polymorphic", cast(bool)t->Struct.is_polymorphic); - } - if (t->Struct.is_poly_specialized) { - data->add("polymorphic_specialized", cast(bool)t->Struct.is_poly_specialized); - } - if (t->Struct.is_packed) { - data->add("packed", cast(bool)t->Struct.is_packed); - } - if (t->Struct.is_raw_union) { - data->add("raw_union", cast(bool)t->Struct.is_raw_union); - } - - auto *fields = query_value_array(); - data->add("fields", fields); - fields->reserve(t->Struct.fields.count); - fields->packed = true; - - for_array(j, t->Struct.fields) { - Entity *e = t->Struct.fields[j]; - String name = e->token.string; - if (is_blank_ident(name)) { - continue; - } - - fields->add(name); - } - } else if (is_type_union(e->type)) { - auto *data = query_value_map(); - data->reserve(4); - - def->add("data", data); - Type *t = base_type(e->type); - GB_ASSERT(t->kind == Type_Union); - - if (t->Union.is_polymorphic) { - data->add("polymorphic", cast(bool)t->Union.is_polymorphic); - } - if (t->Union.is_poly_specialized) { - data->add("polymorphic_specialized", cast(bool)t->Union.is_poly_specialized); - } - - auto *variants = query_value_array(); - variants->reserve(t->Union.variants.count); - data->add("variants", variants); - - for_array(j, t->Union.variants) { - Type *vt = t->Union.variants[j]; - - gbString str = type_to_string(vt); - String type_str = make_string(cast(u8 *)str, gb_string_length(str)); - variants->add(type_str); - } - } - } - - if (e->kind == Entity_Procedure) { - Type *t = base_type(e->type); - GB_ASSERT(t->kind == Type_Proc); - - bool is_polymorphic = t->Proc.is_polymorphic; - bool is_poly_specialized = t->Proc.is_poly_specialized; - bool ok = is_polymorphic || is_poly_specialized; - if (ok) { - auto *data = query_value_map(); - data->reserve(4); - - def->add("data", data); - if (is_polymorphic) { - data->add("polymorphic", cast(bool)is_polymorphic); - } - if (is_poly_specialized) { - data->add("polymorphic_specialized", cast(bool)is_poly_specialized); - } - } - } - - if (e->kind == Entity_ProcGroup) { - auto *procedures = query_value_array(); - procedures->reserve(e->ProcGroup.entities.count); - - for_array(j, e->ProcGroup.entities) { - Entity *p = e->ProcGroup.entities[j]; - - auto *procedure = query_value_map(); - procedure->reserve(2); - procedure->packed = true; - - procedures->add(procedure); - - procedure->add("package", p->pkg->name); - procedure->add("name", p->token.string); - } - def->add("procedures", procedures); - } - - DeclInfo *di = e->decl_info; - if (di != nullptr) { - if (di->is_using) { - def->add("using", query_value_boolean(true)); - } - } - } - } - - if (build_context.show_timings) { - Timings *t = timings; - timings__stop_current_section(t); - t->total.finish = time_stamp_time_now(); - isize max_len = gb_min(36, t->total.label.len); - for_array(i, t->sections) { - TimeStamp ts = t->sections[i]; - max_len = gb_max(max_len, ts.label.len); - } - t->total_time_seconds = time_stamp_as_s(t->total, t->freq); - - auto *tims = query_value_map(); - tims->reserve(8); - root->add("timings", tims); - tims->add("time_unit", str_lit("s")); - - tims->add(t->total.label, cast(f64)t->total_time_seconds); - - - Parser *p = c->parser; - if (p != nullptr) { - isize lines = p->total_line_count; - isize tokens = p->total_token_count; - isize files = 0; - isize packages = p->packages.count; - isize total_file_size = 0; - for_array(i, p->packages) { - files += p->packages[i]->files.count; - for_array(j, p->packages[i]->files) { - AstFile *file = p->packages[i]->files[j]; - total_file_size += file->tokenizer.end - file->tokenizer.start; - } - } - - tims->add("total_lines", cast(i64)lines); - tims->add("total_tokens", cast(i64)tokens); - tims->add("total_files", cast(i64)files); - tims->add("total_packages", cast(i64)packages); - tims->add("total_file_size", cast(i64)total_file_size); - - auto *sections = query_value_map(); - sections->reserve(t->sections.count); - tims->add("sections", sections); - for_array(i, t->sections) { - TimeStamp ts = t->sections[i]; - f64 section_time = time_stamp_as_s(ts, t->freq); - - auto *section = query_value_map(); - section->reserve(2); - sections->add(ts.label, section); - section->add("time", cast(f64)section_time); - section->add("total_fraction", cast(f64)(section_time/t->total_time_seconds)); - } - } - } - - - print_query_data_as_json(root, !build_context.query_data_set_settings.compact); - gb_printf("\n"); -} - - - -template -struct BinaryArray { - u32 offset; // Offset in bytes from the top of the file - u32 length; // Number of elements in array of type T -}; - -template -gb_internal Array binary_array_from_data(BinaryArray ba, void *data) { - Array res = {}; - res.data = cast(T *)(cast(u8 *)data + ba.offset); - res.count = ba.length; - res.capacity = ba.length; - return res; -} - -typedef BinaryArray BinaryString; - -struct GoToDefIdent { - u64 use_offset; // offset of identifier use in bytes from the start of the file that contains it - u32 len; // length in bytes of the identifier - u32 def_file_id; - u64 def_offset; // offset of entity definition in bytes from the start of the file that contains it -}; - -struct GoToDefFile { - u32 id; - BinaryString path; - BinaryArray idents; -}; - -struct GoToDefHeader { - u8 magic[4]; // ogtd (odin-go-to-definitions) - u32 version; // 1 - BinaryArray files; -}; - -struct GoToDefFileMap { - AstFile *f; - u32 id; - Array idents; -}; - - -gb_internal int go_to_def_file_map_compare(void const *a, void const *b) { - GoToDefFileMap const *x = cast(GoToDefFileMap const *)a; - GoToDefFileMap const *y = cast(GoToDefFileMap const *)b; - if (x == y) { - return 0; - } else if (x != nullptr && y == nullptr) { - return -1; - } else if (x == nullptr && y != nullptr) { - return +1; - } - if (x->f->id < y->f->id) { - return -1; - } else if (x->f->id > y->f->id) { - return +1; - } - return 0; -} - -gb_internal int quick_ident_compare(void const *a, void const *b) { - Ast *x = *cast(Ast **)a; - Ast *y = *cast(Ast **)b; - - // NOTE(bill): This assumes that the file is same - if (x->Ident.token.pos.offset < y->Ident.token.pos.offset) { - return -1; - } else if (x->Ident.token.pos.offset > y->Ident.token.pos.offset) { - return +1; - } - return 0; -} - - -gb_internal void generate_and_print_query_data_go_to_definitions(Checker *c) { - GB_ASSERT(c->info.allow_identifier_uses); - - gbAllocator a = query_value_allocator; - - isize file_path_memory_needed = 0; - auto files = array_make(a, 0, c->info.files.entries.count); - for (auto const &entry : c->info.files) { - AstFile *f = entry.value; - file_path_memory_needed += f->fullpath.len+1; // add NUL terminator - - - GoToDefFileMap x = {}; - x.f = f; - array_init(&x.idents, a); - array_add(&files, x); - } - gb_sort_array(files.data, files.count, go_to_def_file_map_compare); - - auto file_id_map_to_index = array_make(a, files[files.count-1].f->id + 1); - for_array(i, file_id_map_to_index) { - file_id_map_to_index[i] = -1; - } - for_array(i, files) { - file_id_map_to_index[files[i].f->id] = i; - } - - - - for_array(i, c->info.identifier_uses) { - Ast *ast = c->info.identifier_uses[i]; - GB_ASSERT(ast->kind == Ast_Ident); - TokenPos pos = ast->Ident.token.pos; - Entity *e = ast->Ident.entity; - if (e == nullptr) { - continue; - } - - - AstFile **use_file_found = string_map_get(&c->info.files, get_file_path_string(pos.file_id)); - GB_ASSERT(use_file_found != nullptr); - AstFile *use_file = *use_file_found; - GB_ASSERT(use_file != nullptr); - - if (e->scope == nullptr) { - GB_ASSERT(e->flags & EntityFlag_Field); - continue; - } - if (e->scope->flags & ScopeFlag_Global) { - continue; - } - - isize idx = file_id_map_to_index[use_file->id]; - if (idx >= 0) { - array_add(&files[idx].idents, ast); - } else { - // TODO(bill): Handle invalid map case? - } - } - - for_array(i, files) { - GoToDefFileMap *f = &files[i]; - gb_sort_array(f->idents.data, f->idents.count, quick_ident_compare); - // gb_printf_err("%lld %.*s -> %lld\n", f->f->id, LIT(f->f->fullpath), f->idents.count); - } - - - - isize data_min_size = 0; - - u32 header_offset = cast(u32)data_min_size; gb_unused(header_offset); - data_min_size += gb_size_of(GoToDefHeader); - data_min_size = align_formula_isize(data_min_size, 8); - - u32 file_offset = cast(u32)data_min_size; - data_min_size += gb_size_of(GoToDefFile) * files.count; - data_min_size = align_formula_isize(data_min_size, 8); - - u32 file_path_offset = cast(u32)data_min_size; - data_min_size += file_path_memory_needed; - data_min_size = align_formula_isize(data_min_size, 8); - - u32 idents_offset = cast(u32)data_min_size; - data_min_size += gb_size_of(GoToDefIdent) * c->info.identifier_uses.count; - - - auto data = array_make(a, 0, data_min_size); - defer (array_free(&data)); - - GoToDefHeader header = {}; - gb_memmove(header.magic, "ogtd", 4); - header.version = 1; - header.files.length = cast(u32)files.count; - header.files.offset = file_offset; - - array_add_elems(&data, cast(u8 *)&header, gb_size_of(header)); - - array_resize(&data, data_min_size); - - auto binary_files = binary_array_from_data(header.files, data.data); - - u32 file_path_offset_index = file_path_offset; - u32 idents_offset_index = idents_offset; - for_array(i, files) { - GoToDefFileMap *f_map = &files[i]; - AstFile *f = f_map->f; - binary_files[i].id = cast(u32)f->id; - - binary_files[i].path.offset = file_path_offset_index; - binary_files[i].path.length = cast(u32)f->fullpath.len; - - binary_files[i].idents.offset = idents_offset_index; - binary_files[i].idents.length = cast(u32)f_map->idents.count; - - auto path = binary_array_from_data(binary_files[i].path, data.data); - gb_memmove(path.data, f->fullpath.text, f->fullpath.len); - path.data[f->fullpath.len] = 0; - - - auto idents = binary_array_from_data(binary_files[i].idents, data.data); - for_array(j, f_map->idents) { - Ast *ast = f_map->idents[j]; - GB_ASSERT(ast->kind == Ast_Ident); - - Entity *e = ast->Ident.entity; - TokenPos def = e->token.pos; - AstFile *def_file = e->file; - - if (def_file == nullptr) { - auto *def_file_found = string_map_get(&c->info.files, get_file_path_string(e->token.pos.file_id)); - if (def_file_found == nullptr) { - continue; - } - def_file = *def_file_found; - } - - isize file_index = file_id_map_to_index[def_file->id]; - GB_ASSERT(file_index >= 0); - - idents[j].use_offset = cast(u64)ast->Ident.token.pos.offset; - idents[j].len = cast(u32)ast->Ident.token.string.len; - idents[j].def_file_id = cast(u32)def_file->id; - idents[j].def_offset = cast(u64)e->token.pos.offset; - - // gb_printf_err("%llu %llu %llu %llu\n", idents[j].len, idents[j].use_offset, idents[j].def_file_id, idents[j].def_offset); - } - - file_path_offset_index += cast(u32)(f->fullpath.len + 1); - idents_offset_index += cast(u32)(f_map->idents.count * gb_size_of(GoToDefIdent)); - } - - - gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.data, data.count*gb_size_of(*data.data)); -} - diff --git a/src/range_cache.cpp b/src/range_cache.cpp index 1f98c4b9e..fc85e2a2e 100644 --- a/src/range_cache.cpp +++ b/src/range_cache.cpp @@ -59,12 +59,12 @@ gb_internal bool range_cache_add_range(RangeCache *c, i64 lo, i64 hi) { } -gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) { - for_array(i, c->ranges) { - RangeValue v = c->ranges[i]; - if (v.lo <= index && index <= v.hi) { - return true; - } - } - return false; -} +// gb_internal bool range_cache_index_exists(RangeCache *c, i64 index) { +// for_array(i, c->ranges) { +// RangeValue v = c->ranges[i]; +// if (v.lo <= index && index <= v.hi) { +// return true; +// } +// } +// return false; +// } diff --git a/src/string.cpp b/src/string.cpp index aeb31c7b0..8cce0f1ef 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -89,14 +89,6 @@ gb_internal char *alloc_cstring(gbAllocator a, String s) { return c_str; } -gb_internal char *cstring_duplicate(gbAllocator a, char const *s) { - isize len = gb_strlen(s); - char *c_str = gb_alloc_array(a, char, len+1); - gb_memmove(c_str, s, len); - c_str[len] = '\0'; - return c_str; -} - gb_internal gb_inline bool str_eq_ignore_case(String const &a, String const &b) { @@ -166,12 +158,6 @@ gb_internal isize string_index_byte(String const &s, u8 x) { return -1; } -gb_internal GB_COMPARE_PROC(string_cmp_proc) { - String x = *(String *)a; - String y = *(String *)b; - return string_compare(x, y); -} - gb_internal gb_inline bool str_eq(String const &a, String const &b) { if (a.len != b.len) return false; return memcmp(a.text, b.text, a.len) == 0; diff --git a/src/string_map.cpp b/src/string_map.cpp index e289d4c9b..9f9374ece 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -18,8 +18,6 @@ gb_internal gb_inline bool string_hash_key_equal(StringHashKey const &a, StringH } return false; } -gb_internal bool operator==(StringHashKey const &a, StringHashKey const &b) { return string_hash_key_equal(a, b); } -gb_internal bool operator!=(StringHashKey const &a, StringHashKey const &b) { return !string_hash_key_equal(a, b); } template struct StringMapEntry { diff --git a/src/threading.cpp b/src/threading.cpp index 511d1b477..b74d087b4 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -1,6 +1,10 @@ #if defined(GB_SYSTEM_LINUX) #include #endif +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(push) + #pragma warning(disable: 4505) +#endif struct BlockingMutex; struct RecursiveMutex; @@ -269,48 +273,6 @@ struct MutexGuard { } #endif - - -struct Barrier { - BlockingMutex mutex; - Condition cond; - isize index; - isize generation_id; - isize thread_count; -}; - -gb_internal void barrier_init(Barrier *b, isize thread_count) { - mutex_init(&b->mutex); - condition_init(&b->cond); - b->index = 0; - b->generation_id = 0; - b->thread_count = 0; -} - -gb_internal void barrier_destroy(Barrier *b) { - condition_destroy(&b->cond); - mutex_destroy(&b->mutex); -} - -// Returns true if it is the leader -gb_internal bool barrier_wait(Barrier *b) { - mutex_lock(&b->mutex); - defer (mutex_unlock(&b->mutex)); - isize local_gen = b->generation_id; - b->index += 1; - if (b->index < b->thread_count) { - while (local_gen == b->generation_id && b->index < b->thread_count) { - condition_wait(&b->cond, &b->mutex); - } - return false; - } - b->index = 0; - b->generation_id += 1; - condition_broadcast(&b->cond); - return true; -} - - gb_internal u32 thread_current_id(void) { @@ -494,3 +456,7 @@ gb_internal void thread_set_name(Thread *t, char const *name) { #endif } + +#if defined(GB_SYSTEM_WINDOWS) + #pragma warning(pop) +#endif \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index c8e24f01d..b1d3883c6 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -430,15 +430,6 @@ gb_internal Selection sub_selection(Selection const &sel, isize offset) { return res; } -gb_internal Selection sub_selection_with_length(Selection const &sel, isize offset, isize len) { - Selection res = {}; - res.index.data = sel.index.data + offset; - res.index.count = gb_max(len, gb_max(sel.index.count - offset, 0)); - res.index.capacity = res.index.count; - return res; -} - - gb_global Type basic_types[] = { {Type_Basic, {Basic_Invalid, 0, 0, STR_LIT("invalid type")}}, @@ -1089,15 +1080,6 @@ gb_internal Type *alloc_type_proc(Scope *scope, Type *params, isize param_count, gb_internal bool is_type_valid_for_keys(Type *t); -gb_internal Type *alloc_type_map(i64 count, Type *key, Type *value) { - if (key != nullptr) { - GB_ASSERT(value != nullptr); - } - Type *t = alloc_type(Type_Map); - t->Map.key = key; - t->Map.value = value; - return t; -} gb_internal Type *alloc_type_bit_set() { Type *t = alloc_type(Type_BitSet); @@ -1152,19 +1134,6 @@ gb_internal bool is_type_named(Type *t) { } return t->kind == Type_Named; } -gb_internal bool is_type_named_alias(Type *t) { - if (!is_type_named(t)) { - return false; - } - Entity *e = t->Named.type_name; - if (e == nullptr) { - return false; - } - if (e->kind != Entity_TypeName) { - return false; - } - return e->TypeName.is_type_alias; -} gb_internal bool is_type_boolean(Type *t) { // t = core_type(t); @@ -1329,27 +1298,6 @@ gb_internal bool is_type_complex_or_quaternion(Type *t) { } return false; } -gb_internal bool is_type_f16(Type *t) { - t = core_type(t); - if (t->kind == Type_Basic) { - return t->Basic.kind == Basic_f16; - } - return false; -} -gb_internal bool is_type_f32(Type *t) { - t = core_type(t); - if (t->kind == Type_Basic) { - return t->Basic.kind == Basic_f32; - } - return false; -} -gb_internal bool is_type_f64(Type *t) { - t = core_type(t); - if (t->kind == Type_Basic) { - return t->Basic.kind == Basic_f64; - } - return false; -} gb_internal bool is_type_pointer(Type *t) { t = base_type(t); if (t->kind == Type_Basic) { @@ -1550,10 +1498,6 @@ gb_internal bool is_type_asm_proc(Type *t) { t = base_type(t); return t->kind == Type_Proc && t->Proc.calling_convention == ProcCC_InlineAsm; } -gb_internal bool is_type_poly_proc(Type *t) { - t = base_type(t); - return t->kind == Type_Proc && t->Proc.is_polymorphic; -} gb_internal bool is_type_simd_vector(Type *t) { t = base_type(t); return t->kind == Type_SimdVector; @@ -1915,11 +1859,6 @@ gb_internal bool is_type_empty_union(Type *t) { t = base_type(t); return t->kind == Type_Union && t->Union.variants.count == 0; } -gb_internal bool is_type_empty_struct(Type *t) { - t = base_type(t); - return t->kind == Type_Struct && !t->Struct.is_raw_union && t->Struct.fields.count == 0; -} - gb_internal bool is_type_valid_for_keys(Type *t) { t = core_type(t); @@ -4051,20 +3990,6 @@ gb_internal Type *reduce_tuple_to_single_type(Type *original_type) { return original_type; } - -gb_internal Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, bool is_packed) { - Type *t = alloc_type_struct(); - t->Struct.fields = slice_make(heap_allocator(), field_count); - - Scope *scope = nullptr; - for_array(i, t->Struct.fields) { - t->Struct.fields[i] = alloc_entity_field(scope, blank_token, field_types[i], false, cast(i32)i, EntityState_Resolved); - } - t->Struct.is_packed = is_packed; - - return t; -} - gb_internal Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, bool is_packed, bool must_be_tuple) { if (field_count == 0) { return nullptr; -- cgit v1.2.3 From 00823ca88c870d49186dbcaa21c54384c0b9364f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Dec 2022 13:03:34 +0000 Subject: Remove a few `TODO`s --- src/build_settings.cpp | 3 +-- src/check_builtin.cpp | 7 ++----- src/check_decl.cpp | 8 -------- src/checker.cpp | 9 ++------- src/checker.hpp | 4 ++-- 5 files changed, 7 insertions(+), 24 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 630cec601..080e9dddc 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -394,7 +394,7 @@ gb_global TargetMetrics target_darwin_arm64 = { TargetArch_arm64, 8, 8, 16, str_lit("arm64-apple-macosx11.0.0"), - str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct? + str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), }; gb_global TargetMetrics target_freebsd_i386 = { @@ -585,7 +585,6 @@ struct LibraryCollections { gb_global Array library_collections = {0}; gb_internal void add_library_collection(String name, String path) { - // TODO(bill): Check the path is valid and a directory LibraryCollections lc = {name, string_trim_whitespace(path)}; array_add(&library_collections, lc); } diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 1c13b6b5e..99d956f5e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -89,7 +89,6 @@ gb_internal void check_or_else_split_types(CheckerContext *c, Operand *x, String gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint) { - // TODO(bill): better error message gbString t = type_to_string(x.type); error(x.expr, "'%.*s' does not return a value, value is of type %s", LIT(name), t); if (is_type_union(type_deref(x.type))) { @@ -2559,7 +2558,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As if (is_type_struct(type)) { isize variable_count = type->Struct.fields.count; slice_init(&tuple->Tuple.variables, a, variable_count); - // TODO(bill): Should I copy each of the entities or is this good enough? + // NOTE(bill): don't copy the entities, this should be good enough gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count); } else if (is_type_array(type)) { isize variable_count = cast(isize)type->Array.count; @@ -3766,9 +3765,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As mp_err err = mp_pack(rop, max_count, &written, MP_LSB_FIRST, size, endian, nails, &x.value.value_integer); GB_ASSERT(err == MP_OKAY); - if (id == BuiltinProc_reverse_bits) { - // TODO(bill): Should this even be allowed at compile time? - } else { + if (id != BuiltinProc_reverse_bits) { u64 v = 0; switch (id) { case BuiltinProc_count_ones: diff --git a/src/check_decl.cpp b/src/check_decl.cpp index d982a69fc..59beae56d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -10,7 +10,6 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o gbString expr_str = expr_to_string(operand->expr); // TODO(bill): is this a good enough error message? - // TODO(bill): Actually allow built in procedures to be passed around and thus be created on use error(operand->expr, "Cannot assign built-in procedure '%s' in %.*s", expr_str, @@ -122,13 +121,6 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false); isize rhs_count = operands.count; - for_array(i, operands) { - if (operands[i].mode == Addressing_Invalid) { - // TODO(bill): Should I ignore invalid parameters? - // rhs_count--; - } - } - isize max = gb_min(lhs_count, rhs_count); for (isize i = 0; i < max; i++) { Entity *e = lhs[i]; diff --git a/src/checker.cpp b/src/checker.cpp index 29e4b6667..b78da2827 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -404,7 +404,6 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s if (found) { Entity *e = *found; if (gone_thru_proc) { - // IMPORTANT TODO(bill): Is this correct?! if (e->kind == Entity_Label) { continue; } @@ -1409,8 +1408,7 @@ gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_f entry_index = *found_entry_index; } if (entry_index < 0) { - // NOTE(bill): Do manual search - // TODO(bill): This is O(n) and can be very slow + // NOTE(bill): Do manual linear search for (auto const &e : info->type_info_map) { if (are_types_identical_unique_tuples(e.key, type)) { entry_index = e.value; @@ -2350,7 +2348,7 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; - if (e->scope == builtin_pkg->scope) { // TODO(bill): is the check enough? + if (e->scope == builtin_pkg->scope) { if (e->type == nullptr) { add_dependency_to_set(c, e); } @@ -3965,7 +3963,6 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n if (curr_file == nullptr) { error(decl, "import declarations are only allowed in the file scope"); // NOTE(bill): _Should_ be caught by the parser - // TODO(bill): Better error handling if it isn't continue; } // Will be handled later @@ -3976,7 +3973,6 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice const &n if ((c->scope->flags&ScopeFlag_File) == 0) { error(decl, "%.*s declarations are only allowed in the file scope", LIT(fl->token.string)); // NOTE(bill): _Should_ be caught by the parser - // TODO(bill): Better error handling if it isn't continue; } check_add_foreign_import_decl(c, decl); @@ -4167,7 +4163,6 @@ gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMapsucc, m); import_graph_node_set_add(&m->pred, n); ptr_set_add(&m->scope->imported, n->scope); diff --git a/src/checker.hpp b/src/checker.hpp index 6799503cd..1d6019b79 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -390,7 +390,7 @@ struct CheckerContext { // Order doesn't matter after this u32 state_flags; - bool in_defer; // TODO(bill): Actually handle correctly + bool in_defer; Type * type_hint; String proc_name; @@ -401,7 +401,7 @@ struct CheckerContext { ForeignContext foreign_context; CheckerTypePath *type_path; - isize type_level; // TODO(bill): Actually handle correctly + isize type_level; UntypedExprInfoMap *untyped; -- cgit v1.2.3 From 015fe924b8f9a1d8cb78d307a4f8ef6791402bea Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 12:28:38 +0000 Subject: Remove use of queues for procedure checking. --- src/check_decl.cpp | 2 +- src/check_expr.cpp | 10 ++--- src/checker.cpp | 108 ++++++++++++++++++++-------------------------------- src/checker.hpp | 6 +-- src/thread_pool.cpp | 4 ++ 5 files changed, 52 insertions(+), 78 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 59beae56d..4e3c1b405 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -986,7 +986,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { GB_ASSERT(pl->body->kind == Ast_BlockStmt); if (!pt->is_polymorphic) { - check_procedure_later(ctx, ctx->file, e->token, d, proc_type, pl->body, pl->tags); + check_procedure_later(ctx->checker, ctx->file, e->token, d, proc_type, pl->body, pl->tags); } } else if (!is_foreign) { if (e->Procedure.is_export) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index ed1ddd1f1..eb9f76547 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -417,8 +417,6 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E CheckerContext nctx = *old_c; - nctx.procs_to_check_queue = old_c->procs_to_check_queue; - Scope *scope = create_scope(info, base_entity->scope); scope->flags |= ScopeFlag_Proc; nctx.scope = scope; @@ -566,7 +564,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } // NOTE(bill): Check the newly generated procedure body - check_procedure_later(&nctx, proc_info); + check_procedure_later(nctx.checker, proc_info); return true; } @@ -6187,7 +6185,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op decl->where_clauses_evaluated = true; if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) { - check_procedure_later(c, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); + check_procedure_later(c->checker, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); } } return data; @@ -6225,7 +6223,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op decl->where_clauses_evaluated = true; if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) { - check_procedure_later(c, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); + check_procedure_later(c->checker, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); } } return data; @@ -9447,7 +9445,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast } pl->decl = decl; - check_procedure_later(&ctx, ctx.file, empty_token, decl, type, pl->body, pl->tags); + check_procedure_later(ctx.checker, ctx.file, empty_token, decl, type, pl->body, pl->tags); } check_close_scope(&ctx); diff --git a/src/checker.cpp b/src/checker.cpp index 1e40f04a6..30e7409f9 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1195,7 +1195,6 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp GB_ASSERT(ctx->checker != nullptr); mutex_lock(&ctx->mutex); - auto *queue = ctx->procs_to_check_queue; auto type_path = ctx->type_path; array_clear(type_path); @@ -1211,7 +1210,6 @@ gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, Untyp add_curr_ast_file(ctx, file); - ctx->procs_to_check_queue = queue; ctx->untyped = untyped; mutex_unlock(&ctx->mutex); @@ -1232,7 +1230,7 @@ gb_internal void init_checker(Checker *c) { mpmc_init(&c->procs_with_deferred_to_check, a, 1<<10); // NOTE(bill): 1 Mi elements should be enough on average - mpmc_init(&c->procs_to_check_queue, heap_allocator(), 1<<20); + array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20); mpmc_init(&c->global_untyped_queue, a, 1<<20); @@ -1244,7 +1242,7 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); - mpmc_destroy(&c->procs_to_check_queue); + array_free(&c->procs_to_check); mpmc_destroy(&c->global_untyped_queue); } @@ -1941,23 +1939,19 @@ gb_global std::atomic global_procedure_body_in_worker_queue = false; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc); -gb_internal void check_procedure_later(CheckerContext *c, ProcInfo *info) { +gb_internal void check_procedure_later(Checker *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); if (MULTITHREAD_CHECKER && global_procedure_body_in_worker_queue) { thread_pool_add_task(check_proc_info_worker_proc, info); } else { - if (build_context.threaded_checker && global_procedure_body_in_worker_queue) { - GB_ASSERT(c->procs_to_check_queue != nullptr); - } - - auto *queue = c->procs_to_check_queue ? c->procs_to_check_queue : &c->checker->procs_to_check_queue; - mpmc_enqueue(queue, info); + GB_ASSERT(global_procedure_body_in_worker_queue == false); + array_add(&c->procs_to_check, info); } } -gb_internal void check_procedure_later(CheckerContext *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { +gb_internal void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { ProcInfo *info = gb_alloc_item(permanent_allocator(), ProcInfo); info->file = file; info->token = token; @@ -4677,11 +4671,7 @@ struct CollectEntityWorkerData { gb_global CollectEntityWorkerData *collect_entity_worker_data; gb_internal WORKER_TASK_PROC(check_collect_entities_all_worker_proc) { - isize thread_idx = 0; - if (current_thread) { - thread_idx = current_thread->idx; - } - CollectEntityWorkerData *wd = &collect_entity_worker_data[thread_idx]; + CollectEntityWorkerData *wd = &collect_entity_worker_data[current_thread_index()]; Checker *c = wd->c; CheckerContext *ctx = &wd->ctx; @@ -4738,10 +4728,8 @@ gb_internal void check_export_entities_in_pkg(CheckerContext *ctx, AstPackage *p } gb_internal WORKER_TASK_PROC(check_export_entities_worker_proc) { - isize thread_idx = current_thread ? current_thread->idx : 0; - AstPackage *pkg = (AstPackage *)data; - auto *wd = &collect_entity_worker_data[thread_idx]; + auto *wd = &collect_entity_worker_data[current_thread_index()]; check_export_entities_in_pkg(&wd->ctx, pkg, &wd->untyped); return 0; } @@ -5069,7 +5057,7 @@ gb_internal void calculate_global_init_order(Checker *c) { } -gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, ProcBodyQueue *procs_to_check_queue) { +gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { if (pi == nullptr) { return false; } @@ -5085,17 +5073,16 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u } return true; } + if (e != nullptr && (e->flags & EntityFlag_ProcBodyChecked) != 0) { + GB_ASSERT(pi->decl->proc_checked); + return true; + } + pi->decl->proc_checked = true; + if (e != nullptr) { + e->flags |= EntityFlag_ProcBodyChecked; + } } - CheckerContext ctx = make_checker_context(c); - defer (destroy_checker_context(&ctx)); - reset_checker_context(&ctx, pi->file, untyped); - ctx.decl = pi->decl; - - GB_ASSERT(procs_to_check_queue != nullptr || MULTITHREAD_CHECKER); - - ctx.procs_to_check_queue = procs_to_check_queue; - GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; String name = pi->token.string; @@ -5116,6 +5103,12 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u } } + + CheckerContext ctx = make_checker_context(c); + defer (destroy_checker_context(&ctx)); + reset_checker_context(&ctx, pi->file, untyped); + ctx.decl = pi->decl; + bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0; bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0; @@ -5138,24 +5131,14 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u ctx.state_flags &= ~StateFlag_type_assert; } - if (pi->body != nullptr && e != nullptr) { - GB_ASSERT((e->flags & EntityFlag_ProcBodyChecked) == 0); - } - check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); - MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) { - if (e != nullptr) { - e->flags |= EntityFlag_ProcBodyChecked; - } - pi->decl->proc_checked = true; - } add_untyped_expressions(&c->info, ctx.untyped); return true; } GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *)); -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped); +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped); gb_internal void check_unchecked_bodies(Checker *c) { // NOTE(2021-02-26, bill): Sanity checker @@ -5193,15 +5176,13 @@ gb_internal void check_unchecked_bodies(Checker *c) { } debugf("unchecked: %.*s\n", LIT(e->token.string)); - mpmc_enqueue(&c->procs_to_check_queue, pi); + array_add(&c->procs_to_check, pi); } } - auto *q = &c->procs_to_check_queue; - ProcInfo *pi = nullptr; - while (mpmc_dequeue(q, &pi)) { + for (ProcInfo *pi : c->procs_to_check) { Entity *e = pi->decl->entity; - if (consume_proc_info_queue(c, pi, q, &untyped)) { + if (consume_proc_info_queue(c, pi, &untyped)) { add_dependency_to_set(c, e); GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); } @@ -5245,7 +5226,7 @@ gb_internal void check_test_procedures(Checker *c) { gb_global std::atomic total_bodies_checked; -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue *q, UntypedExprInfoMap *untyped) { +gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { GB_ASSERT(pi->decl != nullptr); if (pi->decl->parent && pi->decl->parent->entity) { Entity *parent = pi->decl->parent->entity; @@ -5253,14 +5234,14 @@ gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, ProcBodyQueue // This is prevent any possible race conditions in evaluation when multithreaded // NOTE(bill): In single threaded mode, this should never happen if (parent->kind == Entity_Procedure && (parent->flags & EntityFlag_ProcBodyChecked) == 0) { - mpmc_enqueue(q, pi); + check_procedure_later(c, pi); return false; } } if (untyped) { map_clear(untyped); } - bool ok = check_proc_info(c, pi, untyped, q); + bool ok = check_proc_info(c, pi, untyped); total_bodies_checked.fetch_add(1, std::memory_order_relaxed); return ok; } @@ -5273,12 +5254,9 @@ struct CheckProcedureBodyWorkerData { gb_global CheckProcedureBodyWorkerData *check_procedure_bodies_worker_data; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { - isize thread_idx = 0; - if (current_thread) { - thread_idx = current_thread->idx; - } - UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[thread_idx].untyped; - Checker *c = check_procedure_bodies_worker_data[thread_idx].c; + auto *wd = &check_procedure_bodies_worker_data[current_thread_index()]; + UntypedExprInfoMap *untyped = &wd->untyped; + Checker *c = wd->c; ProcInfo *pi = cast(ProcInfo *)data; @@ -5294,7 +5272,7 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { } } map_clear(untyped); - bool ok = check_proc_info(c, pi, untyped, nullptr); + bool ok = check_proc_info(c, pi, untyped); total_bodies_checked.fetch_add(1, std::memory_order_relaxed); return !ok; } @@ -5321,13 +5299,11 @@ gb_internal void check_procedure_bodies(Checker *c) { }); if (thread_count == 1) { - auto *this_queue = &c->procs_to_check_queue; - UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; - - for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) { - consume_proc_info_queue(c, pi, this_queue, untyped); + for_array(i, c->procs_to_check) { + consume_proc_info_queue(c, c->procs_to_check[i], untyped); } + array_clear(&c->procs_to_check); debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); return; @@ -5335,12 +5311,12 @@ gb_internal void check_procedure_bodies(Checker *c) { global_procedure_body_in_worker_queue = true; - for (ProcInfo *pi = nullptr; mpmc_dequeue(&c->procs_to_check_queue, &pi); /**/) { - thread_pool_add_task(check_proc_info_worker_proc, pi); + isize prev_procs_to_check_count = c->procs_to_check.count; + for_array(i, c->procs_to_check) { + thread_pool_add_task(check_proc_info_worker_proc, c->procs_to_check[i]); } - - isize global_remaining = c->procs_to_check_queue.count.load(std::memory_order_relaxed); - GB_ASSERT(global_remaining == 0); + GB_ASSERT(prev_procs_to_check_count == c->procs_to_check.count); + array_clear(&c->procs_to_check); thread_pool_wait(); diff --git a/src/checker.hpp b/src/checker.hpp index 1d6019b79..eaad1fa63 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -418,8 +418,6 @@ struct CheckerContext { Scope * polymorphic_scope; Ast *assignment_lhs_hint; - - ProcBodyQueue *procs_to_check_queue; }; @@ -430,9 +428,7 @@ struct Checker { CheckerContext builtin_ctx; MPMCQueue procs_with_deferred_to_check; - - ProcBodyQueue procs_to_check_queue; - Semaphore procs_to_check_semaphore; + Array procs_to_check; // TODO(bill): Technically MPSC queue MPMCQueue global_untyped_queue; diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 9ac1af039..939d3c533 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -21,6 +21,10 @@ struct ThreadPool { Futex tasks_left; }; +gb_internal isize current_thread_index(void) { + return current_thread ? current_thread->idx : 0; +} + gb_internal void thread_pool_init(ThreadPool *pool, gbAllocator const &a, isize thread_count, char const *worker_name) { pool->allocator = a; slice_init(&pool->threads, a, thread_count + 1); -- cgit v1.2.3 From 529383f5b17d74f66bebb8679820a69476635b6a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 15:30:04 +0000 Subject: Correct a race condition when checking the procedure body --- src/build_settings.cpp | 1 + src/check_decl.cpp | 25 ++--- src/check_expr.cpp | 23 ++++- src/checker.cpp | 224 ++++++++++++++++++++++++++++++++++--------- src/checker.hpp | 21 +++- src/llvm_backend.cpp | 6 ++ src/llvm_backend.hpp | 1 + src/llvm_backend_expr.cpp | 6 +- src/llvm_backend_general.cpp | 5 +- src/llvm_backend_proc.cpp | 3 +- src/llvm_backend_stmt.cpp | 6 +- src/main.cpp | 5 + 12 files changed, 260 insertions(+), 66 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 97b512b81..f59b5c0f7 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -291,6 +291,7 @@ struct BuildContext { bool show_error_line; bool ignore_lazy; + bool ignore_llvm_build; bool use_subsystem_windows; bool ignore_microsoft_magic; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4e3c1b405..8f95c1a49 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1419,9 +1419,9 @@ struct ProcUsingVar { }; -gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { +gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) { if (body == nullptr) { - return; + return false; } GB_ASSERT(body->kind == Ast_BlockStmt); @@ -1502,7 +1502,7 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) { Entity *e = using_entities[i].e; Entity *uvar = using_entities[i].uvar; - Entity *prev = scope_insert(ctx->scope, uvar, false); + Entity *prev = scope_insert_no_mutex(ctx->scope, uvar); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string)); error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string)); @@ -1514,7 +1514,7 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated); if (!where_clause_ok) { // NOTE(bill, 2019-08-31): Don't check the body as the where clauses failed - return; + return false; } check_open_scope(ctx, body); @@ -1526,7 +1526,12 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de // NOTE(bill): Don't err here } - GB_ASSERT(decl->defer_use_checked == false); + GB_ASSERT(decl->proc_checked_state != ProcCheckedState_Checked); + if (decl->defer_use_checked) { + GB_ASSERT(is_type_polymorphic(type, true)); + error(token, "Defer Use Checked: %.*s", LIT(decl->entity->token.string)); + GB_ASSERT(decl->defer_use_checked == false); + } check_stmt_list(ctx, bs->stmts, Stmt_CheckScopeDecls); @@ -1575,10 +1580,8 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de if (decl->parent != nullptr) { Scope *ps = decl->parent->scope; if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - return; - } else { - mutex_lock(&ctx->info->deps_mutex); - + return true; + } else MUTEX_GUARD_BLOCK(&ctx->info->deps_mutex) { // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level for (auto const &entry : decl->deps) { @@ -1589,8 +1592,8 @@ gb_internal void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de Type *t = entry.ptr; ptr_set_add(&decl->parent->type_info_deps, t); } - - mutex_unlock(&ctx->info->deps_mutex); } } + + return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index eb9f76547..5445e73c7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -86,7 +86,6 @@ gb_internal Entity * find_polymorphic_record_entity (CheckerContext *c, Type *or gb_internal void check_not_tuple (CheckerContext *c, Operand *operand); gb_internal void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); gb_internal gbString expr_to_string (Ast *expression); -gb_internal void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body); gb_internal void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); gb_internal bool check_is_terminating (Ast *node, String const &label); gb_internal bool check_has_break (Ast *stmt, String const &label, bool implicit); @@ -478,6 +477,22 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E if (poly_proc_data) { poly_proc_data->gen_entity = other; } + + DeclInfo *decl = other->decl_info; + if (decl->proc_checked_state != ProcCheckedState_Checked) { + ProcInfo *proc_info = gb_alloc_item(permanent_allocator(), ProcInfo); + proc_info->file = other->file; + proc_info->token = other->token; + proc_info->decl = decl; + proc_info->type = other->type; + proc_info->body = decl->proc_lit->ProcLit.body; + proc_info->tags = other->Procedure.tags;; + proc_info->generated_from_polymorphic = true; + proc_info->poly_def_node = poly_def_node; + + check_procedure_later(nctx.checker, proc_info); + } + return true; } } @@ -518,7 +533,8 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E d->gen_proc_type = final_proc_type; d->type_expr = pl->type; d->proc_lit = proc_lit; - d->proc_checked = false; + d->proc_checked_state = ProcCheckedState_Unchecked; + d->defer_use_checked = false; Entity *entity = alloc_entity_procedure(nullptr, token, final_proc_type, tags); entity->identifier = ident; @@ -528,7 +544,8 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E entity->scope = scope->parent; entity->file = base_entity->file; entity->pkg = base_entity->pkg; - entity->flags &= ~EntityFlag_ProcBodyChecked; + entity->flags = 0; + d->entity = entity; AstFile *file = nullptr; { diff --git a/src/checker.cpp b/src/checker.cpp index d3a9c3d2c..f4c9b6822 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,3 +1,5 @@ +#define DEBUG_CHECK_ALL_PROCEDURES 1 + #include "entity.cpp" #include "types.cpp" @@ -179,6 +181,7 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { + gb_zero_item(d); d->parent = parent; d->scope = scope; ptr_set_init(&d->deps, heap_allocator()); @@ -438,9 +441,44 @@ gb_internal Entity *scope_lookup(Scope *s, String const &name) { return entity; } +gb_internal Entity *scope_insert_with_name_no_mutex(Scope *s, String const &name, Entity *entity) { + if (name == "") { + return nullptr; + } + StringHashKey key = string_hash_string(name); + Entity **found = nullptr; + Entity *result = nullptr; + + found = string_map_get(&s->elements, key); + + if (found) { + if (entity != *found) { + result = *found; + } + goto end; + } + if (s->parent != nullptr && (s->parent->flags & ScopeFlag_Proc) != 0) { + found = string_map_get(&s->parent->elements, key); + if (found) { + if ((*found)->flags & EntityFlag_Result) { + if (entity != *found) { + result = *found; + } + goto end; + } + } + } + + string_map_set(&s->elements, key, entity); + if (entity->scope == nullptr) { + entity->scope = s; + } +end:; + return result; +} -gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { +gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { if (name == "") { return nullptr; } @@ -448,9 +486,8 @@ gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity Entity **found = nullptr; Entity *result = nullptr; - if (use_mutex) mutex_lock(&s->mutex); - defer (if (use_mutex) mutex_unlock(&s->mutex)); - + MUTEX_GUARD(&s->mutex); + found = string_map_get(&s->elements, key); if (found) { @@ -479,9 +516,14 @@ end:; return result; } -gb_internal Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { +gb_internal Entity *scope_insert(Scope *s, Entity *entity) { String name = entity->token.string; - return scope_insert_with_name(s, name, entity, use_mutex); + return scope_insert_with_name(s, name, entity); +} + +gb_internal Entity *scope_insert_no_mutex(Scope *s, Entity *entity) { + String name = entity->token.string; + return scope_insert_with_name_no_mutex(s, name, entity); } @@ -1135,6 +1177,9 @@ gb_internal void init_checker_info(CheckerInfo *i) { map_init(&i->objc_msgSend_types, a); string_map_init(&i->load_file_cache, a); + + array_init(&i->all_procedures, heap_allocator()); + } gb_internal void destroy_checker_info(CheckerInfo *i) { @@ -1934,6 +1979,7 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { gb_global std::atomic global_procedure_body_in_worker_queue = false; +gb_global std::atomic global_after_checking_procedure_bodies = false; gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc); @@ -1941,12 +1987,24 @@ gb_internal void check_procedure_later(Checker *c, ProcInfo *info) { GB_ASSERT(info != nullptr); GB_ASSERT(info->decl != nullptr); - if (global_procedure_body_in_worker_queue) { + if (global_after_checking_procedure_bodies) { + Entity *e = info->decl->entity; + debugf("CHECK PROCEDURE LATER! %.*s :: %s {...}\n", LIT(e->token.string), type_to_string(e->type)); + } + + if (global_procedure_body_in_worker_queue.load()) { thread_pool_add_task(check_proc_info_worker_proc, info); } else { - GB_ASSERT(global_procedure_body_in_worker_queue == false); array_add(&c->procs_to_check, info); } + + if (DEBUG_CHECK_ALL_PROCEDURES) { + MUTEX_GUARD_BLOCK(&c->info.all_procedures_mutex) { + GB_ASSERT(info != nullptr); + GB_ASSERT(info->decl != nullptr); + array_add(&c->info.all_procedures, info); + } + } } gb_internal void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, Ast *body, u64 tags) { @@ -5010,24 +5068,26 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u if (pi->type == nullptr) { return false; } - Entity *e = pi->decl->entity; - MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) { - if (pi->decl->proc_checked) { - if (e != nullptr) { - GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); - } - return true; - } - if (e != nullptr && (e->flags & EntityFlag_ProcBodyChecked) != 0) { - GB_ASSERT(pi->decl->proc_checked); - return true; + MUTEX_GUARD(&pi->decl->proc_checked_mutex); + + Entity *e = pi->decl->entity; + switch (pi->decl->proc_checked_state.load()) { + case ProcCheckedState_InProgress: + if (e) { + GB_ASSERT(global_procedure_body_in_worker_queue.load()); } - pi->decl->proc_checked = true; + return false; + case ProcCheckedState_Checked: if (e != nullptr) { - e->flags |= EntityFlag_ProcBodyChecked; + GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); } + return true; + case ProcCheckedState_Unchecked: + // okay + break; } + pi->decl->proc_checked_state.store(ProcCheckedState_InProgress); GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; @@ -5039,17 +5099,21 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u token = ast_token(pi->poly_def_node); } error(token, "Unspecialized polymorphic procedure '%.*s'", LIT(name)); + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); return false; } if (pt->is_polymorphic && pt->is_poly_specialized) { + Entity *e = pi->decl->entity; + GB_ASSERT(e != nullptr); if ((e->flags & EntityFlag_Used) == 0) { // NOTE(bill, 2019-08-31): It was never used, don't check + // NOTE(bill, 2023-01-02): This may need to be checked again if it is used elsewhere? + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); return false; } } - CheckerContext ctx = make_checker_context(c); defer (destroy_checker_context(&ctx)); reset_checker_context(&ctx, pi->file, untyped); @@ -5077,14 +5141,34 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u ctx.state_flags &= ~StateFlag_type_assert; } - check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); + bool body_was_checked = check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body); + + if (body_was_checked) { + pi->decl->proc_checked_state.store(ProcCheckedState_Checked); + if (pi->body) { + Entity *e = pi->decl->entity; + if (e != nullptr) { + e->flags |= EntityFlag_ProcBodyChecked; + } + } + } else { + pi->decl->proc_checked_state.store(ProcCheckedState_Unchecked); + if (pi->body) { + Entity *e = pi->decl->entity; + if (e != nullptr) { + e->flags &= ~EntityFlag_ProcBodyChecked; + } + } + } + add_untyped_expressions(&c->info, ctx.untyped); + return true; } GB_STATIC_ASSERT(sizeof(isize) == sizeof(void *)); -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped); +gb_internal bool consume_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped); gb_internal void check_unchecked_bodies(Checker *c) { // NOTE(2021-02-26, bill): Sanity checker @@ -5092,10 +5176,15 @@ gb_internal void check_unchecked_bodies(Checker *c) { // even ones which should not exist, due to the multithreaded nature of the parser // HACK TODO(2021-02-26, bill): Actually fix this race condition + GB_ASSERT(c->procs_to_check.count == 0); + UntypedExprInfoMap untyped = {}; map_init(&untyped, heap_allocator()); defer (map_destroy(&untyped)); + // use the `procs_to_check` array + global_procedure_body_in_worker_queue = false; + for (auto const &entry : c->info.minimum_dependency_set) { Entity *e = entry.ptr; if (e == nullptr || e->kind != Entity_Procedure) { @@ -5122,19 +5211,22 @@ gb_internal void check_unchecked_bodies(Checker *c) { } debugf("unchecked: %.*s\n", LIT(e->token.string)); - array_add(&c->procs_to_check, pi); + check_procedure_later(c, pi); } } - for (ProcInfo *pi : c->procs_to_check) { - Entity *e = pi->decl->entity; - if (consume_proc_info_queue(c, pi, &untyped)) { - add_dependency_to_set(c, e); - GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked); + if (!global_procedure_body_in_worker_queue) { + for_array(i, c->procs_to_check) { + ProcInfo *pi = c->procs_to_check[i]; + consume_proc_info(c, pi, &untyped); } + array_clear(&c->procs_to_check); + } else { + thread_pool_wait(); } - thread_pool_wait(); + global_procedure_body_in_worker_queue = false; + global_after_checking_procedure_bodies = true; } gb_internal void check_test_procedures(Checker *c) { @@ -5172,8 +5264,15 @@ gb_internal void check_test_procedures(Checker *c) { gb_global std::atomic total_bodies_checked; -gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { +gb_internal bool consume_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped) { GB_ASSERT(pi->decl != nullptr); + switch (pi->decl->proc_checked_state.load()) { + case ProcCheckedState_InProgress: + return false; + case ProcCheckedState_Checked: + return true; + } + if (pi->decl->parent && pi->decl->parent->entity) { Entity *parent = pi->decl->parent->entity; // NOTE(bill): Only check a nested procedure if its parent's body has been checked first @@ -5187,9 +5286,11 @@ gb_internal bool consume_proc_info_queue(Checker *c, ProcInfo *pi, UntypedExprIn if (untyped) { map_clear(untyped); } - bool ok = check_proc_info(c, pi, untyped); - total_bodies_checked.fetch_add(1, std::memory_order_relaxed); - return ok; + if (check_proc_info(c, pi, untyped)) { + total_bodies_checked.fetch_add(1, std::memory_order_relaxed); + return true; + } + return false; } struct CheckProcedureBodyWorkerData { @@ -5218,9 +5319,11 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { } } map_clear(untyped); - bool ok = check_proc_info(c, pi, untyped); - total_bodies_checked.fetch_add(1, std::memory_order_relaxed); - return !ok; + if (check_proc_info(c, pi, untyped)) { + total_bodies_checked.fetch_add(1, std::memory_order_relaxed); + return 0; + } + return 1; } @@ -5247,7 +5350,7 @@ gb_internal void check_procedure_bodies(Checker *c) { if (thread_count == 1) { UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; for_array(i, c->procs_to_check) { - consume_proc_info_queue(c, c->procs_to_check[i], untyped); + consume_proc_info(c, c->procs_to_check[i], untyped); } array_clear(&c->procs_to_check); @@ -5266,9 +5369,6 @@ gb_internal void check_procedure_bodies(Checker *c) { thread_pool_wait(); - debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); - - global_procedure_body_in_worker_queue = false; } gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) { @@ -5662,9 +5762,6 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("check test procedures"); check_test_procedures(c); - TIME_SECTION("check bodies have all been checked"); - check_unchecked_bodies(c); - TIME_SECTION("add type info for type definitions"); add_type_info_for_type_definitions(c); check_merge_queues_into_arrays(c); @@ -5672,6 +5769,12 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("generate minimum dependency set"); generate_minimum_dependency_set(c, c->info.entry_point); + TIME_SECTION("check bodies have all been checked"); + check_unchecked_bodies(c); + + check_merge_queues_into_arrays(c); + + TIME_SECTION("check entry point"); if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) { Scope *s = c->info.init_scope; @@ -5694,11 +5797,39 @@ gb_internal void check_parsed_files(Checker *c) { } } + thread_pool_wait(); + GB_ASSERT(c->procs_to_check.count == 0); + + if (DEBUG_CHECK_ALL_PROCEDURES) { + UntypedExprInfoMap untyped = {}; + map_init(&untyped, heap_allocator()); + defer (map_destroy(&untyped)); + + for_array(i, c->info.all_procedures) { + ProcInfo *pi = c->info.all_procedures[i]; + GB_ASSERT(pi != nullptr); + GB_ASSERT(pi->decl != nullptr); + Entity *e = pi->decl->entity; + auto proc_checked_state = pi->decl->proc_checked_state.load(); + if (e && ((e->flags & EntityFlag_ProcBodyChecked) == 0)) { + if ((e->flags & EntityFlag_Used) != 0) { + debugf("%.*s :: %s\n", LIT(e->token.string), type_to_string(e->type)); + debugf("proc body unchecked\n"); + debugf("Checked State: %s\n\n", ProcCheckedState_strings[proc_checked_state]); + + consume_proc_info(c, pi, &untyped); + } + } + } + } + + debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); + TIME_SECTION("check unique package names"); check_unique_package_names(c); - TIME_SECTION("sanity checks"); + check_merge_queues_into_arrays(c); GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0); GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0); @@ -5717,5 +5848,6 @@ gb_internal void check_parsed_files(Checker *c) { } } + TIME_SECTION("type check finish"); } diff --git a/src/checker.hpp b/src/checker.hpp index eaad1fa63..37aff41b1 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -142,6 +142,20 @@ typedef DECL_ATTRIBUTE_PROC(DeclAttributeProc); gb_internal void check_decl_attributes(CheckerContext *c, Array const &attributes, DeclAttributeProc *proc, AttributeContext *ac); +enum ProcCheckedState : u8 { + ProcCheckedState_Unchecked, + ProcCheckedState_InProgress, + ProcCheckedState_Checked, + + ProcCheckedState_COUNT +}; + +char const *ProcCheckedState_strings[ProcCheckedState_COUNT] { + "Unchecked", + "In Progress", + "Checked", +}; + // DeclInfo is used to store information of certain declarations to allow for "any order" usage struct DeclInfo { DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment @@ -157,7 +171,7 @@ struct DeclInfo { Type * gen_proc_type; // Precalculated bool is_using; bool where_clauses_evaluated; - bool proc_checked; + std::atomic proc_checked_state; BlockingMutex proc_checked_mutex; isize defer_used; bool defer_use_checked; @@ -375,6 +389,9 @@ struct CheckerInfo { BlockingMutex load_file_mutex; StringMap load_file_cache; + + BlockingMutex all_procedures_mutex;; + Array all_procedures; }; struct CheckerContext { @@ -458,7 +475,7 @@ gb_internal Entity *entity_of_node(Ast *expr); gb_internal Entity *scope_lookup_current(Scope *s, String const &name); gb_internal Entity *scope_lookup (Scope *s, String const &name); gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_); -gb_internal Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true); +gb_internal Entity *scope_insert (Scope *s, Entity *entity); gb_internal void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1c401552e..3e62f678a 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2255,6 +2255,12 @@ gb_internal void lb_generate_code(lbGenerator *gen) { } } + if (build_context.ignore_llvm_build) { + gb_printf_err("LLVM SUCCESS!\n"); + gb_exit(1); + return; + } + if (do_threading && non_empty_module_count > 1) { for (auto const &entry : gen->modules) { lbModule *m = entry.value; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 9f7caa3bb..50fb5701f 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -301,6 +301,7 @@ struct lbProcedure { lbBlock * curr_block; lbTargetList * target_list; PtrMap direct_parameters; + PtrMap local_entity_map; Ast *curr_stmt; diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index d574caf4c..28a68b065 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3404,7 +3404,11 @@ gb_internal lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *exp lbValue v = {}; - lbValue *found = map_get(&p->module->values, e); + lbValue *found = nullptr; + found = map_get(&p->local_entity_map, e); + if (found == nullptr) { + found = map_get(&p->module->values, e); + } if (found) { v = *found; } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) { diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 0508c6171..940c94a13 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2714,7 +2714,6 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) { return g; } } - GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); return {}; } @@ -2845,6 +2844,10 @@ gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero lb_mem_zero_ptr(p, ptr, type, alignment); } + if (e != nullptr) { + map_set(&p->local_entity_map, e, val); + } + return lb_addr(val); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 384d29ca7..9691afebc 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -68,7 +68,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i GB_ASSERT(entity != nullptr); GB_ASSERT(entity->kind == Entity_Procedure); if (!entity->Procedure.is_foreign) { - GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s", LIT(entity->token.string), type_to_string(entity->type)); + GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s (was parapoly: %d)", LIT(entity->token.string), type_to_string(entity->type), is_type_polymorphic(entity->type, true)); } String link_name = {}; @@ -487,6 +487,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { lb_start_block(p, p->entry_block); map_init(&p->direct_parameters, heap_allocator()); + map_init(&p->local_entity_map, heap_allocator()); GB_ASSERT(p->type != nullptr); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 6400a8a9d..cdfb28aa7 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1531,6 +1531,9 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { lbValue global_val = {global, alloc_type_pointer(e->type)}; lb_add_entity(p->module, e, global_val); lb_add_member(p->module, mangled_name, global_val); + if (e) { + map_set(&p->local_entity_map, e, global_val); + } } } gb_internal void lb_append_tuple_values(lbProcedure *p, Array *dst_values, lbValue src_value) { @@ -2188,9 +2191,10 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { for_array(i, vd->names) { Ast *name = vd->names[i]; if (!is_blank_ident(name)) { + GB_ASSERT(name->kind == Ast_Ident); Entity *e = entity_of_node(name); TokenPos pos = ast_token(name).pos; - GB_ASSERT_MSG(e != nullptr, "%s", token_pos_to_string(pos)); + GB_ASSERT_MSG(e != nullptr, "\n%s missing entity for %.*s", token_pos_to_string(pos), LIT(name->Ident.token.string)); if (e->flags & EntityFlag_Static) { // NOTE(bill): If one of the entities is static, they all are is_static = true; diff --git a/src/main.cpp b/src/main.cpp index 3ad0e160f..42d6f8e87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -660,6 +660,7 @@ enum BuildFlagKind { // internal use only BuildFlag_InternalIgnoreLazy, + BuildFlag_InternalIgnoreLLVMBuild, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -832,6 +833,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_ErrorPosStyle, str_lit("error-pos-style"), BuildFlagParam_String, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all); #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); @@ -1491,6 +1493,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_InternalIgnoreLazy: build_context.ignore_lazy = true; break; + case BuildFlag_InternalIgnoreLLVMBuild: + build_context.ignore_llvm_build = true; + break; #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: { GB_ASSERT(value.kind == ExactValue_Invalid); -- cgit v1.2.3 From d2ec2d1606013eb28f608d2ecaec3a654ec3598f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 19:46:55 +0000 Subject: Remove another use of a global mutex --- src/check_decl.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 8f95c1a49..32d50e36d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1581,16 +1581,21 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de Scope *ps = decl->parent->scope; if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { return true; - } else MUTEX_GUARD_BLOCK(&ctx->info->deps_mutex) { + } else { // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level - for (auto const &entry : decl->deps) { - Entity *e = entry.ptr; - ptr_set_add(&decl->parent->deps, e); + + MUTEX_GUARD_BLOCK(decl->deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { + for (auto const &entry : decl->deps) { + Entity *e = entry.ptr; + ptr_set_add(&decl->parent->deps, e); + } } - for (auto const &entry : decl->type_info_deps) { - Type *t = entry.ptr; - ptr_set_add(&decl->parent->type_info_deps, t); + MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { + for (auto const &entry : decl->type_info_deps) { + Type *t = entry.ptr; + ptr_set_add(&decl->parent->type_info_deps, t); + } } } } -- cgit v1.2.3 From bc9ee8e1a4ce797a894e5648fa92216c212b6999 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 22:13:49 +0000 Subject: Remove loops within futex signals on Linux --- src/check_decl.cpp | 2 +- src/threading.cpp | 24 ++++++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 32d50e36d..2b6868f05 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1471,7 +1471,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de continue; } if (is_blank_ident(e->token)) { - error(e->token, "'using' a procedure parameter requires a non blank identifier"); + error(e->token, "'using' a procedure parameter requires a non blank identifier"); break; } diff --git a/src/threading.cpp b/src/threading.cpp index cda8fe89b..aca77cd8f 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -472,26 +472,18 @@ gb_internal void thread_set_name(Thread *t, char const *name) { #include gb_internal void futex_signal(Futex *addr) { - for (;;) { - int ret = syscall(SYS_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL, 0); - if (ret == -1) { - perror("Futex wake"); - GB_PANIC("Failed in futex wake!\n"); - } else if (ret > 0) { - return; - } + int ret = syscall(SYS_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL, 0); + if (ret == -1) { + perror("Futex wake"); + GB_PANIC("Failed in futex wake!\n"); } } gb_internal void futex_broadcast(Futex *addr) { - for (;;) { - int ret = syscall(SYS_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, INT32_MAX, NULL, NULL, 0); - if (ret == -1) { - perror("Futex wake"); - GB_PANIC("Failed in futex wake!\n"); - } else if (ret > 0) { - return; - } + int ret = syscall(SYS_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, INT32_MAX, NULL, NULL, 0); + if (ret == -1) { + perror("Futex wake"); + GB_PANIC("Failed in futex wake!\n"); } } -- cgit v1.2.3 From 69b075782bac981ceeea5eea8f544e346f0fe6b5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 Jan 2023 22:40:28 +0000 Subject: Use a package local mutex for `add_type_and_value` --- src/check_decl.cpp | 9 ++++++--- src/check_expr.cpp | 56 +++++++++++++++++++++++++++--------------------------- src/check_type.cpp | 2 +- src/checker.cpp | 13 +++++++++---- src/checker.hpp | 2 +- src/parser.hpp | 1 + 6 files changed, 46 insertions(+), 37 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 2b6868f05..e3486924c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -45,7 +45,7 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o if (operand->mode == Addressing_Type) { if (e->type != nullptr && is_type_typeid(e->type)) { add_type_info_type(ctx, operand->type); - add_type_and_value(ctx->info, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type)); + add_type_and_value(ctx, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type)); return e->type; } else { gbString t = type_to_string(operand->type); @@ -1585,13 +1585,16 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level - MUTEX_GUARD_BLOCK(decl->deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { + MUTEX_GUARD_BLOCK(decl->deps_mutex) + MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { for (auto const &entry : decl->deps) { Entity *e = entry.ptr; ptr_set_add(&decl->parent->deps, e); } } - MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { + + MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) + MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { for (auto const &entry : decl->type_info_deps) { Type *t = entry.ptr; ptr_set_add(&decl->parent->type_info_deps, t); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index b40c48459..9feac93ea 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -852,7 +852,7 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand PolyProcData poly_proc_data = {}; if (check_polymorphic_procedure_assignment(c, operand, type, operand->expr, &poly_proc_data)) { Entity *e = poly_proc_data.gen_entity; - add_type_and_value(c->info, operand->expr, Addressing_Value, e->type, {}); + add_type_and_value(c, operand->expr, Addressing_Value, e->type, {}); add_entity_use(c, operand->expr, e); return 4; } @@ -1082,7 +1082,7 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ if (check_is_assignable_to(c, operand, type)) { if (operand->mode == Addressing_Type && is_type_typeid(type)) { add_type_info_type(c, operand->type); - add_type_and_value(c->info, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); + add_type_and_value(c, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type)); } } else { gbString expr_str = expr_to_string(operand->expr); @@ -2374,7 +2374,7 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok if (x->mode == Addressing_Type && is_type_typeid(y->type)) { add_type_info_type(c, x->type); add_type_info_type(c, y->type); - add_type_and_value(c->info, x->expr, Addressing_Value, y->type, exact_value_typeid(x->type)); + add_type_and_value(c, x->expr, Addressing_Value, y->type, exact_value_typeid(x->type)); x->mode = Addressing_Value; x->type = t_untyped_bool; @@ -2382,7 +2382,7 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok } else if (is_type_typeid(x->type) && y->mode == Addressing_Type) { add_type_info_type(c, x->type); add_type_info_type(c, y->type); - add_type_and_value(c->info, y->expr, Addressing_Value, x->type, exact_value_typeid(y->type)); + add_type_and_value(c, y->expr, Addressing_Value, x->type, exact_value_typeid(y->type)); x->mode = Addressing_Value; x->type = t_untyped_bool; @@ -3615,7 +3615,7 @@ gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, if (old == nullptr) { if (type != nullptr && type != t_invalid) { if (e->tav.type == nullptr || e->tav.type == t_invalid) { - add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); + add_type_and_value(c, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); if (e->kind == Ast_TernaryIfExpr) { update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final); update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final); @@ -3721,7 +3721,7 @@ gb_internal void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, return; } - add_type_and_value(c->info, e, old->mode, type, old->value); + add_type_and_value(c, e, old->mode, type, old->value); } gb_internal void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue value) { @@ -4569,7 +4569,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod operand->mode = Addressing_ProcGroup; operand->proc_group = entity; - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } GB_ASSERT_MSG(entity->type != nullptr, "%.*s (%.*s)", LIT(entity->token.string), LIT(entity_strings[entity->kind])); @@ -4738,7 +4738,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod } Entity *swizzle_entity = alloc_entity_variable(nullptr, make_token_ident(field_name), operand->type, EntityState_Resolved); - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return swizzle_entity; } end_of_array_selector_swizzle:; @@ -4782,7 +4782,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod operand->value = field_value; operand->type = entity->type; add_entity_use(c, selector, entity); - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } @@ -4807,7 +4807,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod operand->value = field_value; operand->type = entity->type; add_entity_use(c, selector, entity); - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } @@ -4895,7 +4895,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod break; } - add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return entity; } @@ -5361,7 +5361,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { if (o.mode == Addressing_Type && is_type_typeid(e->type)) { add_type_info_type(c, o.type); - add_type_and_value(c->info, o.expr, Addressing_Value, e->type, exact_value_typeid(o.type)); + add_type_and_value(c, o.expr, Addressing_Value, e->type, exact_value_typeid(o.type)); } else if (show_error && is_type_untyped(o.type)) { update_untyped_expr_type(c, o.expr, t, true); } @@ -5412,7 +5412,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } if (o.mode == Addressing_Type && is_type_typeid(t)) { add_type_info_type(c, o.type); - add_type_and_value(c->info, o.expr, Addressing_Value, t, exact_value_typeid(o.type)); + add_type_and_value(c, o.expr, Addressing_Value, t, exact_value_typeid(o.type)); } else if (show_error && is_type_untyped(o.type)) { update_untyped_expr_type(c, o.expr, t, true); } @@ -5425,7 +5425,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { data->score = score; data->result_type = final_proc_type->Proc.results; data->gen_entity = gen_entity; - add_type_and_value(c->info, ce->proc, Addressing_Value, final_proc_type, {}); + add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); } return err; @@ -5625,7 +5625,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { if (o->mode == Addressing_Type && is_type_typeid(e->type)) { add_type_info_type(c, o->type); - add_type_and_value(c->info, o->expr, Addressing_Value, e->type, exact_value_typeid(o->type)); + add_type_and_value(c, o->expr, Addressing_Value, e->type, exact_value_typeid(o->type)); } } @@ -5633,7 +5633,7 @@ gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { data->score = score; data->result_type = pt->results; data->gen_entity = gen_entity; - add_type_and_value(c->info, ce->proc, Addressing_Value, proc_type, {}); + add_type_and_value(c, ce->proc, Addressing_Value, proc_type, {}); } return err; @@ -6635,7 +6635,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c operand->builtin_id = BuiltinProc_DIRECTIVE; operand->expr = proc; operand->type = t_invalid; - add_type_and_value(c->info, proc, operand->mode, operand->type, operand->value); + add_type_and_value(c, proc, operand->mode, operand->type, operand->value); } else { error(proc, "Unknown directive: #%.*s", LIT(name)); operand->expr = proc; @@ -6713,7 +6713,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c GB_ASSERT(ot->kind == Type_Named); Entity *e = ot->Named.type_name; add_entity_use(c, ident, e); - add_type_and_value(c->info, call, Addressing_Type, ot, empty_exact_value); + add_type_and_value(c, call, Addressing_Type, ot, empty_exact_value); } else { operand->mode = Addressing_Invalid; operand->type = t_invalid; @@ -6885,7 +6885,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c } } - // add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value); + // add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value); return Expr_Expr; } @@ -7129,8 +7129,8 @@ gb_internal bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand * return false; } - add_type_and_value(c->info, ie->left, x->mode, x->type, x->value); - add_type_and_value(c->info, ie->right, y->mode, y->type, y->value); + add_type_and_value(c, ie->left, x->mode, x->type, x->value); + add_type_and_value(c, ie->right, y->mode, y->type, y->value); return true; } @@ -7146,7 +7146,7 @@ gb_internal bool check_is_operand_compound_lit_constant(CheckerContext *c, Opera return true; } if (expr->kind == Ast_ProcLit) { - add_type_and_value(c->info, expr, Addressing_Constant, type_of_expr(expr), exact_value_procedure(expr)); + add_type_and_value(c, expr, Addressing_Constant, type_of_expr(expr), exact_value_procedure(expr)); return true; } } @@ -7255,7 +7255,7 @@ gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type * Type *pt = base_type(type_of_expr(expr->CallExpr.proc)); if (is_type_proc(pt)) { Type *tuple = pt->Proc.results; - add_type_and_value(c->info, x->expr, x->mode, tuple, x->value); + add_type_and_value(c, x->expr, x->mode, tuple, x->value); if (pt->Proc.result_count >= 2) { if (ok_type_) *ok_type_ = tuple->Tuple.variables[1]->type; @@ -7268,7 +7268,7 @@ gb_internal void check_promote_optional_ok(CheckerContext *c, Operand *x, Type * Type *tuple = make_optional_ok_type(x->type); if (ok_type_) *ok_type_ = tuple->Tuple.variables[1]->type; - add_type_and_value(c->info, x->expr, x->mode, tuple, x->value); + add_type_and_value(c, x->expr, x->mode, tuple, x->value); x->type = tuple; GB_ASSERT(is_type_tuple(type_of_expr(x->expr))); } @@ -7688,7 +7688,7 @@ gb_internal ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node Type *left_type = nullptr; Type *right_type = nullptr; check_or_else_split_types(c, &x, name, &left_type, &right_type); - add_type_and_value(&c->checker->info, arg, x.mode, x.type, x.value); + add_type_and_value(c, arg, x.mode, x.type, x.value); if (left_type != nullptr) { if (!y_is_diverging) { @@ -7723,7 +7723,7 @@ gb_internal ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *no Type *left_type = nullptr; Type *right_type = nullptr; check_or_return_split_types(c, &x, name, &left_type, &right_type); - add_type_and_value(&c->checker->info, re->expr, x.mode, x.type, x.value); + add_type_and_value(c, re->expr, x.mode, x.type, x.value); if (right_type == nullptr) { check_or_else_expr_no_value_error(c, name, x, type_hint); @@ -8149,7 +8149,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * error(elem, "Expected a constant integer as an array field"); continue; } - // add_type_and_value(c->info, op_index.expr, op_index.mode, op_index.type, op_index.value); + // add_type_and_value(c, op_index.expr, op_index.mode, op_index.type, op_index.value); i64 index = exact_value_to_i64(op_index.value); @@ -9783,7 +9783,7 @@ gb_internal ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, T } check_rtti_type_disallowed(node, o->type, "An expression is using a type, %s, which has been disallowed"); - add_type_and_value(c->info, node, o->mode, o->type, o->value); + add_type_and_value(c, node, o->mode, o->type, o->value); return kind; } diff --git a/src/check_type.cpp b/src/check_type.cpp index 4634e1fbe..05fdbf4d3 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -3045,7 +3045,7 @@ gb_internal Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) #endif if (is_type_typed(type)) { - add_type_and_value(ctx->info, e, Addressing_Type, type, empty_exact_value); + add_type_and_value(ctx, e, Addressing_Type, type, empty_exact_value); } else { gbString name = type_to_string(type); error(e, "Invalid type definition of %s", name); diff --git a/src/checker.cpp b/src/checker.cpp index f80ea9e4c..e48142c82 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1440,7 +1440,7 @@ gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, check_set_expr_info(c, expr, mode, type, value); } -gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { if (expr == nullptr) { return; } @@ -1451,7 +1451,12 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo return; } - mutex_lock(&i->type_and_value_mutex); + BlockingMutex *mutex = &ctx->info->type_and_value_mutex; + if (ctx->pkg) { + mutex = &ctx->pkg->type_and_value_mutex; + } + + mutex_lock(mutex); Ast *prev_expr = nullptr; while (prev_expr != expr) { prev_expr = expr; @@ -1473,7 +1478,7 @@ gb_internal void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mo expr = unparen_expr(expr); } - mutex_unlock(&i->type_and_value_mutex); + mutex_unlock(mutex); } gb_internal void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) { @@ -5701,7 +5706,7 @@ gb_internal void check_parsed_files(Checker *c) { if (is_type_typed(u.info->type)) { compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); } - add_type_and_value(&c->info, u.expr, u.info->mode, u.info->type, u.info->value); + add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); } diff --git a/src/checker.hpp b/src/checker.hpp index 62f655f95..04cb1e311 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -482,7 +482,7 @@ gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **s gb_internal Entity *scope_insert (Scope *s, Entity *entity); -gb_internal void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); +gb_internal void add_type_and_value (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue value); gb_internal ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr); gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value); gb_internal void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity); diff --git a/src/parser.hpp b/src/parser.hpp index c33739ebe..b492cfa85 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -174,6 +174,7 @@ struct AstPackage { BlockingMutex files_mutex; BlockingMutex foreign_files_mutex; + BlockingMutex type_and_value_mutex; MPMCQueue exported_entity_queue; -- cgit v1.2.3 From 600f2b7284b8974a18827242c18e790dab0cf06a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 11:53:59 +0000 Subject: Use heap_allocator for all hash set types --- src/build_settings.cpp | 2 +- src/check_builtin.cpp | 2 +- src/check_decl.cpp | 2 +- src/check_expr.cpp | 1 - src/check_stmt.cpp | 1 - src/checker.cpp | 24 +++++++----------------- src/llvm_backend_general.cpp | 2 +- src/llvm_backend_type.cpp | 2 +- src/main.cpp | 8 ++++---- src/parser.cpp | 2 +- src/ptr_set.cpp | 21 +++++++++++++++------ src/string_set.cpp | 18 +++++++++++++----- 12 files changed, 45 insertions(+), 40 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 04d1ada93..75615a901 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1369,7 +1369,7 @@ gb_internal bool init_build_paths(String init_filename) { // NOTE(Jeroen): We're pre-allocating BuildPathCOUNT slots so that certain paths are always at the same enumerated index. array_init(&bc->build_paths, permanent_allocator(), BuildPathCOUNT); - string_set_init(&bc->target_features_set, heap_allocator(), 1024); + string_set_init(&bc->target_features_set, 1024); // [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path. bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename); diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 99d956f5e..36dc9b7a1 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3086,7 +3086,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } } StringSet name_set = {}; - string_set_init(&name_set, heap_allocator(), 2*ce->args.count); + string_set_init(&name_set, 2*ce->args.count); for_array(i, ce->args) { String name = {}; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index e3486924c..0c1a7c325 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1235,7 +1235,7 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, pg_entity->type = t_invalid; PtrSet entity_set = {}; - ptr_set_init(&entity_set, heap_allocator(), 2*pg->args.count); + ptr_set_init(&entity_set, 2*pg->args.count); for_array(i, pg->args) { Ast *arg = pg->args[i]; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 3c998fc44..7a00b5353 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -196,7 +196,6 @@ gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, b MUTEX_GUARD(objc_metadata->mutex); StringSet set = {}; - string_set_init(&set, heap_allocator()); defer (string_set_destroy(&set)); populate_check_did_you_mean_objc_entity(&set, e, is_type); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cf111e84c..945ba8f02 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1185,7 +1185,6 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ } PtrSet seen = {}; - ptr_set_init(&seen, heap_allocator()); defer (ptr_set_destroy(&seen)); for_array(i, bs->stmts) { diff --git a/src/checker.cpp b/src/checker.cpp index ccd0f3627..8da659461 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -72,7 +72,7 @@ gb_internal void entity_graph_node_set_destroy(EntityGraphNodeSet *s) { gb_internal void entity_graph_node_set_add(EntityGraphNodeSet *s, EntityGraphNode *n) { if (s->hashes.data == nullptr) { - ptr_set_init(s, heap_allocator()); + ptr_set_init(s); } ptr_set_add(s, n); } @@ -118,15 +118,10 @@ gb_internal void entity_graph_node_swap(EntityGraphNode **data, isize i, isize j gb_internal void import_graph_node_set_destroy(ImportGraphNodeSet *s) { - if (s->hashes.data != nullptr) { - ptr_set_destroy(s); - } + ptr_set_destroy(s); } gb_internal void import_graph_node_set_add(ImportGraphNodeSet *s, ImportGraphNode *n) { - if (s->hashes.data == nullptr) { - ptr_set_init(s, heap_allocator()); - } ptr_set_add(s, n); } @@ -185,8 +180,8 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { gb_zero_item(d); d->parent = parent; d->scope = scope; - ptr_set_init(&d->deps, heap_allocator()); - ptr_set_init(&d->type_info_deps, heap_allocator()); + ptr_set_init(&d->deps); + ptr_set_init(&d->type_info_deps); array_init (&d->labels, heap_allocator()); } @@ -227,7 +222,7 @@ gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_ele Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; string_map_init(&s->elements, heap_allocator(), init_elements_capacity); - ptr_set_init(&s->imported, heap_allocator(), 0); + ptr_set_init(&s->imported, 0); if (parent != nullptr && parent != builtin_pkg->scope) { Scope *prev_head_child = parent->head_child.exchange(s, std::memory_order_acq_rel); @@ -2270,8 +2265,8 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { isize entity_count = c->info.entities.count; isize min_dep_set_cap = next_pow2_isize(entity_count*4); // empirically determined factor - ptr_set_init(&c->info.minimum_dependency_set, heap_allocator(), min_dep_set_cap); - ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator()); + ptr_set_init(&c->info.minimum_dependency_set, min_dep_set_cap); + ptr_set_init(&c->info.minimum_dependency_type_info_set); #define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \ if (condition) { \ @@ -3388,7 +3383,6 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at } StringSet set = {}; - string_set_init(&set, heap_allocator()); defer (string_set_destroy(&set)); for_array(i, attributes) { @@ -4759,7 +4753,6 @@ gb_internal void check_import_entities(Checker *c) { auto pq = priority_queue_create(dep_graph, import_graph_node_cmp, import_graph_node_swap); PtrSet emitted = {}; - ptr_set_init(&emitted, heap_allocator()); defer (ptr_set_destroy(&emitted)); Array package_order = {}; @@ -4773,7 +4766,6 @@ gb_internal void check_import_entities(Checker *c) { if (n->dep_count > 0) { PtrSet visited = {}; - ptr_set_init(&visited, heap_allocator()); defer (ptr_set_destroy(&visited)); auto path = find_import_path(c, pkg, pkg, &visited); @@ -4927,7 +4919,6 @@ gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet< bool made_visited = false; if (visited == nullptr) { made_visited = true; - ptr_set_init(&visited_, heap_allocator()); visited = &visited_; } defer (if (made_visited) { @@ -4990,7 +4981,6 @@ gb_internal void calculate_global_init_order(Checker *c) { auto pq = priority_queue_create(dep_graph, entity_graph_node_cmp, entity_graph_node_swap); PtrSet emitted = {}; - ptr_set_init(&emitted, heap_allocator()); defer (ptr_set_destroy(&emitted)); TIME_SECTION("calculate_global_init_order: queue sort"); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 22628e895..75675474a 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -133,7 +133,7 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { array_init(&gen->foreign_libraries, heap_allocator(), 0, 1024); - ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024); + ptr_set_init(&gen->foreign_libraries_set, 1024); if (USE_SEPARATE_MODULES) { for (auto const &entry : gen->info->packages) { diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 26bb614e6..c306cdead 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -2,7 +2,7 @@ gb_internal isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_ auto *set = &info->minimum_dependency_type_info_set; isize index = type_info_index(info, type, err_on_not_found); if (index >= 0) { - isize i = ptr_entry_index(set, index); + isize i = ptr_set_entry_index(set, index); if (i >= 0) { return i+1; } diff --git a/src/main.cpp b/src/main.cpp index ad9d6b0ef..91dcbdb01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -212,11 +212,11 @@ gb_internal i32 linker_stage(lbGenerator *gen) { StringSet libs = {}; - string_set_init(&libs, heap_allocator(), 64); + string_set_init(&libs, 64); defer (string_set_destroy(&libs)); StringSet asm_files = {}; - string_set_init(&asm_files, heap_allocator(), 64); + string_set_init(&asm_files, 64); defer (string_set_destroy(&asm_files)); for_array(j, gen->foreign_libraries) { @@ -371,7 +371,7 @@ gb_internal i32 linker_stage(lbGenerator *gen) { defer (gb_string_free(lib_str)); StringSet libs = {}; - string_set_init(&libs, heap_allocator(), 64); + string_set_init(&libs, 64); defer (string_set_destroy(&libs)); for_array(j, gen->foreign_libraries) { @@ -2518,7 +2518,7 @@ int main(int arg_count, char const **arg_ptr) { map_init(&build_context.defined_values, heap_allocator()); build_context.extra_packages.allocator = heap_allocator(); - string_set_init(&build_context.test_names, heap_allocator()); + string_set_init(&build_context.test_names); Array args = setup_args(arg_count, arg_ptr); diff --git a/src/parser.cpp b/src/parser.cpp index 4d2a8ecf4..046469c16 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4854,7 +4854,7 @@ gb_internal void destroy_ast_file(AstFile *f) { gb_internal bool init_parser(Parser *p) { GB_ASSERT(p != nullptr); - string_set_init(&p->imported_files, heap_allocator()); + string_set_init(&p->imported_files); array_init(&p->packages, heap_allocator()); return true; } diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index 9ecf1043e..affde5c2f 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -6,11 +6,11 @@ struct PtrSetEntry { template struct PtrSet { - Slice hashes; + Slice hashes; Array> entries; }; -template gb_internal void ptr_set_init (PtrSet *s, gbAllocator a, isize capacity = 16); +template gb_internal void ptr_set_init (PtrSet *s, isize capacity = 16); template gb_internal void ptr_set_destroy(PtrSet *s); template gb_internal T ptr_set_add (PtrSet *s, T ptr); template gb_internal bool ptr_set_update (PtrSet *s, T ptr); // returns true if it previously existed @@ -21,15 +21,18 @@ template gb_internal void ptr_set_grow (PtrSet *s); template gb_internal void ptr_set_rehash (PtrSet *s, isize new_count); template gb_internal void ptr_set_reserve(PtrSet *h, isize cap); +gb_internal gbAllocator ptr_set_allocator(void) { + return heap_allocator(); +} template -gb_internal void ptr_set_init(PtrSet *s, gbAllocator a, isize capacity) { +gb_internal void ptr_set_init(PtrSet *s, isize capacity) { if (capacity != 0) { capacity = next_pow2_isize(gb_max(16, capacity)); } - slice_init(&s->hashes, a, capacity); - array_init(&s->entries, a, 0, capacity); + slice_init(&s->hashes, ptr_set_allocator(), capacity); + array_init(&s->entries, ptr_set_allocator(), 0, capacity); for (isize i = 0; i < capacity; i++) { s->hashes.data[i] = MAP_SENTINEL; } @@ -37,6 +40,9 @@ gb_internal void ptr_set_init(PtrSet *s, gbAllocator a, isize capacity) { template gb_internal void ptr_set_destroy(PtrSet *s) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = ptr_set_allocator(); + } slice_free(&s->hashes, s->entries.allocator); array_free(&s->entries); } @@ -118,6 +124,9 @@ gb_internal void ptr_set_reset_entries(PtrSet *s) { template gb_internal void ptr_set_reserve(PtrSet *s, isize cap) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = ptr_set_allocator(); + } array_reserve(&s->entries, cap); if (s->entries.count*2 < s->hashes.count) { return; @@ -139,7 +148,7 @@ gb_internal gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { } template -gb_internal gb_inline isize ptr_entry_index(PtrSet *s, T ptr) { +gb_internal gb_inline isize ptr_set_entry_index(PtrSet *s, T ptr) { isize index = ptr_set__find(s, ptr).entry_index; if (index != MAP_SENTINEL) { return index; diff --git a/src/string_set.cpp b/src/string_set.cpp index 1c97d253e..753afa9bf 100644 --- a/src/string_set.cpp +++ b/src/string_set.cpp @@ -10,7 +10,7 @@ struct StringSet { }; -gb_internal void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16); +gb_internal void string_set_init (StringSet *s, isize capacity = 16); gb_internal void string_set_destroy(StringSet *s); gb_internal void string_set_add (StringSet *s, String const &str); gb_internal bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed @@ -20,18 +20,24 @@ gb_internal void string_set_clear (StringSet *s); gb_internal void string_set_grow (StringSet *s); gb_internal void string_set_rehash (StringSet *s, isize new_count); +gb_internal gbAllocator string_set_allocator(void) { + return heap_allocator(); +} -gb_internal gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) { +gb_internal gb_inline void string_set_init(StringSet *s, isize capacity) { capacity = next_pow2_isize(gb_max(16, capacity)); - slice_init(&s->hashes, a, capacity); - array_init(&s->entries, a, 0, capacity); + slice_init(&s->hashes, string_set_allocator(), capacity); + array_init(&s->entries, string_set_allocator(), 0, capacity); for (isize i = 0; i < capacity; i++) { s->hashes.data[i] = MAP_SENTINEL; } } gb_internal gb_inline void string_set_destroy(StringSet *s) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = string_set_allocator(); + } slice_free(&s->hashes, s->entries.allocator); array_free(&s->entries); } @@ -106,6 +112,9 @@ gb_internal void string_set_reset_entries(StringSet *s) { } gb_internal void string_set_reserve(StringSet *s, isize cap) { + if (s->entries.allocator.proc == nullptr) { + s->entries.allocator = string_set_allocator(); + } array_reserve(&s->entries, cap); if (s->entries.count*2 < s->hashes.count) { return; @@ -217,7 +226,6 @@ gb_internal gb_inline void string_set_clear(StringSet *s) { } - gb_internal StringSetEntry *begin(StringSet &m) { return m.entries.data; } -- cgit v1.2.3 From 747a11a954824da7960a247299986f56d1316773 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 12:18:35 +0000 Subject: Allow all set entry types to be implicitly cast to their key/value type to allow for easier iteration --- src/build_settings.cpp | 6 ++---- src/check_decl.cpp | 6 ++---- src/check_expr.cpp | 7 +++---- src/checker.cpp | 38 +++++++++++++------------------------- src/ptr_set.cpp | 12 ++++++++---- src/string_map.cpp | 13 ++++++++++--- src/string_set.cpp | 15 +++++++++++---- src/types.cpp | 3 +-- 8 files changed, 50 insertions(+), 50 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 75615a901..1dff5f43e 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1332,11 +1332,10 @@ gb_internal void enable_target_feature(TokenPos pos, String const &target_featur gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) { isize len = 0; isize i = 0; - for (auto const &entry : build_context.target_features_set) { + for (String const &feature : build_context.target_features_set) { if (i != 0) { len += 1; } - String feature = entry.value; len += feature.len; if (with_quotes) len += 2; i += 1; @@ -1344,13 +1343,12 @@ gb_internal char const *target_features_set_to_cstring(gbAllocator allocator, bo char *features = gb_alloc_array(allocator, char, len+1); len = 0; i = 0; - for (auto const &entry : build_context.target_features_set) { + for (String const &feature : build_context.target_features_set) { if (i != 0) { features[len++] = ','; } if (with_quotes) features[len++] = '"'; - String feature = entry.value; gb_memmove(features + len, feature.text, feature.len); len += feature.len; if (with_quotes) features[len++] = '"'; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 0c1a7c325..7b229db08 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1587,16 +1587,14 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de MUTEX_GUARD_BLOCK(decl->deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { - for (auto const &entry : decl->deps) { - Entity *e = entry.ptr; + for (Entity *e : decl->deps) { ptr_set_add(&decl->parent->deps, e); } } MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { - for (auto const &entry : decl->type_info_deps) { - Type *t = entry.ptr; + for (Type *t : decl->type_info_deps) { ptr_set_add(&decl->parent->type_info_deps, t); } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 030bfb8e6..2924f9d13 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -202,8 +202,8 @@ gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, b DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name); defer (did_you_mean_destroy(&d)); - for (auto const &entry : set) { - did_you_mean_append(&d, entry.value); + for (String const &target : set) { + did_you_mean_append(&d, target); } check_did_you_mean_print(&d, prefix); } @@ -4942,8 +4942,7 @@ gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lh if (e != nullptr) { DeclInfo *decl = decl_info_of_entity(e); if (decl != nullptr) { - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { ptr_set_add(&c->decl->deps, dep); } } diff --git a/src/checker.cpp b/src/checker.cpp index 8779d9d45..0075fa543 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2222,12 +2222,11 @@ gb_internal void add_dependency_to_set(Checker *c, Entity *entity) { return; } - for (auto const &entry : decl->type_info_deps) { - add_min_dep_type_info(c, entry.ptr); + for (Type *t : decl->type_info_deps) { + add_min_dep_type_info(c, t); } - for (auto const &entry : decl->deps) { - Entity *e = entry.ptr; + for (Entity *e : decl->deps) { add_dependency_to_set(c, e); if (e->kind == Entity_Procedure && e->Procedure.is_foreign) { Entity *fl = e->Procedure.foreign_library; @@ -2510,8 +2509,7 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf DeclInfo *decl = decl_info_of_entity(e); GB_ASSERT(decl != nullptr); - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { if (dep->flags & EntityFlag_Field) { continue; } @@ -2537,15 +2535,12 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf if (e->kind == Entity_Procedure) { // Connect each pred 'p' of 'n' with each succ 's' and from // the procedure node - for (auto const &p_entry : n->pred) { - EntityGraphNode *p = p_entry.ptr; - + for (EntityGraphNode *p : n->pred) { // Ignore self-cycles if (p != n) { // Each succ 's' of 'n' becomes a succ of 'p', and // each pred 'p' of 'n' becomes a pred of 's' - for (auto const &s_entry : n->succ) { - EntityGraphNode *s = s_entry.ptr; + for (EntityGraphNode *s : n->succ) { // Ignore self-cycles if (s != n) { if (p->entity->kind == Entity_Procedure && @@ -4784,8 +4779,7 @@ gb_internal void check_import_entities(Checker *c) { } } - for (auto const &entry : n->pred) { - ImportGraphNode *p = entry.ptr; + for (ImportGraphNode *p : n->pred) { p->dep_count = gb_max(p->dep_count-1, 0); priority_queue_fix(&pq, p->index); } @@ -4893,8 +4887,7 @@ gb_internal bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSetdeps) { - Entity *dep = entry.ptr; + for (Entity *dep : var_decl->deps) { if (dep == end) { auto path = array_make(heap_allocator()); array_add(&path, dep); @@ -4944,8 +4937,7 @@ gb_internal Array find_entity_path(Entity *start, Entity *end, PtrSet< return path; } } else { - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { if (dep == end) { auto path = array_make(heap_allocator()); array_add(&path, dep); @@ -5002,8 +4994,7 @@ gb_internal void calculate_global_init_order(Checker *c) { } } - for (auto const &entry : n->pred) { - EntityGraphNode *p = entry.ptr; + for (EntityGraphNode *p : n->pred) { p->dep_count -= 1; p->dep_count = gb_max(p->dep_count, 0); priority_queue_fix(&pq, p->index); @@ -5163,8 +5154,7 @@ gb_internal void check_unchecked_bodies(Checker *c) { // use the `procs_to_check` array global_procedure_body_in_worker_queue = false; - for (auto const &entry : c->info.minimum_dependency_set) { - Entity *e = entry.ptr; + for (Entity *e : c->info.minimum_dependency_set) { if (e == nullptr || e->kind != Entity_Procedure) { continue; } @@ -5239,8 +5229,7 @@ gb_internal void check_test_procedures(Checker *c) { AstPackage *pkg = c->info.init_package; Scope *s = pkg->scope; - for (auto const &entry : build_context.test_names) { - String name = entry.value; + for (String const &name : build_context.test_names) { Entity *e = scope_lookup(s, name); if (e == nullptr) { Token tok = {}; @@ -5744,8 +5733,7 @@ gb_internal void check_parsed_files(Checker *c) { DeclInfo *decl = e->decl_info; ast_node(pl, ProcLit, decl->proc_lit); if (pl->inlining == ProcInlining_inline) { - for (auto const &entry : decl->deps) { - Entity *dep = entry.ptr; + for (Entity *dep : decl->deps) { if (dep == e) { error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string)); break; diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index affde5c2f..303bde07e 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -2,6 +2,10 @@ template struct PtrSetEntry { T ptr; MapIndex next; + + operator T() const noexcept { + return this->ptr; + } }; template @@ -245,21 +249,21 @@ gb_internal gb_inline void ptr_set_clear(PtrSet *s) { template -gb_internal PtrSetEntry *begin(PtrSet &m) { +gb_internal PtrSetEntry *begin(PtrSet &m) noexcept { return m.entries.data; } template -gb_internal PtrSetEntry const *begin(PtrSet const &m) { +gb_internal PtrSetEntry const *begin(PtrSet const &m) noexcept { return m.entries.data; } template -gb_internal PtrSetEntry *end(PtrSet &m) { +gb_internal PtrSetEntry *end(PtrSet &m) noexcept { return m.entries.data + m.entries.count; } template -gb_internal PtrSetEntry const *end(PtrSet const &m) { +gb_internal PtrSetEntry const *end(PtrSet const &m) noexcept { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/string_map.cpp b/src/string_map.cpp index b5db63e90..74a16de73 100644 --- a/src/string_map.cpp +++ b/src/string_map.cpp @@ -1,6 +1,13 @@ struct StringHashKey { u32 hash; String string; + + operator String() const noexcept { + return this->string; + } + operator String const &() const noexcept { + return this->string; + } }; gb_internal gb_inline StringHashKey string_hash_string(String const &s) { @@ -283,11 +290,11 @@ gb_internal gb_inline void string_map_clear(StringMap *h) { template -gb_internal StringMapEntry *begin(StringMap &m) { +gb_internal StringMapEntry *begin(StringMap &m) noexcept { return m.entries.data; } template -gb_internal StringMapEntry const *begin(StringMap const &m) { +gb_internal StringMapEntry const *begin(StringMap const &m) noexcept { return m.entries.data; } @@ -298,6 +305,6 @@ gb_internal StringMapEntry *end(StringMap &m) { } template -gb_internal StringMapEntry const *end(StringMap const &m) { +gb_internal StringMapEntry const *end(StringMap const &m) noexcept { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/string_set.cpp b/src/string_set.cpp index 753afa9bf..fb4640c20 100644 --- a/src/string_set.cpp +++ b/src/string_set.cpp @@ -2,6 +2,13 @@ struct StringSetEntry { u32 hash; MapIndex next; String value; + + operator String const() const noexcept { + return this->value; + } + operator String const &() const noexcept { + return this->value; + } }; struct StringSet { @@ -226,18 +233,18 @@ gb_internal gb_inline void string_set_clear(StringSet *s) { } -gb_internal StringSetEntry *begin(StringSet &m) { +gb_internal StringSetEntry *begin(StringSet &m) noexcept { return m.entries.data; } -gb_internal StringSetEntry const *begin(StringSet const &m) { +gb_internal StringSetEntry const *begin(StringSet const &m) noexcept { return m.entries.data; } -gb_internal StringSetEntry *end(StringSet &m) { +gb_internal StringSetEntry *end(StringSet &m) noexcept { return m.entries.data + m.entries.count; } -gb_internal StringSetEntry const *end(StringSet const &m) { +gb_internal StringSetEntry const *end(StringSet const &m) noexcept { return m.entries.data + m.entries.count; } \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index 1e2d85ac6..d33c36e94 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -823,8 +823,7 @@ gb_internal bool type_ptr_set_exists(PtrSet *s, Type *t) { // TODO(bill, 2019-10-05): This is very slow and it's probably a lot // faster to cache types correctly - for (auto const &entry : *s) { - Type *f = entry.ptr; + for (Type *f : *s) { if (are_types_identical(t, f)) { ptr_set_add(s, t); return true; -- cgit v1.2.3 From 69934c3b0b1b8ad0a499574c39c1ab177a1fe30a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 13:04:09 +0000 Subject: More `for_array(i, y)` to `for (x : y)` translations --- src/check_builtin.cpp | 15 ++++------ src/check_decl.cpp | 27 +++++++---------- src/check_stmt.cpp | 73 ++++++++++++++++------------------------------ src/llvm_backend.cpp | 9 ++---- src/llvm_backend_expr.cpp | 18 ++++-------- src/llvm_backend_stmt.cpp | 74 +++++++++++++++++++---------------------------- 6 files changed, 80 insertions(+), 136 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index af196234e..7c5521dde 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -96,8 +96,7 @@ gb_internal void check_or_else_expr_no_value_error(CheckerContext *c, String con gbString th = nullptr; if (type_hint != nullptr) { GB_ASSERT(bsrc->kind == Type_Union); - for_array(i, bsrc->Union.variants) { - Type *vt = bsrc->Union.variants[i]; + for (Type *vt : bsrc->Union.variants) { if (are_types_identical(vt, type_hint)) { th = type_to_string(type_hint); break; @@ -198,8 +197,7 @@ gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_t { auto variables = array_make(permanent_allocator(), 0, param_types.count); - for_array(i, param_types) { - Type *type = param_types[i]; + for (Type *type : param_types) { Entity *param = alloc_entity_param(scope, blank_token, type, false, true); array_add(&variables, param); } @@ -3071,8 +3069,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); bool fail = false; - for_array(i, ce->args) { - Ast *arg = ce->args[i]; + for (Ast *arg : ce->args) { bool mix = false; if (first_is_field_value) { mix = arg->kind != Ast_FieldValue; @@ -3088,9 +3085,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As StringSet name_set = {}; string_set_init(&name_set, 2*ce->args.count); - for_array(i, ce->args) { + for (Ast *arg : ce->args) { String name = {}; - Ast *arg = ce->args[i]; if (arg->kind == Ast_FieldValue) { Ast *ename = arg->FieldValue.field; if (!fail && ename->kind != Ast_Ident) { @@ -4987,8 +4983,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As bool is_variant = false; - for_array(i, u->Union.variants) { - Type *vt = u->Union.variants[i]; + for (Type *vt : u->Union.variants) { if (are_types_identical(v, vt)) { is_variant = true; break; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 7b229db08..66f16546c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -354,8 +354,7 @@ gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *t = base_type(e->type); if (t->kind == Type_Enum) { - for_array(i, t->Enum.fields) { - Entity *f = t->Enum.fields[i]; + for (Entity *f : t->Enum.fields) { if (f->kind != Entity_Constant) { continue; } @@ -1237,8 +1236,7 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, PtrSet entity_set = {}; ptr_set_init(&entity_set, 2*pg->args.count); - for_array(i, pg->args) { - Ast *arg = pg->args[i]; + for (Ast *arg : pg->args) { Entity *e = nullptr; Operand o = {}; if (arg->kind == Ast_Ident) { @@ -1271,7 +1269,7 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, ptr_set_destroy(&entity_set); - for_array(j, pge->entities) { + for (isize j = 0; j < pge->entities.count; j++) { Entity *p = pge->entities[j]; if (p->type == t_invalid) { // NOTE(bill): This invalid overload has already been handled @@ -1462,8 +1460,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de { if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; - for_array(i, params->variables) { - Entity *e = params->variables[i]; + for (Entity *e : params->variables) { if (e->kind != Entity_Variable) { continue; } @@ -1499,9 +1496,9 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de } } - MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) { - Entity *e = using_entities[i].e; - Entity *uvar = using_entities[i].uvar; + MUTEX_GUARD_BLOCK(ctx->scope->mutex) for (auto const &entry : using_entities) { + Entity *e = entry.e; + Entity *uvar = entry.uvar; Entity *prev = scope_insert_no_mutex(ctx->scope, uvar); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string)); @@ -1519,8 +1516,8 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_open_scope(ctx, body); { - for_array(i, using_entities) { - Entity *uvar = using_entities[i].uvar; + for (auto const &entry : using_entities) { + Entity *uvar = entry.uvar; Entity *prev = scope_insert(ctx->scope, uvar); gb_unused(prev); // NOTE(bill): Don't err here @@ -1537,12 +1534,10 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de decl->defer_use_checked = true; - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { if (stmt->kind == Ast_ValueDecl) { ast_node(vd, ValueDecl, stmt); - for_array(j, vd->names) { - Ast *name = vd->names[j]; + for (Ast *name : vd->names) { if (!is_blank_ident(name)) { if (name->kind == Ast_Ident) { GB_ASSERT(name->Ident.entity != nullptr); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 7192b16b5..e075297a4 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -931,16 +931,15 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags SeenMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue defer (map_destroy(&seen)); - for_array(stmt_index, bs->stmts) { - Ast *stmt = bs->stmts[stmt_index]; + for (Ast *stmt : bs->stmts) { if (stmt->kind != Ast_CaseClause) { // NOTE(bill): error handled by above multiple default checker continue; } ast_node(cc, CaseClause, stmt); - for_array(j, cc->list) { - Ast *expr = unparen_expr(cc->list[j]); + for (Ast *expr : cc->list) { + expr = unparen_expr(expr); if (is_ast_range(expr)) { ast_node(be, BinaryExpr, expr); @@ -1052,8 +1051,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags auto unhandled = array_make(temporary_allocator(), 0, fields.count); - for_array(i, fields) { - Entity *f = fields[i]; + for (Entity *f : fields) { if (f->kind != Entity_Constant) { continue; } @@ -1072,8 +1070,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags error_no_newline(node, "Unhandled switch case: %.*s", LIT(unhandled[0]->token.string)); } else { error(node, "Unhandled switch cases:"); - for_array(i, unhandled) { - Entity *f = unhandled[i]; + for (Entity *f : unhandled) { error_line("\t%.*s\n", LIT(f->token.string)); } } @@ -1154,8 +1151,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ // NOTE(bill): Check for multiple defaults Ast *first_default = nullptr; ast_node(bs, BlockStmt, ss->body); - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { Ast *default_stmt = nullptr; if (stmt->kind == Ast_CaseClause) { ast_node(cc, CaseClause, stmt); @@ -1186,8 +1182,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ PtrSet seen = {}; defer (ptr_set_destroy(&seen)); - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { if (stmt->kind != Ast_CaseClause) { // NOTE(bill): error handled by above multiple default checker continue; @@ -1198,8 +1193,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ Type *bt = base_type(type_deref(x.type)); Type *case_type = nullptr; - for_array(type_index, cc->list) { - Ast *type_expr = cc->list[type_index]; + for (Ast *type_expr : cc->list) { if (type_expr != nullptr) { // Otherwise it's a default expression Operand y = {}; check_expr_or_type(ctx, &y, type_expr); @@ -1213,8 +1207,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ if (switch_kind == TypeSwitch_Union) { GB_ASSERT(is_type_union(bt)); bool tag_type_found = false; - for_array(j, bt->Union.variants) { - Type *vt = bt->Union.variants[j]; + for (Type *vt : bt->Union.variants) { if (are_types_identical(vt, y.type)) { tag_type_found = true; break; @@ -1288,8 +1281,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ auto unhandled = array_make(temporary_allocator(), 0, variants.count); - for_array(i, variants) { - Type *t = variants[i]; + for (Type *t : variants) { if (!type_ptr_set_exists(&seen, t)) { array_add(&unhandled, t); } @@ -1302,8 +1294,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ gb_string_free(s); } else { error_no_newline(node, "Unhandled switch cases:\n"); - for_array(i, unhandled) { - Type *t = unhandled[i]; + for (Type *t : unhandled) { gbString s = type_to_string(t); error_line("\t%s\n", s); gb_string_free(s); @@ -1340,8 +1331,7 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { isize stmt_count = 0; Ast *the_stmt = nullptr; - for_array(i, bs->stmts) { - Ast *stmt = bs->stmts[i]; + for (Ast *stmt : bs->stmts) { GB_ASSERT(stmt != nullptr); switch (stmt->kind) { case_ast_node(es, EmptyStmt, stmt); @@ -1359,8 +1349,7 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { if (stmt_count == 1) { if (the_stmt->kind == Ast_ValueDecl) { - for_array(i, the_stmt->ValueDecl.names) { - Ast *name = the_stmt->ValueDecl.names[i]; + for (Ast *name : the_stmt->ValueDecl.names) { if (name->kind != Ast_Ident) { continue; } @@ -1376,8 +1365,8 @@ gb_internal void check_block_stmt_for_errors(CheckerContext *ctx, Ast *body) { gb_internal bool all_operands_valid(Array const &operands) { if (any_errors()) { - for_array(i, operands) { - if (operands[i].type == t_invalid) { + for (Operand const &o : operands) { + if (o.type == t_invalid) { return false; } } @@ -1548,16 +1537,9 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) check_assignment_arguments(ctx, lhs_operands, &rhs_operands, as->rhs); - isize rhs_count = rhs_operands.count; - for_array(i, rhs_operands) { - if (rhs_operands[i].mode == Addressing_Invalid) { - // TODO(bill): Should I ignore invalid parameters? - // rhs_count--; - } - } - auto lhs_to_ignore = array_make(temporary_allocator(), lhs_count); + isize rhs_count = rhs_operands.count; isize max = gb_min(lhs_count, rhs_count); for (isize i = 0; i < max; i++) { if (lhs_to_ignore[i]) { @@ -1856,8 +1838,8 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) break; } - for_array(ti, t->Tuple.variables) { - array_add(&vals, t->Tuple.variables[ti]->type); + for (Entity *e : t->Tuple.variables) { + array_add(&vals, e->type); } if (rs->vals.count > 1 && rs->vals[1] != nullptr && count < 3) { @@ -1976,8 +1958,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) } } - for_array(i, entities) { - Entity *e = entities[i]; + for (Entity *e : entities) { DeclInfo *d = decl_info_of_entity(e); GB_ASSERT(d == nullptr); add_entity(ctx, ctx->scope, e->identifier, e); @@ -2091,8 +2072,8 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) error(us->token, "Empty 'using' list"); return; } - for_array(i, us->list) { - Ast *expr = unparen_expr(us->list[i]); + for (Ast *expr : us->list) { + expr = unparen_expr(expr); Entity *e = nullptr; bool is_selector = false; @@ -2132,8 +2113,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) check_decl_attributes(&c, fb->attributes, foreign_block_decl_attribute, nullptr); ast_node(block, BlockStmt, fb->body); - for_array(i, block->stmts) { - Ast *decl = block->stmts[i]; + for (Ast *decl : block->stmts) { if (decl->kind == Ast_ValueDecl && decl->ValueDecl.is_mutable) { check_stmt(&c, decl, flags); } @@ -2146,8 +2126,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) isize entity_count = 0; isize new_name_count = 0; - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { Entity *entity = nullptr; if (name->kind != Ast_Ident) { error(name, "A variable declaration must be an identifier"); @@ -2193,8 +2172,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) begin_error_block(); error(node, "No new declarations on the left hand side"); bool all_underscore = true; - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { if (name->kind == Ast_Ident) { if (!is_blank_ident(name)) { all_underscore = false; @@ -2388,8 +2366,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) } else { // constant value declaration // NOTE(bill): Check `_` declarations - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { if (is_blank_ident(name)) { Entity *e = name->Ident.entity; DeclInfo *d = decl_info_of_entity(e); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 3e62f678a..304e5ef36 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -240,11 +240,10 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, left_tag.value, block_false->block, cast(unsigned)type->Union.variants.count); - for_array(i, type->Union.variants) { + for (Type *v : type->Union.variants) { lbBlock *case_block = lb_create_block(p, "bcase"); lb_start_block(p, case_block); - Type *v = type->Union.variants[i]; lbValue case_tag = lb_const_union_tag(p->module, type, v); Type *vp = alloc_type_pointer(v); @@ -374,11 +373,10 @@ gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) { LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, tag.value, end_block->block, cast(unsigned)type->Union.variants.count); - for_array(i, type->Union.variants) { + for (Type *v : type->Union.variants) { lbBlock *case_block = lb_create_block(p, "bcase"); lb_start_block(p, case_block); - Type *v = type->Union.variants[i]; lbValue case_tag = lb_const_union_tag(p->module, type, v); lbValue variant_hasher = lb_hasher_proc_for_type(m, v); @@ -2235,8 +2233,7 @@ gb_internal void lb_generate_code(lbGenerator *gen) { for (auto const &entry : gen->modules) { lbModule *m = entry.value; - for_array(i, m->info->required_foreign_imports_through_force) { - Entity *e = m->info->required_foreign_imports_through_force[i]; + for (Entity *e : m->info->required_foreign_imports_through_force) { lb_add_foreign_library_path(m, e); } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index d574caf4c..c28e9fb2b 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -61,8 +61,7 @@ gb_internal lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, As GB_ASSERT(incoming_values.count > 0); LLVMTypeRef phi_type = nullptr; - for_array(i, incoming_values) { - LLVMValueRef incoming_value = incoming_values[i]; + for (LLVMValueRef incoming_value : incoming_values) { if (!LLVMIsConstant(incoming_value)) { phi_type = LLVMTypeOf(incoming_value); break; @@ -1921,8 +1920,7 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_union(dst)) { - for_array(i, dst->Union.variants) { - Type *vt = dst->Union.variants[i]; + for (Type *vt : dst->Union.variants) { if (are_types_identical(vt, src_type)) { lbAddr parent = lb_add_local_generated(p, t, true); lb_emit_store_union_variant(p, parent.addr, value, vt); @@ -3596,8 +3594,7 @@ gb_internal void lb_build_addr_compound_lit_populate(lbProcedure *p, Slice const &temp_data) { - for_array(i, temp_data) { - auto td = temp_data[i]; + for (auto const &td : temp_data) { if (td.value.value != nullptr) { if (td.elem_length > 0) { auto loop_data = lb_loop_start(p, cast(isize)td.elem_length, t_i32); @@ -4129,8 +4126,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { lbValue err = lb_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos); gb_unused(err); - for_array(field_index, cl->elems) { - Ast *elem = cl->elems[field_index]; + for (Ast *elem : cl->elems) { ast_node(fv, FieldValue, elem); lbValue key = lb_build_expr(p, fv->field); @@ -4304,8 +4300,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); lbValue lower = lb_const_value(p->module, t_int, exact_value_i64(bt->BitSet.lower)); - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; + for (Ast *elem : cl->elems) { GB_ASSERT(elem->kind != Ast_FieldValue); if (lb_is_elem_const(elem, et)) { @@ -4359,8 +4354,7 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) { // TODO(bill): reduce the need for individual `insertelement` if a `shufflevector` // might be a better option - for_array(i, temp_data) { - auto td = temp_data[i]; + for (auto const &td : temp_data) { if (td.value.value != nullptr) { if (td.elem_length > 0) { for (i64 k = 0; k < td.elem_length; k++) { diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 2703c511a..c48115079 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -7,8 +7,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) static i32 global_guid = 0; - for_array(i, vd->names) { - Ast *ident = vd->names[i]; + for (Ast *ident : vd->names) { GB_ASSERT(ident->kind == Ast_Ident); Entity *e = entity_of_node(ident); GB_ASSERT(e != nullptr); @@ -106,8 +105,7 @@ gb_internal void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) gb_internal void lb_build_stmt_list(lbProcedure *p, Slice const &stmts) { - for_array(i, stmts) { - Ast *stmt = stmts[i]; + for (Ast *stmt : stmts) { switch (stmt->kind) { case_ast_node(vd, ValueDecl, stmt); lb_build_constant_value_decl(p, vd); @@ -118,8 +116,8 @@ gb_internal void lb_build_stmt_list(lbProcedure *p, Slice const &stmts) { case_end; } } - for_array(i, stmts) { - lb_build_stmt(p, stmts[i]); + for (Ast *stmt : stmts) { + lb_build_stmt(p, stmt); } } @@ -129,10 +127,9 @@ gb_internal lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) { GB_ASSERT(ident->kind == Ast_Ident); Entity *e = entity_of_node(ident); GB_ASSERT(e->kind == Entity_Label); - for_array(i, p->branch_blocks) { - lbBranchBlocks *b = &p->branch_blocks[i]; - if (b->label == e->Label.node) { - return *b; + for (lbBranchBlocks const &b : p->branch_blocks) { + if (b.label == e->Label.node) { + return b; } } @@ -153,13 +150,12 @@ gb_internal lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBloc if (label != nullptr) { // Set label blocks GB_ASSERT(label->kind == Ast_Label); - for_array(i, p->branch_blocks) { - lbBranchBlocks *b = &p->branch_blocks[i]; - GB_ASSERT(b->label != nullptr && label != nullptr); - GB_ASSERT(b->label->kind == Ast_Label); - if (b->label == label) { - b->break_ = break_; - b->continue_ = continue_; + for (lbBranchBlocks &b : p->branch_blocks) { + GB_ASSERT(b.label != nullptr && label != nullptr); + GB_ASSERT(b.label->kind == Ast_Label); + if (b.label == label) { + b.break_ = break_; + b.continue_ = continue_; return tl; } } @@ -1095,8 +1091,7 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo } ast_node(body, BlockStmt, ss->body); - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); if (cc->list.count == 0) { @@ -1104,8 +1099,8 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo continue; } - for_array(j, cc->list) { - Ast *expr = unparen_expr(cc->list[j]); + for (Ast *expr : cc->list) { + expr = unparen_expr(expr); if (is_ast_range(expr)) { return false; } @@ -1166,8 +1161,7 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * LLVMValueRef switch_instr = nullptr; if (is_trivial) { isize num_cases = 0; - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); num_cases += cc->list.count; } @@ -1204,8 +1198,8 @@ gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope * } lbBlock *next_cond = nullptr; - for_array(j, cc->list) { - Ast *expr = unparen_expr(cc->list[j]); + for (Ast *expr : cc->list) { + expr = unparen_expr(expr); if (switch_instr != nullptr) { lbValue on_val = {}; @@ -1384,8 +1378,7 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss lbBlock *default_block = nullptr; isize num_cases = 0; - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); num_cases += cc->list.count; if (cc->list.count == 0) { @@ -1405,8 +1398,7 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss switch_instr = LLVMBuildSwitch(p->builder, tag.value, else_block->block, cast(unsigned)num_cases); } - for_array(i, body->stmts) { - Ast *clause = body->stmts[i]; + for (Ast *clause : body->stmts) { ast_node(cc, CaseClause, clause); lb_open_scope(p, cc->scope); if (cc->list.count == 0) { @@ -1420,9 +1412,8 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss if (p->debug_info != nullptr) { LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, clause)); } - Type *case_type = nullptr; - for_array(type_index, cc->list) { - case_type = type_of_expr(cc->list[type_index]); + for (Ast *type_expr : cc->list) { + Type *case_type = type_of_expr(type_expr); lbValue on_val = {}; if (switch_kind == TypeSwitch_Union) { Type *ut = base_type(type_deref(parent.type)); @@ -1538,8 +1529,8 @@ gb_internal void lb_append_tuple_values(lbProcedure *p, Array *dst_valu if (t->kind == Type_Tuple) { lbTupleFix *tf = map_get(&p->tuple_fix_map, src_value.value); if (tf) { - for_array(j, tf->values) { - array_add(dst_values, tf->values[j]); + for (lbValue const &value : tf->values) { + array_add(dst_values, value); } } else { for_array(i, t->Tuple.variables) { @@ -1560,8 +1551,7 @@ gb_internal void lb_build_assignment(lbProcedure *p, Array &lvals, Slice auto inits = array_make(permanent_allocator(), 0, lvals.count); - for_array(i, values) { - Ast *rhs = values[i]; + for (Ast *rhs : values) { lbValue init = lb_build_expr(p, rhs); lb_append_tuple_values(p, &inits, init); } @@ -1971,8 +1961,7 @@ gb_internal void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr auto indices_handled = slice_make(temporary_allocator(), bt->Array.count); auto indices = slice_make(temporary_allocator(), bt->Array.count); i32 index_count = 0; - for_array(i, lhs.swizzle_large.indices) { - i32 index = lhs.swizzle_large.indices[i]; + for (i32 index : lhs.swizzle_large.indices) { if (indices_handled[index]) { continue; } @@ -2049,8 +2038,7 @@ gb_internal void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) { if (as->op.kind == Token_Eq) { auto lvals = array_make(permanent_allocator(), 0, as->lhs.count); - for_array(i, as->lhs) { - Ast *lhs = as->lhs[i]; + for (Ast *lhs : as->lhs) { lbAddr lval = {}; if (!is_blank_ident(lhs)) { lval = lb_build_addr(p, lhs); @@ -2185,8 +2173,7 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { bool is_static = false; if (vd->names.count > 0) { - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { if (!is_blank_ident(name)) { GB_ASSERT(name->kind == Ast_Ident); Entity *e = entity_of_node(name); @@ -2208,8 +2195,7 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { auto lvals = array_make(permanent_allocator(), 0, vd->names.count); - for_array(i, vd->names) { - Ast *name = vd->names[i]; + for (Ast *name : vd->names) { lbAddr lval = {}; if (!is_blank_ident(name)) { Entity *e = entity_of_node(name); -- cgit v1.2.3 From c7a704d345e9bda38da18807a1d7cd5bc5accc17 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 15:26:47 +0000 Subject: Use `RwMutex` for the `Scope` --- src/check_decl.cpp | 12 ++++--- src/check_expr.cpp | 4 ++- src/check_stmt.cpp | 5 ++- src/checker.cpp | 21 +++++++----- src/checker.hpp | 2 +- src/thread_pool.cpp | 27 ++++++++------- src/threading.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 138 insertions(+), 29 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 66f16546c..4afde6e51 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -381,8 +381,8 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e if (found_scope == nullptr) { return; } - mutex_lock(&found_scope->mutex); - defer (mutex_unlock(&found_scope->mutex)); + rw_mutex_lock(&found_scope->mutex); + defer (rw_mutex_unlock(&found_scope->mutex)); // IMPORTANT NOTE(bill, 2021-04-10): Overriding behaviour was flawed in that the // original entity was still used check checked, but the checking was only @@ -1478,7 +1478,8 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de if (t->kind == Type_Struct) { Scope *scope = t->Struct.scope; GB_ASSERT(scope != nullptr); - MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_lock(&scope->mutex); + for (auto const &entry : scope->elements) { Entity *f = entry.value; if (f->kind == Entity_Variable) { Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr); @@ -1488,6 +1489,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de array_add(&using_entities, puv); } } + rw_mutex_unlock(&scope->mutex); } else { error(e->token, "'using' can only be applied to variables of type struct"); break; @@ -1496,7 +1498,8 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de } } - MUTEX_GUARD_BLOCK(ctx->scope->mutex) for (auto const &entry : using_entities) { + rw_mutex_lock(&ctx->scope->mutex); + for (auto const &entry : using_entities) { Entity *e = entry.e; Entity *uvar = entry.uvar; Entity *prev = scope_insert_no_mutex(ctx->scope, uvar); @@ -1506,6 +1509,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de break; } } + rw_mutex_unlock(&ctx->scope->mutex); bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1787e7b6..d9ab328cb 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -236,10 +236,12 @@ gb_internal void check_did_you_mean_scope(String const &name, Scope *scope, char DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); defer (did_you_mean_destroy(&d)); - MUTEX_GUARD_BLOCK(&scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_shared_lock(&scope->mutex); + for (auto const &entry : scope->elements) { Entity *e = entry.value; did_you_mean_append(&d, e->token.string); } + rw_mutex_shared_unlock(&scope->mutex); check_did_you_mean_print(&d, prefix); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index e075297a4..6e84d0789 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -622,7 +622,10 @@ gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, case Entity_ImportName: { Scope *scope = e->ImportName.scope; - MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_lock(&scope->mutex); + defer (rw_mutex_unlock(&scope->mutex)); + + for (auto const &entry : scope->elements) { String name = entry.key.string; Entity *decl = entry.value; if (!is_entity_exported(decl)) continue; diff --git a/src/checker.cpp b/src/checker.cpp index 0075fa543..1d536074d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -51,10 +51,11 @@ gb_internal bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *f gb_internal void scope_reset(Scope *scope) { if (scope == nullptr) return; - MUTEX_GUARD(&scope->mutex); + rw_mutex_lock(&scope->mutex); scope->head_child.store(nullptr, std::memory_order_relaxed); string_map_clear(&scope->elements); ptr_set_clear(&scope->imported); + rw_mutex_unlock(&scope->mutex); } gb_internal void scope_reserve(Scope *scope, isize capacity) { @@ -180,9 +181,9 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { gb_zero_item(d); d->parent = parent; d->scope = scope; - ptr_set_init(&d->deps); - ptr_set_init(&d->type_info_deps); - array_init (&d->labels, heap_allocator()); + ptr_set_init(&d->deps, 0); + ptr_set_init(&d->type_info_deps, 0); + d->labels.allocator = heap_allocator(); } gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { @@ -394,9 +395,9 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s StringHashKey key = string_hash_string(name); for (Scope *s = scope; s != nullptr; s = s->parent) { Entity **found = nullptr; - mutex_lock(&s->mutex); + rw_mutex_shared_lock(&s->mutex); found = string_map_get(&s->elements, key); - mutex_unlock(&s->mutex); + rw_mutex_shared_unlock(&s->mutex); if (found) { Entity *e = *found; if (gone_thru_proc) { @@ -482,7 +483,7 @@ gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity Entity **found = nullptr; Entity *result = nullptr; - MUTEX_GUARD(&s->mutex); + rw_mutex_lock(&s->mutex); found = string_map_get(&s->elements, key); @@ -509,6 +510,8 @@ gb_internal Entity *scope_insert_with_name(Scope *s, String const &name, Entity entity->scope = s; } end:; + rw_mutex_unlock(&s->mutex); + return result; } @@ -669,7 +672,8 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { Array vetted_entities = {}; array_init(&vetted_entities, heap_allocator()); - MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) { + rw_mutex_shared_lock(&scope->mutex); + for (auto const &entry : scope->elements) { Entity *e = entry.value; if (e == nullptr) continue; VettedEntity ve_unused = {}; @@ -686,6 +690,7 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { array_add(&vetted_entities, ve_shadowed); } } + rw_mutex_shared_unlock(&scope->mutex); gb_sort(vetted_entities.data, vetted_entities.count, gb_size_of(VettedEntity), vetted_entity_variable_pos_cmp); diff --git a/src/checker.hpp b/src/checker.hpp index cc92fce28..53052d5cd 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -224,7 +224,7 @@ struct Scope { std::atomic next; std::atomic head_child; - BlockingMutex mutex; + RwMutex mutex; StringMap elements; PtrSet imported; diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 276e93dff..2c369eaad 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -47,7 +47,7 @@ gb_internal void thread_pool_destroy(ThreadPool *pool) { for_array_off(i, 1, pool->threads) { Thread *t = &pool->threads[i]; - pool->tasks_available.fetch_add(1, std::memory_order_release); + pool->tasks_available.fetch_add(1, std::memory_order_relaxed); futex_broadcast(&pool->tasks_available); thread_join_and_destroy(t); } @@ -74,7 +74,7 @@ void thread_pool_queue_push(Thread *thread, WorkerTask task) { } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture)); thread->pool->tasks_left.fetch_add(1, std::memory_order_release); - thread->pool->tasks_available.fetch_add(1, std::memory_order_release); + thread->pool->tasks_available.fetch_add(1, std::memory_order_relaxed); futex_broadcast(&thread->pool->tasks_available); } @@ -82,7 +82,7 @@ bool thread_pool_queue_pop(Thread *thread, WorkerTask *task) { u64 capture; u64 new_capture; do { - capture = thread->head_and_tail.load(); + capture = thread->head_and_tail.load(std::memory_order_acquire); u64 mask = thread->capacity - 1; u64 head = (capture >> 32) & mask; @@ -97,7 +97,7 @@ bool thread_pool_queue_pop(Thread *thread, WorkerTask *task) { *task = thread->queue[tail]; new_capture = (head << 32) | new_tail; - } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture)); + } while (!thread->head_and_tail.compare_exchange_weak(capture, new_capture, std::memory_order_release)); return true; } @@ -168,22 +168,21 @@ gb_internal THREAD_PROC(thread_pool_thread_proc) { Thread *thread = &pool->threads.data[idx]; WorkerTask task; - if (!thread_pool_queue_pop(thread, &task)) { - continue; - } - task.do_work(task.data); - pool->tasks_left.fetch_sub(1, std::memory_order_release); + if (thread_pool_queue_pop(thread, &task)) { + task.do_work(task.data); + pool->tasks_left.fetch_sub(1, std::memory_order_release); - if (pool->tasks_left.load(std::memory_order_acquire) == 0) { - futex_signal(&pool->tasks_left); - } + if (pool->tasks_left.load(std::memory_order_acquire) == 0) { + futex_signal(&pool->tasks_left); + } - goto main_loop_continue; + goto main_loop_continue; + } } } // if we've done all our work, and there's nothing to steal, go to sleep - state = pool->tasks_available.load(); + state = pool->tasks_available.load(std::memory_order_acquire); futex_wait(&pool->tasks_available, state); main_loop_continue:; diff --git a/src/threading.cpp b/src/threading.cpp index 78943150e..27a17112e 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -8,10 +8,12 @@ struct BlockingMutex; struct RecursiveMutex; +struct RwMutex; struct Semaphore; struct Condition; struct Thread; struct ThreadPool; +struct Parker; #define THREAD_PROC(name) isize name(struct Thread *thread) gb_internal THREAD_PROC(thread_pool_thread_proc); @@ -56,6 +58,13 @@ gb_internal void mutex_lock (RecursiveMutex *m); gb_internal bool mutex_try_lock(RecursiveMutex *m); gb_internal void mutex_unlock (RecursiveMutex *m); +gb_internal void rw_mutex_lock (RwMutex *m); +gb_internal bool rw_mutex_try_lock (RwMutex *m); +gb_internal void rw_mutex_unlock (RwMutex *m); +gb_internal void rw_mutex_shared_lock (RwMutex *m); +gb_internal bool rw_mutex_try_shared_lock(RwMutex *m); +gb_internal void rw_mutex_shared_unlock (RwMutex *m); + gb_internal void semaphore_post (Semaphore *s, i32 count); gb_internal void semaphore_wait (Semaphore *s); gb_internal void semaphore_release(Semaphore *s) { semaphore_post(s, 1); } @@ -65,6 +74,10 @@ gb_internal void condition_broadcast(Condition *c); gb_internal void condition_signal(Condition *c); gb_internal void condition_wait(Condition *c, BlockingMutex *m); +gb_internal void park(Parker *p); +gb_internal void unpark_one(Parker *p); +gb_internal void unpark_all(Parker *p); + gb_internal u32 thread_current_id(void); gb_internal void thread_init (ThreadPool *pool, Thread *t, isize idx); @@ -205,6 +218,30 @@ gb_internal void semaphore_wait(Semaphore *s) { gb_internal void condition_wait(Condition *c, BlockingMutex *m) { SleepConditionVariableSRW(&c->cond, &m->srwlock, INFINITE, 0); } + + struct RwMutex { + SRWLOCK srwlock; + }; + + gb_internal void rw_mutex_lock(RwMutex *m) { + AcquireSRWLockExclusive(&m->srwlock); + } + gb_internal bool rw_mutex_try_lock(RwMutex *m) { + return !!TryAcquireSRWLockExclusive(&m->srwlock); + } + gb_internal void rw_mutex_unlock(RwMutex *m) { + ReleaseSRWLockExclusive(&m->srwlock); + } + + gb_internal void rw_mutex_shared_lock(RwMutex *m) { + AcquireSRWLockShared(&m->srwlock); + } + gb_internal bool rw_mutex_try_shared_lock(RwMutex *m) { + return !!TryAcquireSRWLockShared(&m->srwlock); + } + gb_internal void rw_mutex_shared_unlock(RwMutex *m) { + ReleaseSRWLockShared(&m->srwlock); + } #else enum Internal_Mutex_State : i32 { Internal_Mutex_State_Unlocked = 0, @@ -306,8 +343,67 @@ gb_internal void semaphore_wait(Semaphore *s) { futex_wait(&c->state(), state); mutex_lock(m); } + + struct RwMutex { + // TODO(bill): make this a proper RW mutex + BlockingMutex mutex; + }; + + gb_internal void rw_mutex_lock(RwMutex *m) { + mutex_lock(&m->mutex); + } + gb_internal bool rw_mutex_try_lock(RwMutex *m) { + return mutex_try_lock(&m->mutex); + } + gb_internal void rw_mutex_unlock(RwMutex *m) { + mutex_unlock(&m->mutex); + } + + gb_internal void rw_mutex_shared_lock(RwMutex *m) { + mutex_lock(&m->mutex); + } + gb_internal bool rw_mutex_try_shared_lock(RwMutex *m) { + return mutex_try_lock(&m->mutex); + } + gb_internal void rw_mutex_shared_unlock(RwMutex *m) { + mutex_unlock(&m->mutex); + } #endif +struct Parker { + Futex state; +}; +enum ParkerState : u32 { + ParkerState_Empty = 0, + ParkerState_Notified = 1, + ParkerState_Parked = UINT32_MAX, +}; + +gb_internal void park(Parker *p) { + if (p->state.fetch_sub(1, std::memory_order_acquire) == ParkerState_Notified) { + return; + } + for (;;) { + futex_wait(&p->state, ParkerState_Parked); + i32 notified = ParkerState_Empty; + if (p->state.compare_exchange_strong(notified, ParkerState_Empty, std::memory_order_acquire, std::memory_order_acquire)) { + return; + } + } +} + +gb_internal void unpark_one(Parker *p) { + if (p->state.exchange(ParkerState_Notified, std::memory_order_release) == ParkerState_Parked) { + futex_signal(&p->state); + } +} + +gb_internal void unpark_all(Parker *p) { + if (p->state.exchange(ParkerState_Notified, std::memory_order_release) == ParkerState_Parked) { + futex_broadcast(&p->state); + } +} + gb_internal u32 thread_current_id(void) { u32 thread_id; -- cgit v1.2.3 From 3dee3205b299b2a2e803a3bc248f0a9ffdcce69e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 Jan 2023 15:34:52 +0000 Subject: Use `RwMutex` for `DeclInfo` `deps --- src/check_decl.cpp | 27 +++++++++++++++++---------- src/check_expr.cpp | 6 ++++-- src/checker.cpp | 8 ++++---- src/checker.hpp | 4 ++-- 4 files changed, 27 insertions(+), 18 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4afde6e51..72c69b5dc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1584,19 +1584,26 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de // NOTE(bill): Add the dependencies from the procedure literal (lambda) // But only at the procedure level - MUTEX_GUARD_BLOCK(decl->deps_mutex) - MUTEX_GUARD_BLOCK(decl->parent->deps_mutex) { - for (Entity *e : decl->deps) { - ptr_set_add(&decl->parent->deps, e); - } + rw_mutex_shared_lock(&decl->deps_mutex); + rw_mutex_lock(&decl->parent->deps_mutex); + + for (Entity *e : decl->deps) { + ptr_set_add(&decl->parent->deps, e); } - MUTEX_GUARD_BLOCK(decl->type_info_deps_mutex) - MUTEX_GUARD_BLOCK(decl->parent->type_info_deps_mutex) { - for (Type *t : decl->type_info_deps) { - ptr_set_add(&decl->parent->type_info_deps, t); - } + rw_mutex_unlock(&decl->parent->deps_mutex); + rw_mutex_shared_unlock(&decl->deps_mutex); + + + rw_mutex_shared_lock(&decl->type_info_deps_mutex); + rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + for (Type *t : decl->type_info_deps) { + ptr_set_add(&decl->parent->type_info_deps, t); } + + rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + rw_mutex_shared_unlock(&decl->type_info_deps_mutex); } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d9ab328cb..e3cd66db6 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4928,21 +4928,23 @@ gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = fals gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) { if (lhs != nullptr && c->decl != nullptr) { - mutex_lock(&c->info->deps_mutex); + // mutex_lock(&c->info->deps_mutex); for (isize j = 0; (tuple_index + j) < lhs_count && j < tuple_count; j++) { Entity *e = lhs[tuple_index + j]; if (e != nullptr) { DeclInfo *decl = decl_info_of_entity(e); if (decl != nullptr) { + rw_mutex_lock(&c->decl->deps_mutex); for (Entity *dep : decl->deps) { ptr_set_add(&c->decl->deps, dep); } + rw_mutex_unlock(&c->decl->deps_mutex); } } } - mutex_unlock(&c->info->deps_mutex); + // mutex_unlock(&c->info->deps_mutex); } return tuple_count; } diff --git a/src/checker.cpp b/src/checker.cpp index 1d536074d..fd80d07de 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -744,17 +744,17 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope) { gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { - mutex_lock(&d->deps_mutex); + rw_mutex_lock(&d->deps_mutex); ptr_set_add(&d->deps, e); - mutex_unlock(&d->deps_mutex); + rw_mutex_unlock(&d->deps_mutex); } gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) { if (d == nullptr) { return; } - mutex_lock(&d->type_info_deps_mutex); + rw_mutex_lock(&d->type_info_deps_mutex); ptr_set_add(&d->type_info_deps, type); - mutex_unlock(&d->type_info_deps_mutex); + rw_mutex_unlock(&d->type_info_deps_mutex); } gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { diff --git a/src/checker.hpp b/src/checker.hpp index 53052d5cd..50f4a204c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -179,10 +179,10 @@ struct DeclInfo { CommentGroup *comment; CommentGroup *docs; - BlockingMutex deps_mutex; + RwMutex deps_mutex; PtrSet deps; - BlockingMutex type_info_deps_mutex; + RwMutex type_info_deps_mutex; PtrSet type_info_deps; Array labels; -- cgit v1.2.3 From d4e18109da5fa051d689be84a6ecf1e77348c74e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Jan 2023 13:52:38 +0000 Subject: Move walking of dependencies for procedures to just before calculating the min dep set --- src/check_builtin.cpp | 3 +- src/check_decl.cpp | 31 --------------------- src/checker.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++-------- src/checker.hpp | 5 ++++ 4 files changed, 71 insertions(+), 44 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 606283c32..294bc7da8 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1118,8 +1118,7 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String } }); - char *c_str = alloc_cstring(heap_allocator(), path); - defer (gb_free(heap_allocator(), c_str)); + char *c_str = alloc_cstring(temporary_allocator(), path); gbFile f = {}; if (cache == nullptr) { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 72c69b5dc..07b547feb 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1576,36 +1576,5 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - if (decl->parent != nullptr) { - Scope *ps = decl->parent->scope; - if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - return true; - } else { - // NOTE(bill): Add the dependencies from the procedure literal (lambda) - // But only at the procedure level - - rw_mutex_shared_lock(&decl->deps_mutex); - rw_mutex_lock(&decl->parent->deps_mutex); - - for (Entity *e : decl->deps) { - ptr_set_add(&decl->parent->deps, e); - } - - rw_mutex_unlock(&decl->parent->deps_mutex); - rw_mutex_shared_unlock(&decl->deps_mutex); - - - rw_mutex_shared_lock(&decl->type_info_deps_mutex); - rw_mutex_lock(&decl->parent->type_info_deps_mutex); - - for (Type *t : decl->type_info_deps) { - ptr_set_add(&decl->parent->type_info_deps, t); - } - - rw_mutex_unlock(&decl->parent->type_info_deps_mutex); - rw_mutex_shared_unlock(&decl->type_info_deps_mutex); - } - } - return true; } diff --git a/src/checker.cpp b/src/checker.cpp index b8709f15e..5fc9a5551 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -174,6 +174,12 @@ gb_internal void import_graph_node_swap(ImportGraphNode **data, isize i, isize j gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { gb_zero_item(d); + if (parent) { + mutex_lock(&parent->next_mutex); + d->next_sibling = parent->next_child; + parent->next_child = d; + mutex_unlock(&parent->next_mutex); + } d->parent = parent; d->scope = scope; ptr_set_init(&d->deps, 0); @@ -5316,15 +5322,8 @@ gb_internal WORKER_TASK_PROC(check_proc_info_worker_proc) { return 1; } - -gb_internal void check_procedure_bodies(Checker *c) { - GB_ASSERT(c != nullptr); - - +gb_internal void check_init_worker_data(Checker *c) { u32 thread_count = cast(u32)global_thread_pool.threads.count; - if (!build_context.threaded_checker) { - thread_count = 1; - } check_procedure_bodies_worker_data = gb_alloc_array(permanent_allocator(), CheckProcedureBodyWorkerData, thread_count); @@ -5332,10 +5331,15 @@ gb_internal void check_procedure_bodies(Checker *c) { check_procedure_bodies_worker_data[i].c = c; map_init(&check_procedure_bodies_worker_data[i].untyped); } +} - defer (for (isize i = 0; i < thread_count; i++) { - map_destroy(&check_procedure_bodies_worker_data[i].untyped); - }); +gb_internal void check_procedure_bodies(Checker *c) { + GB_ASSERT(c != nullptr); + + u32 thread_count = cast(u32)global_thread_pool.threads.count; + if (!build_context.threaded_checker) { + thread_count = 1; + } if (thread_count == 1) { UntypedExprInfoMap *untyped = &check_procedure_bodies_worker_data[0].untyped; @@ -5636,6 +5640,50 @@ gb_internal void add_type_info_for_type_definitions(Checker *c) { } } +gb_internal void check_walk_all_dependencies(DeclInfo *decl) { + if (decl == nullptr) { + return; + } + for (DeclInfo *child = decl->next_child; child != nullptr; child = child->next_sibling) { + check_walk_all_dependencies(child); + } + if (decl->parent && decl->parent->entity && decl->parent->entity->kind == Entity_Procedure) { + Scope *ps = decl->parent->scope; + if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { + return; + } else { + // NOTE(bill): Add the dependencies from the procedure literal (lambda) + // But only at the procedure level + rw_mutex_shared_lock(&decl->deps_mutex); + rw_mutex_lock(&decl->parent->deps_mutex); + + for (Entity *e : decl->deps) { + ptr_set_add(&decl->parent->deps, e); + } + + rw_mutex_unlock(&decl->parent->deps_mutex); + rw_mutex_shared_unlock(&decl->deps_mutex); + + rw_mutex_shared_lock(&decl->type_info_deps_mutex); + rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + for (Type *t : decl->type_info_deps) { + ptr_set_add(&decl->parent->type_info_deps, t); + } + + rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + rw_mutex_shared_unlock(&decl->type_info_deps_mutex); + } + } +} + +gb_internal void check_update_dependency_tree_for_procedures(Checker *c) { + for (Entity *e : c->info.entities) { + DeclInfo *decl = e->decl_info; + check_walk_all_dependencies(decl); + } +} + gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("map full filepaths to scope"); add_type_info_type(&c->builtin_ctx, t_invalid); @@ -5657,6 +5705,9 @@ gb_internal void check_parsed_files(Checker *c) { } } + TIME_SECTION("init worker data"); + check_init_worker_data(c); + TIME_SECTION("create file scopes"); check_create_file_scopes(c); @@ -5744,6 +5795,9 @@ gb_internal void check_parsed_files(Checker *c) { add_type_info_for_type_definitions(c); check_merge_queues_into_arrays(c); + TIME_SECTION("update dependency tree for procedures"); + check_update_dependency_tree_for_procedures(c); + TIME_SECTION("generate minimum dependency set"); generate_minimum_dependency_set(c, c->info.entry_point); diff --git a/src/checker.hpp b/src/checker.hpp index bb870e077..821d43922 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -159,6 +159,11 @@ char const *ProcCheckedState_strings[ProcCheckedState_COUNT] { // DeclInfo is used to store information of certain declarations to allow for "any order" usage struct DeclInfo { DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment + + BlockingMutex next_mutex; + DeclInfo * next_child; + DeclInfo * next_sibling; + Scope * scope; Entity *entity; -- cgit v1.2.3 From 9455918eec18f3101d040adea09a628f684563f9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 Jan 2023 22:20:18 +0000 Subject: Fix min dep type info problem caused by const ref of `map_set` --- src/check_decl.cpp | 29 +++++++++++++++++++++++++++++ src/checker.cpp | 5 ++++- src/llvm_backend_type.cpp | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 07b547feb..644771dcd 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1576,5 +1576,34 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); + // if (decl->parent) { + // Scope *ps = decl->parent->scope; + // if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { + // return true; + // } else { + // // NOTE(bill): Add the dependencies from the procedure literal (lambda) + // // But only at the procedure level + // rw_mutex_shared_lock(&decl->deps_mutex); + // rw_mutex_lock(&decl->parent->deps_mutex); + + // for (Entity *e : decl->deps) { + // ptr_set_add(&decl->parent->deps, e); + // } + + // rw_mutex_unlock(&decl->parent->deps_mutex); + // rw_mutex_shared_unlock(&decl->deps_mutex); + + // rw_mutex_shared_lock(&decl->type_info_deps_mutex); + // rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + // for (Type *t : decl->type_info_deps) { + // ptr_set_add(&decl->parent->type_info_deps, t); + // } + + // rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + // rw_mutex_shared_unlock(&decl->type_info_deps_mutex); + // } + // } + return true; } diff --git a/src/checker.cpp b/src/checker.cpp index 0bebce232..8cb6ea99d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2030,7 +2030,10 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { // Type already exists; return; } - map_set(set, ti_index, set->entries.count); + // IMPORTANT NOTE(bill): this must be copied as `map_set` takes a const ref + // and effectively assigns the `+1` of the value + isize const count = set->entries.count; + map_set(set, ti_index, count); // Add nested types if (t->kind == Type_Named) { diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index b9b450404..e2b5c9dd0 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -186,7 +186,7 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup if (entry_index <= 0) { continue; } - + if (entries_handled[entry_index]) { continue; } -- cgit v1.2.3 From 1517f1d7793c8985664600a820e3434dfdf83810 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 Jan 2023 11:54:21 +0000 Subject: Add uncomment `add_type_info_type` calls for type assertions --- src/check_decl.cpp | 60 ++++++++++++++++++++++++++++------------------------ src/check_expr.cpp | 8 +++---- src/checker.cpp | 38 +++++---------------------------- src/llvm_backend.cpp | 1 + src/ptr_map.cpp | 29 +++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 65 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 644771dcd..d4ae9c59d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1411,6 +1411,37 @@ end:; } +gb_internal void add_deps_from_child_to_parent(DeclInfo *decl) { + if (decl && decl->parent) { + Scope *ps = decl->parent->scope; + if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { + return; + } else { + // NOTE(bill): Add the dependencies from the procedure literal (lambda) + // But only at the procedure level + rw_mutex_shared_lock(&decl->deps_mutex); + rw_mutex_lock(&decl->parent->deps_mutex); + + for (Entity *e : decl->deps) { + ptr_set_add(&decl->parent->deps, e); + } + + rw_mutex_unlock(&decl->parent->deps_mutex); + rw_mutex_shared_unlock(&decl->deps_mutex); + + rw_mutex_shared_lock(&decl->type_info_deps_mutex); + rw_mutex_lock(&decl->parent->type_info_deps_mutex); + + for (Type *t : decl->type_info_deps) { + ptr_set_add(&decl->parent->type_info_deps, t); + } + + rw_mutex_unlock(&decl->parent->type_info_deps_mutex); + rw_mutex_shared_unlock(&decl->type_info_deps_mutex); + } + } +} + struct ProcUsingVar { Entity *e; Entity *uvar; @@ -1576,34 +1607,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - // if (decl->parent) { - // Scope *ps = decl->parent->scope; - // if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - // return true; - // } else { - // // NOTE(bill): Add the dependencies from the procedure literal (lambda) - // // But only at the procedure level - // rw_mutex_shared_lock(&decl->deps_mutex); - // rw_mutex_lock(&decl->parent->deps_mutex); - - // for (Entity *e : decl->deps) { - // ptr_set_add(&decl->parent->deps, e); - // } - - // rw_mutex_unlock(&decl->parent->deps_mutex); - // rw_mutex_shared_unlock(&decl->deps_mutex); - - // rw_mutex_shared_lock(&decl->type_info_deps_mutex); - // rw_mutex_lock(&decl->parent->type_info_deps_mutex); - - // for (Type *t : decl->type_info_deps) { - // ptr_set_add(&decl->parent->type_info_deps, t); - // } - - // rw_mutex_unlock(&decl->parent->type_info_deps_mutex); - // rw_mutex_shared_unlock(&decl->type_info_deps_mutex); - // } - // } + add_deps_from_child_to_parent(decl); return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e9e61486e..e0519d26b 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8777,8 +8777,8 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no return kind; } - // add_type_info_type(c, o->type); - // add_type_info_type(c, bsrc->Union.variants[0]); + add_type_info_type(c, o->type); + add_type_info_type(c, bsrc->Union.variants[0]); o->type = bsrc->Union.variants[0]; o->mode = Addressing_OptionalOk; @@ -8810,8 +8810,8 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no return kind; } - // add_type_info_type(c, o->type); - // add_type_info_type(c, t); + add_type_info_type(c, o->type); + add_type_info_type(c, t); o->type = t; o->mode = Addressing_OptionalOk; diff --git a/src/checker.cpp b/src/checker.cpp index 8cb6ea99d..a2ed73119 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2026,14 +2026,13 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { ti_index = type_info_index(&c->info, t, false); } GB_ASSERT(ti_index >= 0); - if (map_get(set, ti_index)) { - // Type already exists; - return; - } // IMPORTANT NOTE(bill): this must be copied as `map_set` takes a const ref // and effectively assigns the `+1` of the value isize const count = set->entries.count; - map_set(set, ti_index, count); + if (map_set_if_not_previously_exists(set, ti_index, count)) { + // Type already exists; + return; + } // Add nested types if (t->kind == Type_Named) { @@ -5650,34 +5649,7 @@ gb_internal void check_walk_all_dependencies(DeclInfo *decl) { for (DeclInfo *child = decl->next_child; child != nullptr; child = child->next_sibling) { check_walk_all_dependencies(child); } - if (decl->parent && decl->parent->entity && decl->parent->entity->kind == Entity_Procedure) { - Scope *ps = decl->parent->scope; - if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) { - return; - } else { - // NOTE(bill): Add the dependencies from the procedure literal (lambda) - // But only at the procedure level - rw_mutex_shared_lock(&decl->deps_mutex); - rw_mutex_lock(&decl->parent->deps_mutex); - - for (Entity *e : decl->deps) { - ptr_set_add(&decl->parent->deps, e); - } - - rw_mutex_unlock(&decl->parent->deps_mutex); - rw_mutex_shared_unlock(&decl->deps_mutex); - - rw_mutex_shared_lock(&decl->type_info_deps_mutex); - rw_mutex_lock(&decl->parent->type_info_deps_mutex); - - for (Type *t : decl->type_info_deps) { - ptr_set_add(&decl->parent->type_info_deps, t); - } - - rw_mutex_unlock(&decl->parent->type_info_deps_mutex); - rw_mutex_shared_unlock(&decl->type_info_deps_mutex); - } - } + add_deps_from_child_to_parent(decl); } gb_internal void check_update_dependency_tree_for_procedures(Checker *c) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 304e5ef36..192e5cc56 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1920,6 +1920,7 @@ gb_internal void lb_generate_code(lbGenerator *gen) { if (!ptr_set_exists(min_dep_set, e)) { continue; } + DeclInfo *decl = decl_info_of_entity(e); if (decl == nullptr) { continue; diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index c33bf9ffb..89d2cbf9d 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -52,6 +52,7 @@ template gb_internal void map_init (PtrMap< template gb_internal void map_destroy (PtrMap *h); template gb_internal V * map_get (PtrMap *h, K key); template gb_internal void map_set (PtrMap *h, K key, V const &value); +template gb_internal bool map_set_if_not_previously_exists(PtrMap *h, K key, V const &value); // returns true if it previously existed template gb_internal void map_remove (PtrMap *h, K key); template gb_internal void map_clear (PtrMap *h); template gb_internal void map_grow (PtrMap *h); @@ -240,6 +241,34 @@ gb_internal void map_set(PtrMap *h, K key, V const &value) { } } +// returns true if it previously existed +template +gb_internal bool map_set_if_not_previously_exists(PtrMap *h, K key, V const &value) { + MapIndex index; + MapFindResult fr; + if (h->hashes.count == 0) { + map_grow(h); + } + fr = map__find(h, key); + if (fr.entry_index != MAP_SENTINEL) { + return true; + } else { + index = map__add_entry(h, key); + if (fr.entry_prev != MAP_SENTINEL) { + h->entries.data[fr.entry_prev].next = index; + } else { + h->hashes.data[fr.hash_index] = index; + } + } + h->entries.data[index].value = value; + + if (map__full(h)) { + map_grow(h); + } + return false; +} + + template gb_internal void map__erase(PtrMap *h, MapFindResult const &fr) { MapFindResult last; -- cgit v1.2.3 From 520ff731de908f63c8f5fe21ea058b8590d4285d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 00:47:20 +0000 Subject: Add `ArenaTemp` to the compiler --- src/big_int.cpp | 1 + src/build_settings.cpp | 1 + src/check_builtin.cpp | 2 ++ src/check_decl.cpp | 1 + src/check_expr.cpp | 37 ++++++++++++++++++++-------- src/check_stmt.cpp | 7 ++++++ src/common.cpp | 4 +++ src/common_memory.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-- 8 files changed, 107 insertions(+), 12 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/big_int.cpp b/src/big_int.cpp index 0f6b921b2..36652005e 100644 --- a/src/big_int.cpp +++ b/src/big_int.cpp @@ -477,6 +477,7 @@ gb_internal void big_int_or(BigInt *dst, BigInt const *x, BigInt const *y) { } gb_internal void debug_print_big_int(BigInt const *x) { + TEMPORARY_ALLOCATOR_GUARD(); String s = big_int_to_string(temporary_allocator(), x, 10); gb_printf_err("[DEBUG] %.*s\n", LIT(s)); } diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0640c7982..122a010b2 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1045,6 +1045,7 @@ gb_internal bool has_asm_extension(String const &path) { // temporary gb_internal char *token_pos_to_string(TokenPos const &pos) { + TEMPORARY_ALLOCATOR_GUARD(); gbString s = gb_string_make_reserve(temporary_allocator(), 128); String file = get_file_path_string(pos.file_id); switch (build_context.ODIN_ERROR_POS_STYLE) { diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 294bc7da8..a7d5536e7 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1118,6 +1118,7 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String } }); + TEMPORARY_ALLOCATOR_GUARD(); char *c_str = alloc_cstring(temporary_allocator(), path); gbFile f = {}; @@ -3062,6 +3063,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } case BuiltinProc_soa_zip: { + TEMPORARY_ALLOCATOR_GUARD(); auto types = array_make(temporary_allocator(), 0, ce->args.count); auto names = array_make(temporary_allocator(), 0, ce->args.count); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index d4ae9c59d..8f4534fb9 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -117,6 +117,7 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation + TEMPORARY_ALLOCATOR_GUARD(); auto operands = array_make(temporary_allocator(), 0, 2*lhs_count); check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e0519d26b..c1fa21dc4 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -86,6 +86,7 @@ gb_internal Entity * find_polymorphic_record_entity (CheckerContext *c, Type *or gb_internal void check_not_tuple (CheckerContext *c, Operand *operand); gb_internal void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); gb_internal gbString expr_to_string (Ast *expression); +gb_internal gbString expr_to_string (Ast *expression, gbAllocator allocator); gb_internal void update_untyped_expr_type (CheckerContext *c, Ast *e, Type *type, bool final); gb_internal bool check_is_terminating (Ast *node, String const &label); gb_internal bool check_has_break (Ast *stmt, String const &label, bool implicit); @@ -2404,8 +2405,8 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok if (x->type == err_type && is_operand_nil(*x)) { err_type = y->type; } - gbString type_string = type_to_string(err_type); - defer (gb_string_free(type_string)); + TEMPORARY_ALLOCATOR_GUARD(); + gbString type_string = type_to_string(err_type, temporary_allocator()); err_str = gb_string_make(temporary_allocator(), gb_bprintf("operator '%.*s' not defined for type '%s'", LIT(token_strings[op]), type_string)); } else { @@ -2417,20 +2418,19 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok add_comparison_procedures_for_fields(c, comparison_type); } } else { + TEMPORARY_ALLOCATOR_GUARD(); gbString xt, yt; if (x->mode == Addressing_ProcGroup) { - xt = gb_string_make(heap_allocator(), "procedure group"); + xt = gb_string_make(temporary_allocator(), "procedure group"); } else { xt = type_to_string(x->type); } if (y->mode == Addressing_ProcGroup) { - yt = gb_string_make(heap_allocator(), "procedure group"); + yt = gb_string_make(temporary_allocator(), "procedure group"); } else { yt = type_to_string(y->type); } err_str = gb_string_make(temporary_allocator(), gb_bprintf("mismatched types '%s' and '%s'", xt, yt)); - gb_string_free(yt); - gb_string_free(xt); } if (err_str != nullptr) { @@ -3893,6 +3893,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar case Type_Union: if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) { + TEMPORARY_ALLOCATOR_GUARD(); + isize count = t->Union.variants.count; ValidIndexAndScore *valids = gb_alloc_array(temporary_allocator(), ValidIndexAndScore, count); isize valid_count = 0; @@ -4057,10 +4059,10 @@ gb_internal bool check_index_value(CheckerContext *c, Type *main_type, bool open (c->state_flags & StateFlag_no_bounds_check) == 0) { BigInt i = exact_value_to_integer(operand.value).value_integer; if (i.sign && !is_type_enum(index_type) && !is_type_multi_pointer(main_type)) { + TEMPORARY_ALLOCATOR_GUARD(); String idx_str = big_int_to_string(temporary_allocator(), &i); - gbString expr_str = expr_to_string(operand.expr); + gbString expr_str = expr_to_string(operand.expr, temporary_allocator()); error(operand.expr, "Index '%s' cannot be a negative value, got %.*s", expr_str, LIT(idx_str)); - gb_string_free(expr_str); if (value) *value = 0; return false; } @@ -4120,10 +4122,10 @@ gb_internal bool check_index_value(CheckerContext *c, Type *main_type, bool open } if (out_of_bounds) { + TEMPORARY_ALLOCATOR_GUARD(); String idx_str = big_int_to_string(temporary_allocator(), &i); - gbString expr_str = expr_to_string(operand.expr); + gbString expr_str = expr_to_string(operand.expr, temporary_allocator()); error(operand.expr, "Index '%s' is out of bounds range 0..<%lld, got %.*s", expr_str, max_count, LIT(idx_str)); - gb_string_free(expr_str); return false; } @@ -5446,6 +5448,8 @@ gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) { bool show_error = show_error_mode == CallArgumentMode_ShowErrors; CallArgumentError err = CallArgumentError_None; + TEMPORARY_ALLOCATOR_GUARD(); + isize param_count = pt->param_count; bool *visited = gb_alloc_array(temporary_allocator(), bool, param_count); auto ordered_operands = array_make(temporary_allocator(), param_count); @@ -6358,6 +6362,8 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O ordered_operands = array_make(permanent_allocator(), param_count); array_copy(&ordered_operands, operands, 0); } else { + TEMPORARY_ALLOCATOR_GUARD(); + bool *visited = gb_alloc_array(temporary_allocator(), bool, param_count); // LEAK(bill) @@ -7146,6 +7152,8 @@ gb_internal bool attempt_implicit_selector_expr(CheckerContext *c, Operand *o, A return true; } if (is_type_union(th)) { + TEMPORARY_ALLOCATOR_GUARD(); + Type *union_type = base_type(th); auto operands = array_make(temporary_allocator(), 0, union_type->Union.variants.count); @@ -7329,6 +7337,8 @@ gb_internal void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Op uintptr key = hash_exact_value(operand.value); TypeAndToken *found = map_get(seen, key); if (found != nullptr) { + TEMPORARY_ALLOCATOR_GUARD(); + isize count = multi_map_count(seen, key); TypeAndToken *taps = gb_alloc_array(temporary_allocator(), TypeAndToken, count); @@ -7895,6 +7905,8 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * } if (cl->elems[0]->kind == Ast_FieldValue) { + TEMPORARY_ALLOCATOR_GUARD(); + bool *fields_visited = gb_alloc_array(temporary_allocator(), bool, field_count); for (Ast *elem : cl->elems) { @@ -8423,6 +8435,8 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * // NOTE(bill): Check for missing cases when `#partial literal` is not present if (cl->elems.count > 0 && !was_error && !is_partial) { + TEMPORARY_ALLOCATOR_GUARD(); + Type *et = base_type(index_type); GB_ASSERT(et->kind == Type_Enum); auto fields = et->Enum.fields; @@ -10469,6 +10483,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan gb_internal gbString expr_to_string(Ast *expression) { return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, false); } +gb_internal gbString expr_to_string(Ast *expression, gbAllocator allocator) { + return write_expr_to_string(gb_string_make(allocator, ""), expression, false); +} gb_internal gbString expr_to_string_shorthand(Ast *expression) { return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, true); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index b4dd4cd7d..a2a688b13 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1048,6 +1048,8 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags } if (!is_partial && is_type_enum(x.type)) { + TEMPORARY_ALLOCATOR_GUARD(); + Type *et = base_type(x.type); GB_ASSERT(is_type_enum(et)); auto fields = et->Enum.fields; @@ -1280,6 +1282,8 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ } if (!is_partial && is_type_union(type_deref(x.type))) { + TEMPORARY_ALLOCATOR_GUARD(); + Type *ut = base_type(type_deref(x.type)); GB_ASSERT(is_type_union(ut)); auto variants = ut->Union.variants; @@ -1523,6 +1527,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) return; } + TEMPORARY_ALLOCATOR_GUARD(); // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation @@ -1743,6 +1748,8 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) case_ast_node(rs, RangeStmt, node); + TEMPORARY_ALLOCATOR_GUARD(); + u32 new_flags = mod_flags | Stmt_BreakAllowed | Stmt_ContinueAllowed; check_open_scope(ctx, node); diff --git a/src/common.cpp b/src/common.cpp index 988a992d0..6a6019482 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -716,6 +716,8 @@ gb_internal LoadedFileError load_file_32(char const *fullpath, LoadedFile *memor if (!copy_file_contents) { #if defined(GB_SYSTEM_WINDOWS) + TEMPORARY_ALLOCATOR_GUARD(); + isize w_len = 0; wchar_t *w_str = gb__alloc_utf8_to_ucs2(temporary_allocator(), fullpath, &w_len); if (w_str == nullptr) { @@ -817,6 +819,8 @@ gb_internal LoadedFileError load_file_32(char const *fullpath, LoadedFile *memor #define USE_DAMERAU_LEVENSHTEIN 1 gb_internal isize levenstein_distance_case_insensitive(String const &a, String const &b) { + TEMPORARY_ALLOCATOR_GUARD(); + isize w = b.len+1; isize h = a.len+1; isize *matrix = gb_alloc_array(temporary_allocator(), isize, w*h); diff --git a/src/common_memory.cpp b/src/common_memory.cpp index 940e79f4b..c7382d6ff 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -48,6 +48,7 @@ struct Arena { MemoryBlock * curr_block; isize minimum_block_size; BlockingMutex mutex; + isize temp_count; }; enum { DEFAULT_MINIMUM_BLOCK_SIZE = 8ll*1024ll*1024ll }; @@ -245,7 +246,66 @@ gb_internal void virtual_memory_dealloc(MemoryBlock *block_to_free) { } } +struct ArenaTemp { + Arena * arena; + MemoryBlock *block; + isize used; +}; + +ArenaTemp arena_temp_begin(Arena *arena) { + GB_ASSERT(arena); + ArenaTemp temp = {}; + temp.arena = arena; + temp.block = arena->curr_block; + if (arena->curr_block != nullptr) { + temp.used = arena->curr_block->used; + } + arena->temp_count += 1; + return temp; +} +void arena_temp_end(ArenaTemp const &temp) { + GB_ASSERT(temp.arena); + Arena *arena = temp.arena; + bool memory_block_found = false; + for (MemoryBlock *block = arena->curr_block; block != nullptr; block = block->prev) { + if (block == temp.block) { + memory_block_found = true; + break; + } + } + GB_ASSERT_MSG(memory_block_found, "memory block stored within ArenaTemp not owned by Arena"); + + while (arena->curr_block != temp.block) { + MemoryBlock *free_block = arena->curr_block; + if (free_block != nullptr) { + arena->curr_block = free_block->prev; + virtual_memory_dealloc(free_block); + } + } + + MemoryBlock *block = arena->curr_block; + if (block) { + GB_ASSERT_MSG(block->used >= temp.used, "out of order use of arena_temp_end"); + isize amount_to_zero = gb_min(block->used - temp.used, block->size - block->used); + gb_zero_size(block->base + temp.used, amount_to_zero); + block->used = temp.used; + } + + GB_ASSERT_MSG(arena->temp_count > 0, "double-use of arena_temp_end"); + arena->temp_count -= 1; +} + + +struct ArenaTempGuard { + ArenaTempGuard(Arena *arena) { + this->temp = arena_temp_begin(arena); + } + ~ArenaTempGuard() { + arena_temp_end(this->temp); + } + ArenaTemp temp; +}; gb_internal GB_ALLOCATOR_PROC(arena_allocator_proc); @@ -294,11 +354,13 @@ gb_internal gbAllocator permanent_allocator() { return arena_allocator(&permanent_arena); } +gb_global gb_thread_local Arena temporary_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE}; gb_internal gbAllocator temporary_allocator() { - return permanent_allocator(); + return arena_allocator(&temporary_arena); } - +#define TEMPORARY_ALLOCATOR_GUARD() ArenaTempGuard GB_DEFER_3(_arena_guard_){&temporary_arena} +#define PERMANENT_ALLOCATOR_GUARD() ArenaTempGuard GB_DEFER_3(_arena_guard_){&permanent_arena} -- cgit v1.2.3 From b470ceb4705477ef42a1efc2c8beb5e3ceef2f88 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 12:59:09 +0000 Subject: Correct `mpsc_dequeue` --- src/check_builtin.cpp | 2 +- src/check_decl.cpp | 2 +- src/checker.cpp | 30 ++++++++++++++++-------------- src/checker.hpp | 8 ++++---- src/common.cpp | 12 +++++++++++- src/ptr_set.cpp | 11 ----------- src/queue.cpp | 5 ++++- 7 files changed, 37 insertions(+), 33 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a7d5536e7..290b1b8cd 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1687,7 +1687,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc___entry_point: operand->mode = Addressing_NoValue; operand->type = nullptr; - mpmc_enqueue(&c->info->intrinsics_entry_point_usage, call); + mpsc_enqueue(&c->info->intrinsics_entry_point_usage, call); break; case BuiltinProc_DIRECTIVE: diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 8f4534fb9..a21461454 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1124,7 +1124,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast if (ac.require_declaration) { e->flags |= EntityFlag_Require; - mpmc_enqueue(&ctx->info->required_global_variable_queue, e); + mpsc_enqueue(&ctx->info->required_global_variable_queue, e); } diff --git a/src/checker.cpp b/src/checker.cpp index 5ffdfab55..354e033aa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1160,11 +1160,11 @@ gb_internal void init_checker_info(CheckerInfo *i) { TIME_SECTION("checker info: mpmc queues"); - mpmc_init(&i->entity_queue, a, 1<<20); - mpsc_init(&i->definition_queue, a); //, 1<<20); - mpmc_init(&i->required_global_variable_queue, a, 1<<10); - mpmc_init(&i->required_foreign_imports_through_force_queue, a, 1<<10); - mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used + mpsc_init(&i->entity_queue, a); // 1<<20); + mpsc_init(&i->definition_queue, a); //); // 1<<20); + mpsc_init(&i->required_global_variable_queue, a); // 1<<10); + mpsc_init(&i->required_foreign_imports_through_force_queue, a); // 1<<10); + mpsc_init(&i->intrinsics_entry_point_usage, a); // 1<<10); // just waste some memory here, even if it probably never used } gb_internal void destroy_checker_info(CheckerInfo *i) { @@ -1181,10 +1181,10 @@ gb_internal void destroy_checker_info(CheckerInfo *i) { array_free(&i->variable_init_order); array_free(&i->required_foreign_imports_through_force); - mpmc_destroy(&i->entity_queue); + mpsc_destroy(&i->entity_queue); mpsc_destroy(&i->definition_queue); - mpmc_destroy(&i->required_global_variable_queue); - mpmc_destroy(&i->required_foreign_imports_through_force_queue); + mpsc_destroy(&i->required_global_variable_queue); + mpsc_destroy(&i->required_foreign_imports_through_force_queue); map_destroy(&i->objc_msgSend_types); string_map_destroy(&i->load_file_cache); @@ -1711,7 +1711,8 @@ gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, En is_lazy = (e->flags & EntityFlag_Lazy) == EntityFlag_Lazy; if (!is_lazy) { - queue_count = mpmc_enqueue(&info->entity_queue, e); + GB_ASSERT(e != nullptr); + queue_count = mpsc_enqueue(&info->entity_queue, e); } if (e->token.pos.file_id != 0) { @@ -2375,12 +2376,12 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { } } - for (Entity *e; mpmc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.required_foreign_imports_through_force_queue, &e); /**/) { array_add(&c->info.required_foreign_imports_through_force, e); add_dependency_to_set(c, e); } - for (Entity *e; mpmc_dequeue(&c->info.required_global_variable_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.required_global_variable_queue, &e); /**/) { e->flags |= EntityFlag_Used; add_dependency_to_set(c, e); } @@ -4058,6 +4059,7 @@ gb_internal void check_all_global_entities(Checker *c) { // Don't bother trying for_array(i, c->info.entities) { Entity *e = c->info.entities[i]; + GB_ASSERT(e != nullptr); if (e->flags & EntityFlag_Lazy) { continue; } @@ -4461,7 +4463,7 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { AttributeContext ac = {}; check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac); if (ac.require_declaration) { - mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); + mpsc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); add_entity_use(ctx, nullptr, e); } if (ac.foreign_import_priority_index != 0) { @@ -5575,7 +5577,7 @@ gb_internal void check_unique_package_names(Checker *c) { gb_internal void check_add_entities_from_queues(Checker *c) { isize cap = c->info.entities.count + c->info.entity_queue.count.load(std::memory_order_relaxed); array_reserve(&c->info.entities, cap); - for (Entity *e; mpmc_dequeue(&c->info.entity_queue, &e); /**/) { + for (Entity *e; mpsc_dequeue(&c->info.entity_queue, &e); /**/) { array_add(&c->info.entities, e); } } @@ -5843,7 +5845,7 @@ gb_internal void check_parsed_files(Checker *c) { if (c->info.intrinsics_entry_point_usage.count > 0) { TIME_SECTION("check intrinsics.__entry_point usage"); Ast *node = nullptr; - while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { + while (mpsc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { if (c->info.entry_point == nullptr && node != nullptr) { if (node->file()->pkg->kind != Package_Runtime) { warning(node, "usage of intrinsics.__entry_point will be a no-op"); diff --git a/src/checker.hpp b/src/checker.hpp index 356dd1fc8..7c545a716 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -380,11 +380,11 @@ struct CheckerInfo { // NOTE(bill): These are actually MPSC queues // TODO(bill): Convert them to be MPSC queues MPSCQueue definition_queue; - MPMCQueue entity_queue; - MPMCQueue required_global_variable_queue; - MPMCQueue required_foreign_imports_through_force_queue; + MPSCQueue entity_queue; + MPSCQueue required_global_variable_queue; + MPSCQueue required_foreign_imports_through_force_queue; - MPMCQueue intrinsics_entry_point_usage; + MPSCQueue intrinsics_entry_point_usage; BlockingMutex objc_types_mutex; PtrMap objc_msgSend_types; diff --git a/src/common.cpp b/src/common.cpp index 6a6019482..68d99ef02 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -43,11 +43,21 @@ gb_internal void debugf(char const *fmt, ...); #error Odin on Windows requires a 64-bit build-system. The 'Developer Command Prompt' for VS still defaults to 32-bit shell. The 64-bit shell can be found under the name 'x64 Native Tools Command Prompt' for VS. For more information, please see https://odin-lang.org/docs/install/#for-windows #endif +template +struct TypeIsPointer { + enum {value = false}; +}; + +template +struct TypeIsPointer { + enum {value = true}; +}; + #include "unicode.cpp" #include "array.cpp" #include "threading.cpp" -#include "queue.cpp" #include "common_memory.cpp" +#include "queue.cpp" #include "string.cpp" #include "range_cache.cpp" diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index 019ede8a5..2b8f38fef 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -1,14 +1,3 @@ -template -struct TypeIsPointer { - enum {value = false}; -}; - -template -struct TypeIsPointer { - enum {value = true}; -}; - - template struct PtrSet { static_assert(TypeIsPointer::value, "PtrSet::T must be a pointer"); diff --git a/src/queue.cpp b/src/queue.cpp index 845f87310..d3fd69c52 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -69,10 +69,13 @@ gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_) { if (next) { q->tail.store(next, std::memory_order_relaxed); // `tail` is now "dead" and needs to be "freed" - if (*value_) *value_ = next->value; + tail->value = next->value; + T value = tail->value; + if (value_) *value_ = value; q->count.fetch_sub(1, std::memory_order_acq_rel); return true; } + GB_ASSERT(q->count.load(std::memory_order_acquire) == 0); return false; } -- cgit v1.2.3 From cbe3791b422728b3ae692009b32836e30c37c9d5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 13:11:17 +0000 Subject: Replace all queues with MPSCQueue where possible --- src/check_decl.cpp | 2 +- src/checker.cpp | 14 +++++++------- src/checker.hpp | 5 ++--- src/parser.hpp | 1 + src/queue.cpp | 24 +++++++++++++++--------- 5 files changed, 26 insertions(+), 20 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index a21461454..f0059424e 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1010,7 +1010,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (ac.deferred_procedure.entity != nullptr) { e->Procedure.deferred_procedure = ac.deferred_procedure; - mpmc_enqueue(&ctx->checker->procs_with_deferred_to_check, e); + mpsc_enqueue(&ctx->checker->procs_with_deferred_to_check, e); } if (is_foreign) { diff --git a/src/checker.cpp b/src/checker.cpp index 354e033aa..8d6462f8b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1254,12 +1254,12 @@ gb_internal void init_checker(Checker *c) { c->info.checker = c; TIME_SECTION("init proc queues"); - mpmc_init(&c->procs_with_deferred_to_check, a, 1<<10); + mpsc_init(&c->procs_with_deferred_to_check, a); //, 1<<10); // NOTE(bill): 1 Mi elements should be enough on average array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20); - mpmc_init(&c->global_untyped_queue, a, 1<<20); + mpsc_init(&c->global_untyped_queue, a); // , 1<<20); c->builtin_ctx = make_checker_context(c); } @@ -1270,7 +1270,7 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); array_free(&c->procs_to_check); - mpmc_destroy(&c->global_untyped_queue); + mpsc_destroy(&c->global_untyped_queue); } @@ -4647,10 +4647,10 @@ gb_internal GB_COMPARE_PROC(sort_file_by_name) { gb_internal void check_create_file_scopes(Checker *c) { for_array(i, c->parser->packages) { AstPackage *pkg = c->parser->packages[i]; - isize total_pkg_decl_count = 0; gb_sort_array(pkg->files.data, pkg->files.count, sort_file_by_name); + isize total_pkg_decl_count = 0; for_array(j, pkg->files) { AstFile *f = pkg->files[j]; string_map_set(&c->info.files, f->fullpath, f); @@ -5382,14 +5382,14 @@ gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap Ast *expr = entry.key; ExprInfo *info = entry.value; if (expr != nullptr && info != nullptr) { - mpmc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info}); + mpsc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info}); } } map_clear(untyped); } gb_internal void check_deferred_procedures(Checker *c) { - for (Entity *src = nullptr; mpmc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { + for (Entity *src = nullptr; mpsc_dequeue(&c->procs_with_deferred_to_check, &src); /**/) { GB_ASSERT(src->kind == Entity_Procedure); DeferredProcedureKind dst_kind = src->Procedure.deferred_procedure.kind; @@ -5831,7 +5831,7 @@ gb_internal void check_parsed_files(Checker *c) { TIME_SECTION("add untyped expression values"); // Add untyped expression values - for (UntypedExprInfo u = {}; mpmc_dequeue(&c->global_untyped_queue, &u); /**/) { + for (UntypedExprInfo u = {}; mpsc_dequeue(&c->global_untyped_queue, &u); /**/) { GB_ASSERT(u.expr != nullptr && u.info != nullptr); if (is_type_typed(u.info->type)) { compiler_error("%s (type %s) is typed!", expr_to_string(u.expr), type_to_string(u.info->type)); diff --git a/src/checker.hpp b/src/checker.hpp index 7c545a716..595618e1d 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -446,11 +446,10 @@ struct Checker { CheckerContext builtin_ctx; - MPMCQueue procs_with_deferred_to_check; + MPSCQueue procs_with_deferred_to_check; Array procs_to_check; - // TODO(bill): Technically MPSC queue - MPMCQueue global_untyped_queue; + MPSCQueue global_untyped_queue; }; diff --git a/src/parser.hpp b/src/parser.hpp index d81194831..6782a9248 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -176,6 +176,7 @@ struct AstPackage { BlockingMutex foreign_files_mutex; BlockingMutex type_and_value_mutex; + // NOTE(bill): This must be a MPMCQueue MPMCQueue exported_entity_queue; // NOTE(bill): Created/set in checker diff --git a/src/queue.cpp b/src/queue.cpp index d3fd69c52..5585b772f 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -10,11 +10,12 @@ struct MPSCNode { // template struct MPSCQueue { + gbAllocator allocator; + std::atomic count; + std::atomic *> head; std::atomic *> tail; - std::atomic count; MPSCNode sentinel; - gbAllocator allocator; }; template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); @@ -29,6 +30,7 @@ gb_internal void mpsc_init(MPSCQueue *q, gbAllocator const &allocator) { q->count.store(0, std::memory_order_relaxed); q->head.store(&q->sentinel, std::memory_order_relaxed); q->tail.store(&q->sentinel, std::memory_order_relaxed); + q->sentinel.next.store(nullptr, std::memory_order_relaxed); } @@ -36,14 +38,20 @@ template gb_internal void mpsc_destroy(MPSCQueue *q) { while (mpsc_dequeue(q, (T *)nullptr)) {} // DO NOTHING for the time being + // free the nodes later } template gb_internal MPSCNode *mpsc_alloc_node(MPSCQueue *q, T const &value) { - auto node = gb_alloc_item(q->allocator, MPSCNode); - node->value = value; - return node; + auto new_node = gb_alloc_item(q->allocator, MPSCNode); + new_node->value = value; + return new_node; +} + +template +gb_internal void mpsc_free_node(MPSCQueue *q, MPSCNode *node) { + // TODO(bill): reuse the free nodes } template @@ -68,10 +76,8 @@ gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_) { auto next = tail->next.load(std::memory_order_relaxed); if (next) { q->tail.store(next, std::memory_order_relaxed); - // `tail` is now "dead" and needs to be "freed" - tail->value = next->value; - T value = tail->value; - if (value_) *value_ = value; + if (value_) *value_ = next->value; + mpsc_free_node(q, tail); q->count.fetch_sub(1, std::memory_order_acq_rel); return true; } -- cgit v1.2.3 From e97bf2ef358eef4499dfee0dc1533bf785d923f2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 15:38:23 +0000 Subject: Minimize contention on the deps for decls --- src/check_decl.cpp | 5 ++++- src/check_expr.cpp | 3 +++ src/checker.cpp | 7 +++++++ src/checker.hpp | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f0059424e..e28861fc6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1608,7 +1608,10 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - add_deps_from_child_to_parent(decl); + if (decl->entity == nullptr) { + // Only care about nested procedure literals + add_deps_from_child_to_parent(decl); + } return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1fa21dc4..52efd9a66 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9455,6 +9455,9 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast pl->decl = decl; check_procedure_later(ctx.checker, ctx.file, empty_token, decl, type, pl->body, pl->tags); + mutex_lock(&ctx.checker->nested_proc_lits_mutex); + array_add(&ctx.checker->nested_proc_lits, decl); + mutex_unlock(&ctx.checker->nested_proc_lits_mutex); } check_close_scope(&ctx); diff --git a/src/checker.cpp b/src/checker.cpp index 6d73348d1..7be3c71d1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1256,6 +1256,7 @@ gb_internal void init_checker(Checker *c) { // NOTE(bill): 1 Mi elements should be enough on average array_init(&c->procs_to_check, heap_allocator(), 0, 1<<20); + array_init(&c->nested_proc_lits, heap_allocator(), 0, 1<<20); mpsc_init(&c->global_untyped_queue, a); // , 1<<20); @@ -1267,6 +1268,7 @@ gb_internal void destroy_checker(Checker *c) { destroy_checker_context(&c->builtin_ctx); + array_free(&c->nested_proc_lits); array_free(&c->procs_to_check); mpsc_destroy(&c->global_untyped_queue); } @@ -5657,6 +5659,11 @@ gb_internal void check_walk_all_dependencies(DeclInfo *decl) { } gb_internal void check_update_dependency_tree_for_procedures(Checker *c) { + mutex_lock(&c->nested_proc_lits_mutex); + for (DeclInfo *decl : c->nested_proc_lits) { + check_walk_all_dependencies(decl); + } + mutex_unlock(&c->nested_proc_lits_mutex); for (Entity *e : c->info.entities) { DeclInfo *decl = e->decl_info; check_walk_all_dependencies(decl); diff --git a/src/checker.hpp b/src/checker.hpp index 595618e1d..d461b1f6e 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -449,6 +449,10 @@ struct Checker { MPSCQueue procs_with_deferred_to_check; Array procs_to_check; + BlockingMutex nested_proc_lits_mutex; + Array nested_proc_lits; + + MPSCQueue global_untyped_queue; }; -- cgit v1.2.3 From 38136e15fca0ee952702c4fccc0a0c6c11565746 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Jan 2023 15:44:55 +0000 Subject: `add_deps_from_child_to_parent` always --- src/check_decl.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index e28861fc6..f0059424e 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1608,10 +1608,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de check_scope_usage(ctx->checker, ctx->scope); - if (decl->entity == nullptr) { - // Only care about nested procedure literals - add_deps_from_child_to_parent(decl); - } + add_deps_from_child_to_parent(decl); return true; } -- cgit v1.2.3 From 94c1331c071d4816bec44345393dfd07f75c97dc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 15 Feb 2023 11:31:51 +0000 Subject: Implement `@(fini)` (opposite of `@(init)`) --- core/runtime/core.odin | 7 +--- core/runtime/default_temporary_allocator.odin | 6 +++ src/check_decl.cpp | 7 +++- src/checker.cpp | 53 ++++++++++++++++++++++++--- src/checker.hpp | 2 + src/entity.cpp | 1 + src/llvm_backend.cpp | 41 +++++++++++++++++++-- src/llvm_backend.hpp | 2 + 8 files changed, 103 insertions(+), 16 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/core/runtime/core.odin b/core/runtime/core.odin index c64ab7d3b..2d20310ae 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -507,11 +507,8 @@ Odin_Endian_Type :: type_of(ODIN_ENDIAN) foreign { @(link_name="__$startup_runtime") _startup_runtime :: proc "odin" () --- -} - -@(link_name="__$cleanup_runtime") -_cleanup_runtime :: proc() { - default_temp_allocator_destroy(&global_default_temp_allocator_data) + @(link_name="__$cleanup_runtime") + _cleanup_runtime :: proc "odin" () --- } _cleanup_runtime_contextless :: proc "contextless" () { diff --git a/core/runtime/default_temporary_allocator.odin b/core/runtime/default_temporary_allocator.odin index b71cd103a..85e76df6c 100644 --- a/core/runtime/default_temporary_allocator.odin +++ b/core/runtime/default_temporary_allocator.odin @@ -198,3 +198,9 @@ default_temp_allocator :: proc(allocator: ^Default_Temp_Allocator) -> Allocator data = allocator, } } + +@(fini, private) +_destroy_temp_allocator_fini :: proc() { + default_temp_allocator_destroy(&global_default_temp_allocator_data) + print_string("fini") +} diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f0059424e..63e6514e0 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -816,9 +816,14 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (ac.test) { e->flags |= EntityFlag_Test; } - if (ac.init) { + if (ac.init && ac.fini) { + error(e->token, "A procedure cannot be both declared as @(init) and @(fini)"); + } else if (ac.init) { e->flags |= EntityFlag_Init; + } else if (ac.fini) { + e->flags |= EntityFlag_Fini; } + if (ac.set_cold) { e->flags |= EntityFlag_Cold; } diff --git a/src/checker.cpp b/src/checker.cpp index 303a2449e..5163fe675 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1148,6 +1148,7 @@ gb_internal void init_checker_info(CheckerInfo *i) { array_init(&i->variable_init_order, a); array_init(&i->testing_procedures, a, 0, 0); array_init(&i->init_procedures, a, 0, 0); + array_init(&i->fini_procedures, a, 0, 0); array_init(&i->required_foreign_imports_through_force, a, 0, 0); map_init(&i->objc_msgSend_types); @@ -1539,7 +1540,7 @@ gb_internal void add_entity_flags_from_file(CheckerContext *c, Entity *e, Scope AstPackage *pkg = c->file->pkg; if (pkg->kind == Package_Init && e->kind == Entity_Procedure && e->token.string == "main") { // Do nothing - } else if (e->flags & (EntityFlag_Test|EntityFlag_Init)) { + } else if (e->flags & (EntityFlag_Test|EntityFlag_Init|EntityFlag_Fini)) { // Do nothing } else { e->flags |= EntityFlag_Lazy; @@ -1607,7 +1608,7 @@ gb_internal bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return false; } - if (e->flags & (EntityFlag_Test|EntityFlag_Init)) { + if (e->flags & (EntityFlag_Test|EntityFlag_Init|EntityFlag_Fini)) { return false; } else if (e->kind == Entity_Variable && e->Variable.is_export) { return false; @@ -2416,6 +2417,28 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { add_dependency_to_set(c, e); array_add(&c->info.init_procedures, e); } + } else if (e->flags & EntityFlag_Fini) { + Type *t = base_type(e->type); + GB_ASSERT(t->kind == Type_Proc); + + bool is_fini = true; + + if (t->Proc.param_count != 0 || t->Proc.result_count != 0) { + gbString str = type_to_string(t); + error(e->token, "@(fini) procedures must have a signature type with no parameters nor results, got %s", str); + gb_string_free(str); + is_fini = false; + } + + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { + error(e->token, "@(fini) procedures must be declared at the file scope"); + is_fini = false; + } + + if (is_fini) { + add_dependency_to_set(c, e); + array_add(&c->info.fini_procedures, e); + } } break; } @@ -2967,6 +2990,12 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } ac->init = true; return true; + } else if (name == "fini") { + if (value != nullptr) { + error(value, "'%.*s' expects no parameter, or a string literal containing \"file\" or \"package\"", LIT(name)); + } + ac->fini = true; + return true; } else if (name == "deferred") { if (value != nullptr) { Operand o = {}; @@ -3608,6 +3637,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { EntityVisiblityKind entity_visibility_kind = c->foreign_context.visibility_kind; bool is_test = false; bool is_init = false; + bool is_fini = false; for_array(i, vd->attributes) { Ast *attr = vd->attributes[i]; @@ -3667,6 +3697,8 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { is_test = true; } else if (name == "init") { is_init = true; + } else if (name == "fini") { + is_fini = true; } } } @@ -3800,8 +3832,12 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (is_test) { e->flags |= EntityFlag_Test; } - if (is_init) { + if (is_init && is_fini) { + error(name, "A procedure cannot be both declared as @(init) and @(fini)"); + } else if (is_init) { e->flags |= EntityFlag_Init; + } else if (is_fini) { + e->flags |= EntityFlag_Fini; } } else if (init->kind == Ast_ProcGroup) { ast_node(pg, ProcGroup, init); @@ -5627,9 +5663,14 @@ gb_internal GB_COMPARE_PROC(init_procedures_cmp) { return i32_cmp(x->token.pos.offset, y->token.pos.offset); } +gb_internal GB_COMPARE_PROC(fini_procedures_cmp) { + return init_procedures_cmp(b, a); +} + -gb_internal void check_sort_init_procedures(Checker *c) { +gb_internal void check_sort_init_and_fini_procedures(Checker *c) { gb_sort_array(c->info.init_procedures.data, c->info.init_procedures.count, init_procedures_cmp); + gb_sort_array(c->info.fini_procedures.data, c->info.fini_procedures.count, fini_procedures_cmp); } gb_internal void add_type_info_for_type_definitions(Checker *c) { @@ -5839,8 +5880,8 @@ gb_internal void check_parsed_files(Checker *c) { add_type_and_value(&c->builtin_ctx, u.expr, u.info->mode, u.info->type, u.info->value); } - TIME_SECTION("sort init procedures"); - check_sort_init_procedures(c); + TIME_SECTION("sort init and fini procedures"); + check_sort_init_and_fini_procedures(c); if (c->info.intrinsics_entry_point_usage.count > 0) { TIME_SECTION("check intrinsics.__entry_point usage"); diff --git a/src/checker.hpp b/src/checker.hpp index d461b1f6e..4c3b8725a 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -117,6 +117,7 @@ struct AttributeContext { bool disabled_proc : 1; bool test : 1; bool init : 1; + bool fini : 1; bool set_cold : 1; u32 optimization_mode; // ProcedureOptimizationMode i64 foreign_import_priority_index; @@ -351,6 +352,7 @@ struct CheckerInfo { Array testing_procedures; Array init_procedures; + Array fini_procedures; Array definitions; Array entities; diff --git a/src/entity.cpp b/src/entity.cpp index 4b0a6a3c8..0c3629b2b 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -75,6 +75,7 @@ enum EntityFlag : u64 { EntityFlag_Test = 1ull<<30, EntityFlag_Init = 1ull<<31, EntityFlag_Subtype = 1ull<<32, + EntityFlag_Fini = 1ull<<33, EntityFlag_CustomLinkName = 1ull<<40, EntityFlag_CustomLinkage_Internal = 1ull<<41, diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 34c1ec9b4..6d35615a3 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1161,6 +1161,34 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc return p; } +gb_internal lbProcedure *lb_create_cleanup_runtime(lbModule *main_module) { // Cleanup Runtime + Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin); + + lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_CLEANUP_RUNTIME_PROC_NAME), proc_type); + p->is_startup = true; + + lb_begin_procedure_body(p); + + CheckerInfo *info = main_module->gen->info; + + for (Entity *e : info->fini_procedures) { + lbValue value = lb_find_procedure_value_from_entity(main_module, e); + lb_emit_call(p, value, {}, ProcInlining_none); + } + + lb_end_procedure_body(p); + + if (!main_module->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) { + gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main"); + LLVMDumpValue(p->value); + gb_printf_err("\n\n\n\n"); + LLVMVerifyFunction(p->value, LLVMAbortProcessAction); + } + + return p; +} + + gb_internal WORKER_TASK_PROC(lb_generate_procedures_and_types_per_module) { lbModule *m = cast(lbModule *)data; for (Entity *e : m->global_procedures_and_types_to_create) { @@ -1328,6 +1356,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) { if (m == &m->gen->default_module) { lb_llvm_function_pass_per_function_internal(m, m->gen->startup_type_info); lb_llvm_function_pass_per_function_internal(m, m->gen->startup_runtime); + lb_llvm_function_pass_per_function_internal(m, m->gen->cleanup_runtime); lb_llvm_function_pass_per_function_internal(m, m->gen->objc_names); } @@ -1674,7 +1703,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading) -gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) { +gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime, lbProcedure *cleanup_runtime) { LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod); lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level); LLVMFinalizeFunctionPassManager(default_function_pass_manager); @@ -1793,7 +1822,7 @@ gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *star if (call_cleanup) { - lbValue cleanup_runtime_value = lb_find_runtime_value(m, str_lit("_cleanup_runtime")); + lbValue cleanup_runtime_value = {cleanup_runtime->value, cleanup_runtime->type}; lb_emit_call(p, cleanup_runtime_value, {}, ProcInlining_none); } @@ -2330,9 +2359,13 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { gen->startup_type_info = lb_create_startup_type_info(default_module); gen->objc_names = lb_create_objc_names(default_module); - TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables & @(init))"); gen->startup_runtime = lb_create_startup_runtime(default_module, gen->startup_type_info, gen->objc_names, global_variables); + TIME_SECTION("LLVM Runtime Cleanup Creation & @(fini)"); + gen->cleanup_runtime = lb_create_cleanup_runtime(default_module); + + if (build_context.ODIN_DEBUG) { for (auto const &entry : builtin_pkg->scope->elements) { Entity *e = entry.value; @@ -2352,7 +2385,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { if (build_context.command_kind == Command_test && !already_has_entry_point) { TIME_SECTION("LLVM main"); - lb_create_main_procedure(default_module, gen->startup_runtime); + lb_create_main_procedure(default_module, gen->startup_runtime, gen->cleanup_runtime); } TIME_SECTION("LLVM Procedure Generation (missing)"); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 7bf287b49..0b3bc2a5a 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -208,6 +208,7 @@ struct lbGenerator { lbProcedure *startup_type_info; lbProcedure *startup_runtime; + lbProcedure *cleanup_runtime; lbProcedure *objc_names; }; @@ -540,6 +541,7 @@ gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type); gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type); #define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime" +#define LB_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime" #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info" #define LB_TYPE_INFO_DATA_NAME "__$type_info_data" #define LB_TYPE_INFO_TYPES_NAME "__$type_info_types_data" -- cgit v1.2.3 From 8a2a70a3c2a7ac14687d100325e12b8d3d02256e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 17 Feb 2023 13:00:37 +0000 Subject: Fix overriding procedure information for literals --- src/check_decl.cpp | 17 +++++++++++++++++ src/check_expr.cpp | 4 +++- src/check_type.cpp | 12 ++++++++---- src/checker.cpp | 4 ++-- src/checker.hpp | 4 ++-- src/llvm_backend_const.cpp | 1 - src/llvm_backend_expr.cpp | 2 +- 7 files changed, 33 insertions(+), 11 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 63e6514e0..dc929cbca 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1480,6 +1480,23 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de ctx->curr_proc_sig = type; ctx->curr_proc_calling_convention = type->Proc.calling_convention; + if (ctx->proc_name == "sort") { + if (type->Proc.param_count > 0) { + TypeTuple *params = &type->Proc.params->Tuple; + for (Entity *e : params->variables) { + if (e->kind == Entity_Constant) { + Ast *ident = e->identifier.load(); + if (ident) { + add_entity(ctx, e->scope, ident, e); + ident->tav.mode = Addressing_Constant; + ident->tav.value = e->Constant.value; + ident->tav.type = e->type; + } + } + } + } + } + if (ctx->pkg->name != "runtime") { switch (type->Proc.calling_convention) { case ProcCC_None: diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 58372f7a3..93db559f8 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5418,7 +5418,9 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { data->score = score; data->result_type = final_proc_type->Proc.results; data->gen_entity = gen_entity; - add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); + if (!are_types_identical(final_proc_type, ce->proc->tav.type)) { + add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); + } } return err; diff --git a/src/check_type.cpp b/src/check_type.cpp index ec661134b..24ca8628e 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1666,17 +1666,21 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para if (is_poly_name) { bool valid = false; if (is_type_proc(op.type)) { - Entity *proc_entity = entity_from_expr(op.expr); - valid = (proc_entity != nullptr) && (op.value.kind == ExactValue_Procedure); - if (valid) { + Ast *expr = unparen_expr(op.expr); + Entity *proc_entity = entity_from_expr(expr); + if (proc_entity) { poly_const = exact_value_procedure(proc_entity->identifier.load() ? proc_entity->identifier.load() : op.expr); + valid = true; + } else if (expr->kind == Ast_ProcLit) { + poly_const = exact_value_procedure(expr); + valid = true; } } if (!valid) { if (op.mode == Addressing_Constant) { poly_const = op.value; } else { - error(op.expr, "Expected a constant value for this polymorphic name parameter"); + error(op.expr, "Expected a constant value for this polymorphic name parameter, got %s", expr_to_string(op.expr)); success = false; } } diff --git a/src/checker.cpp b/src/checker.cpp index 5163fe675..94bbb32e6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1416,7 +1416,7 @@ gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_f } -gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) { if (expr == nullptr) { return; } @@ -1433,7 +1433,7 @@ gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, check_set_expr_info(c, expr, mode, type, value); } -gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue value) { +gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) { if (expr == nullptr) { return; } diff --git a/src/checker.hpp b/src/checker.hpp index 4c3b8725a..b82612813 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -485,9 +485,9 @@ gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **s gb_internal Entity *scope_insert (Scope *s, Entity *entity); -gb_internal void add_type_and_value (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue value); +gb_internal void add_type_and_value (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue const &value); gb_internal ExprInfo *check_get_expr_info (CheckerContext *c, Ast *expr); -gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value); +gb_internal void add_untyped (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue const &value); gb_internal void add_entity_use (CheckerContext *c, Ast *identifier, Entity *entity); gb_internal void add_implicit_entity (CheckerContext *c, Ast *node, Entity *e); gb_internal void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true); diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index ee564bbf1..fc1598024 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -411,7 +411,6 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo Ast *expr = unparen_expr(value.value_procedure); if (expr->kind == Ast_ProcLit) { res = lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr); - } else { Entity *e = entity_from_expr(expr); res = lb_find_procedure_value_from_entity(m, e); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 7cf8d56db..480831a68 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -3138,7 +3138,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { Entity *e = entity_from_expr(expr); e = strip_entity_wrapping(e); - GB_ASSERT_MSG(e != nullptr, "%s", expr_to_string(expr)); + GB_ASSERT_MSG(e != nullptr, "%s in %.*s %p", expr_to_string(expr), LIT(p->name), expr); if (e->kind == Entity_Builtin) { Token token = ast_token(expr); GB_PANIC("TODO(bill): lb_build_expr Entity_Builtin '%.*s'\n" -- cgit v1.2.3 From c40b6c7c2fd8e193951087197c60a1359ad0002b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 17 Feb 2023 13:02:41 +0000 Subject: Add constant data to the identifier directly --- src/check_decl.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index dc929cbca..1adb1e2ed 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1480,23 +1480,6 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de ctx->curr_proc_sig = type; ctx->curr_proc_calling_convention = type->Proc.calling_convention; - if (ctx->proc_name == "sort") { - if (type->Proc.param_count > 0) { - TypeTuple *params = &type->Proc.params->Tuple; - for (Entity *e : params->variables) { - if (e->kind == Entity_Constant) { - Ast *ident = e->identifier.load(); - if (ident) { - add_entity(ctx, e->scope, ident, e); - ident->tav.mode = Addressing_Constant; - ident->tav.value = e->Constant.value; - ident->tav.type = e->type; - } - } - } - } - } - if (ctx->pkg->name != "runtime") { switch (type->Proc.calling_convention) { case ProcCC_None: @@ -1549,6 +1532,19 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de break; } } + + // Add constant data to the identifier directly + for (Entity *e : params->variables) { + if (e->kind == Entity_Constant) { + Ast *ident = e->identifier.load(); + if (ident) { + add_entity(ctx, e->scope, ident, e); + ident->tav.mode = Addressing_Constant; + ident->tav.value = e->Constant.value; + ident->tav.type = e->type; + } + } + } } } -- cgit v1.2.3 From 20eacc4a8493f0d0088ceebbcc1490207c48b5ed Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 19 Feb 2023 12:10:28 +0000 Subject: Fix issue that conflicts with constant parapoly procedures and `deferred_*` procedures --- src/check_decl.cpp | 13 ------------- src/check_expr.cpp | 5 ++--- 2 files changed, 2 insertions(+), 16 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 1adb1e2ed..63e6514e0 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1532,19 +1532,6 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de break; } } - - // Add constant data to the identifier directly - for (Entity *e : params->variables) { - if (e->kind == Entity_Constant) { - Ast *ident = e->identifier.load(); - if (ident) { - add_entity(ctx, e->scope, ident, e); - ident->tav.mode = Addressing_Constant; - ident->tav.value = e->Constant.value; - ident->tav.type = e->type; - } - } - } } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 93db559f8..356f0aaa3 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5418,9 +5418,8 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { data->score = score; data->result_type = final_proc_type->Proc.results; data->gen_entity = gen_entity; - if (!are_types_identical(final_proc_type, ce->proc->tav.type)) { - add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); - } + + add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {}); } return err; -- cgit v1.2.3 From f5d507a9b9d20941bd86ba8559f710f21f0c8ccd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 22 Feb 2023 11:30:08 +0000 Subject: Improve errors about conversions of constant integers --- src/check_decl.cpp | 2 +- src/check_expr.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++------ src/error.cpp | 33 ++++++++++++++++++++++------- 3 files changed, 82 insertions(+), 15 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 63e6514e0..7978aa0ef 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -578,7 +578,7 @@ gb_internal void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr if (operand.mode == Addressing_Invalid || base_type(operand.type) == t_invalid) { gbString str = expr_to_string(init); - error(e->token, "Invalid declaration type '%s'", str); + error(init, "Invalid declaration value '%s'", str); gb_string_free(str); } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c0920bde8..d7e7b29a4 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2019,6 +2019,47 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i } +gb_internal bool check_integer_exceed_suggestion(CheckerContext *c, Operand *o, Type *type) { + if (is_type_integer(type) && o->value.kind == ExactValue_Integer) { + gbString b = type_to_string(type); + + i64 sz = type_size_of(type); + BigInt *bi = &o->value.value_integer; + if (is_type_unsigned(type)) { + if (big_int_is_neg(bi)) { + error_line("\tA negative value cannot be represented by the unsigned integer type '%s'\n", b); + } else { + BigInt one = big_int_make_u64(1); + BigInt max_size = big_int_make_u64(1); + BigInt bits = big_int_make_i64(8*sz); + big_int_shl_eq(&max_size, &bits); + big_int_sub_eq(&max_size, &one); + String max_size_str = big_int_to_string(temporary_allocator(), &max_size); + error_line("\tThe maximum value that can be represented by '%s' is '%.*s'\n", b, LIT(max_size_str)); + } + } else { + BigInt zero = big_int_make_u64(0); + BigInt one = big_int_make_u64(1); + BigInt max_size = big_int_make_u64(1); + BigInt bits = big_int_make_i64(8*sz - 1); + big_int_shl_eq(&max_size, &bits); + if (big_int_is_neg(bi)) { + big_int_neg(&max_size, &max_size); + String max_size_str = big_int_to_string(temporary_allocator(), &max_size); + error_line("\tThe minimum value that can be represented by '%s' is '%.*s'\n", b, LIT(max_size_str)); + } else { + big_int_sub_eq(&max_size, &one); + String max_size_str = big_int_to_string(temporary_allocator(), &max_size); + error_line("\tThe maximum value that can be represented by '%s' is '%.*s'\n", b, LIT(max_size_str)); + } + } + + gb_string_free(b); + + return true; + } + return false; +} gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); @@ -2050,6 +2091,8 @@ gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o error_line("\t whereas slices in general are assumed to be mutable.\n"); } else if (is_type_u8_slice(src) && are_types_identical(dst, t_string) && o->mode != Addressing_Constant) { error_line("\tSuggestion: the expression may be casted to %s\n", b); + } else if (check_integer_exceed_suggestion(c, o, type)) { + return; } } @@ -2089,8 +2132,8 @@ gb_internal void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type } } else if (are_types_identical(src, t_string) && is_type_u8_slice(dst)) { error_line("\tSuggestion: a string may be transmuted to %s\n", b); - } else if (is_type_u8_slice(src) && are_types_identical(dst, t_string) && o->mode != Addressing_Constant) { - error_line("\tSuggestion: the expression may be casted to %s\n", b); + } else if (check_integer_exceed_suggestion(c, o, type)) { + return; } } @@ -2124,10 +2167,11 @@ gb_internal bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *typ error(o->expr, "'%s' truncated to '%s', got %s", a, b, s); } else { if (are_types_identical(o->type, type)) { - error(o->expr, "Numeric value '%s' cannot be represented by '%s', got %s", a, c, s); + error(o->expr, "Numeric value '%s' from '%s' cannot be represented by '%s'", s, a, b); } else { - error(o->expr, "Cannot convert numeric value '%s' to '%s' from '%s', got %s", a, b, c, s); + error(o->expr, "Cannot convert numeric value '%s' from '%s' to '%s' from '%s'", s, a, b, c); } + check_assignment_error_suggestion(ctx, o, type); } } else { @@ -2934,15 +2978,21 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { if (is_const_expr) { gbString val_str = exact_value_to_string(x->value); if (is_type_float(x->type) && is_type_integer(type)) { - error_line("\t%s cannot be expressed without truncation/rounding as the type '%s'\n", val_str, to_type); + error_line("\t%s cannot be represented without truncation/rounding as the type '%s'\n", val_str, to_type); // NOTE(bill): keep the mode and modify the type to minimize errors further on x->mode = Addressing_Constant; x->type = type; } else { - error_line("\t%s cannot be expressed as the type '%s'\n", val_str, to_type); + error_line("\t'%s' cannot be represented as the type '%s'\n", val_str, to_type); + if (is_type_numeric(type)) { + // NOTE(bill): keep the mode and modify the type to minimize errors further on + x->mode = Addressing_Constant; + x->type = type; + } } gb_string_free(val_str); + } check_cast_error_suggestion(c, x, type); diff --git a/src/error.cpp b/src/error.cpp index a0bb4ad5b..33157948f 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -97,15 +97,37 @@ gb_internal AstFile *thread_safe_get_ast_file_from_id(i32 index) { +// NOTE: defined in build_settings.cpp +gb_internal bool global_warnings_as_errors(void); +gb_internal bool global_ignore_warnings(void); +gb_internal bool show_error_line(void); +gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); + +gb_internal void warning(Token const &token, char const *fmt, ...); +gb_internal void error(Token const &token, char const *fmt, ...); +gb_internal void error(TokenPos pos, char const *fmt, ...); +gb_internal void error_line(char const *fmt, ...); +gb_internal void syntax_error(Token const &token, char const *fmt, ...); +gb_internal void syntax_error(TokenPos pos, char const *fmt, ...); +gb_internal void syntax_warning(Token const &token, char const *fmt, ...); +gb_internal void compiler_error(char const *fmt, ...); + gb_internal void begin_error_block(void) { mutex_lock(&global_error_collector.block_mutex); global_error_collector.in_block.store(true); } gb_internal void end_error_block(void) { - if (global_error_collector.error_buffer.count > 0) { - isize n = global_error_collector.error_buffer.count; - u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); + isize n = global_error_collector.error_buffer.count; + if (n > 0) { + u8 *text = global_error_collector.error_buffer.data; + if (show_error_line() && n >= 2 && !(text[n-2] == '\n' && text[n-1] == '\n')) { + // add an extra new line as padding when the error line is being shown + error_line("\n"); + } + + n = global_error_collector.error_buffer.count; + text = gb_alloc_array(permanent_allocator(), u8, n+1); gb_memmove(text, global_error_collector.error_buffer.data, n); text[n] = 0; String s = {text, n}; @@ -152,11 +174,6 @@ gb_internal ERROR_OUT_PROC(default_error_out_va) { gb_global ErrorOutProc *error_out_va = default_error_out_va; -// NOTE: defined in build_settings.cpp -gb_internal bool global_warnings_as_errors(void); -gb_internal bool global_ignore_warnings(void); -gb_internal bool show_error_line(void); -gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); gb_internal void error_out(char const *fmt, ...) { va_list va; -- cgit v1.2.3 From 5f3b6c9722007d731193a90f97e566127120f6ed Mon Sep 17 00:00:00 2001 From: bumbread Date: Mon, 13 Mar 2023 20:25:13 +1100 Subject: Added -no-tls flag --- src/build_settings.cpp | 1 + src/check_decl.cpp | 5 ++++- src/main.cpp | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/check_decl.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 9aee03676..1ca537c01 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -275,6 +275,7 @@ struct BuildContext { bool no_output_files; bool no_crt; bool no_entry_point; + bool no_tls; bool use_lld; bool vet; bool vet_extra; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 7978aa0ef..828009b3d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1143,9 +1143,12 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) { e->Variable.thread_local_model.len = 0; - // NOTE(bill): ignore this message for the time begin + // NOTE(bill): ignore this message for the time being // error(e->token, "@(thread_local) is not supported for this target platform"); } + if(build_context.no_tls) { + e->Variable.thread_local_model.len = 0; + } String context_name = str_lit("variable declaration"); diff --git a/src/main.cpp b/src/main.cpp index 066675b36..66d860bc0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -634,6 +634,7 @@ enum BuildFlagKind { BuildFlag_Microarch, BuildFlag_TargetFeatures, BuildFlag_MinimumOSVersion, + BuildFlag_NoTLS, BuildFlag_RelocMode, BuildFlag_DisableRedZone, @@ -794,6 +795,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoTLS, str_lit("no-tls"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); @@ -1312,6 +1314,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_NoEntryPoint: build_context.no_entry_point = true; break; + case BuildFlag_NoTLS: + build_context.no_tls = true; + break; case BuildFlag_UseLLD: build_context.use_lld = true; break; @@ -2064,6 +2069,10 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Disables automatic linking with the C Run Time"); print_usage_line(0, ""); + print_usage_line(1, "-no-tls"); + print_usage_line(2, "Ignore @thread_local attribute, effectively treating the program as if it is single-threaded"); + print_usage_line(0, ""); + print_usage_line(1, "-lld"); print_usage_line(2, "Use the LLD linker rather than the default"); print_usage_line(0, ""); -- cgit v1.2.3 From 5134d6bc63cf39cc987bf5a11a724ad3db69a0a1 Mon Sep 17 00:00:00 2001 From: bumbread Date: Tue, 14 Mar 2023 16:32:42 +1100 Subject: rename -no-tls to -no-thread-local --- src/build_settings.cpp | 2 +- src/check_decl.cpp | 2 +- src/main.cpp | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 1ca537c01..c97973753 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -275,7 +275,7 @@ struct BuildContext { bool no_output_files; bool no_crt; bool no_entry_point; - bool no_tls; + bool no_thread_local; bool use_lld; bool vet; bool vet_extra; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 828009b3d..5c25dd6a3 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1146,7 +1146,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast // NOTE(bill): ignore this message for the time being // error(e->token, "@(thread_local) is not supported for this target platform"); } - if(build_context.no_tls) { + if(build_context.no_thread_local) { e->Variable.thread_local_model.len = 0; } diff --git a/src/main.cpp b/src/main.cpp index 66d860bc0..9a2a1ebf8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -634,7 +634,7 @@ enum BuildFlagKind { BuildFlag_Microarch, BuildFlag_TargetFeatures, BuildFlag_MinimumOSVersion, - BuildFlag_NoTLS, + BuildFlag_NoThreadLocal, BuildFlag_RelocMode, BuildFlag_DisableRedZone, @@ -795,7 +795,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_NoTLS, str_lit("no-tls"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoThreadLocal, str_lit("no-thread-local"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); @@ -1314,8 +1314,8 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_NoEntryPoint: build_context.no_entry_point = true; break; - case BuildFlag_NoTLS: - build_context.no_tls = true; + case BuildFlag_NoThreadLocal: + build_context.no_thread_local = true; break; case BuildFlag_UseLLD: build_context.use_lld = true; @@ -2069,7 +2069,7 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Disables automatic linking with the C Run Time"); print_usage_line(0, ""); - print_usage_line(1, "-no-tls"); + print_usage_line(1, "-no-thread-local"); print_usage_line(2, "Ignore @thread_local attribute, effectively treating the program as if it is single-threaded"); print_usage_line(0, ""); -- cgit v1.2.3 From 5da76ae34bac2f54b1bda5528cf49c0551e88bba Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Apr 2023 15:36:21 +0100 Subject: Add `struct #no_copy` --- core/runtime/core.odin | 1 + src/check_decl.cpp | 8 ++++++++ src/check_expr.cpp | 20 ++++++++++++++++++++ src/check_stmt.cpp | 4 +++- src/check_type.cpp | 5 +++-- src/llvm_backend_type.cpp | 16 +++++++++------- src/parser.cpp | 11 +++++++++-- src/parser.hpp | 1 + src/types.cpp | 7 +++++++ 9 files changed, 61 insertions(+), 12 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 040590b4a..9939bfc5c 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -119,6 +119,7 @@ Type_Info_Struct :: struct { tags: []string, is_packed: bool, is_raw_union: bool, + is_no_copy: bool, custom_align: bool, equal: Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 5c25dd6a3..5a8080f96 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -131,6 +131,14 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l if (d != nullptr) { d->init_expr = o->expr; } + + if (o->type && is_type_no_copy(o->type)) { + begin_error_block(); + if (check_no_copy_assignment(*o, str_lit("initialization"))) { + error_line("\tInitialization of a #no_copy type must be either implicitly zero, a constant literal, or from a return value a call expression"); + } + end_error_block(); + } } if (rhs_count > 0 && lhs_count != rhs_count) { error(lhs[0]->token, "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f27675301..e55765ff8 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5043,6 +5043,21 @@ gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lh return tuple_count; } +gb_internal bool check_no_copy_assignment(Operand const &o, String const &context) { + if (o.type && is_type_no_copy(o.type)) { + Ast *expr = unparen_expr(o.expr); + if (expr && o.mode != Addressing_Constant) { + if (expr->kind == Ast_CallExpr) { + // Okay + } else { + error(o.expr, "Invalid use a #no_copy value in %.*s", LIT(context)); + return true; + } + } + } + return false; +} + gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { bool optional_ok = false; @@ -5114,6 +5129,7 @@ gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array for (Entity *e : tuple->variables) { o.type = e->type; array_add(operands, o); + check_no_copy_assignment(o, str_lit("assignment")); } tuple_index += tuple->variables.count; @@ -5952,6 +5968,10 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op } } + for (Operand const &o : operands) { + check_no_copy_assignment(o, str_lit("call expression")); + } + if (operand->mode == Addressing_ProcGroup) { check_entity_decl(c, operand->proc_group, nullptr, nullptr); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4e6623fc1..388a64e00 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -326,7 +326,6 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) { - gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) { if (rhs->mode == Addressing_Invalid) { return nullptr; @@ -339,6 +338,8 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O Ast *node = unparen_expr(lhs->expr); + check_no_copy_assignment(*rhs, str_lit("assignment")); + // NOTE(bill): Ignore assignments to '_' if (is_blank_ident(node)) { check_assignment(ctx, rhs, nullptr, str_lit("assignment to '_' identifier")); @@ -400,6 +401,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O } Type *assignment_type = lhs->type; + switch (lhs->mode) { case Addressing_Invalid: return nullptr; diff --git a/src/check_type.cpp b/src/check_type.cpp index 7444f88be..b687e838e 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -609,8 +609,9 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast * context = str_lit("struct #raw_union"); } - struct_type->Struct.scope = ctx->scope; - struct_type->Struct.is_packed = st->is_packed; + struct_type->Struct.scope = ctx->scope; + struct_type->Struct.is_packed = st->is_packed; + struct_type->Struct.is_no_copy = st->is_no_copy; struct_type->Struct.polymorphic_params = check_record_polymorphic_params( ctx, st->polymorphic_params, &struct_type->Struct.is_polymorphic, diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index e8d286fda..3af10112f 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -691,32 +691,34 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup case Type_Struct: { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_struct_ptr); - LLVMValueRef vals[12] = {}; + LLVMValueRef vals[13] = {}; { lbValue is_packed = lb_const_bool(m, t_bool, t->Struct.is_packed); lbValue is_raw_union = lb_const_bool(m, t_bool, t->Struct.is_raw_union); + lbValue is_no_copy = lb_const_bool(m, t_bool, t->Struct.is_no_copy); lbValue is_custom_align = lb_const_bool(m, t_bool, t->Struct.custom_align != 0); vals[5] = is_packed.value; vals[6] = is_raw_union.value; - vals[7] = is_custom_align.value; + vals[7] = is_no_copy.value; + vals[8] = is_custom_align.value; if (is_type_comparable(t) && !is_type_simple_compare(t)) { - vals[8] = lb_equal_proc_for_type(m, t).value; + vals[9] = lb_equal_proc_for_type(m, t).value; } if (t->Struct.soa_kind != StructSoa_None) { - lbValue kind = lb_emit_struct_ep(p, tag, 9); + lbValue kind = lb_emit_struct_ep(p, tag, 10); Type *kind_type = type_deref(kind.type); lbValue soa_kind = lb_const_value(m, kind_type, exact_value_i64(t->Struct.soa_kind)); lbValue soa_type = lb_type_info(m, t->Struct.soa_elem); lbValue soa_len = lb_const_int(m, t_int, t->Struct.soa_count); - vals[9] = soa_kind.value; - vals[10] = soa_type.value; - vals[11] = soa_len.value; + vals[10] = soa_kind.value; + vals[11] = soa_type.value; + vals[12] = soa_len.value; } } diff --git a/src/parser.cpp b/src/parser.cpp index 50a9ba766..790e67db6 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1047,7 +1047,7 @@ gb_internal Ast *ast_dynamic_array_type(AstFile *f, Token token, Ast *elem) { } gb_internal Ast *ast_struct_type(AstFile *f, Token token, Slice fields, isize field_count, - Ast *polymorphic_params, bool is_packed, bool is_raw_union, + Ast *polymorphic_params, bool is_packed, bool is_raw_union, bool is_no_copy, Ast *align, Token where_token, Array const &where_clauses) { Ast *result = alloc_ast_node(f, Ast_StructType); @@ -1057,6 +1057,7 @@ gb_internal Ast *ast_struct_type(AstFile *f, Token token, Slice fields, i result->StructType.polymorphic_params = polymorphic_params; result->StructType.is_packed = is_packed; result->StructType.is_raw_union = is_raw_union; + result->StructType.is_no_copy = is_no_copy; result->StructType.align = align; result->StructType.where_token = where_token; result->StructType.where_clauses = slice_from_array(where_clauses); @@ -2392,6 +2393,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { Ast *polymorphic_params = nullptr; bool is_packed = false; bool is_raw_union = false; + bool no_copy = false; Ast *align = nullptr; if (allow_token(f, Token_OpenParen)) { @@ -2427,6 +2429,11 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string)); } is_raw_union = true; + } else if (tag.string == "no_copy") { + if (is_packed) { + syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string)); + } + no_copy = true; } else { syntax_error(tag, "Invalid struct tag '#%.*s'", LIT(tag.string)); } @@ -2465,7 +2472,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { decls = fields->FieldList.list; } - return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, align, where_token, where_clauses); + return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, no_copy, align, where_token, where_clauses); } break; case Token_union: { diff --git a/src/parser.hpp b/src/parser.hpp index 5e1878cf2..5302fd274 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -693,6 +693,7 @@ AST_KIND(_TypeBegin, "", bool) \ Slice where_clauses; \ bool is_packed; \ bool is_raw_union; \ + bool is_no_copy; \ }) \ AST_KIND(UnionType, "union type", struct { \ Scope *scope; \ diff --git a/src/types.cpp b/src/types.cpp index 5addb5b7b..889269564 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -149,6 +149,7 @@ struct TypeStruct { bool are_offsets_being_processed : 1; bool is_packed : 1; bool is_raw_union : 1; + bool is_no_copy : 1; bool is_poly_specialized : 1; }; @@ -1670,6 +1671,10 @@ gb_internal bool is_type_raw_union(Type *t) { t = base_type(t); return (t->kind == Type_Struct && t->Struct.is_raw_union); } +gb_internal bool is_type_no_copy(Type *t) { + t = base_type(t); + return (t->kind == Type_Struct && t->Struct.is_no_copy); +} gb_internal bool is_type_enum(Type *t) { t = base_type(t); return (t->kind == Type_Enum); @@ -2655,6 +2660,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple case Type_Struct: if (x->Struct.is_raw_union == y->Struct.is_raw_union && + x->Struct.is_no_copy == y->Struct.is_no_copy && x->Struct.fields.count == y->Struct.fields.count && x->Struct.is_packed == y->Struct.is_packed && x->Struct.custom_align == y->Struct.custom_align && @@ -4207,6 +4213,7 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha str = gb_string_appendc(str, "struct"); if (type->Struct.is_packed) str = gb_string_appendc(str, " #packed"); if (type->Struct.is_raw_union) str = gb_string_appendc(str, " #raw_union"); + if (type->Struct.is_no_copy) str = gb_string_appendc(str, " #no_copy"); if (type->Struct.custom_align != 0) str = gb_string_append_fmt(str, " #align %d", cast(int)type->Struct.custom_align); str = gb_string_appendc(str, " {"); -- cgit v1.2.3 From e24315eed892aeb6c53da78c415455a80ccdf5e5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Apr 2023 16:16:16 +0100 Subject: Improve grammar --- src/check_decl.cpp | 2 +- src/check_expr.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 5a8080f96..a984f87a3 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -135,7 +135,7 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l if (o->type && is_type_no_copy(o->type)) { begin_error_block(); if (check_no_copy_assignment(*o, str_lit("initialization"))) { - error_line("\tInitialization of a #no_copy type must be either implicitly zero, a constant literal, or from a return value a call expression"); + error_line("\tInitialization of a #no_copy type must be either implicitly zero, a constant literal, or a return value from a call expression"); } end_error_block(); } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e55765ff8..de9a6b911 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5050,7 +5050,7 @@ gb_internal bool check_no_copy_assignment(Operand const &o, String const &contex if (expr->kind == Ast_CallExpr) { // Okay } else { - error(o.expr, "Invalid use a #no_copy value in %.*s", LIT(context)); + error(o.expr, "Invalid use of #no_copy value in %.*s", LIT(context)); return true; } } -- cgit v1.2.3 From 56c0d32ea0c81ad9913e4e512952b3be25688504 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 18 May 2023 11:52:16 +0100 Subject: Fix #2526 --- src/check_decl.cpp | 12 ++++++++---- src/check_stmt.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index a984f87a3..e97e86e8b 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -43,14 +43,20 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o } if (operand->mode == Addressing_Type) { - if (e->type != nullptr && is_type_typeid(e->type)) { + if (e->type != nullptr && is_type_typeid(e->type) && !is_type_polymorphic(operand->type)) { add_type_info_type(ctx, operand->type); add_type_and_value(ctx, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type)); return e->type; } else { + ERROR_BLOCK(); + gbString t = type_to_string(operand->type); defer (gb_string_free(t)); - error(operand->expr, "Cannot assign a type '%s' to variable '%.*s'", t, LIT(e->token.string)); + if (is_type_polymorphic(operand->type)) { + error(operand->expr, "Cannot assign a non-specialized polymorphic type '%s' to variable '%.*s'", t, LIT(e->token.string)); + } else { + 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)); } @@ -59,8 +65,6 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o } } - - if (e->type == nullptr) { // NOTE(bill): Use the type of the operand diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 388a64e00..1e3b35c21 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -402,6 +402,12 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O Type *assignment_type = lhs->type; + if (rhs->mode == Addressing_Type && is_type_polymorphic(rhs->type)) { + gbString t = type_to_string(rhs->type); + error(rhs->expr, "Invalid use of a non-specialized polymorphic type '%s'", t); + gb_string_free(t); + } + switch (lhs->mode) { case Addressing_Invalid: return nullptr; -- cgit v1.2.3 From d5a8f2298e68c64f2f9e2fe5d0c6ab528db627a8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 22 May 2023 12:37:26 +0100 Subject: Restrict `---` to variable declarations only --- src/check_decl.cpp | 2 +- src/check_expr.cpp | 31 +++++++++++++++++++++++++------ src/check_stmt.cpp | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index e97e86e8b..b16215571 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -123,7 +123,7 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l // an extra allocation TEMPORARY_ALLOCATOR_GUARD(); auto operands = array_make(temporary_allocator(), 0, 2*lhs_count); - check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false); + check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, UnpackFlag_AllowOk|UnpackFlag_AllowUndef); isize rhs_count = operands.count; isize max = gb_min(lhs_count, rhs_count); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1552b1ef5..e0e74a3aa 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5144,8 +5144,20 @@ gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array } +typedef u32 UnpackFlags; +enum UnpackFlag : u32 { + UnpackFlag_None = 0, + UnpackFlag_AllowOk = 1<<0, + UnpackFlag_IsVariadic = 1<<1, + UnpackFlag_AllowUndef = 1<<2, +}; + + +gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, UnpackFlags flags) { + bool allow_ok = (flags & UnpackFlag_AllowOk) != 0; + bool is_variadic = (flags & UnpackFlag_IsVariadic) != 0; + bool allow_undef = (flags & UnpackFlag_AllowUndef) != 0; -gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -5184,7 +5196,13 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize } } - check_expr_base(c, &o, rhs[i], type_hint); + if (allow_undef && rhs[i] != nullptr && rhs[i]->kind == Ast_Undef) { + o.type = t_untyped_undef; + o.mode = Addressing_Value; + o.expr = rhs[i]; + } else { + check_expr_base(c, &o, rhs[i], type_hint); + } if (o.mode == Addressing_NoValue) { error_operand_no_value(&o); o.mode = Addressing_Invalid; @@ -5968,7 +5986,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op lhs = populate_proc_parameter_list(c, proc_type, &lhs_count, &is_variadic); } if (operand->mode != Addressing_ProcGroup) { - check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, is_variadic); + check_unpack_arguments(c, lhs, lhs_count, &operands, args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); } } @@ -6025,7 +6043,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op isize lhs_count = -1; bool is_variadic = false; lhs = populate_proc_parameter_list(c, e->type, &lhs_count, &is_variadic); - check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, is_variadic); + check_unpack_arguments(c, lhs, lhs_count, &operands, args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); CallArgumentData data = {}; CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &data); @@ -6101,7 +6119,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op } - check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, false); + check_unpack_arguments(c, lhs, lhs_count, &operands, args, UnpackFlag_None); if (lhs != nullptr) { gb_free(heap_allocator(), lhs); @@ -6462,7 +6480,7 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O lhs_count = params->variables.count; } - check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, false); + check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, UnpackFlag_None); } } @@ -9583,6 +9601,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast case_ast_node(u, Undef, node); o->mode = Addressing_Value; o->type = t_untyped_undef; + error(node, "Use of --- outside of variable declaration"); case_end; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 1e3b35c21..6c69ad59f 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -2176,7 +2176,7 @@ gb_internal void check_return_stmt(CheckerContext *ctx, Ast *node) { auto operands = array_make(heap_allocator(), 0, 2*rs->results.count); defer (array_free(&operands)); - check_unpack_arguments(ctx, result_entities, result_count, &operands, rs->results, true, false); + check_unpack_arguments(ctx, result_entities, result_count, &operands, rs->results, UnpackFlag_AllowOk); if (result_count == 0 && rs->results.count > 0) { error(rs->results[0], "No return values expected"); -- cgit v1.2.3 From 8bf32ac697ea21ff3b37e5b31fe0fc10e700c9a4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 22 May 2023 12:53:29 +0100 Subject: Minor change to handling of propagation of errors with `---` as a value --- src/check_decl.cpp | 9 ++++----- src/check_expr.cpp | 45 +++++++++++++++++++++----------------------- src/check_type.cpp | 6 +++--- src/checker.cpp | 4 ++-- src/llvm_backend.cpp | 10 ++-------- src/llvm_backend_const.cpp | 2 +- src/llvm_backend_debug.cpp | 2 +- src/llvm_backend_expr.cpp | 16 ++++++++-------- src/llvm_backend_general.cpp | 4 ++-- src/llvm_backend_proc.cpp | 8 ++++---- src/parser.cpp | 14 +++++++------- src/parser.hpp | 2 +- src/parser_pos.cpp | 4 ++-- src/tokenizer.cpp | 6 +++--- src/types.cpp | 19 ++++++++----------- 15 files changed, 69 insertions(+), 82 deletions(-) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index b16215571..84b0d39d8 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -70,13 +70,12 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o // NOTE(bill): Use the type of the operand Type *t = operand->type; if (is_type_untyped(t)) { - if (t == t_invalid || is_type_untyped_nil(t)) { - error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name)); + if (is_type_untyped_uninit(t)) { + error(e->token, "Invalid use of --- in %.*s", LIT(context_name)); e->type = t_invalid; return nullptr; - } - if (t == t_invalid || is_type_untyped_undef(t)) { - error(e->token, "Invalid use of --- in %.*s", LIT(context_name)); + } else if (t == t_invalid || is_type_untyped_nil(t)) { + error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name)); e->type = t_invalid; return nullptr; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 20a690e1e..830b5315d 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -646,11 +646,8 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand Type *src = base_type(s); Type *dst = base_type(type); - if (is_type_untyped_undef(src)) { - if (type_has_undef(dst)) { - return 1; - } - return -1; + if (is_type_untyped_uninit(src)) { + return 1; } if (is_type_untyped_nil(src)) { @@ -993,13 +990,13 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ if (is_type_untyped(operand->type)) { Type *target_type = type; if (type == nullptr || is_type_any(type)) { - if (type == nullptr && is_type_untyped_nil(operand->type)) { - error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name)); + if (type == nullptr && is_type_untyped_uninit(operand->type)) { + error(operand->expr, "Use of --- in %.*s", LIT(context_name)); operand->mode = Addressing_Invalid; return; } - if (type == nullptr && is_type_untyped_undef(operand->type)) { - error(operand->expr, "Use of --- in %.*s", LIT(context_name)); + if (type == nullptr && is_type_untyped_nil(operand->type)) { + error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name)); operand->mode = Addressing_Invalid; return; } @@ -3969,7 +3966,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar case Type_Union: - if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) { + if (!is_operand_nil(*operand) && !is_operand_uninit(*operand)) { TEMPORARY_ALLOCATOR_GUARD(); isize count = t->Union.variants.count; @@ -4036,8 +4033,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar error_line("\n\n"); return; - } else if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) { - target_type = t_untyped_undef; + } else if (is_type_untyped_uninit(operand->type)) { + target_type = t_untyped_uninit; } else if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) { begin_error_block(); defer (end_error_block()); @@ -4070,8 +4067,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar default: - if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) { - target_type = t_untyped_undef; + if (is_type_untyped_uninit(operand->type)) { + target_type = t_untyped_uninit; } else if (is_type_untyped_nil(operand->type) && type_has_nil(target_type)) { target_type = t_untyped_nil; } else { @@ -4083,8 +4080,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar } if (is_type_any(target_type) && is_type_untyped(operand->type)) { - if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) { - + if (is_type_untyped_nil(operand->type) && is_type_untyped_uninit(operand->type)) { + } else { target_type = default_type(operand->type); } @@ -5197,9 +5194,9 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize } Ast *rhs_expr = unparen_expr(rhs[i]); - if (allow_undef && rhs_expr != nullptr && rhs_expr->kind == Ast_Undef) { + if (allow_undef && rhs_expr != nullptr && rhs_expr->kind == Ast_Uninit) { // NOTE(bill): Just handle this very specific logic here - o.type = t_untyped_undef; + o.type = t_untyped_uninit; o.mode = Addressing_Value; o.expr = rhs[i]; add_type_and_value(c, rhs[i], o.mode, o.type, o.value); @@ -7167,11 +7164,11 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 } gb_internal bool ternary_compare_types(Type *x, Type *y) { - if (is_type_untyped_undef(x) && type_has_undef(y)) { + if (is_type_untyped_uninit(x)) { return true; } else if (is_type_untyped_nil(x) && type_has_nil(y)) { return true; - } else if (is_type_untyped_undef(y) && type_has_undef(x)) { + } else if (is_type_untyped_uninit(y)) { return true; } else if (is_type_untyped_nil(y) && type_has_nil(x)) { return true; @@ -7708,7 +7705,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n } o->type = x.type; - if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { + if (is_type_untyped_nil(o->type) || is_type_untyped_uninit(o->type)) { o->type = y.type; } @@ -9601,9 +9598,9 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast check_ident(c, o, node, nullptr, type_hint, false); case_end; - case_ast_node(u, Undef, node); + case_ast_node(u, Uninit, node); o->mode = Addressing_Value; - o->type = t_untyped_undef; + o->type = t_untyped_uninit; error(node, "Use of --- outside of variable declaration"); case_end; @@ -10167,7 +10164,7 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan str = string_append_string(str, bd->name.string); case_end; - case_ast_node(ud, Undef, node); + case_ast_node(ud, Uninit, node); str = gb_string_appendc(str, "---"); case_end; diff --git a/src/check_type.cpp b/src/check_type.cpp index dfe774f6b..bbfc25a12 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -135,7 +135,7 @@ gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slicemodule, var.var); - if (is_type_untyped_undef(init.type)) { - // LLVMSetInitializer(var.var.value, LLVMGetUndef(global_type)); - LLVMSetInitializer(var.var.value, LLVMConstNull(global_type)); - var.is_initialized = true; - continue; - } else if (is_type_untyped_nil(init.type)) { + if (is_type_untyped_nil(init.type)) { LLVMSetInitializer(var.var.value, LLVMConstNull(global_type)); var.is_initialized = true; continue; @@ -2363,8 +2358,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { } } } - if (!var.is_initialized && - (is_type_untyped_nil(tav.type) || is_type_untyped_undef(tav.type))) { + if (!var.is_initialized && is_type_untyped_nil(tav.type)) { var.is_initialized = true; } } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 8db6e2a1f..ea25a4594 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -1,6 +1,6 @@ gb_internal bool lb_is_const(lbValue value) { LLVMValueRef v = value.value; - if (is_type_untyped_nil(value.type) || is_type_untyped_undef(value.type)) { + if (is_type_untyped_nil(value.type)) { // TODO(bill): Is this correct behaviour? return true; } diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index fd26c41a0..bec719a4a 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -282,7 +282,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break; case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break; case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break; - case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break; + case Basic_UntypedUninit: GB_PANIC("Basic_UntypedUninit"); break; default: GB_PANIC("Basic Unhandled"); break; } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 69443c9a3..143e38a8d 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1486,12 +1486,12 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { GB_ASSERT(src != nullptr); GB_ASSERT(dst != nullptr); + if (is_type_untyped_uninit(src)) { + return lb_const_undef(m, t); + } if (is_type_untyped_nil(src)) { return lb_const_nil(m, t); } - if (is_type_untyped_undef(src)) { - return lb_const_undef(m, t); - } if (LLVMIsConstant(value.value)) { if (is_type_any(dst)) { @@ -2132,12 +2132,12 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (is_type_any(dst)) { + if (is_type_untyped_uninit(src)) { + return lb_const_undef(p->module, t); + } if (is_type_untyped_nil(src)) { return lb_const_nil(p->module, t); } - if (is_type_untyped_undef(src)) { - return lb_const_undef(p->module, t); - } lbAddr result = lb_add_local_generated(p, t, true); @@ -3136,11 +3136,11 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { return lb_addr_load(p, lb_build_addr(p, expr)); case_end; - case_ast_node(u, Undef, expr) + case_ast_node(u, Uninit, expr) lbValue res = {}; if (is_type_untyped(type)) { res.value = nullptr; - res.type = t_untyped_undef; + res.type = t_untyped_uninit; } else { res.value = LLVMGetUndef(lb_type(m, type)); res.type = type; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 7d2f574fe..628c1e5fa 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -677,7 +677,7 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { return; } GB_ASSERT(value.type != nullptr); - if (is_type_untyped_undef(value.type)) { + if (is_type_untyped_uninit(value.type)) { Type *t = lb_addr_type(addr); value.type = t; value.value = LLVMGetUndef(lb_type(p->module, t)); @@ -1828,7 +1828,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break; case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break; case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break; - case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break; + case Basic_UntypedUninit: GB_PANIC("Basic_UntypedUninit"); break; } break; case Type_Named: diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index ddf058668..b8353a466 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -3218,10 +3218,10 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { Entity *e = params->variables[i]; if (args[i].type == nullptr) { continue; + } else if (is_type_untyped_uninit(args[i].type)) { + args[i] = lb_const_undef(m, e->type); } else if (is_type_untyped_nil(args[i].type)) { args[i] = lb_const_nil(m, e->type); - } else if (is_type_untyped_undef(args[i].type)) { - args[i] = lb_const_undef(m, e->type); } } @@ -3409,10 +3409,10 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { Entity *e = param_tuple->variables[i]; if (args[i].type == nullptr) { continue; + } else if (is_type_untyped_uninit(args[i].type)) { + args[i] = lb_const_undef(m, e->type); } else if (is_type_untyped_nil(args[i].type)) { args[i] = lb_const_nil(m, e->type); - } else if (is_type_untyped_undef(args[i].type)) { - args[i] = lb_const_undef(m, e->type); } } } diff --git a/src/parser.cpp b/src/parser.cpp index 698ba99ab..bb492fca9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -115,7 +115,7 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->Ident.entity = nullptr; break; case Ast_Implicit: break; - case Ast_Undef: break; + case Ast_Uninit: break; case Ast_BasicLit: break; case Ast_BasicDirective: break; @@ -646,9 +646,9 @@ gb_internal Ast *ast_implicit(AstFile *f, Token token) { result->Implicit = token; return result; } -gb_internal Ast *ast_undef(AstFile *f, Token token) { - Ast *result = alloc_ast_node(f, Ast_Undef); - result->Undef = token; +gb_internal Ast *ast_uninit(AstFile *f, Token token) { + Ast *result = alloc_ast_node(f, Ast_Uninit); + result->Uninit = token; return result; } @@ -2092,8 +2092,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { case Token_Ident: return parse_ident(f); - case Token_Undef: - return ast_undef(f, expect_token(f, Token_Undef)); + case Token_Uninit: + return ast_uninit(f, expect_token(f, Token_Uninit)); case Token_context: return ast_implicit(f, expect_token(f, Token_context)); @@ -2292,7 +2292,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { skip_possible_newline_for_literal(f); - if (allow_token(f, Token_Undef)) { + if (allow_token(f, Token_Uninit)) { if (where_token.kind != Token_Invalid) { syntax_error(where_token, "'where' clauses are not allowed on procedure literals without a defined body (replaced with ---)"); } diff --git a/src/parser.hpp b/src/parser.hpp index aea3bbf21..d4883f287 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -373,7 +373,7 @@ gb_global char const *union_type_kind_strings[UnionType_COUNT] = { Entity *entity; \ }) \ AST_KIND(Implicit, "implicit", Token) \ - AST_KIND(Undef, "undef", Token) \ + AST_KIND(Uninit, "uninitialized value", Token) \ AST_KIND(BasicLit, "basic literal", struct { \ Token token; \ }) \ diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index 1274f05a0..52d49e897 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -2,7 +2,7 @@ gb_internal Token ast_token(Ast *node) { switch (node->kind) { case Ast_Ident: return node->Ident.token; case Ast_Implicit: return node->Implicit; - case Ast_Undef: return node->Undef; + case Ast_Uninit: return node->Uninit; case Ast_BasicLit: return node->BasicLit.token; case Ast_BasicDirective: return node->BasicDirective.token; case Ast_ProcGroup: return node->ProcGroup.token; @@ -137,7 +137,7 @@ Token ast_end_token(Ast *node) { return empty_token; case Ast_Ident: return node->Ident.token; case Ast_Implicit: return node->Implicit; - case Ast_Undef: return node->Undef; + case Ast_Uninit: return node->Uninit; case Ast_BasicLit: return node->BasicLit.token; case Ast_BasicDirective: return node->BasicDirective.token; case Ast_ProcGroup: return node->ProcGroup.close; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 547a864fb..17a396b9f 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -54,7 +54,7 @@ TOKEN_KIND(Token__AssignOpEnd, ""), \ TOKEN_KIND(Token_Increment, "++"), \ TOKEN_KIND(Token_Decrement, "--"), \ TOKEN_KIND(Token_ArrowRight,"->"), \ - TOKEN_KIND(Token_Undef, "---"), \ + TOKEN_KIND(Token_Uninit, "---"), \ \ TOKEN_KIND(Token__ComparisonBegin, ""), \ TOKEN_KIND(Token_CmpEq, "=="), \ @@ -917,7 +917,7 @@ gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) { token->kind = Token_Decrement; if (t->curr_rune == '-') { advance_to_next_rune(t); - token->kind = Token_Undef; + token->kind = Token_Uninit; } break; case '>': @@ -1078,7 +1078,7 @@ semicolon_check:; case Token_Imag: case Token_Rune: case Token_String: - case Token_Undef: + case Token_Uninit: /*fallthrough*/ case Token_Question: case Token_Pointer: diff --git a/src/types.cpp b/src/types.cpp index 70c4bcdbe..35fbb719b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -83,7 +83,7 @@ enum BasicKind { Basic_UntypedString, Basic_UntypedRune, Basic_UntypedNil, - Basic_UntypedUndef, + Basic_UntypedUninit, Basic_COUNT, @@ -515,7 +515,7 @@ gb_global Type basic_types[] = { {Type_Basic, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, 0, STR_LIT("untyped string")}}, {Type_Basic, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, 0, STR_LIT("untyped rune")}}, {Type_Basic, {Basic_UntypedNil, BasicFlag_Untyped, 0, STR_LIT("untyped nil")}}, - {Type_Basic, {Basic_UntypedUndef, BasicFlag_Untyped, 0, STR_LIT("untyped undefined")}}, + {Type_Basic, {Basic_UntypedUninit, BasicFlag_Untyped, 0, STR_LIT("untyped uninitialized")}}, }; // gb_global Type basic_type_aliases[] = { @@ -589,7 +589,7 @@ gb_global Type *t_untyped_quaternion = &basic_types[Basic_UntypedQuaternion]; gb_global Type *t_untyped_string = &basic_types[Basic_UntypedString]; gb_global Type *t_untyped_rune = &basic_types[Basic_UntypedRune]; gb_global Type *t_untyped_nil = &basic_types[Basic_UntypedNil]; -gb_global Type *t_untyped_undef = &basic_types[Basic_UntypedUndef]; +gb_global Type *t_untyped_uninit = &basic_types[Basic_UntypedUninit]; @@ -1866,14 +1866,15 @@ gb_internal bool is_type_typeid(Type *t) { } gb_internal bool is_type_untyped_nil(Type *t) { t = base_type(t); - return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedNil); + // NOTE(bill): checking for `nil` or `---` at once is just to improve the error handling + return (t->kind == Type_Basic && (t->Basic.kind == Basic_UntypedNil || t->Basic.kind == Basic_UntypedUninit)); } -gb_internal bool is_type_untyped_undef(Type *t) { +gb_internal bool is_type_untyped_uninit(Type *t) { t = base_type(t); - return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedUndef); + // NOTE(bill): checking for `nil` or `---` at once is just to improve the error handling + return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedUninit); } - gb_internal bool is_type_empty_union(Type *t) { t = base_type(t); return t->kind == Type_Union && t->Union.variants.count == 0; @@ -2206,10 +2207,6 @@ gb_internal bool is_type_polymorphic(Type *t, bool or_specialized=false) { } -gb_internal gb_inline bool type_has_undef(Type *t) { - return true; -} - gb_internal bool type_has_nil(Type *t) { t = base_type(t); switch (t->kind) { -- cgit v1.2.3 From 1247d36a12b9a0043fda0f73f164bd7fa5dc3897 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 29 May 2023 22:57:42 +0100 Subject: Fix #2562 caused by inlining of procedure call --- src/check_decl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/check_decl.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 84b0d39d8..b651e33e6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -950,6 +950,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (ac.require_declaration) { e->flags |= EntityFlag_Require; + pl->inlining = ProcInlining_no_inline; } -- cgit v1.2.3