Corrected diagnositics, 64-bit fixes and macro fixes
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 14 Jul 2026 18:12:52 +0000 (19:12 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 14 Jul 2026 18:12:52 +0000 (19:12 +0100)
amd64.c
i386.c
parse.c
pp.c
token.c
token.h

diff --git a/amd64.c b/amd64.c
index 146aa823113732629e3402757d1a8055532732dd..4e7c9639a3803dfe62c0184bbcc63fe47233967a 100644 (file)
--- 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 1fc3f1f5c87cf84a0bb6d1e75a9eccc37b6b66f9..0f80607d80ab1b0a07551cbacb72c98b8da9165c 100644 (file)
--- 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 447c0427c4d0b4d2a0967c983dee57d50fb3de4b..5288d5fbe1693319739236d8e0b3b1653f27611e 100644 (file)
--- 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 074f7d7b126a3ad822fe66b15a93261457dc789f..103c3ebdb9f7ea4aa3d574cd122d9e76bbd0cb7c 100755 (executable)
--- 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 0b0f96230160b75722cff8fed491cb7a1e3aa3bd..605ff8b64ad5faf91390ca70ddec61a00ea0c0b1 100755 (executable)
--- 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 6882c8bbb1d43a97d3736f8e0bdab9dcce9edb8e..4e277d9f3ab20fe914cab07c836fcbc666767004 100755 (executable)
--- 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;