2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: ch3mon.c,v 1.17 1994/06/27 07:58:37 ceriel Exp $ */
6 /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
8 #include "botch_free.h"
11 #include "nobitfield.h"
13 #include <flt_arith.h>
22 extern char options[];
23 extern arith full_mask[/*MAXSIZE*/]; /* cstoper.c */
27 register struct expr **expp;
29 /* The monadic prefix operator oper is applied to *expp.
31 register struct expr *expr;
33 if (oper != PLUSPLUS && oper != MINMIN)
37 case '*': /* 3.3.3.2 */
38 /* no FIELD type allowed */
40 if (expr->ex_type->tp_fund != POINTER) {
41 if (expr->ex_type != error_type) {
43 "* applied to non-pointer (%s)",
44 symbol2str(expr->ex_type->tp_fund));
48 /* dereference in administration only */
49 expr->ex_type = expr->ex_type->tp_up;
50 else /* runtime code */
51 *expp = new_oper(expr->ex_type->tp_up, NILEXPR,
55 expr->ex_type->tp_fund != ARRAY &&
56 expr->ex_type->tp_fund != FUNCTION
58 if (expr->ex_lvalue && expr->ex_type->tp_size <= 0) {
59 expr_error(expr, "incomplete type in expression");
61 if (expr->ex_type->tp_typequal & TQ_CONST)
62 expr->ex_flags |= EX_READONLY;
63 if (expr->ex_type->tp_typequal & TQ_VOLATILE)
64 expr->ex_flags |= EX_VOLATILE;
65 expr->ex_flags &= ~EX_ILVALUE;
69 if ((*expp)->ex_type->tp_fund == ARRAY) {
70 (*expp)->ex_type = pointer_to((*expp)->ex_type, 0);
73 if ((*expp)->ex_type->tp_fund == FUNCTION) {
74 (*expp)->ex_type = pointer_to((*expp)->ex_type, 0);
78 if ((*expp)->ex_type->tp_fund == FIELD)
79 expr_error(*expp, "& applied to field variable");
81 #endif /* NOBITFIELD */
82 if (!(*expp)->ex_lvalue)
83 expr_error(*expp, "& applied to non-lvalue");
84 else if ((*expp)->ex_flags & EX_ILVALUE)
85 expr_error(*expp, "& applied to illegal lvalue");
87 /* assume that enums are already filtered out */
89 register struct def *def =
90 (*expp)->VL_IDF->id_def;
92 /* &<var> indicates that <var>
93 cannot be used as register
96 if (def->df_sc == REGISTER) {
98 "& on register variable not allowed");
99 break; /* break case ADDRESSOF */
102 (*expp)->ex_type = pointer_to((*expp)->ex_type,
103 (*expp)->ex_type->tp_typequal);
104 (*expp)->ex_lvalue = 0;
105 (*expp)->ex_flags &= ~(EX_READONLY | EX_VOLATILE);
110 int fund = (*expp)->ex_type->tp_fund;
112 if (fund == FLOAT || fund == DOUBLE || fund == LNGDBL) {
114 "~ not allowed on %s operands",
122 any2arith(expp, oper);
123 if (is_cp_cst(*expp)) {
124 arith o1 = (*expp)->VL_VALUE;
126 (*expp)->VL_VALUE = (oper == '-') ? -o1 :
127 ((*expp)->ex_type->tp_unsigned ?
128 (~o1) & full_mask[(int)(*expp)->ex_type->tp_size] :
133 if (is_fp_cst(*expp))
134 switch_sign_fp(*expp);
136 *expp = new_oper((*expp)->ex_type,
137 NILEXPR, oper, *expp);
140 opnd2test(expp, '!');
141 if (is_cp_cst(*expp)) {
142 (*expp)->VL_VALUE = !((*expp)->VL_VALUE);
143 (*expp)->ex_type = int_type; /* a cast ???(EB) */
146 *expp = new_oper(int_type, NILEXPR, oper, *expp);
147 (*expp)->ex_flags |= EX_LOGICAL;
154 if (ISNAME(*expp) && (*expp)->VL_IDF->id_def->df_formal_array)
155 expr_warning(*expp, "sizeof formal array %s is sizeof pointer!",
156 (*expp)->VL_IDF->id_text);
157 expr = intexpr((*expp)->ex_class == String ?
158 (arith)((*expp)->SG_LEN) :
159 size_of_type((*expp)->ex_type,
160 symbol2str((*expp)->ex_type->tp_fund))
162 expr->ex_flags |= EX_SIZEOF;
163 free_expression(*expp);