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: expr.c,v 3.28 1994/06/24 12:03:38 ceriel Exp $ */
6 /* EXPRESSION TREE HANDLING */
10 #include "botch_free.h"
24 #include "noRoption.h"
27 extern char *symbol2str();
28 extern char options[];
34 /* The rank of the operator oper is returned.
38 return 0; /* INT2INT etc. */
50 return 2; /* monadic */
102 rank_of_expression(ex)
103 register struct expr *ex;
105 /* Returns the rank of the top node in the expression.
107 if (!ex || (ex->ex_flags & EX_PARENS) || ex->ex_class != Oper)
109 return rank_of(ex->OP_OPER);
112 check_conditional(expr, oper, pos_descr)
113 register struct expr *expr;
116 /* Warn if restricted C is in effect and the expression expr,
117 which occurs at the position pos_descr, is not lighter than
120 if (options['R'] && rank_of_expression(expr) >= rank_of(oper))
121 expr_warning(expr, "%s %s is ungrammatical",
122 symbol2str(expr->OP_OPER), pos_descr);
129 /* The token in dot is converted into an expression, a
130 pointer to which is stored in *expp.
132 register struct expr *ex = new_expr();
135 ex->ex_file = dot.tk_file;
136 ex->ex_line = dot.tk_line;
153 crash("bad conversion to expression");
159 register struct expr *expr;
161 /* Dot contains an identifier which is turned into an
163 Note that this constitutes an applied occurrence of
166 register struct idf *idf = dot.tk_idf; /* != 0*/
167 register struct def *def = idf->id_def;
170 if (AHEAD == '(') /* function call, declare name IMPLICITly */
171 add_def(idf, IMPLICIT, funint_type, level); /* RM 13 */
173 if (!is_anon_idf(idf))
174 error("identifier %s undefined", idf->id_text);
175 /* declare idf anyway */
176 add_def(idf, 0, error_type, level);
181 if (def->df_type->tp_fund == LABEL) {
182 expr_error(expr, "illegal use of label %s", idf->id_text);
183 expr->ex_type = error_type;
187 if (! def->df_used) {
189 #ifndef PREPEND_SCOPES
190 code_scope(idf->id_text, def);
191 #endif /* PREPEND_SCOPES */
194 expr->ex_type = def->df_type;
195 if (expr->ex_type == error_type)
196 expr->ex_flags |= EX_ERROR;
199 ( def->df_type->tp_fund == FUNCTION ||
200 def->df_type->tp_fund == ARRAY ||
203 expr->ex_class = Value;
204 if (def->df_sc == ENUM) {
205 expr->VL_CLASS = Const;
206 expr->VL_VALUE = def->df_address;
210 if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
211 expr->VL_CLASS = Label;
212 expr->VL_LBL = def->df_address;
213 expr->VL_VALUE = (arith)0;
217 expr->VL_CLASS = Name;
219 expr->VL_VALUE = (arith)0;
224 register struct expr *expr;
226 /* Dot contains a string which is turned into an expression.
228 expr->ex_type = string_type;
230 expr->ex_class = String;
231 expr->SG_VALUE = dot.tk_bts;
232 expr->SG_LEN = dot.tk_len;
239 /* Dot contains an integer constant which is turned
242 fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
247 register struct expr *expr;
249 /* Dot contains a floating point constant which is turned
252 expr->ex_type = double_type;
253 expr->ex_class = Float;
254 expr->FL_VALUE = dot.tk_fval;
260 intexpr(ivalue, fund)
264 /* The value ivalue is turned into an integer expression of
265 the size indicated by fund.
267 register struct expr *expr = new_expr();
269 expr->ex_file = dot.tk_file;
270 expr->ex_line = dot.tk_line;
271 fill_int_expr(expr, ivalue, fund);
275 fill_int_expr(ex, ivalue, fund)
276 register struct expr *ex;
280 /* Details derived from ivalue and fund are put into the
281 constant integer expression ex.
285 ex->ex_type = int_type;
288 if (ivalue >= 0 && ivalue <= max_int) {
289 ex->ex_type = int_type;
295 (ivalue & (1L << (8*long_size - 1))) ? ulong_type
299 /* We cannot make a test like
300 ivalue <= max_unsigned
302 sizeof(long) == int_size
303 holds, max_unsigned may be a negative long in
304 which case the comparison results in an unexpected
305 answer. We assume that the type "unsigned long"
306 is not part of portable C !
309 (ivalue & ~max_int) ?
310 ( (ivalue & ~max_unsigned) ?
311 ( ivalue & (1L<<(8*long_size-1)) ?
312 ulong_type : long_type
317 crash("(intexpr) bad fund %s\n", symbol2str(fund));
320 ex->ex_class = Value;
321 ex->VL_CLASS = Const;
322 ex->VL_VALUE = ivalue;
327 new_oper(tp, e1, oper, e2)
329 register struct expr *e1, *e2;
331 /* A new expression is constructed which consists of the
332 operator oper which has e1 and e2 as operands; for a
333 monadic operator e1 == NILEXPR.
334 During the construction of the right recursive initialisation
335 tree it is possible for e2 to be NILEXPR.
337 register struct expr *expr = new_expr();
338 register struct oper *op;
341 register struct expr *e = e2;
343 while (e->ex_class == Oper && e->OP_LEFT)
345 expr->ex_file = e->ex_file;
346 expr->ex_line = e->ex_line;
350 register struct expr *e = e1;
352 while (e->ex_class == Oper && e->OP_RIGHT)
354 expr->ex_file = e->ex_file;
355 expr->ex_line = e->ex_line;
358 expr->ex_file = dot.tk_file;
359 expr->ex_line = dot.tk_line;
363 expr->ex_class = Oper;
364 /* combine depths and flags of both expressions */
366 int e1_depth = e1 ? e1->ex_depth : 0;
367 int e1_flags = e1 ? e1->ex_flags : 0;
370 (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
371 expr->ex_flags = (e1_flags | e2->ex_flags) & ~EX_PARENS;
373 op = &expr->ex_object.ex_oper;
385 register struct expr **expp;
387 /* The expression expr is checked for constancy.
389 There are 6 places where constant expressions occur in C:
391 2. in a global initialization
392 3. as size in an array declaration
393 4. as value in an enum declaration
394 5. as width in a bit field
395 6. as case value in a switch
397 The constant expression in a global initialization is
398 handled separately (by IVAL()).
400 There are various disparate restrictions on each of
401 the others in the various C compilers. I have tried some
402 hypotheses to unify them, but all have failed.
404 This routine will give a warning for those operators
405 not allowed by K&R, under the R-option only. The anomalies
406 are cast, logical operators and the expression comma.
407 Special problems (of which there is only one, sizeof in
408 Preprocessor #if) have to be dealt with locally
410 Note that according to K&R the negation ! is illegal in
411 constant expressions and is indeed rejected by the
414 register struct expr *expr = *expp;
415 register int fund = expr->ex_type->tp_fund;
416 register int flags = expr->ex_flags;
420 print_expr("constant_expression", expr);
422 if ( fund != CHAR && fund != SHORT && fund != INT &&
423 fund != ENUM && fund != LONG
425 expr_error(expr, "non-numerical constant expression"), err++;
427 if (!is_ld_cst(expr))
428 expr_error(expr, "expression is not constant"), err++;
432 expr_warning(expr, "cast in constant expression");
433 if (flags & EX_LOGICAL)
435 "logical operator in constant expression");
436 if (flags & EX_COMMA)
438 "expression comma in constant expression");
440 #endif /* NOROPTION */
445 init_expression(eppp, expr)
446 register struct expr ***eppp, *expr;
448 /* The expression expr is added to the tree designated
449 indirectly by **eppp.
450 The natural form of a tree representing an
451 initial_value_list is right-recursive, ie. with the
452 left-most comma as main operator. The iterative grammar in
453 expression.g, however, tends to produce a left-recursive
454 tree, ie. one with the right-most comma as its main
456 To produce a right-recursive tree from the iterative
457 grammar, we keep track of the address of the pointer where
458 the next expression must be hooked in.
460 **eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR);
461 *eppp = &(**eppp)->OP_RIGHT;
466 register struct expr *expr;
468 /* An expression is a `load-time constant' if it is of the form
469 <idf> +/- <integral> or <integral>.
472 if (expr->ex_class == String)
475 return expr->ex_lvalue == 0 && expr->ex_class == Value;
480 register struct expr *expr;
482 /* An expression is a `compile-time constant' if it is a
483 load-time constant, and the idf is not there.
485 return is_ld_cst(expr) && expr->VL_CLASS == Const;
491 register struct expr *expr;
493 /* An expression is a `floating-point constant' if it consists
496 return expr->ex_class == Float;
500 free_expression(expr)
501 register struct expr *expr;
503 /* The expression expr is freed recursively.
506 if (expr->ex_class == Oper) {
507 free_expression(expr->OP_LEFT);
508 free_expression(expr->OP_RIGHT);