@@ -657,7 +657,7 @@ void read_parameter_list_decl(func_t *func, int anon);
657
657
void read_inner_var_decl (var_t * vd , int anon , int is_param )
658
658
{
659
659
vd -> init_val = 0 ;
660
- vd -> is_ptr = 0 ;
660
+ /* Preserve typedef pointer level - don't reset if already inherited */
661
661
662
662
while (lex_accept (T_asterisk ))
663
663
vd -> is_ptr ++ ;
@@ -715,6 +715,11 @@ void read_full_var_decl(var_t *vd, int anon, int is_param)
715
715
}
716
716
717
717
vd -> type = type ;
718
+
719
+ /* Inherit pointer level from typedef */
720
+ if (type -> ptr_level > 0 )
721
+ vd -> is_ptr = type -> ptr_level ;
722
+
718
723
read_inner_var_decl (vd , anon , is_param );
719
724
}
720
725
@@ -963,21 +968,33 @@ void read_expr_operand(block_t *parent, basic_block_t **bb)
963
968
lvalue_t lvalue ;
964
969
965
970
int open_bracket = lex_accept (T_open_bracket );
966
- lex_peek (T_identifier , token );
967
- var_t * var = find_var (token , parent );
968
- read_lvalue (& lvalue , var , parent , bb , true, OP_generic );
969
- if (open_bracket )
971
+ if (open_bracket ) {
972
+ /* Handle expressions like *(++p) */
973
+ read_expr (parent , bb );
970
974
lex_expect (T_close_bracket );
975
+ rs1 = opstack_pop ();
976
+ /* Create a temporary variable for the dereferenced result */
977
+ vd = require_var (parent );
978
+ vd -> type = TY_int ; /* Default to int type for now */
979
+ vd -> is_ptr = 0 ;
980
+ gen_name_to (vd -> var_name );
981
+ opstack_push (vd );
982
+ add_insn (parent , * bb , OP_read , vd , rs1 , NULL , vd -> type -> size , NULL );
983
+ } else {
984
+ lex_peek (T_identifier , token );
985
+ var_t * var = find_var (token , parent );
986
+ read_lvalue (& lvalue , var , parent , bb , true, OP_generic );
971
987
972
- rs1 = opstack_pop ();
973
- vd = require_deref_var (parent , var -> type , var -> is_ptr );
974
- if (lvalue .is_ptr > 1 )
975
- sz = PTR_SIZE ;
976
- else
977
- sz = lvalue .type -> size ;
978
- gen_name_to (vd -> var_name );
979
- opstack_push (vd );
980
- add_insn (parent , * bb , OP_read , vd , rs1 , NULL , sz , NULL );
988
+ rs1 = opstack_pop ();
989
+ vd = require_deref_var (parent , var -> type , var -> is_ptr );
990
+ if (lvalue .is_ptr > 1 )
991
+ sz = PTR_SIZE ;
992
+ else
993
+ sz = lvalue .type -> size ;
994
+ gen_name_to (vd -> var_name );
995
+ opstack_push (vd );
996
+ add_insn (parent , * bb , OP_read , vd , rs1 , NULL , sz , NULL );
997
+ }
981
998
} else if (lex_accept (T_open_bracket )) {
982
999
read_expr (parent , bb );
983
1000
read_ternary_operation (parent , bb );
@@ -1374,8 +1391,31 @@ void read_lvalue(lvalue_t *lvalue,
1374
1391
error ("Cannot apply square operator to non-pointer" );
1375
1392
1376
1393
/* if nested pointer, still pointer */
1377
- if (var -> is_ptr <= 1 && var -> array_size == 0 )
1378
- lvalue -> size = lvalue -> type -> size ;
1394
+ if (var -> is_ptr <= 1 && var -> array_size == 0 ) {
1395
+ /* For typedef pointers, get the size of the base type that the
1396
+ * pointer points to
1397
+ */
1398
+ if (lvalue -> type -> ptr_level > 0 ) {
1399
+ /* This is a typedef pointer, get base type size */
1400
+ switch (lvalue -> type -> base_type ) {
1401
+ case TYPE_char :
1402
+ lvalue -> size = TY_char -> size ;
1403
+ break ;
1404
+ case TYPE_int :
1405
+ lvalue -> size = TY_int -> size ;
1406
+ break ;
1407
+ case TYPE_void :
1408
+ /* void pointers treated as byte pointers */
1409
+ lvalue -> size = 1 ;
1410
+ break ;
1411
+ default :
1412
+ lvalue -> size = lvalue -> type -> size ;
1413
+ break ;
1414
+ }
1415
+ } else {
1416
+ lvalue -> size = lvalue -> type -> size ;
1417
+ }
1418
+ }
1379
1419
1380
1420
read_expr (parent , bb );
1381
1421
@@ -1529,7 +1569,12 @@ void read_lvalue(lvalue_t *lvalue,
1529
1569
if (prefix_op != OP_generic ) {
1530
1570
vd = require_var (parent );
1531
1571
gen_name_to (vd -> var_name );
1532
- vd -> init_val = 1 ;
1572
+ /* For pointer arithmetic, increment by the size of pointed-to type
1573
+ */
1574
+ if (lvalue -> is_ptr )
1575
+ vd -> init_val = lvalue -> type -> size ;
1576
+ else
1577
+ vd -> init_val = 1 ;
1533
1578
opstack_push (vd );
1534
1579
add_insn (parent , * bb , OP_load_constant , vd , NULL , NULL , 0 , NULL );
1535
1580
@@ -1550,6 +1595,8 @@ void read_lvalue(lvalue_t *lvalue,
1550
1595
*/
1551
1596
add_insn (parent , * bb , OP_write , NULL , vd , rs1 , lvalue -> size ,
1552
1597
NULL );
1598
+ /* Push the new value onto the operand stack */
1599
+ opstack_push (rs1 );
1553
1600
} else {
1554
1601
rs1 = vd ;
1555
1602
vd = operand_stack [operand_stack_idx - 1 ];
@@ -3037,6 +3084,14 @@ void read_global_statement(void)
3037
3084
type -> base_type = base -> base_type ;
3038
3085
type -> size = base -> size ;
3039
3086
type -> num_fields = 0 ;
3087
+ type -> ptr_level = 0 ;
3088
+
3089
+ /* Handle pointer types in typedef: typedef char *string; */
3090
+ while (lex_accept (T_asterisk )) {
3091
+ type -> ptr_level ++ ;
3092
+ type -> size = PTR_SIZE ;
3093
+ }
3094
+
3040
3095
lex_ident (T_identifier , type -> type_name );
3041
3096
lex_expect (T_semicolon );
3042
3097
}
0 commit comments