From 2820bbc269bb989052163544f2764bc4287254e4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 5 Jan 2024 13:38:30 +0000 Subject: Add `@(entry_point_only)` for procedures --- src/checker.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 79328d648..ac885222d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3413,6 +3413,9 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { error(elem, "Expected a string value for '%.*s'", LIT(name)); } return true; + } else if (name == "entry_point_only") { + ac->entry_point_only = true; + return true; } return false; } -- cgit v1.2.3 From d7d23e65eae616d44cc070edff8171eb3160b5b0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 5 Jan 2024 13:47:00 +0000 Subject: Clean up error block usage --- src/build_settings.cpp | 1 + src/check_decl.cpp | 7 +++--- src/check_expr.cpp | 68 +++++++++++++++++++++++++++++--------------------- src/check_stmt.cpp | 6 ++--- src/check_type.cpp | 3 +-- src/checker.cpp | 6 ++--- src/main.cpp | 2 ++ 7 files changed, 50 insertions(+), 43 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index d91a31ff2..18ad8ac0d 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -361,6 +361,7 @@ struct BuildContext { bool ignore_warnings; bool warnings_as_errors; bool hide_error_line; + bool terse_errors; bool has_ansi_terminal_colours; bool ignore_lazy; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 85ba4230a..8a3f89877 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -138,11 +138,10 @@ gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize l } if (o->type && is_type_no_copy(o->type)) { - begin_error_block(); + 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 a return value from a call expression"); } - end_error_block(); } } if (rhs_count > 0 && lhs_count != rhs_count) { @@ -1301,8 +1300,8 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, D continue; } - begin_error_block(); - defer (end_error_block()); + + ERROR_BLOCK(); ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type); bool both_have_where_clauses = false; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 14e3bc0de..8d347bec7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -184,6 +184,8 @@ gb_internal void populate_check_did_you_mean_objc_entity(StringSet *set, Entity gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") { + if (build_context.terse_errors) { return; } + ERROR_BLOCK(); GB_ASSERT(e->kind == Entity_TypeName); GB_ASSERT(e->TypeName.objc_metadata != nullptr); @@ -204,6 +206,8 @@ gb_internal void check_did_you_mean_objc_entity(String const &name, Entity *e, b } gb_internal void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { + if (build_context.terse_errors) { return; } + ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); @@ -217,6 +221,8 @@ gb_internal void check_did_you_mean_type(String const &name, Array con gb_internal void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { + if (build_context.terse_errors) { return; } + ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); @@ -229,6 +235,8 @@ gb_internal void check_did_you_mean_type(String const &name, Slice con } gb_internal void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { + if (build_context.terse_errors) { return; } + ERROR_BLOCK(); DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.count, name); @@ -2203,7 +2211,6 @@ gb_internal bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *typ ERROR_BLOCK(); - if (is_type_numeric(o->type) && is_type_numeric(type)) { if (!is_type_integer(o->type) && is_type_integer(type)) { error(o->expr, "'%s' truncated to '%s', got %s", a, b, s); @@ -2264,8 +2271,7 @@ gb_internal void check_old_for_or_switch_value_usage(Ast *expr) { if (e != nullptr && (e->flags & EntityFlag_OldForOrSwitchValue) != 0) { GB_ASSERT(e->kind == Entity_Variable); - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); if ((e->flags & EntityFlag_ForValue) != 0) { Type *parent_type = type_deref(e->Variable.for_loop_parent_type); @@ -2309,8 +2315,7 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast * break; default: { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); error(op, "Cannot take the pointer address of '%s'", str); if (e != nullptr && (e->flags & EntityFlag_ForValue) != 0) { Type *parent_type = type_deref(e->Variable.for_loop_parent_type); @@ -3071,7 +3076,7 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { x->mode = Addressing_Invalid; - begin_error_block(); + ERROR_BLOCK(); error(x->expr, "Cannot cast '%s' as '%s' from '%s'", expr_str, to_type, from_type); if (is_const_expr) { gbString val_str = exact_value_to_string(x->value); @@ -3094,8 +3099,6 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { } check_cast_error_suggestion(c, x, type); - end_error_block(); - return; } @@ -4047,8 +4050,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar if (check_is_assignable_to(c, operand, elem)) { if (t->Matrix.row_count != t->Matrix.column_count) { operand->mode = Addressing_Invalid; - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); convert_untyped_error(c, operand, target_type); error_line("\tNote: Only a square matrix types can be initialized with a scalar value\n"); @@ -4109,8 +4111,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar target_type = t->Union.variants[first_success_index]; break; } else if (valid_count > 1) { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); GB_ASSERT(first_success_index >= 0); operand->mode = Addressing_Invalid; @@ -4136,8 +4137,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar } 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()); + ERROR_BLOCK(); operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); @@ -4714,6 +4714,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod entity = scope_lookup_current(import_scope, entity_name); bool allow_builtin = false; if (!is_entity_declared_for_selector(entity, import_scope, &allow_builtin)) { + ERROR_BLOCK(); error(node, "'%.*s' is not declared by '%.*s'", LIT(entity_name), LIT(import_name)); operand->mode = Addressing_Invalid; operand->expr = node; @@ -4914,6 +4915,8 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod error(op_expr, "Type '%s' has no field '%s'", op_str, sel_str); } } else { + ERROR_BLOCK(); + error(op_expr, "'%s' of type '%s' has no field '%s'", op_str, type_str, sel_str); if (operand->type != nullptr && selector->kind == Ast_Ident) { @@ -6338,8 +6341,7 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, }; if (valids.count == 0) { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); error(operand->expr, "No procedures or ambiguous call for procedure group '%s' that match with the given arguments", expr_name); if (positional_operands.count == 0 && named_operands.count == 0) { @@ -6429,8 +6431,7 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, data.result_type = t_invalid; } else if (valids.count > 1) { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); error(operand->expr, "Ambiguous procedure group call '%s' that match with the given arguments", expr_name); print_argument_types(); @@ -7649,6 +7650,8 @@ gb_internal ExprKind check_implicit_selector_expr(CheckerContext *c, Operand *o, String name = ise->selector->Ident.token.string; if (is_type_enum(th)) { + ERROR_BLOCK(); + Type *bt = base_type(th); GB_ASSERT(bt->kind == Type_Enum); @@ -9050,8 +9053,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * } if (unhandled.count > 0) { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); if (unhandled.count == 1) { error_no_newline(node, "Unhandled enumerated array case: %.*s", LIT(unhandled[0]->token.string)); @@ -9062,9 +9064,11 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * error_line("\t%.*s\n", LIT(f->token.string)); } } - error_line("\n"); - error_line("\tSuggestion: Was '#partial %s{...}' wanted?\n", type_to_string(type)); + if (!build_context.terse_errors) { + error_line("\n"); + error_line("\tSuggestion: Was '#partial %s{...}' wanted?\n", type_to_string(type)); + } } } @@ -9688,7 +9692,9 @@ gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, if (index < 0) { gbString str = expr_to_string(o->expr); error(o->expr, "Cannot index a constant '%s'", str); - error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + if (!build_context.terse_errors) { + error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + } gb_string_free(str); o->mode = Addressing_Invalid; o->expr = node; @@ -9702,7 +9708,9 @@ gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, if (!success) { gbString str = expr_to_string(o->expr); error(o->expr, "Cannot index a constant '%s' with index %lld", str, cast(long long)index); - error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + if (!build_context.terse_errors) { + error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + } gb_string_free(str); o->mode = Addressing_Invalid; o->expr = node; @@ -9890,7 +9898,9 @@ gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, if (!all_constant) { gbString str = expr_to_string(o->expr); error(o->expr, "Cannot slice '%s' with non-constant indices", str); - error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + if (!build_context.terse_errors) { + error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + } gb_string_free(str); o->mode = Addressing_Value; // NOTE(bill): Keep subsequent values going without erring o->expr = node; @@ -10246,15 +10256,15 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast } else { gbString str = expr_to_string(o->expr); gbString typ = type_to_string(o->type); - begin_error_block(); + ERROR_BLOCK(); error(o->expr, "Cannot dereference '%s' of type '%s'", str, typ); if (o->type && is_type_multi_pointer(o->type)) { - error_line("\tDid you mean '%s[0]'?\n", str); + if (!build_context.terse_errors) { + error_line("\tDid you mean '%s[0]'?\n", str); + } } - end_error_block(); - gb_string_free(typ); gb_string_free(str); o->mode = Addressing_Invalid; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index b93be734e..d56e5e212 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1085,8 +1085,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags } if (unhandled.count > 0) { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); if (unhandled.count == 1) { error_no_newline(node, "Unhandled switch case: %.*s", LIT(unhandled[0]->token.string)); @@ -1813,7 +1812,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f } if (new_name_count == 0) { - begin_error_block(); + ERROR_BLOCK(); error(node, "No new declarations on the left hand side"); bool all_underscore = true; for (Ast *name : vd->names) { @@ -1831,7 +1830,6 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f error_line("\tSuggestion: Try changing the declaration (:=) to an assignment (=)\n"); } - end_error_block(); } Type *init_type = nullptr; diff --git a/src/check_type.cpp b/src/check_type.cpp index f11418dc0..a95026711 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2702,14 +2702,13 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T check_expr_or_type(&c, &o, pt->type); if (o.mode != Addressing_Invalid && o.mode != Addressing_Type) { // NOTE(bill): call check_type_expr again to get a consistent error message - begin_error_block(); + ERROR_BLOCK(); elem = check_type_expr(&c, pt->type, nullptr); if (o.mode == Addressing_Variable) { gbString s = expr_to_string(pt->type); error_line("\tSuggestion: ^ is used for pointer types, did you mean '&%s'?\n", s); gb_string_free(s); } - end_error_block(); } else { elem = o.type; } diff --git a/src/checker.cpp b/src/checker.cpp index ac885222d..d25acb15e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4025,12 +4025,11 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (c->foreign_context.default_cc > 0) { cc = c->foreign_context.default_cc; } else if (is_arch_wasm()) { - begin_error_block(); + ERROR_BLOCK(); error(init, "For wasm related targets, it is required that you either define the" " @(default_calling_convention=) on the foreign block or" " explicitly assign it on the procedure signature"); error_line("\tSuggestion: when dealing with normal Odin code (e.g. js_wasm32), use \"contextless\"; when dealing with Emscripten like code, use \"c\"\n"); - end_error_block(); } } e->Procedure.link_prefix = c->foreign_context.link_prefix; @@ -4077,8 +4076,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (e->kind != Entity_Procedure) { if (fl != nullptr) { - begin_error_block(); - defer (end_error_block()); + ERROR_BLOCK(); AstKind kind = init->kind; error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_strings[kind])); diff --git a/src/main.cpp b/src/main.cpp index 4d4e01ada..fd754248b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1160,10 +1160,12 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_TerseErrors: build_context.hide_error_line = true; + build_context.terse_errors = true; break; case BuildFlag_VerboseErrors: gb_printf_err("-verbose-errors is not the default, -terse-errors can now disable it\n"); build_context.hide_error_line = false; + build_context.terse_errors = false; break; case BuildFlag_ErrorPosStyle: -- cgit v1.2.3 From aff8f06e3cb1bdb9c3ffee98a68675c843df78fd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 7 Jan 2024 19:56:00 +0000 Subject: Add frontend stuff instrumentation tooling //+no-instrumentation @(no_instrumentation) @(instrumentation_enter) @(instrumentation_exit) --- src/check_decl.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/checker.cpp | 44 ++++++++++++++++++++++++++++++++++++ src/checker.hpp | 35 ++++++++++++++++++++--------- src/entity.cpp | 1 + src/parser.cpp | 4 +++- src/parser.hpp | 2 ++ 6 files changed, 140 insertions(+), 12 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 8a3f89877..c69d8185e 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -909,6 +909,72 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { e->Procedure.entry_point_only = ac.entry_point_only; e->Procedure.is_export = ac.is_export; + + bool no_instrumentation = false; + if (pl->body == nullptr) { + no_instrumentation = true; + if (ac.no_instrumentation != Instrumentation_Default) { + error(e->token, "@(no_instrumentation) is not allowed on foreign procedures"); + } + } else { + if (e->file) { + no_instrumentation = (e->file->flags & AstFile_NoInstrumentation) != 0; + } + + switch (ac.no_instrumentation) { + case Instrumentation_Enabled: no_instrumentation = false; break; + case Instrumentation_Default: break; + case Instrumentation_Disabled: no_instrumentation = true; break; + } + } + e->Procedure.no_instrumentation = no_instrumentation; + + auto const is_valid_instrumentation_call = [](Type *type) -> bool { + if (type == nullptr || type->kind != Type_Proc) { + return false; + } + if (type->Proc.calling_convention != ProcCC_CDecl) { + return false; + } + if (type->Proc.result_count != 0) { + return false; + } + if (type->Proc.param_count != 2) { + return false; + } + Type *p0 = type->Proc.params->Tuple.variables[0]->type; + Type *p1 = type->Proc.params->Tuple.variables[1]->type; + return is_type_rawptr(p0) && is_type_rawptr(p1); + }; + + if (ac.instrumentation_enter && ac.instrumentation_exit) { + error(e->token, "A procedure cannot be marked with both @(instrumentation_enter) and @(instrumentation_exit)"); + } else if (ac.instrumentation_enter) { + if (!is_valid_instrumentation_call(e->type)) { + gbString s = type_to_string(e->type); + error(e->token, "@(instrumentation_enter) procedures must have the type 'proc \"c\" (rawptr, rawptr)', got %s", s); + gb_string_free(s); + } + MUTEX_GUARD(&ctx->info->instrumentation_mutex); + if (ctx->info->instrumentation_enter_entity != nullptr) { + error(e->token, "@(instrumentation_enter) has already been set"); + } else { + ctx->info->instrumentation_enter_entity = e; + } + } else if (ac.instrumentation_exit) { + if (!is_valid_instrumentation_call(e->type)) { + gbString s = type_to_string(e->type); + error(e->token, "@(instrumentation_exit) procedures must have the type 'proc \"c\" (rawptr, rawptr)', got %s", s); + gb_string_free(s); + } + MUTEX_GUARD(&ctx->info->instrumentation_mutex); + if (ctx->info->instrumentation_exit_entity != nullptr) { + error(e->token, "@(instrumentation_exit) has already been set"); + } else { + ctx->info->instrumentation_exit_entity = e; + } + } + e->deprecated_message = ac.deprecated_message; e->warning_message = ac.warning_message; ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); diff --git a/src/checker.cpp b/src/checker.cpp index d25acb15e..5e46e87fe 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2581,6 +2581,9 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("multi_pointer_slice_expr_error"), ); + add_dependency_to_set(c, c->info.instrumentation_enter_entity); + add_dependency_to_set(c, c->info.instrumentation_exit_entity); + generate_minimum_dependency_set_internal(c, start); @@ -3414,8 +3417,38 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } return true; } else if (name == "entry_point_only") { + if (value != nullptr) { + error(value, "'%.*s' expects no parameter", LIT(name)); + } ac->entry_point_only = true; return true; + } else if (name == "no_instrumentation") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_Invalid) { + ac->no_instrumentation = Instrumentation_Disabled; + } else if (ev.kind == ExactValue_Bool) { + if (ev.value_bool) { + ac->no_instrumentation = Instrumentation_Disabled; + } else { + ac->no_instrumentation = Instrumentation_Enabled; + } + } else { + error(value, "Expected either a boolean or no parameter for '%.*s'", LIT(name)); + return false; + } + return true; + } else if (name == "instrumentation_enter") { + if (value != nullptr) { + error(value, "'%.*s' expects no parameter", LIT(name)); + } + ac->instrumentation_enter = true; + return true; + } else if (name == "instrumentation_exit") { + if (value != nullptr) { + error(value, "'%.*s' expects no parameter", LIT(name)); + } + ac->instrumentation_exit = true; + return true; } return false; } @@ -6216,6 +6249,17 @@ gb_internal void check_parsed_files(Checker *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); + TIME_SECTION("check instrumentation calls"); + { + if ((c->info.instrumentation_enter_entity != nullptr) ^ + (c->info.instrumentation_exit_entity != nullptr)) { + Entity *e = c->info.instrumentation_enter_entity; + if (!e) e = c->info.instrumentation_exit_entity; + error(e->token, "Both @(instrumentation_enter) and @(instrumentation_exit) must be defined"); + } + } + + TIME_SECTION("add untyped expression values"); // Add untyped expression values for (UntypedExprInfo u = {}; mpsc_dequeue(&c->global_untyped_queue, &u); /**/) { diff --git a/src/checker.hpp b/src/checker.hpp index 7c399e50f..9da0f2950 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -103,6 +103,12 @@ struct DeferredProcedure { }; +enum InstrumentationFlag : i32 { + Instrumentation_Enabled = -1, + Instrumentation_Default = 0, + Instrumentation_Disabled = +1, +}; + struct AttributeContext { String link_name; String link_prefix; @@ -113,20 +119,23 @@ struct AttributeContext { String deprecated_message; String warning_message; DeferredProcedure deferred_procedure; - bool is_export : 1; - bool is_static : 1; - bool require_results : 1; - bool require_declaration : 1; - bool has_disabled_proc : 1; - bool disabled_proc : 1; - bool test : 1; - bool init : 1; - bool fini : 1; - bool set_cold : 1; - bool entry_point_only : 1; + bool is_export : 1; + bool is_static : 1; + bool require_results : 1; + bool require_declaration : 1; + bool has_disabled_proc : 1; + bool disabled_proc : 1; + bool test : 1; + bool init : 1; + bool fini : 1; + bool set_cold : 1; + bool entry_point_only : 1; + bool instrumentation_enter : 1; + bool instrumentation_exit : 1; u32 optimization_mode; // ProcedureOptimizationMode i64 foreign_import_priority_index; String extra_linker_flags; + InstrumentationFlag no_instrumentation; String objc_class; String objc_name; @@ -403,6 +412,10 @@ struct CheckerInfo { BlockingMutex all_procedures_mutex; Array all_procedures; + + BlockingMutex instrumentation_mutex; + Entity *instrumentation_enter_entity; + Entity *instrumentation_exit_entity; }; struct CheckerContext { diff --git a/src/entity.cpp b/src/entity.cpp index d0b3cf139..0539386d0 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -251,6 +251,7 @@ struct Entity { bool generated_from_polymorphic : 1; bool target_feature_disabled : 1; bool entry_point_only : 1; + bool no_instrumentation : 1; String target_feature; } Procedure; struct { diff --git a/src/parser.cpp b/src/parser.cpp index c0498b425..2671054df 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5919,7 +5919,7 @@ gb_internal bool parse_file(Parser *p, AstFile *f) { f->vet_flags = parse_vet_tag(tok, lc); f->vet_flags_set = true; } else if (string_starts_with(lc, str_lit("+ignore"))) { - return false; + return false; } else if (string_starts_with(lc, str_lit("+private"))) { f->flags |= AstFile_IsPrivatePkg; String command = string_trim_starts_with(lc, str_lit("+private ")); @@ -5941,6 +5941,8 @@ gb_internal bool parse_file(Parser *p, AstFile *f) { } else { f->flags |= AstFile_IsLazy; } + } else if (lc == "+no-instrumentation") { + f->flags |= AstFile_NoInstrumentation; } else { warning(tok, "Ignoring unknown tag '%.*s'", LIT(lc)); } diff --git a/src/parser.hpp b/src/parser.hpp index bce818652..cc1836ef3 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -76,6 +76,8 @@ enum AstFileFlag : u32 { AstFile_IsTest = 1<<3, AstFile_IsLazy = 1<<4, + + AstFile_NoInstrumentation = 1<<5, }; enum AstDelayQueueKind { -- cgit v1.2.3 From ae52e245eaf737527a3af50ead74ed4e2b143e24 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 17 Jan 2024 21:07:19 +0100 Subject: Add WINDOWS_SUBSYSTEM constant bool true when -subsystem:windows for Windows targets, false otherwise. --- src/build_settings.cpp | 19 +++++++++---------- src/checker.cpp | 2 ++ 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 1f57b5625..ae16841c5 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -298,6 +298,7 @@ struct BuildContext { bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) bool ODIN_FOREIGN_ERROR_PROCEDURES; bool ODIN_VALGRIND_SUPPORT; + bool WINDOWS_SUBSYSTEM; // True only for Windows targets with -subsystem:windows ErrorPosStyle ODIN_ERROR_POS_STYLE; @@ -1282,8 +1283,6 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta GB_ASSERT(metrics->int_size == 2*metrics->ptr_size); } - - bc->metrics = *metrics; switch (subtarget) { case Subtarget_Default: @@ -1300,14 +1299,14 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta break; } - bc->ODIN_OS = target_os_names[metrics->os]; - bc->ODIN_ARCH = target_arch_names[metrics->arch]; - bc->endian_kind = target_endians[metrics->arch]; - bc->ptr_size = metrics->ptr_size; - bc->int_size = metrics->int_size; - bc->max_align = metrics->max_align; - bc->max_simd_align = metrics->max_simd_align; - bc->link_flags = str_lit(" "); + bc->ODIN_OS = target_os_names[metrics->os]; + bc->ODIN_ARCH = target_arch_names[metrics->arch]; + bc->endian_kind = target_endians[metrics->arch]; + bc->ptr_size = metrics->ptr_size; + bc->int_size = metrics->int_size; + bc->max_align = metrics->max_align; + bc->max_simd_align = metrics->max_simd_align; + bc->link_flags = str_lit(" "); #if defined(DEFAULT_TO_THREADED_CHECKER) bc->threaded_checker = true; diff --git a/src/checker.cpp b/src/checker.cpp index 5e46e87fe..a9c1bdde4 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -973,6 +973,8 @@ gb_internal void init_universal(void) { add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME); + add_global_bool_constant("WINDOWS_SUBSYSTEM", bc->use_subsystem_windows); + { GlobalEnumValue values[TargetOs_COUNT] = { {"Unknown", TargetOs_Invalid}, -- cgit v1.2.3 From fc047a8043493787878d064487fc1e410b334b23 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 18 Jan 2024 19:12:39 +0100 Subject: Expand -subsystem option on Windows W:\Odin>odin run sketch.odin -file -subsystem:foo Invalid -subsystem string, got oo. Expected one of: BOOT_APPLICATION, CONSOLE (default), EFI_APPLICATION, EFI_BOOT_SERVICE_DRIVER, EFI_ROM, EFI_RUNTIME_DRIVER, NATIVE, POSIX, WINDOWS (or WINDOW), WINDOWSCE We now also set the constant ODIN_WINDOWS_SUBSYSTEM, which is "" for non-Windows targets. --- src/build_settings.cpp | 50 ++++++++++++++++++++++++++++++++++++++++---------- src/checker.cpp | 9 ++++----- src/linker.cpp | 9 ++++----- src/main.cpp | 43 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 83 insertions(+), 28 deletions(-) (limited to 'src/checker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index ae16841c5..af518bcb4 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -56,6 +56,19 @@ enum TargetABIKind : u16 { TargetABI_COUNT, }; +enum Windows_Subsystem : u8 { + Windows_Subsystem_BOOT_APPLICATION, + Windows_Subsystem_CONSOLE, // Default, + Windows_Subsystem_EFI_APPLICATION, + Windows_Subsystem_EFI_BOOT_SERVICE_DRIVER, + Windows_Subsystem_EFI_ROM, + Windows_Subsystem_EFI_RUNTIME_DRIVER, + Windows_Subsystem_NATIVE, + Windows_Subsystem_POSIX, + Windows_Subsystem_WINDOWS, + Windows_Subsystem_WINDOWSCE, + Windows_Subsystem_COUNT, +}; gb_global String target_os_names[TargetOs_COUNT] = { str_lit(""), @@ -120,6 +133,19 @@ gb_global TargetEndianKind target_endians[TargetArch_COUNT] = { TargetEndian_Little, }; +gb_global String windows_subsystem_names[Windows_Subsystem_COUNT] = { + str_lit("BOOT_APPLICATION"), + str_lit("CONSOLE"), // Default + str_lit("EFI_APPLICATION"), + str_lit("EFI_BOOT_SERVICE_DRIVER"), + str_lit("EFI_ROM"), + str_lit("EFI_RUNTIME_DRIVER"), + str_lit("NATIVE"), + str_lit("POSIX"), + str_lit("WINDOWS"), + str_lit("WINDOWSCE"), +}; + #ifndef ODIN_VERSION_RAW #define ODIN_VERSION_RAW "dev-unknown-unknown" #endif @@ -287,18 +313,18 @@ enum SanitizerFlags : u32 { // This stores the information for the specify architecture of this build struct BuildContext { // Constants - String ODIN_OS; // target operating system - String ODIN_ARCH; // target architecture - String ODIN_VENDOR; // compiler vendor - String ODIN_VERSION; // compiler version - String ODIN_ROOT; // Odin ROOT - String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name - bool ODIN_DEBUG; // Odin in debug mode - bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not + String ODIN_OS; // Target operating system + String ODIN_ARCH; // Target architecture + String ODIN_VENDOR; // Compiler vendor + String ODIN_VERSION; // Compiler version + String ODIN_ROOT; // Odin ROOT + String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name + String ODIN_WINDOWS_SUBSYSTEM; // Empty string for non-Windows targets + bool ODIN_DEBUG; // Odin in debug mode + bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) bool ODIN_FOREIGN_ERROR_PROCEDURES; bool ODIN_VALGRIND_SUPPORT; - bool WINDOWS_SUBSYSTEM; // True only for Windows targets with -subsystem:windows ErrorPosStyle ODIN_ERROR_POS_STYLE; @@ -368,7 +394,6 @@ struct BuildContext { bool ignore_lazy; bool ignore_llvm_build; - bool use_subsystem_windows; bool ignore_microsoft_magic; bool linker_map_file; @@ -1328,6 +1353,11 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta } } + // Default to subsystem:CONSOLE on Windows targets + if (bc->ODIN_WINDOWS_SUBSYSTEM == "" && bc->metrics.os == TargetOs_windows) { + bc->ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_CONSOLE]; + } + // NOTE(zangent): The linker flags to set the build architecture are different // across OSs. It doesn't make sense to allocate extra data on the heap // here, so I just #defined the linker flags to keep things concise. diff --git a/src/checker.cpp b/src/checker.cpp index a9c1bdde4..917340a20 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -968,12 +968,11 @@ gb_internal void init_universal(void) { add_global_bool_constant("true", true); add_global_bool_constant("false", false); - add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); - add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); - add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); + add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); + add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); + add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME); - - add_global_bool_constant("WINDOWS_SUBSYSTEM", bc->use_subsystem_windows); + add_global_string_constant("ODIN_WINDOWS_SUBSYSTEM", bc->ODIN_WINDOWS_SUBSYSTEM); { GlobalEnumValue values[TargetOs_COUNT] = { diff --git a/src/linker.cpp b/src/linker.cpp index 93869633e..c0952d0e0 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -233,7 +233,6 @@ gb_internal i32 linker_stage(LinkerData *gen) { String windows_sdk_bin_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Win_SDK_Bin_Path]); defer (gb_free(heap_allocator(), windows_sdk_bin_path.text)); - char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; if (!build_context.use_lld) { // msvc String res_path = {}; defer (gb_free(heap_allocator(), res_path.text)); @@ -265,14 +264,14 @@ gb_internal i32 linker_stage(LinkerData *gen) { result = system_exec_command_line_app("msvc-link", "\"%.*slink.exe\" %s %.*s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%s " + "/nologo /incremental:no /opt:ref /subsystem:%.*s " "%.*s " "%.*s " "%s " "", LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), link_settings, - subsystem_str, + LIT(build_context.ODIN_WINDOWS_SUBSYSTEM), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str @@ -283,14 +282,14 @@ gb_internal i32 linker_stage(LinkerData *gen) { } else { // lld result = system_exec_command_line_app("msvc-lld-link", "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%s " + "/nologo /incremental:no /opt:ref /subsystem:%.*s " "%.*s " "%.*s " "%s " "", LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), link_settings, - subsystem_str, + LIT(build_context.ODIN_WINDOWS_SUBSYSTEM), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str diff --git a/src/main.cpp b/src/main.cpp index fd754248b..19271d667 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1270,16 +1270,43 @@ gb_internal bool parse_build_flags(Array args) { } case BuildFlag_Subsystem: { + // TODO(Jeroen): Parse optional "[,major[.minor]]" + GB_ASSERT(value.kind == ExactValue_String); String subsystem = value.value_string; - if (str_eq_ignore_case(subsystem, str_lit("console"))) { - build_context.use_subsystem_windows = false; - } else if (str_eq_ignore_case(subsystem, str_lit("window"))) { - build_context.use_subsystem_windows = true; - } else if (str_eq_ignore_case(subsystem, str_lit("windows"))) { - build_context.use_subsystem_windows = true; - } else { - gb_printf_err("Invalid -subsystem string, got %.*s, expected either 'console' or 'windows'\n", LIT(subsystem)); + bool subsystem_found = false; + for (int i = 0; i < Windows_Subsystem_COUNT; i++) { + if (str_eq_ignore_case(subsystem, windows_subsystem_names[i])) { + build_context.ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[i]; + subsystem_found = true; + break; + } + } + + // WINDOW is a hidden alias for WINDOWS. Check it. + String subsystem_windows_alias = str_lit("WINDOW"); + if (!subsystem_found && str_eq_ignore_case(subsystem, subsystem_windows_alias)) { + build_context.ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_WINDOWS]; + subsystem_found = true; + break; + } + + if (!subsystem_found) { + gb_printf_err("Invalid -subsystem string, got %.*s. Expected one of:\n", LIT(subsystem)); + gb_printf_err("\t"); + for (int i = 0; i < Windows_Subsystem_COUNT; i++) { + if (i > 0) { + gb_printf_err(", "); + } + gb_printf_err("%.*s", LIT(windows_subsystem_names[i])); + if (i == Windows_Subsystem_CONSOLE) { + gb_printf_err(" (default)"); + } + if (i == Windows_Subsystem_WINDOWS) { + gb_printf_err(" (or WINDOW)"); + } + } + gb_printf_err("\n"); bad_flags = true; } break; -- cgit v1.2.3 From 2097b09abb74208b2548c93528b9dd775ec3e411 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 22 Jan 2024 21:07:17 +0100 Subject: fix for wasm on llvm 17 --- src/checker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/checker.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 917340a20..4d7514d0b 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1085,7 +1085,7 @@ gb_internal void init_universal(void) { add_global_constant("ODIN_COMPILE_TIMESTAMP", t_untyped_integer, exact_value_i64(odin_compile_timestamp())); - add_global_bool_constant("__ODIN_LLVM_F16_SUPPORTED", lb_use_new_pass_system()); + add_global_bool_constant("__ODIN_LLVM_F16_SUPPORTED", lb_use_new_pass_system() && !is_arch_wasm()); { GlobalEnumValue values[3] = { -- cgit v1.2.3