From: Robert Pengelly Date: Tue, 14 Jul 2026 18:12:52 +0000 (+0100) Subject: Corrected diagnositics, 64-bit fixes and macro fixes X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=65ad6f5a530c36e689b53ff0fcd2db984f989f51;p=scc.git Corrected diagnositics, 64-bit fixes and macro fixes --- diff --git a/amd64.c b/amd64.c index 146aa82..4e7c963 100644 --- a/amd64.c +++ b/amd64.c @@ -192,10 +192,7 @@ static int amd64_member_owner_matches (int mi, int owner_size, const char *owner } if (owner_tag_name && owner_tag_name[0]) { - - return member_infos[mi].owner_tag_name - && strcmp (member_infos[mi].owner_tag_name, owner_tag_name) == 0; - + return member_infos[mi].owner_tag_name && strcmp (member_infos[mi].owner_tag_name, owner_tag_name) == 0; } return member_infos[mi].owner_tag_name == 0; @@ -353,7 +350,7 @@ static void save_typedef_name (const char *name, int size, int is_unsigned, int if (typedef_name_count >= MAX_TYPEDEF_NAMES) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many typedef names"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many typedef names"); return; } @@ -400,8 +397,7 @@ static void save_typedef_name (const char *name, int size, int is_unsigned, int for (mi = 0; mi < member_info_count; mi++) { - if (member_infos[mi].owner_size == size - && member_infos[mi].owner_tag_name == 0) { + if (member_infos[mi].owner_size == size && member_infos[mi].owner_tag_name == 0) { member_infos[mi].owner_tag_name = xstrdup (name); } @@ -6096,13 +6092,13 @@ static void install_pending_params_as_locals (void) { if (local_symbol_count >= MAX_LOCAL_SYMBOLS) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many local symbols"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many local symbols"); break; } if (local_symbol_exists_in_current_scope (pending_params[i].name, 0)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", pending_params[i].name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", pending_params[i].name); } local_symbols[local_symbol_count].name = xstrdup (pending_params[i].name); @@ -8241,7 +8237,7 @@ static void parse_local_initializer_value (struct local_init *init, int object_s if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after '&'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after '&'"); return; } @@ -8636,7 +8632,7 @@ static void parse_block (void) { if (!declaration_phase) { if (state->std == 90) { - report_line_at (get_filename (), get_line_number (), (state->pedantic ? REPORT_ERROR : REPORT_WARNING), tok.start, tok.caret, "ISO C90 forbids mixed declarations and code"); + report_line_at (get_filename (), get_line_number (), (state->pedantic ? REPORT_ERROR : REPORT_WARNING), tok.report_start, tok.report_caret, "ISO C90 forbids mixed declarations and code"); } } @@ -8955,8 +8951,7 @@ static void parse_block (void) { object_offset = new_offset; object_size = elem_index * elem_size; - if (local_symbol_count > 0 && name && local_symbols[local_symbol_count - 1].name - && strcmp (local_symbols[local_symbol_count - 1].name, name) == 0) { + if (local_symbol_count > 0 && name && local_symbols[local_symbol_count - 1].name && strcmp (local_symbols[local_symbol_count - 1].name, name) == 0) { local_symbols[local_symbol_count - 1].offset = object_offset; local_symbols[local_symbol_count - 1].size = object_size; @@ -10826,7 +10821,7 @@ static int parse_incdec_identifier_now (enum token_kind *op, char **name, const if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", *op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", *op == TOK_INCR ? "++" : "--"); *name = 0; return 1; @@ -11081,7 +11076,7 @@ static int emit_load_prefix_incdec_deref_to_reg_now (const char *reg) { if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after *"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after *"); free (saved_tok->ident); free ((char *) saved_tok->start); @@ -11273,7 +11268,7 @@ static int emit_load_prefix_incdec_member_to_reg_now (const char *reg) { if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); return 1; } @@ -11376,7 +11371,7 @@ static int emit_load_prefix_incdec_member_to_reg_now (const char *reg) { if (tok.kind != TOK_ARROW && tok.kind != TOK_DOT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected member after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected member after %s", op == TOK_INCR ? "++" : "--"); return 1; } @@ -12493,6 +12488,8 @@ static int token_is_floating_constant_now (void); static void emit_store_floating_member_to_addr_reg_now (const char *addr_reg, int offset, int size); static void emit_load_floating_rhs_expression_now (int result_size); static void emit_load_assignment_rhs_to_reg (const char *reg); + +static int emit_load_deref_assignment_expression_to_reg_now (const char *reg); static void emit_floating_stack_to_int_pair_now (const char *lo, const char *hi); static void emit_integer_pair_to_floating_stack_now (const char *lo, const char *hi, int size); @@ -12599,6 +12596,13 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { } + if (tok.kind == TOK_STAR && emit_load_deref_assignment_expression_to_reg_now (lo)) { + + emit_extend_pair_high_from_low (lo, hi, DATA_INT & 0x1f, 0); + return; + + } + if (tok.kind != TOK_LPAREN && current_integer_expr_is_foldable_now ()) { int64_s v = const64_from_current_foldable_expr (); @@ -13045,7 +13049,7 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { enum token_kind postfix_op = TOK_EOF; char *name = xstrdup (tok.ident); - const char *name_start = tok.start, *name_caret = tok.caret; + const char *name_start = tok.report_start, *name_caret = tok.report_caret; unsigned long name_line = get_line_number (); int postfix_incdec = 0; @@ -13055,6 +13059,61 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { get_token (); + /* + * An assignment is an expression and may appear anywhere a value is + * accepted, including directly as a function argument: + * + * kmalloc (sector_size = disk->sector_size * count) + * + * The old 64-bit primary parser consumed the identifier as an ordinary + * value and left '=' for the call parser, which then reported + * "expected )". Parse the assignment here, store the converted + * 64-bit value, and leave that same value in the requested result pair. + */ + if (tok.kind == TOK_ASSIGN) { + + struct local_symbol *dst = find_local_symbol (name); + + int dst_global = find_global_symbol (name); + int dst_size = dst ? dst->size : (dst_global >= 0 ? get_global_symbol_size (name) : 0); + int dst_pointer = dst ? (dst->is_array || dst->pointer_depth > 0) : (dst_global >= 0 && (get_global_symbol_array (name) || get_global_symbol_pointer_depth (name) > 0)); + + if (!dst && dst_global < 0) { + + report_line_at (get_filename (), name_line, REPORT_ERROR, name_start, name_caret, "unknown symbol '%s'", name); + get_token (); + + emit_load_assignment_rhs_expression_to_pair (lo, hi, 1); + free (name); + + return; + + } + + if (dst_size == (DATA_LLONG & 0x1f) && !dst_pointer) { + + get_token (); + emit_load_assignment_rhs_expression_to_pair (lo, hi, dst ? dst->is_unsigned : get_global_symbol_unsigned (name)); + + if (dst) { + + if (dst->is_static && dst->static_label) { + emit_store_pair_to_global64 (dst->static_label, lo, hi); + } else { + emit_store_pair_to_local64 (dst->offset, lo, hi); + } + + } else { + emit_store_pair_to_global64 (name, lo, hi); + } + + free (name); + return; + + } + + } + if (strcmp (name, "__scc_builtin_va_arg") == 0 && tok.kind == TOK_LPAREN) { int va_size = DATA_INT & 0x1f; @@ -13962,9 +14021,7 @@ static void emit_apply_postfix_member_access_to_reg_now (const char *reg) { assign_op = tok.kind; get_token (); - if (assign_op == TOK_ASSIGN && subscript_elem_size > (DATA_LLONG & 0x1f) - && tok.kind == TOK_IDENT && tok.ident - && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION) { + if (assign_op == TOK_ASSIGN && subscript_elem_size > (DATA_LLONG & 0x1f) && tok.kind == TOK_IDENT && tok.ident && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION) { char *rhs_name = xstrdup (tok.ident); @@ -14906,7 +14963,7 @@ static int emit_load_address_of_parenthesized_postfix_to_reg_now (const char *re if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after '&('"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after '&('"); expect (TOK_RPAREN, ")"); return 1; @@ -15011,7 +15068,7 @@ static int emit_load_address_of_parenthesized_postfix_to_reg_now (const char *re } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "unknown symbol '%s'", name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "unknown symbol '%s'", name); free (name); expect (TOK_RPAREN, ")"); @@ -15424,8 +15481,7 @@ static int emit_aggregate_copy_from_current_rhs_to_addr_reg_now (const char *add ptr_depth = ptr_sym ? ptr_sym->pointer_depth : get_global_symbol_pointer_depth (ptr_name); ptr_pointed_size = ptr_sym ? ptr_sym->pointed_size : get_global_symbol_pointed_size (ptr_name); - if (!ptr_sym && ptr_global_index >= 0 - && get_global_symbol_kind (ptr_name) == GLOBAL_SYMBOL_FUNCTION) { + if (!ptr_sym && ptr_global_index >= 0 && get_global_symbol_kind (ptr_name) == GLOBAL_SYMBOL_FUNCTION) { const char *call_start = tok.start; const char *call_caret = tok.caret; @@ -15790,7 +15846,7 @@ static int emit_aggregate_copy_from_current_rhs_to_addr_reg_now (const char *add if (tok.kind != TOK_IDENT || !tok.ident) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected member name after %s", member_op == TOK_ARROW ? "->" : "."); free (ptr_name); @@ -16678,7 +16734,7 @@ static int emit_parse_builtin_va_arg_address_to_reg_now (const char *reg, int *o if (!is_type_start (tok.kind)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected type name in __scc_builtin_va_arg"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected type name in __scc_builtin_va_arg"); free (name); return 1; @@ -17928,25 +17984,66 @@ static int source_starts_deref_assignment_at_now (const char *p) { return 0; } - p++; + { - while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + int parens = 0; p++; - } - - if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) { - return 0; - } - - p++; - - while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || - (*p >= '0' && *p <= '9') || *p == '_') { + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + while (*p == '(') { + + parens++; + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + + if (*p == '&') { + + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + + if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) { + return 0; + } + p++; - } + + while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || + (*p >= '0' && *p <= '9') || *p == '_') { + p++; + } + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + while (parens > 0 && *p == ')') { + + parens--; + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + + if (parens != 0) { + return 0; + } - while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { - p++; } if (*p == '=' && p[1] != '=') { @@ -17954,7 +18051,7 @@ static int source_starts_deref_assignment_at_now (const char *p) { } if ((p[0] == '+' || p[0] == '-' || p[0] == '*' || p[0] == '/' || - p[0] == '%' || p[0] == '&' || p[0] == '^' || p[0] == '|') && + p[0] == '%' || p[0] == '&' || p[0] == '^' || p[0] == '|') && p[1] == '=') { return 1; } @@ -17986,6 +18083,8 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { int pointed_size = DATA_INT & 0x1f; int value_pointer_depth = 0; int store_size = DATA_INT & 0x1f; + int operand_parens = 0; + int address_of_operand = 0; if (tok.kind != TOK_STAR) { return 0; @@ -17997,6 +18096,20 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { get_token (); + while (tok.kind == TOK_LPAREN) { + + operand_parens++; + get_token (); + + } + + if (tok.kind == TOK_AMPER) { + + address_of_operand = 1; + get_token (); + + } + name_start = tok.start; name_caret = tok.caret; name_line = get_line_number (); @@ -18011,6 +18124,13 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { name = xstrdup (tok.ident); get_token (); + while (operand_parens > 0) { + + expect (TOK_RPAREN, ")"); + operand_parens--; + + } + if (!is_assignment_operator (tok.kind)) { free (name); @@ -18026,21 +18146,47 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { if (sym) { - pointer_depth = sym->pointer_depth; - pointed_size = sym->pointed_size; + if (address_of_operand) { + + pointer_depth = 1; + pointed_size = sym->size; + + if (sym->is_static && sym->static_label) { + emit_load_address_to_reg_now ("rcx", sym->static_label); + } else { + emit_load_local_address_to_reg_now ("rcx", sym->offset); + } - if (sym->is_static && sym->static_label) { - emit_load_global_to_reg ("rcx", sym->static_label, DATA_PTR); } else { - emit_load_local_to_reg ("rcx", sym->offset, DATA_PTR); + + pointer_depth = sym->pointer_depth; + pointed_size = sym->pointed_size; + + if (sym->is_static && sym->static_label) { + emit_load_global_to_reg ("rcx", sym->static_label, DATA_PTR); + } else { + emit_load_local_to_reg ("rcx", sym->offset, DATA_PTR); + } + } } else if (global_index >= 0) { - pointer_depth = get_global_symbol_pointer_depth (name); - pointed_size = get_global_symbol_pointed_size (name); + if (address_of_operand) { - emit_load_global_to_reg ("rcx", name, DATA_PTR); + pointer_depth = 1; + pointed_size = get_global_symbol_size (name); + + emit_load_address_to_reg_now ("rcx", name); + + } else { + + pointer_depth = get_global_symbol_pointer_depth (name); + pointed_size = get_global_symbol_pointed_size (name); + + emit_load_global_to_reg ("rcx", name, DATA_PTR); + + } } else { @@ -18107,6 +18253,13 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { } + while (tok.kind == TOK_COMMA) { + + get_token (); + emit_load_assignment_rhs_expression_to_reg (reg); + + } + expect (TOK_RPAREN, ")"); if (value_pointer_depth > 0) { @@ -27953,9 +28106,9 @@ static int parse_prefix_incdec_statement (void) { if (tok.kind != TOK_IDENT) { if (indirect) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after *"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after *"); } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); } skip_balanced_until (TOK_SEMI, TOK_EOF, TOK_EOF); @@ -29741,6 +29894,7 @@ static int parse_indirect_assignment_statement (void) { static int source_starts_parenthesized_star_now (void) { const char *p = tok.caret ? tok.caret : tok.start; + int depth = 0; if (!p) { return 0; @@ -29754,13 +29908,38 @@ static int source_starts_parenthesized_star_now (void) { return 0; } + depth = 1; p++; while (*p == ' ' || *p == '\t') { p++; } - return *p == '*'; + if (*p != '*') { + return 0; + } + + while (*p && depth > 0) { + + if (*p == '(') { + depth++; + } else if (*p == ')') { + depth--; + } + + p++; + + } + + if (depth != 0) { + return 0; + } + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + return *p == '.' || (*p == '-' && p[1] == '>'); } @@ -31858,7 +32037,7 @@ static int parse_inline_asm_statement (void) { if (!is_string_token ()) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected asm template string"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected asm template string"); skip_balanced_until (TOK_SEMI, TOK_EOF, TOK_EOF); expect (TOK_SEMI, ";"); @@ -31884,7 +32063,7 @@ static int parse_inline_asm_statement (void) { if (!is_string_token ()) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected asm input constraint string"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected asm input constraint string"); skip_balanced_until (TOK_RPAREN, TOK_EOF, TOK_EOF); break; @@ -33675,7 +33854,7 @@ static void parse_for_header_expression_until (enum token_kind end_token) { free (name); } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); } FINISH_FOR_HEADER_EXPR (0); @@ -34116,7 +34295,7 @@ static void parse_do_statement (void) { } } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected while after do statement"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected while after do statement"); } emit_statement_label (break_label); @@ -36136,8 +36315,8 @@ static int parse_postfix_assignment_statement_now (void) { if (lvalue_size > (DATA_LLONG & 0x1f) && tok.kind == TOK_IDENT && tok.ident && token_identifier_is_function_call_rhs_now () - && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION - && get_global_symbol_size (tok.ident) > (DATA_LLONG & 0x1f)) { + && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION + && get_global_symbol_size (tok.ident) > (DATA_LLONG & 0x1f)) { char *rhs_name = xstrdup (tok.ident); const char *rhs_start = tok.start; @@ -37208,7 +37387,7 @@ static int parse_possible_knr_function (void) { } if (param_name && find_pending_param_from (param_name, old_style_param_start) >= 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", param_name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", param_name); } else { add_pending_param (param_name, param_size, type_alignment (param_size), @@ -37232,7 +37411,7 @@ static int parse_possible_knr_function (void) { } else if (token_is_ident ()) { if (find_pending_param_from (tok.ident, old_style_param_start) >= 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", tok.ident); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", tok.ident); } else { add_pending_param (tok.ident, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0, 0); @@ -37624,7 +37803,7 @@ static void parse_global_initializer_values (int64_s *values, char **symbols, in get_token (); if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after '&'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after '&'"); } else { char addr_symbol[256]; @@ -37900,7 +38079,7 @@ static void emit_global_address (const char *symbol, int size) { } if (size != DATA_PTR) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "address initializer requires pointer-sized object"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "address initializer requires pointer-sized object"); } emit_extern_reference_symbol (symbol, DATA_PTR); @@ -38226,7 +38405,7 @@ static void queue_string_literal_global (const char *label, const int64_s *value if (pending_string_literal_count >= MAX_PENDING_STRING_LITERALS) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many string literals"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many string literals"); return; } @@ -38736,7 +38915,7 @@ static void parse_external_after_type (void) { if (tok.kind == TOK_SEMI) { get_token (); } else if (is_type_start (tok.kind)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "missing ';' after declaration"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "missing ';' after declaration"); } else { expect (TOK_SEMI, ";"); } @@ -38782,7 +38961,7 @@ void compile_translation_unit64 (void) { continue; } - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected external declaration"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected external declaration"); get_token (); } diff --git a/i386.c b/i386.c index 1fc3f1f..0f80607 100644 --- a/i386.c +++ b/i386.c @@ -154,7 +154,7 @@ static void save_typedef_name (const char *name, int size, int is_unsigned, int if (typedef_name_count >= MAX_TYPEDEF_NAMES) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many typedef names"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many typedef names"); return; } @@ -201,8 +201,7 @@ static void save_typedef_name (const char *name, int size, int is_unsigned, int for (mi = 0; mi < member_info_count; mi++) { - if (member_infos[mi].owner_size == size - && member_infos[mi].owner_tag_name == 0) { + if (member_infos[mi].owner_size == size && member_infos[mi].owner_tag_name == 0) { member_infos[mi].owner_tag_name = xstrdup (name); } @@ -5777,13 +5776,13 @@ static void install_pending_params_as_locals (void) { if (local_symbol_count >= MAX_LOCAL_SYMBOLS) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many local symbols"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many local symbols"); break; } if (local_symbol_exists_in_current_scope (pending_params[i].name, 0)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", pending_params[i].name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", pending_params[i].name); } local_symbols[local_symbol_count].name = xstrdup (pending_params[i].name); @@ -7454,7 +7453,7 @@ static void parse_local_initializer_value (struct local_init *init, int object_s if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after '&'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after '&'"); return; } @@ -7812,7 +7811,7 @@ static void parse_block (void) { if (!declaration_phase) { if (state->std == 90) { - report_line_at (get_filename (), get_line_number (), (state->pedantic ? REPORT_ERROR : REPORT_WARNING), tok.start, tok.caret, "ISO C90 forbids mixed declarations and code"); + report_line_at (get_filename (), get_line_number (), (state->pedantic ? REPORT_ERROR : REPORT_WARNING), tok.report_start, tok.report_caret, "ISO C90 forbids mixed declarations and code"); } } @@ -8131,8 +8130,7 @@ static void parse_block (void) { object_offset = new_offset; object_size = elem_index * elem_size; - if (local_symbol_count > 0 && name && local_symbols[local_symbol_count - 1].name - && strcmp (local_symbols[local_symbol_count - 1].name, name) == 0) { + if (local_symbol_count > 0 && name && local_symbols[local_symbol_count - 1].name && strcmp (local_symbols[local_symbol_count - 1].name, name) == 0) { local_symbols[local_symbol_count - 1].offset = object_offset; local_symbols[local_symbol_count - 1].size = object_size; @@ -9469,7 +9467,7 @@ static int parse_incdec_identifier_now (enum token_kind *op, char **name, const if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", *op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", *op == TOK_INCR ? "++" : "--"); *name = 0; return 1; @@ -9724,7 +9722,7 @@ static int emit_load_prefix_incdec_deref_to_reg_now (const char *reg) { if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after *"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after *"); free (saved_tok->ident); free ((char *) saved_tok->start); @@ -9939,7 +9937,7 @@ static int emit_load_prefix_incdec_member_to_reg_now (const char *reg) { if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); return 1; } @@ -10042,7 +10040,7 @@ static int emit_load_prefix_incdec_member_to_reg_now (const char *reg) { if (tok.kind != TOK_ARROW && tok.kind != TOK_DOT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected member after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected member after %s", op == TOK_INCR ? "++" : "--"); return 1; } @@ -11120,6 +11118,8 @@ static int token_is_floating_constant_now (void); static void emit_store_floating_member_to_addr_reg_now (const char *addr_reg, int offset, int size); static void emit_load_floating_rhs_expression_now (int result_size); static void emit_load_assignment_rhs_to_reg (const char *reg); + +static int emit_load_deref_assignment_expression_to_reg_now (const char *reg); static void emit_floating_stack_to_int_pair_now (const char *lo, const char *hi); static void emit_integer_pair_to_floating_stack_now (const char *lo, const char *hi, int size); @@ -11212,6 +11212,13 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { } + if (tok.kind == TOK_STAR && emit_load_deref_assignment_expression_to_reg_now (lo)) { + + emit_extend_pair_high_from_low (lo, hi, DATA_INT & 0x1f, 0); + return; + + } + if (tok.kind != TOK_LPAREN && current_integer_expr_is_foldable_now ()) { int64_s v = const64_from_current_foldable_expr (); @@ -11644,7 +11651,7 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { enum token_kind postfix_op = TOK_EOF; char *name = xstrdup (tok.ident); - const char *name_start = tok.start, *name_caret = tok.caret; + const char *name_start = tok.report_start, *name_caret = tok.report_caret; unsigned long name_line = get_line_number (); int postfix_incdec = 0; @@ -11654,6 +11661,61 @@ static void emit_load_assignment_rhs_to_pair (const char *lo, const char *hi) { get_token (); + /* + * An assignment is an expression and may appear anywhere a value is + * accepted, including directly as a function argument: + * + * kmalloc (sector_size = disk->sector_size * count) + * + * The old 64-bit primary parser consumed the identifier as an ordinary + * value and left '=' for the call parser, which then reported + * "expected )". Parse the assignment here, store the converted + * 64-bit value, and leave that same value in the requested result pair. + */ + if (tok.kind == TOK_ASSIGN) { + + struct local_symbol *dst = find_local_symbol (name); + + int dst_global = find_global_symbol (name); + int dst_size = dst ? dst->size : (dst_global >= 0 ? get_global_symbol_size (name) : 0); + int dst_pointer = dst ? (dst->is_array || dst->pointer_depth > 0) : (dst_global >= 0 && (get_global_symbol_array (name) || get_global_symbol_pointer_depth (name) > 0)); + + if (!dst && dst_global < 0) { + + report_line_at (get_filename (), name_line, REPORT_ERROR, name_start, name_caret, "unknown symbol '%s'", name); + get_token (); + + emit_load_assignment_rhs_expression_to_pair (lo, hi, 1); + free (name); + + return; + + } + + if (dst_size == (DATA_LLONG & 0x1f) && !dst_pointer) { + + get_token (); + emit_load_assignment_rhs_expression_to_pair (lo, hi, dst ? dst->is_unsigned : get_global_symbol_unsigned (name)); + + if (dst) { + + if (dst->is_static && dst->static_label) { + emit_store_pair_to_global64 (dst->static_label, lo, hi); + } else { + emit_store_pair_to_local64 (dst->offset, lo, hi); + } + + } else { + emit_store_pair_to_global64 (name, lo, hi); + } + + free (name); + return; + + } + + } + if (strcmp (name, "__scc_builtin_va_arg") == 0 && tok.kind == TOK_LPAREN) { int va_size = DATA_INT & 0x1f; @@ -12939,9 +13001,7 @@ static void emit_apply_postfix_member_access_to_reg_now (const char *reg) { assign_op = tok.kind; get_token (); - if (assign_op == TOK_ASSIGN && subscript_elem_size > (DATA_LLONG & 0x1f) - && tok.kind == TOK_IDENT && tok.ident - && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION) { + if (assign_op == TOK_ASSIGN && subscript_elem_size > (DATA_LLONG & 0x1f) && tok.kind == TOK_IDENT && tok.ident && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION) { char *rhs_name = xstrdup (tok.ident); @@ -13799,7 +13859,7 @@ static int emit_load_address_of_parenthesized_postfix_to_reg_now (const char *re if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after '&('"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after '&('"); expect (TOK_RPAREN, ")"); return 1; @@ -13904,7 +13964,7 @@ static int emit_load_address_of_parenthesized_postfix_to_reg_now (const char *re } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "unknown symbol '%s'", name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "unknown symbol '%s'", name); free (name); expect (TOK_RPAREN, ")"); @@ -14317,8 +14377,7 @@ static int emit_aggregate_copy_from_current_rhs_to_addr_reg_now (const char *add ptr_depth = ptr_sym ? ptr_sym->pointer_depth : get_global_symbol_pointer_depth (ptr_name); ptr_pointed_size = ptr_sym ? ptr_sym->pointed_size : get_global_symbol_pointed_size (ptr_name); - if (!ptr_sym && ptr_global_index >= 0 - && get_global_symbol_kind (ptr_name) == GLOBAL_SYMBOL_FUNCTION) { + if (!ptr_sym && ptr_global_index >= 0 && get_global_symbol_kind (ptr_name) == GLOBAL_SYMBOL_FUNCTION) { const char *call_start = tok.start; const char *call_caret = tok.caret; @@ -14683,7 +14742,7 @@ static int emit_aggregate_copy_from_current_rhs_to_addr_reg_now (const char *add if (tok.kind != TOK_IDENT || !tok.ident) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected member name after %s", member_op == TOK_ARROW ? "->" : "."); free (ptr_name); @@ -15552,7 +15611,7 @@ static int emit_parse_builtin_va_arg_address_to_reg_now (const char *reg, int *o if (!is_type_start (tok.kind)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected type name in __scc_builtin_va_arg"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected type name in __scc_builtin_va_arg"); free (name); return 1; @@ -16784,25 +16843,66 @@ static int source_starts_deref_assignment_at_now (const char *p) { return 0; } - p++; + { - while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + int parens = 0; p++; - } - - if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) { - return 0; - } - - p++; - - while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || - (*p >= '0' && *p <= '9') || *p == '_') { + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + while (*p == '(') { + + parens++; + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + + if (*p == '&') { + + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + + if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_')) { + return 0; + } + p++; - } - while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { - p++; + while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || + (*p >= '0' && *p <= '9') || *p == '_') { + p++; + } + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + while (parens > 0 && *p == ')') { + + parens--; + p++; + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + } + + if (parens != 0) { + return 0; + } + } if (*p == '=' && p[1] != '=') { @@ -16838,6 +16938,9 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { enum token_kind op; + int operand_parens = 0; + int address_of_operand = 0; + int pointer_depth = 0; int pointed_size = DATA_INT & 0x1f; int value_pointer_depth = 0; @@ -16853,6 +16956,20 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { get_token (); + while (tok.kind == TOK_LPAREN) { + + operand_parens++; + get_token (); + + } + + if (tok.kind == TOK_AMPER) { + + address_of_operand = 1; + get_token (); + + } + name_start = tok.start; name_caret = tok.caret; name_line = get_line_number (); @@ -16867,6 +16984,13 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { name = xstrdup (tok.ident); get_token (); + while (operand_parens > 0) { + + expect (TOK_RPAREN, ")"); + operand_parens--; + + } + if (!is_assignment_operator (tok.kind)) { free (name); @@ -16882,21 +17006,47 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { if (sym) { - pointer_depth = sym->pointer_depth; - pointed_size = sym->pointed_size; + if (address_of_operand) { + + pointer_depth = 1; + pointed_size = sym->size; + + if (sym->is_static && sym->static_label) { + emit_load_address_to_reg_now ("ecx", sym->static_label); + } else { + emit_load_local_address_to_reg_now ("ecx", sym->offset); + } - if (sym->is_static && sym->static_label) { - emit_load_global_to_reg ("ecx", sym->static_label, DATA_PTR); } else { - emit_load_local_to_reg ("ecx", sym->offset, DATA_PTR); + + pointer_depth = sym->pointer_depth; + pointed_size = sym->pointed_size; + + if (sym->is_static && sym->static_label) { + emit_load_global_to_reg ("ecx", sym->static_label, DATA_PTR); + } else { + emit_load_local_to_reg ("ecx", sym->offset, DATA_PTR); + } + } } else if (global_index >= 0) { - pointer_depth = get_global_symbol_pointer_depth (name); - pointed_size = get_global_symbol_pointed_size (name); + if (address_of_operand) { - emit_load_global_to_reg ("ecx", name, DATA_PTR); + pointer_depth = 1; + pointed_size = get_global_symbol_size (name); + + emit_load_address_to_reg_now ("ecx", name); + + } else { + + pointer_depth = get_global_symbol_pointer_depth (name); + pointed_size = get_global_symbol_pointed_size (name); + + emit_load_global_to_reg ("ecx", name, DATA_PTR); + + } } else { @@ -16963,6 +17113,13 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { } + while (tok.kind == TOK_COMMA) { + + get_token (); + emit_load_assignment_rhs_expression_to_reg (reg); + + } + expect (TOK_RPAREN, ")"); if (value_pointer_depth > 0) { @@ -23975,10 +24132,7 @@ static int emit_load_assignment_binary_expression_prec_to_reg (const char *reg, * CHECK_READ macro in pdld with address_type fields), load the low word * from the member address instead of adding the member address itself. */ - if (postfix_member_seen - && postfix_member_pointer_depth == 0 - && postfix_member_size == (DATA_LLONG & 0x1f) - && !postfix_member_is_floating) { + if (postfix_member_seen && postfix_member_pointer_depth == 0 && postfix_member_size == (DATA_LLONG & 0x1f) && !postfix_member_is_floating) { emit_load_deref_reg_now (reg, DATA_INT & 0x1f); postfix_member_size = DATA_INT & 0x1f; @@ -25302,9 +25456,9 @@ static int parse_prefix_incdec_statement (void) { if (tok.kind != TOK_IDENT) { if (indirect) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after *"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after *"); } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); } skip_balanced_until (TOK_SEMI, TOK_EOF, TOK_EOF); @@ -27074,6 +27228,7 @@ static int parse_indirect_assignment_statement (void) { static int source_starts_parenthesized_star_now (void) { const char *p = tok.caret ? tok.caret : tok.start; + int depth = 0; if (!p) { return 0; @@ -27087,13 +27242,38 @@ static int source_starts_parenthesized_star_now (void) { return 0; } + depth = 1; p++; while (*p == ' ' || *p == '\t') { p++; } - return *p == '*'; + if (*p != '*') { + return 0; + } + + while (*p && depth > 0) { + + if (*p == '(') { + depth++; + } else if (*p == ')') { + depth--; + } + + p++; + + } + + if (depth != 0) { + return 0; + } + + while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { + p++; + } + + return *p == '.' || (*p == '-' && p[1] == '>'); } @@ -29195,7 +29375,7 @@ static int parse_inline_asm_statement (void) { if (!is_string_token ()) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected asm template string"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected asm template string"); skip_balanced_until (TOK_SEMI, TOK_EOF, TOK_EOF); expect (TOK_SEMI, ";"); @@ -29221,7 +29401,7 @@ static int parse_inline_asm_statement (void) { if (!is_string_token ()) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected asm input constraint string"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected asm input constraint string"); skip_balanced_until (TOK_RPAREN, TOK_EOF, TOK_EOF); break; @@ -31178,7 +31358,7 @@ static void parse_for_header_expression_until (enum token_kind end_token) { free (name); } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after %s", op == TOK_INCR ? "++" : "--"); } FINISH_FOR_HEADER_EXPR (0); @@ -31624,7 +31804,7 @@ static void parse_do_statement (void) { } } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected while after do statement"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected while after do statement"); } emit_statement_label (break_label); @@ -33637,8 +33817,8 @@ static int parse_postfix_assignment_statement_now (void) { if (lvalue_size > (DATA_LLONG & 0x1f) && tok.kind == TOK_IDENT && tok.ident && token_identifier_is_function_call_rhs_now () - && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION - && get_global_symbol_size (tok.ident) > (DATA_LLONG & 0x1f)) { + && get_global_symbol_kind (tok.ident) == GLOBAL_SYMBOL_FUNCTION + && get_global_symbol_size (tok.ident) > (DATA_LLONG & 0x1f)) { char *rhs_name = xstrdup (tok.ident); const char *rhs_start = tok.start; @@ -34678,7 +34858,7 @@ static int parse_possible_knr_function (void) { } if (param_name && find_pending_param_from (param_name, old_style_param_start) >= 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", param_name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", param_name); } else { add_pending_param (param_name, param_size, type_alignment (param_size), @@ -34702,7 +34882,7 @@ static int parse_possible_knr_function (void) { } else if (token_is_ident ()) { if (find_pending_param_from (tok.ident, old_style_param_start) >= 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", tok.ident); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", tok.ident); } else { add_pending_param (tok.ident, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0, 0); @@ -35094,7 +35274,7 @@ static void parse_global_initializer_values (int64_s *values, char **symbols, in get_token (); if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected identifier after '&'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected identifier after '&'"); } else { char addr_symbol[256]; @@ -35370,7 +35550,7 @@ static void emit_global_address (const char *symbol, int size) { } if (size != DATA_PTR) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "address initializer requires pointer-sized object"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "address initializer requires pointer-sized object"); } emit_extern_reference_symbol (symbol, DATA_PTR); @@ -36150,7 +36330,7 @@ static void parse_external_after_type (void) { if (tok.kind == TOK_SEMI) { get_token (); } else if (is_type_start (tok.kind)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "missing ';' after declaration"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "missing ';' after declaration"); } else { expect (TOK_SEMI, ";"); } @@ -36201,7 +36381,7 @@ void compile_translation_unit32 (void) { continue; } - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected external declaration"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected external declaration"); get_token (); } diff --git a/parse.c b/parse.c index 447c042..5288d5f 100644 --- a/parse.c +++ b/parse.c @@ -126,7 +126,7 @@ int expect (enum token_kind k, const char *what) { } - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected %s", what); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected %s", what); return 0; } @@ -348,7 +348,7 @@ static void parse_enum_body (void) { if (!token_is_ident ()) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected enum constant"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected enum constant"); get_token (); continue; @@ -408,9 +408,9 @@ static void parse_decl_modifier (void) { } else if (tok.kind == TOK_DLLEXPORT) { if (parsed_dllexport) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate '__dllexport'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__dllexport'"); } else if (parsed_dllimport) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "'__dllexport' and '__dllimport' cannot both be specified"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "'__dllexport' and '__dllimport' cannot both be specified"); } else { declarator_dllexport = 1; @@ -421,9 +421,9 @@ static void parse_decl_modifier (void) { } else if (tok.kind == TOK_DLLIMPORT) { if (parsed_dllimport) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate '__dllimport'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__dllimport'"); } else if (parsed_dllexport) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "'__dllexport' and '__dllimport' cannot both be specified"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "'__dllexport' and '__dllimport' cannot both be specified"); } else { declarator_dllimport = 1; @@ -694,7 +694,7 @@ static int parse_sizeof_member_expr_size (int leading_stars, int *out_size) { array_element_size = get_global_symbol_array_element_size (tok.ident); } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "unknown symbol '%s'", tok.ident ? tok.ident : ""); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "unknown symbol '%s'", tok.ident ? tok.ident : ""); } final_pointer_depth = pointer_depth; @@ -719,7 +719,7 @@ static int parse_sizeof_member_expr_size (int leading_stars, int *out_size) { if (tok.kind != TOK_IDENT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected member name after %s", member_op == TOK_ARROW ? "->" : "."); break; @@ -750,7 +750,7 @@ static int parse_sizeof_member_expr_size (int leading_stars, int *out_size) { } else { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "unknown member '%s'", tok.ident ? tok.ident : ""); } @@ -2253,7 +2253,7 @@ void add_pending_param (const char *name, int size, int align, int is_unsigned, if (pending_param_count >= MAX_PENDING_PARAMS) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many function parameters"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many function parameters"); return; } @@ -2444,9 +2444,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_EXTERN) { if (parsed_storage_class == STORAGE_EXTERN) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'extern'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'extern'"); } else if (parsed_storage_class != STORAGE_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple storage classes in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple storage classes in declaration specifiers"); } else { parsed_storage_class = STORAGE_EXTERN; } @@ -2454,9 +2454,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_STATIC) { if (parsed_storage_class == STORAGE_STATIC) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'static'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'static'"); } else if (parsed_storage_class != STORAGE_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple storage classes in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple storage classes in declaration specifiers"); } else { parsed_storage_class = STORAGE_STATIC; } @@ -2464,9 +2464,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_TYPEDEF) { if (parsed_storage_class == STORAGE_TYPEDEF) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'typedef'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'typedef'"); } else if (parsed_storage_class != STORAGE_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple storage classes in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple storage classes in declaration specifiers"); } else { parsed_storage_class = STORAGE_TYPEDEF; } @@ -2478,9 +2478,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_CHAR) { if (parsed_type_size == DATA_CHAR) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'char'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'char'"); } else if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_CHAR; } @@ -2488,9 +2488,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_SHORT) { if (parsed_type_size == DATA_SHORT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'short'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'short'"); } else if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_SHORT; } @@ -2498,9 +2498,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_INT) { if (parsed_type_size == DATA_INT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'int'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'int'"); } else if (parsed_type_size != DATA_NONE) { - /*report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers");*/ + /*report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers");*/ } else { parsed_type_size = DATA_INT; } @@ -2510,9 +2510,9 @@ void parse_type_spec (void) { if (parsed_type_size == DATA_LONG) { parsed_type_size = DATA_LLONG; } else if (parsed_type_size == DATA_LLONG) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "too many 'long' keywords"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "too many 'long' keywords"); } else if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_LONG; } @@ -2524,9 +2524,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_FLOAT) { if (parsed_type_size == DATA_FLOAT) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'float'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'float'"); } else if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_FLOAT; @@ -2542,9 +2542,9 @@ void parse_type_spec (void) { saw_double = 1; } else if (parsed_type_size == DATA_DOUBLE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'double'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'double'"); } else if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_DOUBLE; @@ -2555,9 +2555,9 @@ void parse_type_spec (void) { } else if (tok.kind == TOK_VOID) { if (parsed_type_size == DATA_VOID) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate 'void'"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate 'void'"); } else if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_VOID; @@ -2572,7 +2572,7 @@ void parse_type_spec (void) { if (strcmp (tok.ident, "__int8") == 0) { if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_CHAR & 0x1f; } @@ -2580,7 +2580,7 @@ void parse_type_spec (void) { } else if (strcmp (tok.ident, "__int16") == 0) { if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_SHORT & 0x1f; } @@ -2588,7 +2588,7 @@ void parse_type_spec (void) { } else if (strcmp (tok.ident, "__int32") == 0) { if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_INT & 0x1f; } @@ -2596,7 +2596,7 @@ void parse_type_spec (void) { } else { if (parsed_type_size != DATA_NONE) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "multiple data types in declaration specifiers"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "multiple data types in declaration specifiers"); } else { parsed_type_size = DATA_LLONG & 0x1f; } @@ -2740,7 +2740,7 @@ void parse_type_spec (void) { if (!is_type_start (tok.kind)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected member declaration"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected member declaration"); skip_balanced_until (TOK_SEMI, TOK_RBRACE, TOK_EOF); _accept (TOK_SEMI); @@ -3081,11 +3081,11 @@ void parse_type_spec (void) { parsed_type_is_floating = (saw_float || saw_double) ? 1 : 0; if (saw_signed && saw_unsigned) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "both signed and unsigned specified"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "both signed and unsigned specified"); } if ((saw_signed || saw_unsigned) && (saw_float || saw_double || saw_void)) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "signed/unsigned invalid for this type"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "signed/unsigned invalid for this type"); } parsed_type_is_unsigned = saw_unsigned ? 1 : 0; @@ -3093,7 +3093,7 @@ void parse_type_spec (void) { if (!saw) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "expected type"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected type"); get_token (); } @@ -3321,7 +3321,7 @@ void parse_direct_declarator (char **out_name) { if (declarator_depth == 1) { if (find_pending_param_from (param_name, old_style_param_start) >= 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", param_name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", param_name); } else { add_pending_param (param_name, param_size, type_alignment (param_size), 0, 0, unknown_typedef_pointer ? 1 : 0, DATA_INT & 0x1f, 0); } @@ -3341,7 +3341,7 @@ void parse_direct_declarator (char **out_name) { if (declarator_depth == 1) { if (find_pending_param_from (maybe_type_name, old_style_param_start) >= 0) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.start, tok.caret, "duplicate parameter '%s'", maybe_type_name); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", maybe_type_name); } else { add_pending_param (maybe_type_name, DATA_INT & 0x1f, type_alignment (DATA_INT & 0x1f), 0, 0, 0, 0, 0); } diff --git a/pp.c b/pp.c index 074f7d7..103c3eb 100755 --- a/pp.c +++ b/pp.c @@ -1139,6 +1139,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = temp; tok->len = (caret - start); @@ -1165,6 +1168,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = xstrndup (start, (int) (caret - start)); tok->len = (caret - start); @@ -1220,6 +1226,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = temp; tok->len = (caret - start); @@ -1246,6 +1255,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = xstrndup (start, (int) (caret - start)); tok->len = (caret - start); @@ -1374,6 +1386,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = xstrndup (start, (int) (caret - start)); tok->len = (caret - start); @@ -1432,6 +1447,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = xstrndup (start, (int) (caret - start)); tok->len = (caret - start); @@ -1544,6 +1562,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + tok->ident = xstrndup (start, (int) (caret - start)); tok->len = (caret - start); @@ -1604,6 +1625,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret, tok->start = in_macro ? *line : (real_start ? real_start : *line); tok->caret = in_macro ? start : (real_caret ? real_caret : start); + tok->report_start = in_macro ? (real_start ? real_start : *line) : *line; + tok->report_caret = in_macro ? (real_caret ? real_caret : start) : start; + vec_push (&vector_tokens, tok); continue; diff --git a/token.c b/token.c index 0b0f962..605ff8b 100755 --- a/token.c +++ b/token.c @@ -926,7 +926,7 @@ static void scan_ch (struct token *tok, int is_long) { if (!has_warned) { - report_line_at (get_filename (), get_line_number (), REPORT_WARNING, tok->start, tok->caret, "multi-character character constant"); + report_line_at (get_filename (), get_line_number (), REPORT_WARNING, tok->report_start, tok->report_caret, "multi-character character constant"); has_warned = 1; } @@ -1780,7 +1780,7 @@ static void parse_number (struct token *tok) { } else if (t == 'U') { if (ucount >= 1) { - report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok->start, tok->caret, "two 'U's in integer constant"); + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok->report_start, tok->report_caret, "two 'U's in integer constant"); } ucount++; @@ -1881,6 +1881,9 @@ void unget_token (struct token *saved_tok) { tok.start = saved_tok->start; tok.caret = saved_tok->caret; + tok.report_start = saved_tok->report_start; + tok.report_caret = saved_tok->report_caret; + tok.ident = saved_tok->ident; tok.len = saved_tok->len; diff --git a/token.h b/token.h index 6882c8b..4e277d9 100755 --- a/token.h +++ b/token.h @@ -134,8 +134,8 @@ enum token_kind { struct token { - const char *start; - const char *caret; + const char *start, *report_start; + const char *caret, *report_caret; char *ident; unsigned long len;