|
14 | 14 | /* |
15 | 15 | * fix up references |
16 | 16 | */ |
| 17 | +static void |
| 18 | +AdjustReference(AST **astptr, AST *ast, AST *typ, int incdecop, AST *memtype, AST *index) |
| 19 | +{ |
| 20 | + AST *deref; |
| 21 | + ASTReportInfo saveinfo; |
| 22 | + |
| 23 | + if (incdecop == '@') return; |
| 24 | + AstReportAs(ast, &saveinfo); |
| 25 | + if (!index) index = AstInteger(0); |
| 26 | + if (memtype) { |
| 27 | + deref = NewAST(AST_CAST, |
| 28 | + NewAST(AST_PTRTYPE, memtype, NULL), |
| 29 | + ast); |
| 30 | + } else { |
| 31 | + deref = ast; |
| 32 | + } |
| 33 | + if (incdecop) { |
| 34 | + switch (incdecop) { |
| 35 | + case K_REF_POSTDEC: |
| 36 | + ast = AstOperator(K_DECREMENT, deref, NULL); break; |
| 37 | + case K_REF_POSTINC: |
| 38 | + ast = AstOperator(K_INCREMENT, deref, NULL); break; |
| 39 | + case K_REF_PREDEC: |
| 40 | + ast = AstOperator(K_DECREMENT, NULL, deref); break; |
| 41 | + case K_REF_PREINC: |
| 42 | + ast = AstOperator(K_INCREMENT, NULL, deref); break; |
| 43 | + default: |
| 44 | + ERROR(ast, "Internal compiler error: unknown op\n"); break; |
| 45 | + } |
| 46 | + } |
| 47 | + deref = NewAST(AST_MEMREF, typ->left, ast); |
| 48 | + deref = NewAST(AST_ARRAYREF, deref, index); |
| 49 | + *astptr = deref; |
| 50 | + AstReportDone(&saveinfo); |
| 51 | +} |
| 52 | + |
17 | 53 | static void |
18 | 54 | fixReferences(AST **astptr, int incdecop, AST *memtype) |
19 | 55 | { |
20 | 56 | AST *ast = *astptr; |
21 | 57 | AST *typ; |
22 | | - AST *deref; |
23 | | - ASTReportInfo saveinfo; |
24 | 58 |
|
25 | 59 | if (!ast) return; |
26 | 60 | switch (ast->kind) { |
| 61 | + case AST_ARRAYREF: |
| 62 | + fixReferences(&ast->left, '@', memtype); |
| 63 | + fixReferences(&ast->right, incdecop, memtype); |
| 64 | + typ = ExprType(ast->left); |
| 65 | + if (typ && IsRefType(typ)) { |
| 66 | + AdjustReference(astptr, ast->left, typ, incdecop, memtype, ast->right); |
| 67 | + } |
| 68 | + return; |
27 | 69 | case AST_IDENTIFIER: |
28 | 70 | case AST_LOCAL_IDENTIFIER: |
29 | 71 | typ = ExprType(ast); |
30 | 72 | if (typ && IsRefType(typ)) { |
31 | | - if (incdecop == '@') return; |
32 | | - AstReportAs(ast, &saveinfo); |
33 | | - if (memtype) { |
34 | | - deref = NewAST(AST_CAST, |
35 | | - NewAST(AST_PTRTYPE, memtype, NULL), |
36 | | - ast); |
37 | | - } else { |
38 | | - deref = ast; |
39 | | - } |
40 | | - if (incdecop) { |
41 | | - switch (incdecop) { |
42 | | - case K_REF_POSTDEC: |
43 | | - ast = AstOperator(K_DECREMENT, deref, NULL); break; |
44 | | - case K_REF_POSTINC: |
45 | | - ast = AstOperator(K_INCREMENT, deref, NULL); break; |
46 | | - case K_REF_PREDEC: |
47 | | - ast = AstOperator(K_DECREMENT, NULL, deref); break; |
48 | | - case K_REF_PREINC: |
49 | | - ast = AstOperator(K_INCREMENT, NULL, deref); break; |
50 | | - default: |
51 | | - ERROR(ast, "Internal compiler error: unknown op\n"); break; |
52 | | - } |
53 | | - } |
54 | | - deref = NewAST(AST_MEMREF, typ->left, ast); |
55 | | - deref = NewAST(AST_ARRAYREF, deref, AstInteger(0)); |
56 | | - *astptr = deref; |
57 | | - AstReportDone(&saveinfo); |
| 73 | + AdjustReference(astptr, ast, typ, incdecop, memtype, NULL); |
58 | 74 | } |
59 | 75 | return; |
60 | 76 | case AST_ASSIGN_INIT: |
|
0 commit comments