@@ -856,6 +856,13 @@ static inline bool is_stmt_expr_open(Token *t) {
856856 return match_ch (t , '(' ) && tok_next (t ) && match_ch (tok_next (t ), '{' );
857857}
858858
859+ // 'else' keyword (TT_IF covers both if and else; 'e' distinguishes)
860+ static inline bool is_else_kw (Token * t ) { return (t -> tag & TT_IF ) && t -> ch0 == 'e' ; }
861+ // 'do' keyword (TT_LOOP covers for/while/do; 'd' distinguishes)
862+ static inline bool is_do_kw (Token * t ) { return (t -> tag & TT_LOOP ) && t -> ch0 == 'd' ; }
863+ // Either else or do (no-condition ctrl-flow)
864+ static inline bool is_else_or_do (Token * t ) { return is_else_kw (t ) || is_do_kw (t ); }
865+
859866static inline bool _equal_2 (Token * tok , const char * s ) {
860867 if (tok -> len != 2 || tok -> ch0 != (uint8_t )s [0 ]) return false;
861868 return tok_loc (tok )[1 ] == s [1 ];
@@ -2122,12 +2129,12 @@ typedef enum {
21222129
21232130typedef struct {
21242131 char * name ; // Points into token stream (no alloc needed)
2125- int len ;
2126- int scope_depth ; // Scope where defined (aligns with ctx->block_depth)
2127- int prev_index ; // Index of previous entry with same name (-1 if none), for hash map chaining
2132+ int prev_index ; // Index of previous entry with same name (-1 if none)
21282133 uint32_t token_index ; // Token pool index of the declaration
21292134 uint32_t scope_open_idx ; // Token index of enclosing '{' (0 for file scope)
21302135 uint32_t scope_close_idx ; // Token index of matching '}' (UINT32_MAX for file scope)
2136+ uint16_t len ;
2137+ uint16_t scope_depth ; // Scope where defined (aligns with ctx->block_depth)
21312138 bool is_vla : 1 ;
21322139 bool is_void : 1 ;
21332140 bool is_const : 1 ;
@@ -2140,7 +2147,7 @@ typedef struct {
21402147 bool is_aggregate : 1 ;
21412148 bool is_func : 1 ;
21422149 bool is_param : 1 ;
2143- } TypedefEntry ;
2150+ } TypedefEntry ; // 32 bytes — two entries per 64-byte cache line
21442151
21452152typedef struct {
21462153 TypedefEntry * entries ;
@@ -2178,6 +2185,10 @@ static PRISM_THREAD_LOCAL uint32_t td_scope_open = 0;
21782185static PRISM_THREAD_LOCAL uint32_t td_scope_close = UINT32_MAX ;
21792186static PRISM_THREAD_LOCAL bool p1_typedef_annotated ; // true after p1_annotate_typedefs(); enables O(1) is_known_typedef
21802187
2188+ // Save/restore typedef scope range context (used 5+ sites).
2189+ #define TD_SCOPE_SAVE () uint32_t _tds_o = td_scope_open, _tds_c = td_scope_close
2190+ #define TD_SCOPE_RESTORE () do { td_scope_open = _tds_o; td_scope_close = _tds_c; } while(0)
2191+
21812192// --- Utility Inlines ---
21822193
21832194#define is_c23_attr (t ) ((t) && ((t)->flags & TF_C23_ATTR))
@@ -2365,6 +2376,18 @@ static inline bool is_valid_varname(Token *tok) {
23652376 return tok -> kind == TK_IDENT || (tok -> flags & TF_RAW ) || (tok -> tag & (TT_DEFER | TT_ORELSE ));
23662377}
23672378
2379+ // Token ends an expression (value-producing): ident, keyword, num, str, ), ].
2380+ static inline bool is_expr_ending (Token * t ) {
2381+ return (t -> kind == TK_IDENT || t -> kind == TK_KEYWORD ||
2382+ t -> kind == TK_NUM || t -> kind == TK_STR ) ||
2383+ match_set (t , CH (')' ) | CH (']' ));
2384+ }
2385+
2386+ // Extended version including '}' (for compound literal / brace init contexts).
2387+ static inline bool is_expr_ending_brace (Token * t ) {
2388+ return is_expr_ending (t ) || match_ch (t , '}' );
2389+ }
2390+
23682391static DeclResult parse_declarator (Token * tok , bool emit );
23692392
23702393// Register enum constants as typedef shadows. tok points to opening '{'.
@@ -2983,17 +3006,24 @@ static void parse_typedef_declaration(Token *tok, int scope_depth) {
29833006
29843007// --- skip_one_stmt ---
29853008
3009+ // Limits for skip_one_stmt_impl stack arrays.
3010+ // if_depth can exceed SOS_IF_MAX (cache optimization degrades gracefully).
3011+ // do_depth is hard-capped at SOS_DO_MAX (gives up on pathological input).
3012+ #define SOS_IF_MAX 512
3013+ #define SOS_DO_MAX 128
3014+ #define SOS_SNAP_MAX 1024
3015+
29863016static Token * skip_one_stmt_impl (Token * tok , uint32_t * cache ) {
29873017 int if_depth = 0 ;
29883018 int do_depth = 0 ;
2989- int do_if_save [4096 ];
2990- int do_tn_save [4096 ];
2991- int do_snap_buf [4096 ]; // flat buffer saving if_trail_snap per do level
2992- int do_snap_start [4096 ];
3019+ int do_if_save [SOS_DO_MAX ];
3020+ int do_tn_save [SOS_DO_MAX ];
3021+ int do_snap_buf [SOS_SNAP_MAX ]; // flat buffer saving if_trail_snap per do level
3022+ int do_snap_start [SOS_DO_MAX ];
29933023 int do_snap_top = 0 ;
29943024 uint32_t trail [256 ];
29953025 int tn = 0 ;
2996- int if_trail_snap [4096 ]; // trail length snapshot at each if_depth entry
3026+ int if_trail_snap [SOS_IF_MAX ]; // trail length snapshot at each if_depth entry
29973027restart :
29983028 tok = skip_prep_dirs (tok );
29993029 tok = skip_noise (tok );
@@ -3014,7 +3044,7 @@ static Token *skip_one_stmt_impl(Token *tok, uint32_t *cache) {
30143044 if (tok -> ch0 == 'e' ) { tok = tok_next (tok ); goto restart ; }
30153045 Token * p = skip_prep_dirs (tok_next (tok ));
30163046 if (!p || !(p -> len == 1 && p -> ch0 == '(' ) || !tok_match (p )) return NULL ;
3017- if (if_depth < 4096 ) if_trail_snap [if_depth ] = tn ;
3047+ if (if_depth < SOS_IF_MAX ) if_trail_snap [if_depth ] = tn ;
30183048 if_depth ++ ;
30193049 tok = tok_next (tok_match (p )); goto restart ;
30203050 }
@@ -3026,11 +3056,11 @@ static Token *skip_one_stmt_impl(Token *tok, uint32_t *cache) {
30263056 }
30273057
30283058 if ((tok -> tag & TT_LOOP ) && tok -> ch0 == 'd' ) {
3029- if (do_depth >= 4096 ) return NULL ;
3059+ if (do_depth >= SOS_DO_MAX ) return NULL ;
30303060 do_if_save [do_depth ] = if_depth ;
30313061 do_tn_save [do_depth ] = tn ;
30323062 do_snap_start [do_depth ] = do_snap_top ;
3033- for (int i = 0 ; i < if_depth && do_snap_top < 4096 ; i ++ )
3063+ for (int i = 0 ; i < if_depth && i < SOS_IF_MAX && do_snap_top < SOS_SNAP_MAX ; i ++ )
30343064 do_snap_buf [do_snap_top ++ ] = if_trail_snap [i ];
30353065 do_depth ++ ;
30363066 if_depth = 0 ;
@@ -3071,7 +3101,7 @@ static Token *skip_one_stmt_impl(Token *tok, uint32_t *cache) {
30713101 if (n && (n -> tag & TT_IF ) && n -> ch0 == 'e' ) {
30723102 // Only flush trail entries from THIS if level (true-branch),
30733103 // not parent tokens that span the entire if-else.
3074- int snap = (if_depth < 4096 ) ? if_trail_snap [if_depth ] : 0 ;
3104+ int snap = (if_depth < SOS_IF_MAX ) ? if_trail_snap [if_depth ] : 0 ;
30753105 if (cache && tok ) {
30763106 uint32_t val = tok_idx (tok ) + 1 ;
30773107 for (int i = snap ; i < tn ; i ++ ) cache [trail [i ]] = val ;
0 commit comments