diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index dcf09b4db..845e7d032 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -222,6 +222,7 @@ expr_t *return_expr (struct function_s *f, expr_t *e); expr_t *conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2); expr_t *incop_expr (int op, expr_t *e, int postop); expr_t *array_expr (expr_t *array, expr_t *index); +expr_t *pointer_expr (expr_t *pointer); expr_t *address_expr (expr_t *e1, expr_t *e2, struct type_s *t); expr_t *assign_expr (expr_t *e1, expr_t *e2); expr_t *cast_expr (struct type_s *t, expr_t *e); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 86b9558b8..3af6e48ba 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2267,6 +2267,16 @@ array_expr (expr_t *array, expr_t *index) return e; } +expr_t * +pointer_expr (expr_t *pointer) +{ + type_t *pointer_type = get_type (pointer); + + if (pointer_type->type != ev_pointer) + return error (pointer, "not a pointer"); + return array_expr (pointer, new_integer_expr (0)); +} + expr_t * address_expr (expr_t *e1, expr_t *e2, type_t *t) { diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 30673923f..4914a6b77 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1104,6 +1104,7 @@ unary_expr | '!' cast_expr %prec UNARY { $$ = unary_expr ('!', $2); } | '~' cast_expr %prec UNARY { $$ = unary_expr ('~', $2); } | '&' cast_expr %prec UNARY { $$ = address_expr ($2, 0, 0); } + | '*' cast_expr %prec UNARY { $$ = pointer_expr ($2); } | SIZEOF unary_expr %prec UNARY { $$ = sizeof_expr ($2, 0); } | SIZEOF '(' type ')' %prec HYPERUNARY { $$ = sizeof_expr (0, $3); } ;