MAcro and codegen fixes
authorRobert Pengelly <robertapengelly@hotmail.com>
Wed, 15 Jul 2026 19:54:54 +0000 (20:54 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Wed, 15 Jul 2026 19:54:54 +0000 (20:54 +0100)
amd64.c
i386.c
parse.c
pp.c

diff --git a/amd64.c b/amd64.c
index 31071487f0ff476e4da2ecdbe3a033366ee73c30..5b46d6377f7b099b63df9e4e6cc20de9dd5eb321 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -6516,13 +6516,7 @@ static int recover_unknown_rhs_identifier (void) {
 }*/
 
 static void skip_initializer (void) {
-
-    if (tok.kind == TOK_LBRACE) {
-        skip_balanced_until (TOK_COMMA, TOK_SEMI, TOK_EOF);
-    } else {
-        skip_balanced_until (TOK_COMMA, TOK_SEMI, TOK_EOF);
-    }
-
+    skip_balanced_until (TOK_COMMA, TOK_RBRACE, TOK_EOF);
 }
 
 static void apply_typedef_array_to_declarator (void) {
@@ -8322,12 +8316,15 @@ static void parse_local_string_field_initializer (struct local_init *inits, int
 static void parse_local_aggregate_initializer_values (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count) {
 
     int field_index = 0;
-    long field_offset = 0;
     int braced = 0;
     
+    long field_offset = 0;
+    
     if (tok.kind == TOK_LBRACE) {
+    
         braced = 1;
         get_token ();
+    
     }
     
     while (field_index < field_count) {
@@ -26973,8 +26970,8 @@ static int emit_load_assignment_binary_expression_prec_to_reg (const char *reg,
      * The normal arithmetic path below can operate on the qword value already
      * held in REG.
      */
-    if (postfix_member_seen && postfix_member_is_unsigned) {
-        is_unsigned = 1;
+    if (postfix_member_seen) {
+        is_unsigned = postfix_member_is_unsigned ? 1 : 0;
     }
     
     expr_pointer_depth = rhs_last_pointer_depth;
@@ -27141,18 +27138,10 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) {
     int64_s rhs_enum_value;
     enum token_kind op;
     
-    int lhs_pointer_depth;
-    int is_unsigned;
+    int is_unsigned = emit_load_assignment_binary_expression_prec_to_reg (reg, 1);;
+    int lhs_pointer_depth = rhs_last_pointer_depth;
     int rhs_is_enum;
     
-    is_unsigned = rhs_current_operand_is_unsigned_now ();
-    
-    if (emit_load_assignment_binary_expression_prec_to_reg (reg, 1)) {
-        is_unsigned = 1;
-    }
-    
-    lhs_pointer_depth = rhs_last_pointer_depth;
-    
     if (assignment32_stop_before_condition_operator && is_assignment32_condition_stop_operator (tok.kind)) {
         return;
     }
@@ -33404,8 +33393,8 @@ static int emit_statement_member_enum_compare_jump_if_false_now (int label) {
         emit_apply_postfix_member_access_to_reg_now ("rax");
     }
     
-    if (postfix_member_seen && postfix_member_is_unsigned) {
-        is_unsigned = 1;
+    if (postfix_member_seen) {
+        is_unsigned = postfix_member_is_unsigned ? 1 : 0;
     }
     
     if (!token_is_statement_compare_operator (tok.kind)) {
@@ -37627,6 +37616,42 @@ static int global_initializer_cast_before_string_now (void) {
 
 }
 
+static int global_initializer_cast_before_symbol_now (void) {
+
+    const char *p = tok.caret;
+    int depth;
+    
+    if (!p || *p != '(') {
+        return 0;
+    }
+    
+    p++;
+    depth = 1;
+    
+    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 ident_start_now ((unsigned char) *p);
+
+}
+
 static void append_global_zero_initializer_value (int64_s *values, char **symbols, int max_values, int *count) {
 
     if (*count < max_values) {
@@ -37767,6 +37792,36 @@ static void parse_global_initializer_values (int64_s *values, char **symbols, in
             expect (TOK_RPAREN, ")");
             (*count)++;
         
+        } else if (global_initializer_accept_symbol_addresses && tok.kind == TOK_LPAREN && global_initializer_cast_before_symbol_now ()) {
+        
+            int cast_size = 0;
+            int cast_is_unsigned = 0;
+            int cast_is_pointer = 0;
+            
+            get_token ();
+            
+            if (!token_starts_type_name () || !parse_cast_type_name (&cast_size, &cast_is_unsigned, &cast_is_pointer)) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "invalid cast in global initializer");
+            } else if (tok.kind != TOK_IDENT || find_global_symbol (tok.ident) < 0) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "global symbol expected after cast");
+            } else {
+            
+                if (*count < max_values) {
+                
+                    values[*count].low = 0;
+                    values[*count].high = 0;
+                    
+                    if (symbols) {
+                        symbols[*count] = xstrdup (tok.ident);
+                    }
+                
+                }
+                
+                (*count)++;
+                get_token ();
+            
+            }
+        
         } else if (tok.kind == TOK_LPAREN && global_initializer_cast_before_string_now ()) {
         
             int cast_size = 0;
diff --git a/i386.c b/i386.c
index 3cc6f35feaa93958560fe2527962766989c757a7..d5a9c6d982f55f34736c2fdcfb6fc49cbcc15e6a 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -6102,13 +6102,7 @@ static int recover_unknown_rhs_identifier (void) {
 }*/
 
 static void skip_initializer (void) {
-
-    if (tok.kind == TOK_LBRACE) {
-        skip_balanced_until (TOK_COMMA, TOK_SEMI, TOK_EOF);
-    } else {
-        skip_balanced_until (TOK_COMMA, TOK_SEMI, TOK_EOF);
-    }
-
+    skip_balanced_until (TOK_COMMA, TOK_RBRACE, TOK_EOF);
 }
 
 static void apply_typedef_array_to_declarator (void) {
@@ -7538,12 +7532,15 @@ static void parse_local_string_field_initializer (struct local_init *inits, int
 static void parse_local_aggregate_initializer_values (struct local_init *inits, int *init_count, int max_inits, long base_offset, const int *fields, int field_count) {
 
     int field_index = 0;
-    long field_offset = 0;
     int braced = 0;
     
+    long field_offset = 0;
+    
     if (tok.kind == TOK_LBRACE) {
+    
         braced = 1;
         get_token ();
+    
     }
     
     while (field_index < field_count) {
@@ -24150,8 +24147,8 @@ static int emit_load_assignment_binary_expression_prec_to_reg (const char *reg,
     
     }
     
-    if (postfix_member_seen && postfix_member_is_unsigned) {
-        is_unsigned = 1;
+    if (postfix_member_seen) {
+        is_unsigned = postfix_member_is_unsigned ? 1 : 0;
     }
     
     expr_pointer_depth = rhs_last_pointer_depth;
@@ -24318,18 +24315,10 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) {
     int64_s rhs_enum_value;
     enum token_kind op;
     
-    int lhs_pointer_depth;
-    int is_unsigned;
+    int is_unsigned = emit_load_assignment_binary_expression_prec_to_reg (reg, 1);;
+    int lhs_pointer_depth = rhs_last_pointer_depth;
     int rhs_is_enum;
     
-    is_unsigned = rhs_current_operand_is_unsigned_now ();
-    
-    if (emit_load_assignment_binary_expression_prec_to_reg (reg, 1)) {
-        is_unsigned = 1;
-    }
-    
-    lhs_pointer_depth = rhs_last_pointer_depth;
-    
     if (assignment32_stop_before_condition_operator && is_assignment32_condition_stop_operator (tok.kind)) {
         return;
     }
@@ -30741,8 +30730,8 @@ static int emit_statement_member_enum_compare_jump_if_false_now (int label) {
         emit_apply_postfix_member_access_to_reg_now ("eax");
     }
     
-    if (postfix_member_seen && postfix_member_is_unsigned) {
-        is_unsigned = 1;
+    if (postfix_member_seen) {
+        is_unsigned = postfix_member_is_unsigned ? 1 : 0;
     }
     
     if (!token_is_statement_compare_operator (tok.kind)) {
@@ -35114,6 +35103,42 @@ static int global_initializer_cast_before_string_now (void) {
 
 }
 
+static int global_initializer_cast_before_symbol_now (void) {
+
+    const char *p = tok.caret;
+    int depth;
+    
+    if (!p || *p != '(') {
+        return 0;
+    }
+    
+    p++;
+    depth = 1;
+    
+    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 ident_start_now ((unsigned char) *p);
+
+}
+
 static void append_global_zero_initializer_value (int64_s *values, char **symbols, int max_values, int *count) {
 
     if (*count < max_values) {
@@ -35254,6 +35279,36 @@ static void parse_global_initializer_values (int64_s *values, char **symbols, in
             expect (TOK_RPAREN, ")");
             (*count)++;
         
+        } else if (global_initializer_accept_symbol_addresses && tok.kind == TOK_LPAREN && global_initializer_cast_before_symbol_now ()) {
+        
+            int cast_size = 0;
+            int cast_is_unsigned = 0;
+            int cast_is_pointer = 0;
+            
+            get_token ();
+            
+            if (!token_starts_type_name () || !parse_cast_type_name (&cast_size, &cast_is_unsigned, &cast_is_pointer)) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "invalid cast in global initializer");
+            } else if (tok.kind != TOK_IDENT || find_global_symbol (tok.ident) < 0) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "global symbol expected after cast");
+            } else {
+            
+                if (*count < max_values) {
+                
+                    values[*count].low = 0;
+                    values[*count].high = 0;
+                    
+                    if (symbols) {
+                        symbols[*count] = xstrdup (tok.ident);
+                    }
+                
+                }
+                
+                (*count)++;
+                get_token ();
+            
+            }
+        
         } else if (tok.kind == TOK_LPAREN && global_initializer_cast_before_string_now ()) {
         
             int cast_size = 0;
diff --git a/parse.c b/parse.c
index b119613a8ff9c63b1f3ff50791a0fe4c71c2e4b1..01c535aaaded05df8a34792d9474c4a3b20144b7 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -974,7 +974,7 @@ void skip_balanced_until (enum token_kind stop1, enum token_kind stop2, enum tok
                 brace--;
             } else {
             
-                if (stop1 == TOK_RPAREN || stop2 == TOK_RPAREN || stop3 == TOK_RPAREN) {
+                if (stop1 == TOK_RBRACE || stop2 == TOK_RBRACE || stop3 == TOK_RBRACE) {
                     return;
                 }
             
@@ -988,7 +988,7 @@ void skip_balanced_until (enum token_kind stop1, enum token_kind stop2, enum tok
                 brack--;
             } else {
             
-                if (stop1 == TOK_RPAREN || stop2 == TOK_RPAREN || stop3 == TOK_RPAREN) {
+                if (stop1 == TOK_RBRACK || stop2 == TOK_RBRACK || stop3 == TOK_RBRACK) {
                     return;
                 }
             
diff --git a/pp.c b/pp.c
index 103c3ebdb9f7ea4aa3d574cd122d9e76bbd0cb7c..03389b22a2919904c2b124a325defee5e0fa461d 100755 (executable)
--- a/pp.c
+++ b/pp.c
@@ -1274,11 +1274,11 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret,
             
                 char *pm;
                 
-                if ((key = find_macro (sname))) {
+                if ((key = find_macro (sname)) && (m = get_macro (key)) && (m->nargs < 0 || *skip_whitespace (caret) == '(')) {
                 
                     hashtab_put (&hashtab_seen_macros, key, sname);
                     
-                    if ((m = get_macro (key))) {
+                    {
                     
                         if (m->nargs >= 0) {
                             caret = skip_whitespace (caret);
@@ -1348,34 +1348,20 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret,
                     
                     hashtab_remove (&hashtab_seen_macros, key);
                     
-                    /*while (!is_end_of_line[(int) *caret]) {
-                    
-                        if (isspace ((int) *caret)) {
-                            break;
-                        }
-                        
-                        if (state->mode == CC_MODE_PREPROCESS) {
-                            fputc (*caret, state->ofp);
-                        }
-                        
-                        caret++;
-                    
-                    }*/
-                    
+                    free (sname);
                     continue;
                 
                 }
             
             }
             
-            free (sname);
-            
             if (state->mode == CC_MODE_PREPROCESS) {
             
                 if (state->ofp) {
-                    fprintf (state->ofp, "%.*s", (int) (caret - start), start);
+                    fprintf (state->ofp, "%s", sname);
                 }
                 
+                free (sname);
                 continue;
             
             }
@@ -1389,10 +1375,9 @@ struct vector *preprocess_line (char **line, char *real_start, char *real_caret,
             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);
-            
+            tok->len = strlen (tok->ident = sname);
             vec_push (&vector_tokens, tok);
+            
             continue;
         
         }