]> gcc.gnu.org Git - gcc.git/blob - gcc/ch/expr.c
Warning fixes:
[gcc.git] / gcc / ch / expr.c
1 /* Convert language-specific tree expression to rtl instructions,
2 for GNU CHILL compiler.
3 Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "expr.h"
28 #include "ch-tree.h"
29 #include "assert.h"
30 #include "lex.h"
31 #include "convert.h"
32 #include "toplev.h"
33
34 extern char **boolean_code_name;
35 extern int flag_old_strings;
36 extern tree long_unsigned_type_node;
37 extern int ignore_case;
38 extern int special_UC;
39
40 /* definitions for duration built-ins */
41 #define MILLISECS_MULTIPLIER 1
42 #define SECS_MULTIPLIER MILLISECS_MULTIPLIER * 1000
43 #define MINUTES_MULTIPLIER SECS_MULTIPLIER * 60
44 #define HOURS_MULTIPLIER MINUTES_MULTIPLIER * 60
45 #define DAYS_MULTIPLIER HOURS_MULTIPLIER * 24
46
47 /* the maximum value for each of the calls */
48 #define MILLISECS_MAX 0xffffffff
49 #define SECS_MAX 4294967
50 #define MINUTES_MAX 71582
51 #define HOURS_MAX 1193
52 #define DAYS_MAX 49
53
54 /* forward declaration */
55 rtx chill_expand_expr PROTO((tree, rtx, enum machine_mode,
56 enum expand_modifier));
57
58 /* variable to hold the type the DESCR built-in returns */
59 static tree descr_type = NULL_TREE;
60
61 \f
62 /* called from ch-lex.l */
63 void
64 init_chill_expand ()
65 {
66 lang_expand_expr = chill_expand_expr;
67 }
68
69 /* Take the address of something that needs to be passed by reference. */
70 tree
71 force_addr_of (value)
72 tree value;
73 {
74 /* FIXME. Move to memory, if needed. */
75 if (TREE_CODE (value) == INDIRECT_REF)
76 return convert_to_pointer (ptr_type_node, TREE_OPERAND (value, 0));
77 mark_addressable (value);
78 return build1 (ADDR_EXPR, ptr_type_node, value);
79 }
80
81 /* Check that EXP has a known type. */
82
83 tree
84 check_have_mode (exp, context)
85 tree exp;
86 char *context;
87 {
88 if (TREE_CODE (exp) != ERROR_MARK && TREE_TYPE (exp) == NULL_TREE)
89 {
90 if (TREE_CODE (exp) == CONSTRUCTOR)
91 error ("tuple without specified mode not allowed in %s", context);
92 else if (TREE_CODE (exp) == COND_EXPR || TREE_CODE (exp) == CASE_EXPR)
93 error ("conditional expression not allowed in %s", context);
94 else
95 error ("internal error: unknown expression mode in %s", context);
96
97 return error_mark_node;
98 }
99 return exp;
100 }
101
102 /* Check that EXP is discrete. Handle conversion if flag_old_strings. */
103
104 tree
105 check_case_selector (exp)
106 tree exp;
107 {
108 if (exp != NULL_TREE && TREE_TYPE (exp) != NULL_TREE)
109 exp = convert_to_discrete (exp);
110 if (exp)
111 return exp;
112 error ("CASE selector is not a discrete expression");
113 return error_mark_node;
114 }
115
116 tree
117 check_case_selector_list (list)
118 tree list;
119 {
120 tree selector, exp, return_list = NULL_TREE;
121
122 for (selector = list; selector != NULL_TREE; selector = TREE_CHAIN (selector))
123 {
124 exp = check_case_selector (TREE_VALUE (selector));
125 if (exp == error_mark_node)
126 {
127 return_list = error_mark_node;
128 break;
129 }
130 return_list = tree_cons (TREE_PURPOSE (selector), exp, return_list);
131 }
132
133 return nreverse(return_list);
134 }
135
136 tree
137 chill_expand_case_expr (expr)
138 tree expr;
139 {
140 tree selector_list = TREE_OPERAND (expr, 0), selector;
141 tree alternatives = TREE_OPERAND (expr, 1);
142 tree type = TREE_TYPE (expr);
143 int else_seen = 0;
144 tree result;
145
146 if (TREE_CODE (selector_list) != TREE_LIST
147 || TREE_CODE (alternatives) != TREE_LIST)
148 abort();
149 if (TREE_CHAIN (selector_list) != NULL_TREE)
150 abort ();
151
152 /* make a temp for the case result */
153 result = decl_temp1 (get_unique_identifier ("CASE_EXPR"),
154 type, 0, NULL_TREE, 0, 0);
155
156 selector = check_case_selector (TREE_VALUE (selector_list));
157
158 expand_start_case (1, selector, TREE_TYPE (selector), "CASE expression");
159
160 alternatives = nreverse (alternatives);
161 for ( ; alternatives != NULL_TREE; alternatives = TREE_CHAIN (alternatives))
162 {
163 tree labels = TREE_PURPOSE (alternatives), t;
164
165 if (labels == NULL_TREE)
166 {
167 chill_handle_case_default ();
168 else_seen++;
169 }
170 else
171 {
172 tree label;
173 if (labels != NULL_TREE)
174 {
175 for (label = TREE_VALUE (labels);
176 label != NULL_TREE; label = TREE_CHAIN (label))
177 chill_handle_case_label (TREE_VALUE (label), selector);
178 labels = TREE_CHAIN (labels);
179 if (labels != NULL_TREE)
180 error ("The number of CASE selectors does not match the number "
181 "of CASE label lists");
182
183 }
184 }
185
186 t = build (MODIFY_EXPR, type, result,
187 convert (type, TREE_VALUE (alternatives)));
188 TREE_SIDE_EFFECTS (t) = 1;
189 expand_expr_stmt (t);
190 expand_exit_something ();
191 }
192
193 if (!else_seen)
194 {
195 chill_handle_case_default ();
196 expand_exit_something ();
197 #if 0
198 expand_raise ();
199 #endif
200
201 check_missing_cases (TREE_TYPE (selector));
202 }
203
204 expand_end_case (selector);
205 return result;
206 }
207 \f
208 /* Hook used by expand_expr to expand CHILL-specific tree codes. */
209
210 rtx
211 chill_expand_expr (exp, target, tmode, modifier)
212 tree exp;
213 rtx target;
214 enum machine_mode tmode;
215 enum expand_modifier modifier;
216 {
217 tree type = TREE_TYPE (exp);
218 register enum machine_mode mode = TYPE_MODE (type);
219 register enum tree_code code = TREE_CODE (exp);
220 rtx original_target = target;
221 rtx op0, op1;
222 int ignore = target == const0_rtx;
223 char *lib_func; /* name of library routine */
224
225 if (ignore)
226 target = 0, original_target = 0;
227
228 /* No sense saving up arithmetic to be done
229 if it's all in the wrong mode to form part of an address.
230 And force_operand won't know whether to sign-extend or zero-extend. */
231
232 if (mode != Pmode && modifier == EXPAND_SUM)
233 modifier = EXPAND_NORMAL;
234
235 switch (code)
236 {
237 case STRING_EQ_EXPR:
238 case STRING_LT_EXPR:
239 {
240 rtx func = gen_rtx (SYMBOL_REF, Pmode,
241 code == STRING_EQ_EXPR ? "__eqstring"
242 : "__ltstring");
243 tree exp0 = TREE_OPERAND (exp, 0);
244 tree exp1 = TREE_OPERAND (exp, 1);
245 tree size0, size1;
246 rtx op0, op1, siz0, siz1;
247 if (chill_varying_type_p (TREE_TYPE (exp0)))
248 {
249 exp0 = save_if_needed (exp0);
250 size0 = convert (integer_type_node,
251 build_component_ref (exp0, var_length_id));
252 exp0 = build_component_ref (exp0, var_data_id);
253 }
254 else
255 size0 = size_in_bytes (TREE_TYPE (exp0));
256 if (chill_varying_type_p (TREE_TYPE (exp1)))
257 {
258 exp1 = save_if_needed (exp1);
259 size1 = convert (integer_type_node,
260 build_component_ref (exp1, var_length_id));
261 exp1 = build_component_ref (exp1, var_data_id);
262 }
263 else
264 size1 = size_in_bytes (TREE_TYPE (exp1));
265
266 op0 = expand_expr (force_addr_of (exp0),
267 NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
268 op1 = expand_expr (force_addr_of (exp1),
269 NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
270 siz0 = expand_expr (size0, NULL_RTX, VOIDmode, 0);
271 siz1 = expand_expr (size1, NULL_RTX, VOIDmode, 0);
272 return emit_library_call_value (func, target,
273 0, QImode, 4,
274 op0, GET_MODE (op0),
275 siz0, TYPE_MODE (sizetype),
276 op1, GET_MODE (op1),
277 siz1, TYPE_MODE (sizetype));
278 }
279
280 case CASE_EXPR:
281 return expand_expr (chill_expand_case_expr (exp),
282 NULL_RTX, VOIDmode, 0);
283 break;
284
285 case SLICE_EXPR:
286 {
287 tree func_call;
288 tree array = TREE_OPERAND (exp, 0);
289 tree min_value = TREE_OPERAND (exp, 1);
290 tree length = TREE_OPERAND (exp, 2);
291 tree new_type = TREE_TYPE (exp);
292 tree temp = decl_temp1 (get_unique_identifier ("BITSTRING"),
293 new_type, 0, NULL_TREE, 0, 0);
294 if (! CH_REFERABLE (array) && TYPE_MODE (TREE_TYPE (array)) != BLKmode)
295 array = decl_temp1 (get_unique_identifier ("BSTRINGVAL"),
296 TREE_TYPE (array), 0, array, 0, 0);
297 func_call = build_chill_function_call (
298 lookup_name (get_identifier ("__psslice")),
299 tree_cons (NULL_TREE,
300 build_chill_addr_expr (temp, (char *)0),
301 tree_cons (NULL_TREE, length,
302 tree_cons (NULL_TREE,
303 force_addr_of (array),
304 tree_cons (NULL_TREE, powersetlen (array),
305 tree_cons (NULL_TREE, convert (integer_type_node, min_value),
306 tree_cons (NULL_TREE, length, NULL_TREE)))))));
307 expand_expr (func_call, const0_rtx, VOIDmode, 0);
308 emit_queue ();
309 return expand_expr (temp, ignore ? const0_rtx : target,
310 VOIDmode, 0);
311 }
312
313 /* void __concatstring (char *out, char *left, unsigned left_len,
314 char *right, unsigned right_len) */
315 case CONCAT_EXPR:
316 {
317 tree exp0 = TREE_OPERAND (exp, 0);
318 tree exp1 = TREE_OPERAND (exp, 1);
319 rtx size0, size1;
320 rtx targetx;
321
322 if (TREE_CODE (exp1) == UNDEFINED_EXPR)
323 {
324 if (TYPE_MODE (TREE_TYPE (exp0)) == BLKmode
325 && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
326 {
327 rtx temp = expand_expr (exp0, target, tmode, modifier);
328 if (temp == target || target == NULL_RTX)
329 return temp;
330 emit_block_move (target, temp, expr_size (exp0),
331 TYPE_ALIGN (TREE_TYPE(exp0)) / BITS_PER_UNIT);
332 return target;
333 }
334 else
335 {
336 exp0 = force_addr_of (exp0);
337 exp0 = convert (build_pointer_type (TREE_TYPE (exp)), exp0);
338 exp0 = build1 (INDIRECT_REF, TREE_TYPE (exp), exp0);
339 return expand_expr (exp0,
340 NULL_RTX, Pmode, EXPAND_CONST_ADDRESS);
341 }
342 }
343
344 if (TREE_CODE (type) == ARRAY_TYPE)
345 {
346 /* No need to handle scalars or varying strings here, since that
347 was done in convert or build_concat_expr. */
348 size0 = expand_expr (size_in_bytes (TREE_TYPE (exp0)),
349 NULL_RTX, Pmode, EXPAND_CONST_ADDRESS);
350
351 size1 = expand_expr (size_in_bytes (TREE_TYPE (exp1)),
352 NULL_RTX, Pmode, EXPAND_CONST_ADDRESS);
353
354 /* build a temp for the result, target is its address */
355 if (target == NULL_RTX)
356 {
357 tree type0 = TREE_TYPE (exp0);
358 tree type1 = TREE_TYPE (exp1);
359 int len0 = int_size_in_bytes (type0);
360 int len1 = int_size_in_bytes (type1);
361
362 if (len0 < 0 && TYPE_ARRAY_MAX_SIZE (type0)
363 && TREE_CODE (TYPE_ARRAY_MAX_SIZE (type0)) == INTEGER_CST)
364 len0 = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type0));
365
366 if (len1 < 0 && TYPE_ARRAY_MAX_SIZE (type1)
367 && TREE_CODE (TYPE_ARRAY_MAX_SIZE (type1)) == INTEGER_CST)
368 len1 = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type1));
369
370 if (len0 < 0 || len1 < 0)
371 fatal ("internal error - don't know how much space is needed for concatenation");
372 target = assign_stack_temp (mode, len0 + len1, 0);
373 preserve_temp_slots (target);
374 }
375 }
376 else if (TREE_CODE (type) == SET_TYPE)
377 {
378 if (target == NULL_RTX)
379 {
380 target = assign_stack_temp (mode, int_size_in_bytes (type), 0);
381 preserve_temp_slots (target);
382 }
383 }
384 else
385 abort ();
386
387 if (GET_CODE (target) == MEM)
388 targetx = target;
389 else
390 targetx = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
391
392 /* expand 1st operand to a pointer to the array */
393 op0 = expand_expr (force_addr_of (exp0),
394 NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
395
396 /* expand 2nd operand to a pointer to the array */
397 op1 = expand_expr (force_addr_of (exp1),
398 NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
399
400 if (TREE_CODE (type) == SET_TYPE)
401 {
402 size0 = expand_expr (powersetlen (exp0),
403 NULL_RTX, VOIDmode, 0);
404 size1 = expand_expr (powersetlen (exp1),
405 NULL_RTX, VOIDmode, 0);
406
407 emit_library_call (gen_rtx(SYMBOL_REF, Pmode, "__concatps"),
408 0, Pmode, 5, XEXP (targetx, 0), Pmode,
409 op0, GET_MODE (op0),
410 convert_to_mode (TYPE_MODE (sizetype),
411 size0, TREE_UNSIGNED (sizetype)),
412 TYPE_MODE (sizetype),
413 op1, GET_MODE (op1),
414 convert_to_mode (TYPE_MODE (sizetype),
415 size1, TREE_UNSIGNED (sizetype)),
416 TYPE_MODE (sizetype));
417 }
418 else
419 {
420 /* copy left, then right array to target */
421 emit_library_call (gen_rtx(SYMBOL_REF, Pmode, "__concatstring"),
422 0, Pmode, 5, XEXP (targetx, 0), Pmode,
423 op0, GET_MODE (op0),
424 convert_to_mode (TYPE_MODE (sizetype),
425 size0, TREE_UNSIGNED (sizetype)),
426 TYPE_MODE (sizetype),
427 op1, GET_MODE (op1),
428 convert_to_mode (TYPE_MODE (sizetype),
429 size1, TREE_UNSIGNED (sizetype)),
430 TYPE_MODE (sizetype));
431 }
432 if (targetx != target)
433 emit_move_insn (target, targetx);
434 return target;
435 }
436 \f
437 /* FIXME: the set_length computed below is a compile-time constant;
438 you'll need to re-write that part for VARYING bit arrays, and
439 possibly the set pointer will need to be adjusted to point past
440 the word containing its dynamic length. */
441
442 /* void __notpowerset (char *out, char *src,
443 unsigned long bitlength) */
444 case SET_NOT_EXPR:
445 {
446
447 tree expr = TREE_OPERAND (exp, 0);
448 tree tsize = powersetlen (expr);
449 rtx targetx;
450
451 if (TREE_CODE (TREE_TYPE (expr)) != SET_TYPE)
452 tsize = fold (build (MULT_EXPR, sizetype, tsize,
453 size_int (BITS_PER_UNIT)));
454
455 /* expand 1st operand to a pointer to the set */
456 op0 = expand_expr (force_addr_of (expr),
457 NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
458
459 /* build a temp for the result, target is its address */
460 if (target == NULL_RTX)
461 {
462 target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)),
463 int_size_in_bytes (TREE_TYPE (exp)),
464 0);
465 preserve_temp_slots (target);
466 }
467 if (GET_CODE (target) == MEM)
468 targetx = target;
469 else
470 targetx = assign_stack_temp (GET_MODE (target),
471 GET_MODE_SIZE (GET_MODE (target)),
472 0);
473 emit_library_call (gen_rtx(SYMBOL_REF, Pmode, "__notpowerset"),
474 0, VOIDmode, 3, XEXP (targetx, 0), Pmode,
475 op0, GET_MODE (op0),
476 expand_expr (tsize, NULL_RTX, MEM,
477 EXPAND_CONST_ADDRESS),
478 TYPE_MODE (long_unsigned_type_node));
479 if (targetx != target)
480 emit_move_insn (target, targetx);
481 return target;
482 }
483
484 case SET_DIFF_EXPR:
485 lib_func = "__diffpowerset";
486 goto format_2;
487
488 case SET_IOR_EXPR:
489 lib_func = "__orpowerset";
490 goto format_2;
491
492 case SET_XOR_EXPR:
493 lib_func = "__xorpowerset";
494 goto format_2;
495
496 /* void __diffpowerset (char *out, char *left, char *right,
497 unsigned bitlength) */
498 case SET_AND_EXPR:
499 lib_func = "__andpowerset";
500 format_2:
501 {
502 tree expr = TREE_OPERAND (exp, 0);
503 tree tsize = powersetlen (expr);
504 rtx targetx;
505
506 if (TREE_CODE (TREE_TYPE (expr)) != SET_TYPE)
507 tsize = fold (build (MULT_EXPR, long_unsigned_type_node,
508 tsize,
509 size_int (BITS_PER_UNIT)));
510
511 /* expand 1st operand to a pointer to the set */
512 op0 = expand_expr (force_addr_of (expr),
513 NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
514
515 /* expand 2nd operand to a pointer to the set */
516 op1 = expand_expr (force_addr_of (TREE_OPERAND (exp, 1)),
517 NULL_RTX, MEM,
518 EXPAND_CONST_ADDRESS);
519
520 /* FIXME: re-examine this code - the unary operator code above has recently
521 (93/03/12) been changed a lot. Should this code also change? */
522 /* build a temp for the result, target is its address */
523 if (target == NULL_RTX)
524 {
525 target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)),
526 int_size_in_bytes (TREE_TYPE (exp)),
527 0);
528 preserve_temp_slots (target);
529 }
530 if (GET_CODE (target) == MEM)
531 targetx = target;
532 else
533 targetx = assign_stack_temp (GET_MODE (target),
534 GET_MODE_SIZE (GET_MODE (target)), 0);
535 emit_library_call (gen_rtx(SYMBOL_REF, Pmode, lib_func),
536 0, VOIDmode, 4, XEXP (targetx, 0), Pmode,
537 op0, GET_MODE (op0), op1, GET_MODE (op1),
538 expand_expr (tsize, NULL_RTX, MEM,
539 EXPAND_CONST_ADDRESS),
540 TYPE_MODE (long_unsigned_type_node));
541 if (target != targetx)
542 emit_move_insn (target, targetx);
543 return target;
544 }
545
546 case SET_IN_EXPR:
547 {
548 tree set = TREE_OPERAND (exp, 1);
549 tree pos = convert (long_unsigned_type_node, TREE_OPERAND (exp, 0));
550 tree set_type = TREE_TYPE (set);
551 tree set_length = discrete_count (TYPE_DOMAIN (set_type));
552 tree min_val = convert (long_integer_type_node,
553 TYPE_MIN_VALUE (TYPE_DOMAIN (set_type)));
554 tree fcall;
555
556 /* FIXME: Function-call not needed if pos and width are constant! */
557 if (! mark_addressable (set))
558 {
559 error ("powerset is not addressable");
560 return const0_rtx;
561 }
562 /* we use different functions for bitstrings and powersets */
563 if (CH_BOOLS_TYPE_P (set_type))
564 fcall =
565 build_chill_function_call (
566 lookup_name (get_identifier ("__inbitstring")),
567 tree_cons (NULL_TREE,
568 convert (long_unsigned_type_node, pos),
569 tree_cons (NULL_TREE,
570 build1 (ADDR_EXPR, build_pointer_type (set_type), set),
571 tree_cons (NULL_TREE,
572 convert (long_unsigned_type_node, set_length),
573 tree_cons (NULL_TREE, min_val,
574 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
575 build_tree_list (NULL_TREE, get_chill_linenumber ())))))));
576 else
577 fcall =
578 build_chill_function_call (
579 lookup_name (get_identifier ("__inpowerset")),
580 tree_cons (NULL_TREE,
581 convert (long_unsigned_type_node, pos),
582 tree_cons (NULL_TREE,
583 build1 (ADDR_EXPR, build_pointer_type (set_type), set),
584 tree_cons (NULL_TREE,
585 convert (long_unsigned_type_node, set_length),
586 build_tree_list (NULL_TREE, min_val)))));
587 return expand_expr (fcall, NULL_RTX, VOIDmode, 0);
588 }
589
590 case PACKED_ARRAY_REF:
591 {
592 tree array = TREE_OPERAND (exp, 0);
593 tree pos = save_expr (TREE_OPERAND (exp, 1));
594 tree array_type = TREE_TYPE (array);
595 tree array_length = discrete_count (TYPE_DOMAIN (array_type));
596 tree min_val = convert (long_integer_type_node,
597 TYPE_MIN_VALUE (TYPE_DOMAIN (array_type)));
598 tree fcall;
599
600 /* FIXME: Function-call not needed if pos and width are constant! */
601 /* TODO: make sure this makes sense. */
602 if (! mark_addressable (array))
603 {
604 error ("array is not addressable");
605 return const0_rtx;
606 }
607 fcall =
608 build_chill_function_call (
609 lookup_name (get_identifier ("__inpowerset")),
610 tree_cons (NULL_TREE,
611 convert (long_unsigned_type_node, pos),
612 tree_cons (NULL_TREE,
613 build1 (ADDR_EXPR, build_pointer_type (array_type), array),
614 tree_cons (NULL_TREE,
615 convert (long_unsigned_type_node, array_length),
616 build_tree_list (NULL_TREE, min_val)))));
617 return expand_expr (fcall, NULL_RTX, VOIDmode, 0);
618 }
619
620 case UNDEFINED_EXPR:
621 if (target == 0)
622 {
623 target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)),
624 int_size_in_bytes (TREE_TYPE (exp)), 0);
625 preserve_temp_slots (target);
626 }
627 /* We don't actually need to *do* anything ... */
628 return target;
629
630 default:
631 break;
632 }
633
634 /* NOTREACHED */
635 return NULL;
636 }
637 \f
638 /* Check that the argument list has a length in [min_length .. max_length].
639 (max_length == -1 means "infinite".)
640 If so return the actual length.
641 Otherwise, return an error message and return -1. */
642
643 static int
644 check_arglist_length (args, min_length, max_length, name)
645 tree args;
646 int min_length;
647 int max_length;
648 tree name;
649 {
650 int length = list_length (args);
651 if (length < min_length)
652 error ("Too few arguments in call to `%s'", IDENTIFIER_POINTER (name));
653 else if (max_length != -1 && length > max_length)
654 error ("Too many arguments in call to `%s'", IDENTIFIER_POINTER (name));
655 else
656 return length;
657 return -1;
658 }
659 \f
660 /*
661 * This is the code from c-typeck.c, with the C-specific cruft
662 * removed (possibly I just didn't understand it, but it was
663 * apparently simply discarding part of my LIST).
664 */
665 static tree
666 internal_build_compound_expr (list, first_p)
667 tree list;
668 int first_p ATTRIBUTE_UNUSED;
669 {
670 register tree rest;
671
672 if (TREE_CHAIN (list) == 0)
673 return TREE_VALUE (list);
674
675 rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
676
677 if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
678 return rest;
679
680 return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);
681 }
682
683
684 /* Given a list of expressions, return a compound expression
685 that performs them all and returns the value of the last of them. */
686 /* FIXME: this should be merged with the C version */
687 tree
688 build_chill_compound_expr (list)
689 tree list;
690 {
691 return internal_build_compound_expr (list, TRUE);
692 }
693 \f
694 /* Given an expression PTR for a pointer, return an expression
695 for the value pointed to.
696 do_empty_check is 0, don't perform a NULL pointer check,
697 else do it. */
698
699 tree
700 build_chill_indirect_ref (ptr, mode, do_empty_check)
701 tree ptr;
702 tree mode;
703 int do_empty_check;
704 {
705 register tree type;
706
707 if (ptr == NULL_TREE || TREE_CODE (ptr) == ERROR_MARK)
708 return ptr;
709 if (mode != NULL_TREE && TREE_CODE (mode) == ERROR_MARK)
710 return error_mark_node;
711
712 type = TREE_TYPE (ptr);
713
714 if (TREE_CODE (type) == REFERENCE_TYPE)
715 {
716 type = TREE_TYPE (type);
717 ptr = convert (type, ptr);
718 }
719
720 /* check for ptr is really a POINTER */
721 if (TREE_CODE (type) != POINTER_TYPE)
722 {
723 error ("cannot dereference, not a pointer.");
724 return error_mark_node;
725 }
726
727 if (mode && TREE_CODE (mode) == IDENTIFIER_NODE)
728 {
729 tree decl = lookup_name (mode);
730 if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
731 {
732 if (pass == 2)
733 error ("missing '.' operator or undefined mode name `%s'.",
734 IDENTIFIER_POINTER (mode));
735 #if 0
736 error ("You have forgotten the '.' operator which must");
737 error (" precede a STRUCT field reference, or `%s' is an undefined mode",
738 IDENTIFIER_POINTER (mode));
739 #endif
740 return error_mark_node;
741 }
742 }
743
744 if (mode)
745 {
746 mode = get_type_of (mode);
747 ptr = convert (build_pointer_type (mode), ptr);
748 }
749 else if (type == ptr_type_node)
750 {
751 error ("Can't dereference PTR value using unary `->'.");
752 return error_mark_node;
753 }
754
755 if (do_empty_check)
756 ptr = check_non_null (ptr);
757
758 type = TREE_TYPE (ptr);
759
760 if (TREE_CODE (type) == POINTER_TYPE)
761 {
762 if (TREE_CODE (ptr) == ADDR_EXPR
763 && !flag_volatile
764 && (TREE_TYPE (TREE_OPERAND (ptr, 0))
765 == TREE_TYPE (type)))
766 return TREE_OPERAND (ptr, 0);
767 else
768 {
769 tree t = TREE_TYPE (type);
770 register tree ref = build1 (INDIRECT_REF,
771 TYPE_MAIN_VARIANT (t), ptr);
772
773 if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
774 {
775 error ("dereferencing pointer to incomplete type");
776 return error_mark_node;
777 }
778 if (TREE_CODE (t) == VOID_TYPE)
779 warning ("dereferencing `void *' pointer");
780
781 /* We *must* set TREE_READONLY when dereferencing a pointer to const,
782 so that we get the proper error message if the result is used
783 to assign to. Also, &* is supposed to be a no-op.
784 And ANSI C seems to specify that the type of the result
785 should be the const type. */
786 /* A de-reference of a pointer to const is not a const. It is valid
787 to change it via some other pointer. */
788 TREE_READONLY (ref) = TYPE_READONLY (t);
789 TREE_SIDE_EFFECTS (ref)
790 = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (ptr) || flag_volatile;
791 TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t) || flag_volatile;
792 return ref;
793 }
794 }
795 else if (TREE_CODE (ptr) != ERROR_MARK)
796 error ("invalid type argument of `->'");
797 return error_mark_node;
798 }
799
800 /* NODE is a COMPONENT_REF whose mode is an IDENTIFIER,
801 which is replaced by the proper FIELD_DECL.
802 Also do the right thing for variant records. */
803
804 tree
805 resolve_component_ref (node)
806 tree node;
807 {
808 tree datum = TREE_OPERAND (node, 0);
809 tree field_name = TREE_OPERAND (node, 1);
810 tree type = TREE_TYPE (datum);
811 tree field;
812 if (TREE_CODE (datum) == ERROR_MARK)
813 return error_mark_node;
814 if (TREE_CODE (type) == REFERENCE_TYPE)
815 {
816 type = TREE_TYPE (type);
817 TREE_OPERAND (node, 0) = datum = convert (type, datum);
818 }
819 if (TREE_CODE (type) != RECORD_TYPE)
820 {
821 error ("operand of '.' is not a STRUCT");
822 return error_mark_node;
823 }
824
825 TREE_READONLY (node) = TREE_READONLY (datum);
826 TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (datum);
827
828 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
829 {
830 if (TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
831 {
832 tree variant;
833 for (variant = TYPE_FIELDS (TREE_TYPE (field));
834 variant; variant = TREE_CHAIN (variant))
835 {
836 tree vfield;
837 for (vfield = TYPE_FIELDS (TREE_TYPE (variant));
838 vfield; vfield = TREE_CHAIN (vfield))
839 {
840 if (DECL_NAME (vfield) == field_name)
841 { /* Found a variant field */
842 datum = build (COMPONENT_REF, TREE_TYPE (field),
843 datum, field);
844 datum = build (COMPONENT_REF, TREE_TYPE (variant),
845 datum, variant);
846 TREE_OPERAND (node, 0) = datum;
847 TREE_OPERAND (node, 1) = vfield;
848 TREE_TYPE (node) = TREE_TYPE (vfield);
849 TREE_READONLY (node) |= TYPE_READONLY (TREE_TYPE (node));
850 #if 0
851 if (flag_testing_tags)
852 {
853 tree tagtest = NOT IMPLEMENTED;
854 tree tagf = ridpointers[(int) RID_RANGEFAIL];
855 node = check_expression (node, tagtest,
856 tagf);
857 }
858 #endif
859 return node;
860 }
861 }
862 }
863 }
864
865 if (DECL_NAME (field) == field_name)
866 { /* Found a fixed field */
867 TREE_OPERAND (node, 1) = field;
868 TREE_TYPE (node) = TREE_TYPE (field);
869 TREE_READONLY (node) |= TYPE_READONLY (TREE_TYPE (node));
870 return fold (node);
871 }
872 }
873
874 error ("No field named `%s'", IDENTIFIER_POINTER (field_name));
875 return error_mark_node;
876 }
877
878 tree
879 build_component_ref (datum, field_name)
880 tree datum, field_name;
881 {
882 tree node = build_nt (COMPONENT_REF, datum, field_name);
883 if (pass != 1)
884 node = resolve_component_ref (node);
885 return node;
886 }
887
888 /*
889 function checks (for build_chill_component_ref) if a given
890 type is really an instance type. CH_IS_INSTANCE_MODE is not
891 strict enough in this case, i.e. SYNMODE foo = STRUCT (a, b UINT)
892 is compatible to INSTANCE. */
893
894 static int
895 is_really_instance (type)
896 tree type;
897 {
898 tree decl = TYPE_NAME (type);
899
900 if (decl == NULL_TREE)
901 /* this is not an instance */
902 return 0;
903
904 if (DECL_NAME (decl) == ridpointers[(int)RID_INSTANCE])
905 /* this is an instance */
906 return 1;
907
908 if (TYPE_FIELDS (type) == TYPE_FIELDS (instance_type_node))
909 /* we have a NEWMODE'd instance */
910 return 1;
911
912 return 0;
913 }
914
915 /* This function is called by the parse.
916 Here we check if the user tries to access a field in a type which is
917 layouted as a structure but isn't like INSTANCE, BUFFER, EVENT, ASSOCIATION,
918 ACCESS, TEXT, or VARYING array or character string.
919 We don't do this in build_component_ref cause this function gets
920 called from the compiler to access fields in one of the above mentioned
921 modes. */
922 tree
923 build_chill_component_ref (datum, field_name)
924 tree datum, field_name;
925 {
926 tree type = TREE_TYPE (datum);
927 if ((type != NULL_TREE && TREE_CODE (type) == RECORD_TYPE) &&
928 ((CH_IS_INSTANCE_MODE (type) && is_really_instance (type)) ||
929 CH_IS_BUFFER_MODE (type) ||
930 CH_IS_EVENT_MODE (type) || CH_IS_ASSOCIATION_MODE (type) ||
931 CH_IS_ACCESS_MODE (type) || CH_IS_TEXT_MODE (type) ||
932 chill_varying_type_p (type)))
933 {
934 error ("operand of '.' is not a STRUCT");
935 return error_mark_node;
936 }
937 return build_component_ref (datum, field_name);
938 }
939 \f
940 /*
941 * Check for invalid binary operands & unary operands
942 * RIGHT is 1 if checking right operand or unary operand;
943 * it is 0 if checking left operand.
944 *
945 * return 1 if the given operand is NOT compatible as the
946 * operand of the given operator
947 *
948 * return 0 if they might be compatible
949 */
950 static int
951 invalid_operand (code, type, right)
952 enum chill_tree_code code;
953 tree type;
954 int right; /* 1 if right operand */
955 {
956 switch ((int)code)
957 {
958 case ADDR_EXPR:
959 break;
960 case BIT_AND_EXPR:
961 case BIT_IOR_EXPR:
962 case BIT_NOT_EXPR:
963 case BIT_XOR_EXPR:
964 goto relationals;
965 case CASE_EXPR:
966 break;
967 case CEIL_MOD_EXPR:
968 goto numerics;
969 case CONCAT_EXPR: /* must be static or varying char array */
970 if (TREE_CODE (type) == CHAR_TYPE)
971 return 0;
972 if (TREE_CODE (type) == ARRAY_TYPE
973 && TREE_CODE (TREE_TYPE (type)) == CHAR_TYPE)
974 return 0;
975 if (!chill_varying_type_p (type))
976 return 1;
977 if (TREE_CODE (TREE_TYPE (CH_VARYING_ARRAY_TYPE (type)))
978 == CHAR_TYPE)
979 return 0;
980 else
981 return 1;
982 /* note: CHILL conditional expressions (COND_EXPR) won't come
983 * through here; they're routed straight to C-specific code */
984 case EQ_EXPR:
985 return 0; /* ANYTHING can be compared equal */
986 case FLOOR_MOD_EXPR:
987 if (TREE_CODE (type) == REAL_TYPE)
988 return 1;
989 goto numerics;
990 case GE_EXPR:
991 case GT_EXPR:
992 goto relatables;
993 case SET_IN_EXPR:
994 if (TREE_CODE (type) == SET_TYPE)
995 return 0;
996 else
997 return 1;
998 case PACKED_ARRAY_REF:
999 if (TREE_CODE (type) == ARRAY_TYPE)
1000 return 0;
1001 else
1002 return 1;
1003 case LE_EXPR:
1004 case LT_EXPR:
1005 relatables:
1006 switch ((int)TREE_CODE(type)) /* right operand must be set/bitarray type */
1007 {
1008 case ARRAY_TYPE:
1009 if (TREE_CODE (TREE_TYPE (type)) == CHAR_TYPE)
1010 return 0;
1011 else
1012 return 1;
1013 case BOOLEAN_TYPE:
1014 case CHAR_TYPE:
1015 case COMPLEX_TYPE:
1016 case ENUMERAL_TYPE:
1017 case INTEGER_TYPE:
1018 case OFFSET_TYPE:
1019 case POINTER_TYPE:
1020 case REAL_TYPE:
1021 case SET_TYPE:
1022 return 0;
1023 case FILE_TYPE:
1024 case FUNCTION_TYPE:
1025 case GRANT_TYPE:
1026 case LANG_TYPE:
1027 case METHOD_TYPE:
1028 return 1;
1029 case RECORD_TYPE:
1030 if (chill_varying_type_p (type)
1031 && TREE_CODE (TREE_TYPE (CH_VARYING_ARRAY_TYPE (type))) == CHAR_TYPE)
1032 return 0;
1033 else
1034 return 1;
1035 case REFERENCE_TYPE:
1036 case SEIZE_TYPE:
1037 case UNION_TYPE:
1038 case VOID_TYPE:
1039 return 1;
1040 }
1041 break;
1042 case MINUS_EXPR:
1043 case MULT_EXPR:
1044 goto numerics;
1045 case NEGATE_EXPR:
1046 if (TREE_CODE (type) == BOOLEAN_TYPE)
1047 return 0;
1048 else
1049 goto numerics;
1050 case NE_EXPR:
1051 return 0; /* ANYTHING can be compared unequal */
1052 case NOP_EXPR:
1053 return 0; /* ANYTHING can be converted */
1054 case PLUS_EXPR:
1055 numerics:
1056 switch ((int)TREE_CODE(type)) /* left operand must be discrete type */
1057 {
1058 case ARRAY_TYPE:
1059 if (right || TREE_CODE (TREE_TYPE (type)) != BOOLEAN_TYPE)
1060 return 1;
1061 else
1062 return 0;
1063 case CHAR_TYPE:
1064 return right;
1065 case BOOLEAN_TYPE:
1066 case COMPLEX_TYPE:
1067 case FILE_TYPE:
1068 case FUNCTION_TYPE:
1069 case GRANT_TYPE:
1070 case LANG_TYPE:
1071 case METHOD_TYPE:
1072 case RECORD_TYPE:
1073 case REFERENCE_TYPE:
1074 case SEIZE_TYPE:
1075 case UNION_TYPE:
1076 case VOID_TYPE:
1077 return 1;
1078 case ENUMERAL_TYPE:
1079 case INTEGER_TYPE:
1080 case OFFSET_TYPE:
1081 case POINTER_TYPE:
1082 case REAL_TYPE:
1083 case SET_TYPE:
1084 return 0;
1085 }
1086 break;
1087 case RANGE_EXPR:
1088 break;
1089
1090 case REPLICATE_EXPR:
1091 switch ((int)TREE_CODE(type)) /* right operand must be set/bitarray type */
1092 {
1093 case COMPLEX_TYPE:
1094 case FILE_TYPE:
1095 case FUNCTION_TYPE:
1096 case GRANT_TYPE:
1097 case LANG_TYPE:
1098 case METHOD_TYPE:
1099 case OFFSET_TYPE:
1100 case POINTER_TYPE:
1101 case RECORD_TYPE:
1102 case REAL_TYPE:
1103 case SEIZE_TYPE:
1104 case UNION_TYPE:
1105 case VOID_TYPE:
1106 return 1;
1107 case ARRAY_TYPE:
1108 case BOOLEAN_TYPE:
1109 case CHAR_TYPE:
1110 case ENUMERAL_TYPE:
1111 case INTEGER_TYPE:
1112 case REFERENCE_TYPE:
1113 case SET_TYPE:
1114 return 0;
1115 }
1116
1117 case TRUNC_DIV_EXPR:
1118 goto numerics;
1119 case TRUNC_MOD_EXPR:
1120 if (TREE_CODE (type) == REAL_TYPE)
1121 return 1;
1122 goto numerics;
1123 case TRUTH_ANDIF_EXPR:
1124 case TRUTH_AND_EXPR:
1125 case TRUTH_NOT_EXPR:
1126 case TRUTH_ORIF_EXPR:
1127 case TRUTH_OR_EXPR:
1128 relationals:
1129 switch ((int)TREE_CODE(type)) /* left operand must be discrete type */
1130 {
1131 case ARRAY_TYPE:
1132 case CHAR_TYPE:
1133 case COMPLEX_TYPE:
1134 case ENUMERAL_TYPE:
1135 case FILE_TYPE:
1136 case FUNCTION_TYPE:
1137 case GRANT_TYPE:
1138 case INTEGER_TYPE:
1139 case LANG_TYPE:
1140 case METHOD_TYPE:
1141 case OFFSET_TYPE:
1142 case POINTER_TYPE:
1143 case REAL_TYPE:
1144 case RECORD_TYPE:
1145 case REFERENCE_TYPE:
1146 case SEIZE_TYPE:
1147 case UNION_TYPE:
1148 case VOID_TYPE:
1149 return 1;
1150 case BOOLEAN_TYPE:
1151 case SET_TYPE:
1152 return 0;
1153 }
1154 break;
1155
1156 default:
1157 return 1; /* perhaps you forgot to add a new DEFTREECODE? */
1158 }
1159 return 1;
1160 }
1161
1162
1163 static int
1164 invalid_right_operand (code, type)
1165 enum chill_tree_code code;
1166 tree type;
1167 {
1168 return invalid_operand (code, type, 1);
1169 }
1170 \f
1171 tree
1172 build_chill_abs (expr)
1173 tree expr;
1174 {
1175 tree temp;
1176
1177 if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
1178 || discrete_type_p (TREE_TYPE (expr)))
1179 temp = fold (build1 (ABS_EXPR, TREE_TYPE (expr), expr));
1180 else
1181 {
1182 error("ABS argument must be discrete or real mode");
1183 return error_mark_node;
1184 }
1185 /* FIXME: should call
1186 * cond_type_range_exception (temp);
1187 */
1188 return temp;
1189 }
1190
1191 tree
1192 build_chill_abstime (exprlist)
1193 tree exprlist;
1194 {
1195 int mask = 0, i, numargs;
1196 tree args = NULL_TREE;
1197 tree filename, lineno;
1198 int had_errors = 0;
1199 tree tmp;
1200
1201 if (exprlist != NULL_TREE && TREE_CODE (exprlist) == ERROR_MARK)
1202 return error_mark_node;
1203
1204 /* check for integer expressions */
1205 i = 1;
1206 tmp = exprlist;
1207 while (tmp != NULL_TREE)
1208 {
1209 tree exp = TREE_VALUE (tmp);
1210
1211 if (exp == NULL_TREE || TREE_CODE (exp) == ERROR_MARK)
1212 had_errors = 1;
1213 else if (TREE_CODE (TREE_TYPE (exp)) != INTEGER_TYPE)
1214 {
1215 error ("argument %d to ABSTIME must be of integer type.", i);
1216 had_errors = 1;
1217 }
1218 tmp = TREE_CHAIN (tmp);
1219 i++;
1220 }
1221 if (had_errors)
1222 return error_mark_node;
1223
1224 numargs = list_length (exprlist);
1225 for (i = 0; i < numargs; i++)
1226 mask |= (1 << i);
1227
1228 /* make it all arguments */
1229 for (i = numargs; i < 6; i++)
1230 exprlist = tree_cons (NULL_TREE, integer_zero_node, exprlist);
1231
1232 args = tree_cons (NULL_TREE, build_int_2 (mask, 0), exprlist);
1233
1234 filename = force_addr_of (get_chill_filename ());
1235 lineno = get_chill_linenumber ();
1236 args = chainon (args, tree_cons (NULL_TREE, filename,
1237 tree_cons (NULL_TREE, lineno, NULL_TREE)));
1238
1239 return build_chill_function_call (
1240 lookup_name (get_identifier ("_abstime")), args);
1241 }
1242
1243
1244 tree
1245 build_allocate_memory_call (ptr, size)
1246 tree ptr, size;
1247 {
1248 int err = 0;
1249
1250 /* check for ptr is referable */
1251 if (! CH_REFERABLE (ptr))
1252 {
1253 error ("parameter 1 must be referable.");
1254 err++;
1255 }
1256 /* check for pointer */
1257 else if (TREE_CODE (TREE_TYPE (ptr)) != POINTER_TYPE)
1258 {
1259 error ("mode mismatch in parameter 1.");
1260 err++;
1261 }
1262
1263 /* check for size > 0 if it is a constant */
1264 if (TREE_CODE (size) == INTEGER_CST && TREE_INT_CST_LOW (size) <= 0)
1265 {
1266 error ("parameter 2 must be a positive integer.");
1267 err++;
1268 }
1269 if (err)
1270 return error_mark_node;
1271
1272 if (TREE_TYPE (ptr) != ptr_type_node)
1273 ptr = build_chill_cast (ptr_type_node, ptr);
1274
1275 return build_chill_function_call (
1276 lookup_name (get_identifier ("_allocate_memory")),
1277 tree_cons (NULL_TREE, ptr,
1278 tree_cons (NULL_TREE, size,
1279 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
1280 tree_cons (NULL_TREE, get_chill_linenumber (),
1281 NULL_TREE)))));
1282 }
1283
1284
1285 tree
1286 build_allocate_global_memory_call (ptr, size)
1287 tree ptr, size;
1288 {
1289 int err = 0;
1290
1291 /* check for ptr is referable */
1292 if (! CH_REFERABLE (ptr))
1293 {
1294 error ("parameter 1 must be referable.");
1295 err++;
1296 }
1297 /* check for pointer */
1298 else if (TREE_CODE (TREE_TYPE (ptr)) != POINTER_TYPE)
1299 {
1300 error ("mode mismatch in parameter 1.");
1301 err++;
1302 }
1303
1304 /* check for size > 0 if it is a constant */
1305 if (TREE_CODE (size) == INTEGER_CST && TREE_INT_CST_LOW (size) <= 0)
1306 {
1307 error ("parameter 2 must be a positive integer.");
1308 err++;
1309 }
1310 if (err)
1311 return error_mark_node;
1312
1313 if (TREE_TYPE (ptr) != ptr_type_node)
1314 ptr = build_chill_cast (ptr_type_node, ptr);
1315
1316 return build_chill_function_call (
1317 lookup_name (get_identifier ("_allocate_global_memory")),
1318 tree_cons (NULL_TREE, ptr,
1319 tree_cons (NULL_TREE, size,
1320 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
1321 tree_cons (NULL_TREE, get_chill_linenumber (),
1322 NULL_TREE)))));
1323 }
1324
1325
1326 tree
1327 build_return_memory (ptr)
1328 tree ptr;
1329 {
1330 /* check input */
1331 if (ptr == NULL_TREE || TREE_CODE (ptr) == ERROR_MARK)
1332 return error_mark_node;
1333
1334 /* check for pointer */
1335 if (TREE_CODE (TREE_TYPE (ptr)) != POINTER_TYPE)
1336 {
1337 error ("mode mismatch in parameter 1.");
1338 return error_mark_node;
1339 }
1340
1341 if (TREE_TYPE (ptr) != ptr_type_node)
1342 ptr = build_chill_cast (ptr_type_node, ptr);
1343
1344 return build_chill_function_call (
1345 lookup_name (get_identifier ("_return_memory")),
1346 tree_cons (NULL_TREE, ptr,
1347 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
1348 tree_cons (NULL_TREE, get_chill_linenumber (),
1349 NULL_TREE))));
1350 }
1351
1352
1353 /* Compute the number of runtime members of the
1354 * given powerset.
1355 */
1356 tree
1357 build_chill_card (powerset)
1358 tree powerset;
1359 {
1360 if (pass == 2)
1361 {
1362 tree temp;
1363 tree card_func = lookup_name (get_identifier ("__cardpowerset"));
1364
1365 if (powerset == NULL_TREE || TREE_CODE (powerset) == ERROR_MARK)
1366 return error_mark_node;
1367
1368 if (TREE_CODE (powerset) == IDENTIFIER_NODE)
1369 powerset = lookup_name (powerset);
1370
1371 if (TREE_CODE (TREE_TYPE(powerset)) == SET_TYPE)
1372 { int size;
1373
1374 /* Do constant folding, if possible. */
1375 if (TREE_CODE (powerset) == CONSTRUCTOR
1376 && TREE_CONSTANT (powerset)
1377 && (size = int_size_in_bytes (TREE_TYPE (powerset))) >= 0)
1378 {
1379 int bit_size = size * BITS_PER_UNIT;
1380 char* buffer = (char*) alloca (bit_size);
1381 temp = get_set_constructor_bits (powerset, buffer, bit_size);
1382 if (!temp)
1383 { int i;
1384 int count = 0;
1385 for (i = 0; i < bit_size; i++)
1386 if (buffer[i])
1387 count++;
1388 temp = build_int_2 (count, 0);
1389 TREE_TYPE (temp) = TREE_TYPE (TREE_TYPE (card_func));
1390 return temp;
1391 }
1392 }
1393 temp = build_chill_function_call (card_func,
1394 tree_cons (NULL_TREE, force_addr_of (powerset),
1395 tree_cons (NULL_TREE, powersetlen (powerset), NULL_TREE)));
1396 /* FIXME: should call
1397 * cond_type_range_exception (op0);
1398 */
1399 return temp;
1400 }
1401 error("CARD argument must be powerset mode");
1402 return error_mark_node;
1403 }
1404 return NULL_TREE;
1405 }
1406
1407 /* function to build the type needed for the DESCR-built-in
1408 */
1409
1410 void build_chill_descr_type ()
1411 {
1412 tree decl1, decl2;
1413
1414 if (descr_type != NULL_TREE)
1415 /* already done */
1416 return;
1417
1418 decl1 = build_decl (FIELD_DECL, get_identifier ("datap"), ptr_type_node);
1419 decl2 = build_decl (FIELD_DECL, get_identifier ("len"),
1420 TREE_TYPE (lookup_name (
1421 get_identifier ((ignore_case || ! special_UC) ? "ulong" : "ULONG"))));
1422 TREE_CHAIN (decl1) = decl2;
1423 TREE_CHAIN (decl2) = NULL_TREE;
1424 decl2 = build_chill_struct_type (decl1);
1425 descr_type = build_decl (TYPE_DECL, get_identifier ("__tmp_DESCR_type"), decl2);
1426 pushdecl (descr_type);
1427 DECL_SOURCE_LINE (descr_type) = 0;
1428 satisfy_decl (descr_type, 0);
1429 }
1430
1431 /* build a pointer to a descriptor.
1432 * descriptor = STRUCT (datap PTR,
1433 * len ULONG);
1434 * This descriptor is build in variable descr_type.
1435 */
1436
1437 tree
1438 build_chill_descr (expr)
1439 tree expr;
1440 {
1441 if (pass == 2)
1442 {
1443 tree tuple, decl, descr_var, datap, len, tmp;
1444 int is_static;
1445
1446 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
1447 return error_mark_node;
1448
1449 /* check for expression is referable */
1450 if (! CH_REFERABLE (expr))
1451 {
1452 error ("expression for DESCR-builtin must be referable.");
1453 return error_mark_node;
1454 }
1455
1456 mark_addressable (expr);
1457 #if 0
1458 datap = build1 (ADDR_EXPR, build_chill_pointer_type (descr_type), expr);
1459 #else
1460 datap = build_chill_arrow_expr (expr, 1);
1461 #endif
1462 len = size_in_bytes (TREE_TYPE (expr));
1463
1464 descr_var = get_unique_identifier ("DESCR");
1465 tuple = build_nt (CONSTRUCTOR, NULL_TREE,
1466 tree_cons (NULL_TREE, datap,
1467 tree_cons (NULL_TREE, len, NULL_TREE)));
1468
1469 is_static = (current_function_decl == global_function_decl) && TREE_STATIC (expr);
1470 decl = decl_temp1 (descr_var, TREE_TYPE (descr_type), is_static,
1471 tuple, 0, 0);
1472 #if 0
1473 tmp = force_addr_of (decl);
1474 #else
1475 tmp = build_chill_arrow_expr (decl, 1);
1476 #endif
1477 return tmp;
1478 }
1479 return NULL_TREE;
1480 }
1481
1482 /* this function process the builtin's
1483 MILLISECS, SECS, MINUTES, HOURS and DAYS.
1484 The built duration value is in milliseconds. */
1485
1486 tree
1487 build_chill_duration (expr, multiplier, fnname, maxvalue)
1488 tree expr;
1489 unsigned long multiplier;
1490 tree fnname;
1491 unsigned long maxvalue;
1492 {
1493 tree temp;
1494
1495 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
1496 return error_mark_node;
1497
1498 if (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
1499 {
1500 error ("argument to `%s' must be of integer type.", IDENTIFIER_POINTER (fnname));
1501 return error_mark_node;
1502 }
1503
1504 temp = convert (duration_timing_type_node, expr);
1505 temp = fold (build (MULT_EXPR, duration_timing_type_node,
1506 temp, build_int_2 (multiplier, 0)));
1507
1508 if (range_checking)
1509 temp = check_range (temp, expr, integer_zero_node, build_int_2 (maxvalue, 0));
1510
1511 return temp;
1512 }
1513
1514 /* build function call to one of the floating point functions */
1515 static tree
1516 build_chill_floatcall (expr, chillname, funcname)
1517 tree expr;
1518 char *chillname;
1519 char *funcname;
1520 {
1521 tree result;
1522 tree type;
1523
1524 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
1525 return error_mark_node;
1526
1527 /* look if expr is a REAL_TYPE */
1528 type = TREE_TYPE (expr);
1529 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
1530 return error_mark_node;
1531 if (TREE_CODE (type) != REAL_TYPE)
1532 {
1533 error ("argument 1 to `%s' must be of floating point mode", chillname);
1534 return error_mark_node;
1535 }
1536 result = build_chill_function_call (
1537 lookup_name (get_identifier (funcname)),
1538 tree_cons (NULL_TREE, expr, NULL_TREE));
1539 return result;
1540 }
1541
1542 /* common function for ALLOCATE and GETSTACK */
1543 static tree
1544 build_allocate_getstack (mode, value, chill_name, fnname, filename, linenumber)
1545 tree mode;
1546 tree value;
1547 char *chill_name;
1548 char *fnname;
1549 tree filename;
1550 tree linenumber;
1551 {
1552 tree type, result;
1553 tree expr = NULL_TREE;
1554 tree args, tmpvar, fncall, ptr, outlist = NULL_TREE;
1555
1556 if (mode == NULL_TREE || TREE_CODE (mode) == ERROR_MARK)
1557 return error_mark_node;
1558
1559 if (TREE_CODE (mode) == TYPE_DECL)
1560 type = TREE_TYPE (mode);
1561 else
1562 type = mode;
1563
1564 /* check if we have a mode */
1565 if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
1566 {
1567 error ("First argument to `%s' must be a mode", chill_name);
1568 return error_mark_node;
1569 }
1570
1571 /* check if we have a value if type is READonly */
1572 if (TYPE_READONLY_PROPERTY (type) && value == NULL_TREE)
1573 {
1574 error ("READonly modes for %s must have a value", chill_name);
1575 return error_mark_node;
1576 }
1577
1578 if (value != NULL_TREE)
1579 {
1580 if (TREE_CODE (value) == ERROR_MARK)
1581 return error_mark_node;
1582 expr = chill_convert_for_assignment (type, value, "assignment");
1583 }
1584
1585 /* build function arguments */
1586 if (filename == NULL_TREE)
1587 args = tree_cons (NULL_TREE, size_in_bytes (type), NULL_TREE);
1588 else
1589 args = tree_cons (NULL_TREE, size_in_bytes (type),
1590 tree_cons (NULL_TREE, force_addr_of (filename),
1591 tree_cons (NULL_TREE, linenumber, NULL_TREE)));
1592
1593 ptr = build_chill_pointer_type (type);
1594 tmpvar = decl_temp1 (get_unique_identifier (chill_name),
1595 ptr, 0, NULL_TREE, 0, 0);
1596 fncall = build_chill_function_call (
1597 lookup_name (get_identifier (fnname)), args);
1598 outlist = tree_cons (NULL_TREE,
1599 build_chill_modify_expr (tmpvar, fncall), outlist);
1600 if (expr == NULL_TREE)
1601 {
1602 /* set allocated memory to 0 */
1603 fncall = build_chill_function_call (
1604 lookup_name (get_identifier ("memset")),
1605 tree_cons (NULL_TREE, convert (ptr_type_node, tmpvar),
1606 tree_cons (NULL_TREE, integer_zero_node,
1607 tree_cons (NULL_TREE, size_in_bytes (type), NULL_TREE))));
1608 outlist = tree_cons (NULL_TREE, fncall, outlist);
1609 }
1610 else
1611 {
1612 /* write the init value to allocated memory */
1613 outlist = tree_cons (NULL_TREE,
1614 build_chill_modify_expr (build_chill_indirect_ref (tmpvar, NULL_TREE, 0),
1615 expr),
1616 outlist);
1617 }
1618 outlist = tree_cons (NULL_TREE, tmpvar, outlist);
1619 result = build_chill_compound_expr (nreverse (outlist));
1620 return result;
1621 }
1622
1623 /* process the ALLOCATE built-in */
1624 tree
1625 build_chill_allocate (mode, value)
1626 tree mode;
1627 tree value;
1628 {
1629 return build_allocate_getstack (mode, value, "ALLOCATE", "__allocate",
1630 get_chill_filename (), get_chill_linenumber ());
1631 }
1632
1633 /* process the GETSTACK built-in */
1634 tree
1635 build_chill_getstack (mode, value)
1636 tree mode;
1637 tree value;
1638 {
1639 return build_allocate_getstack (mode, value, "GETSTACK", "__builtin_alloca",
1640 NULL_TREE, NULL_TREE);
1641 }
1642
1643 /* process the TERMINATE built-in */
1644 tree
1645 build_chill_terminate (ptr)
1646 tree ptr;
1647 {
1648 tree result;
1649 tree type;
1650
1651 if (ptr == NULL_TREE || TREE_CODE (ptr) == ERROR_MARK)
1652 return error_mark_node;
1653
1654 type = TREE_TYPE (ptr);
1655 if (type == NULL_TREE || TREE_CODE (type) != POINTER_TYPE)
1656 {
1657 error ("argument to TERMINATE must be a reference primitive value");
1658 return error_mark_node;
1659 }
1660 result = build_chill_function_call (
1661 lookup_name (get_identifier ("__terminate")),
1662 tree_cons (NULL_TREE, convert (ptr_type_node, ptr),
1663 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
1664 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
1665 return result;
1666 }
1667
1668 /* build the type passed to _inttime function */
1669 void
1670 build_chill_inttime_type ()
1671 {
1672 tree idxlist;
1673 tree arrtype;
1674 tree decl;
1675
1676 idxlist = build_tree_list (NULL_TREE,
1677 build_chill_range_type (NULL_TREE,
1678 integer_zero_node,
1679 build_int_2 (5, 0)));
1680 arrtype = build_chill_array_type (ptr_type_node, idxlist, 0, NULL_TREE);
1681
1682 decl = build_decl (TYPE_DECL, get_identifier ("__tmp_INTTIME_type"), arrtype);
1683 pushdecl (decl);
1684 DECL_SOURCE_LINE (decl) = 0;
1685 satisfy_decl (decl, 0);
1686 }
1687
1688 tree
1689 build_chill_inttime (t, loclist)
1690 tree t, loclist;
1691 {
1692 int had_errors = 0, cnt;
1693 tree tmp;
1694 tree init = NULL_TREE;
1695 int numargs;
1696 tree tuple, var;
1697
1698 if (t == NULL_TREE || TREE_CODE (t) == ERROR_MARK)
1699 return error_mark_node;
1700 if (loclist == NULL_TREE || TREE_CODE (loclist) == ERROR_MARK)
1701 return error_mark_node;
1702
1703 /* check first argument to be NEWMODE TIME */
1704 if (TREE_TYPE (t) != abs_timing_type_node)
1705 {
1706 error ("argument 1 to INTTIME must be of mode TIME.");
1707 had_errors = 1;
1708 }
1709
1710 cnt = 2;
1711 tmp = loclist;
1712 while (tmp != NULL_TREE)
1713 {
1714 tree loc = TREE_VALUE (tmp);
1715 char errmsg[200];
1716 char *p, *p1;
1717 int write_error = 0;
1718
1719 sprintf (errmsg, "argument %d to INTTIME must be ", cnt);
1720 p = errmsg + strlen (errmsg);
1721 p1 = p;
1722
1723 if (loc == NULL_TREE || TREE_CODE (loc) == ERROR_MARK)
1724 had_errors = 1;
1725 else
1726 {
1727 if (! CH_REFERABLE (loc))
1728 {
1729 strcpy (p, "referable");
1730 p += strlen (p);
1731 write_error = 1;
1732 had_errors = 1;
1733 }
1734 if (TREE_CODE (TREE_TYPE (loc)) != INTEGER_TYPE)
1735 {
1736 if (p != p1)
1737 {
1738 strcpy (p, " and ");
1739 p += strlen (p);
1740 }
1741 strcpy (p, "of integer type");
1742 write_error = 1;
1743 had_errors = 1;
1744 }
1745 /* FIXME: what's about ranges can't hold the result ?? */
1746 if (write_error)
1747 error ("%s.", errmsg);
1748 }
1749 /* next location */
1750 tmp = TREE_CHAIN (tmp);
1751 cnt++;
1752 }
1753
1754 if (had_errors)
1755 return error_mark_node;
1756
1757 /* make it always 6 arguments */
1758 numargs = list_length (loclist);
1759 for (cnt = numargs; cnt < 6; cnt++)
1760 init = tree_cons (NULL_TREE, null_pointer_node, init);
1761
1762 /* append the given one's */
1763 tmp = loclist;
1764 while (tmp != NULL_TREE)
1765 {
1766 init = chainon (init,
1767 build_tree_list (NULL_TREE,
1768 build_chill_descr (TREE_VALUE (tmp))));
1769 tmp = TREE_CHAIN (tmp);
1770 }
1771
1772 tuple = build_nt (CONSTRUCTOR, NULL_TREE, init);
1773 var = decl_temp1 (get_unique_identifier ("INTTIME"),
1774 TREE_TYPE (lookup_name (get_identifier ("__tmp_INTTIME_type"))),
1775 0, tuple, 0, 0);
1776
1777 return build_chill_function_call (
1778 lookup_name (get_identifier ("_inttime")),
1779 tree_cons (NULL_TREE, t,
1780 tree_cons (NULL_TREE, force_addr_of (var),
1781 NULL_TREE)));
1782 }
1783
1784
1785 /* Compute the runtime length of the given string variable
1786 * or expression.
1787 */
1788 tree
1789 build_chill_length (expr)
1790 tree expr;
1791 {
1792 if (pass == 2)
1793 {
1794 tree type;
1795
1796 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
1797 return error_mark_node;
1798
1799 if (TREE_CODE (expr) == IDENTIFIER_NODE)
1800 expr = lookup_name (expr);
1801
1802 type = TREE_TYPE (expr);
1803
1804 if (TREE_CODE(type) == ERROR_MARK)
1805 return type;
1806 if (chill_varying_type_p (type))
1807 {
1808 tree temp = convert (integer_type_node,
1809 build_component_ref (expr, var_length_id));
1810 /* FIXME: should call
1811 * cond_type_range_exception (temp);
1812 */
1813 return temp;
1814 }
1815
1816 if ((TREE_CODE (type) == ARRAY_TYPE ||
1817 /* should work for a bitstring too */
1818 (TREE_CODE (type) == SET_TYPE && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE)) &&
1819 integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
1820 {
1821 tree temp = fold (build (PLUS_EXPR, chill_integer_type_node,
1822 integer_one_node,
1823 TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
1824 return convert (chill_integer_type_node, temp);
1825 }
1826
1827 if (CH_IS_BUFFER_MODE (type) || CH_IS_EVENT_MODE (type))
1828 {
1829 tree len = max_queue_size (type);
1830
1831 if (len == NULL_TREE)
1832 len = integer_minus_one_node;
1833 return len;
1834 }
1835
1836 if (CH_IS_TEXT_MODE (type))
1837 {
1838 if (TREE_CODE (expr) == TYPE_DECL)
1839 {
1840 /* text mode name */
1841 return text_length (type);
1842 }
1843 else
1844 {
1845 /* text location */
1846 tree temp = build_component_ref (
1847 build_component_ref (expr, get_identifier ("tloc")),
1848 var_length_id);
1849 return convert (integer_type_node, temp);
1850 }
1851 }
1852
1853 error("LENGTH argument must be string, buffer, event mode, text location or mode");
1854 return error_mark_node;
1855 }
1856 return NULL_TREE;
1857 }
1858
1859 /* Compute the declared minimum/maximum value of the variable,
1860 * expression or declared type
1861 */
1862 static tree
1863 build_chill_lower_or_upper (what, is_upper)
1864 tree what;
1865 int is_upper; /* o -> LOWER; 1 -> UPPER */
1866 {
1867 if (pass == 2)
1868 {
1869 tree type;
1870 struct ch_class class;
1871
1872 if (what == NULL_TREE || TREE_CODE (what) == ERROR_MARK)
1873 return error_mark_node;
1874
1875 if (TREE_CODE_CLASS (TREE_CODE (what)) == 't')
1876 type = what;
1877 else
1878 type = TREE_TYPE (what);
1879 if (type == NULL_TREE)
1880 {
1881 if (is_upper)
1882 error ("UPPER argument must have a mode, or be a mode");
1883 else
1884 error ("LOWER argument must have a mode, or be a mode");
1885 return error_mark_node;
1886 }
1887 while (TREE_CODE (type) == REFERENCE_TYPE)
1888 type = TREE_TYPE (type);
1889 if (chill_varying_type_p (type))
1890 type = CH_VARYING_ARRAY_TYPE (type);
1891
1892 if (discrete_type_p (type))
1893 {
1894 tree val = is_upper ? TYPE_MAX_VALUE (type) : TYPE_MIN_VALUE (type);
1895 class.kind = CH_VALUE_CLASS;
1896 class.mode = type;
1897 return convert_to_class (class, val);
1898 }
1899 else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == SET_TYPE)
1900 {
1901 if (TYPE_STRING_FLAG (type))
1902 {
1903 class.kind = CH_DERIVED_CLASS;
1904 class.mode = integer_type_node;
1905 }
1906 else
1907 {
1908 class.kind = CH_VALUE_CLASS;
1909 class.mode = TYPE_DOMAIN (type);
1910 }
1911 type = TYPE_DOMAIN (type);
1912 return convert_to_class (class,
1913 is_upper
1914 ? TYPE_MAX_VALUE (type)
1915 : TYPE_MIN_VALUE (type));
1916 }
1917 if (is_upper)
1918 error("UPPER argument must be string, array, mode or integer");
1919 else
1920 error("LOWER argument must be string, array, mode or integer");
1921 return error_mark_node;
1922 }
1923 return NULL_TREE;
1924 }
1925
1926 tree
1927 build_chill_lower (what)
1928 tree what;
1929 {
1930 return build_chill_lower_or_upper (what, 0);
1931 }
1932
1933 static tree
1934 build_max_min (expr, max_min)
1935 tree expr;
1936 int max_min; /* 0: calculate MIN; 1: calculate MAX */
1937 {
1938 if (pass == 2)
1939 {
1940 tree type, temp, setminval;
1941 tree set_base_type;
1942 int size_in_bytes;
1943
1944 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
1945 return error_mark_node;
1946
1947 if (TREE_CODE (expr) == IDENTIFIER_NODE)
1948 expr = lookup_name (expr);
1949
1950 type = TREE_TYPE (expr);
1951 set_base_type = TYPE_DOMAIN (type);
1952 setminval = TYPE_MIN_VALUE (set_base_type);
1953
1954 if (TREE_CODE (type) != SET_TYPE)
1955 {
1956 error("%s argument must be POWERSET mode",
1957 max_min ? "MAX" : "MIN");
1958 return error_mark_node;
1959 }
1960
1961 /* find max/min of constant powerset at compile time */
1962 if (TREE_CODE (expr) == CONSTRUCTOR && TREE_CONSTANT (expr)
1963 && (size_in_bytes = int_size_in_bytes (type)) >= 0)
1964 {
1965 HOST_WIDE_INT min_val = -1, max_val = -1;
1966 HOST_WIDE_INT i, i_hi = 0;
1967 HOST_WIDE_INT size_in_bits = size_in_bytes * BITS_PER_UNIT;
1968 char *buffer = (char*) alloca (size_in_bits);
1969 if (buffer == NULL
1970 || get_set_constructor_bits (expr, buffer, size_in_bits))
1971 abort ();
1972 for (i = 0; i < size_in_bits; i++)
1973 {
1974 if (buffer[i])
1975 {
1976 if (min_val < 0)
1977 min_val = i;
1978 max_val = i;
1979 }
1980 }
1981 if (min_val < 0)
1982 error ("%s called for empty POWERSET", max_min ? "MAX" : "MIN");
1983 i = max_min ? max_val : min_val;
1984 temp = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (expr)));
1985 add_double (i, i_hi,
1986 TREE_INT_CST_LOW (temp), TREE_INT_CST_HIGH (temp),
1987 &i, &i_hi);
1988 temp = build_int_2 (i, i_hi);
1989 TREE_TYPE (temp) = set_base_type;
1990 return temp;
1991 }
1992 else
1993 {
1994 tree parmlist, filename, lineno;
1995 char *funcname;
1996
1997 /* set up to call appropriate runtime function */
1998 if (max_min)
1999 funcname = "__flsetpowerset";
2000 else
2001 funcname = "__ffsetpowerset";
2002
2003 setminval = convert (long_integer_type_node, setminval);
2004 filename = force_addr_of (get_chill_filename());
2005 lineno = get_chill_linenumber();
2006 parmlist = tree_cons (NULL_TREE, force_addr_of (expr),
2007 tree_cons (NULL_TREE, powersetlen (expr),
2008 tree_cons (NULL_TREE, setminval,
2009 tree_cons (NULL_TREE, filename,
2010 build_tree_list (NULL_TREE, lineno)))));
2011 temp = lookup_name (get_identifier (funcname));
2012 temp = build_chill_function_call (temp, parmlist);
2013 TREE_TYPE (temp) = set_base_type;
2014 return temp;
2015 }
2016 }
2017 return NULL_TREE;
2018 }
2019
2020
2021 /* Compute the current runtime maximum value of the powerset
2022 */
2023 tree
2024 build_chill_max (expr)
2025 tree expr;
2026 {
2027 return build_max_min (expr, 1);
2028 }
2029
2030
2031 /* Compute the current runtime minimum value of the powerset
2032 */
2033 tree
2034 build_chill_min (expr)
2035 tree expr;
2036 {
2037 return build_max_min (expr, 0);
2038 }
2039
2040
2041 /* Build a conversion from the given expression to an INT,
2042 * but only when the expression's type is the same size as
2043 * an INT.
2044 */
2045 tree
2046 build_chill_num (expr)
2047 tree expr;
2048 {
2049 if (pass == 2)
2050 {
2051 tree temp;
2052 int need_unsigned;
2053
2054 if (expr == NULL_TREE || TREE_CODE(expr) == ERROR_MARK)
2055 return error_mark_node;
2056
2057 if (TREE_CODE (expr) == IDENTIFIER_NODE)
2058 expr = lookup_name (expr);
2059
2060 expr = convert_to_discrete (expr);
2061 if (expr == NULL_TREE)
2062 {
2063 error ("argument to NUM is not discrete");
2064 return error_mark_node;
2065 }
2066
2067 /* enumeral types and string slices of length 1 must be kept unsigned */
2068 need_unsigned = (TREE_CODE (TREE_TYPE (expr)) == ENUMERAL_TYPE)
2069 || TREE_UNSIGNED (TREE_TYPE (expr));
2070
2071 temp = type_for_size (TYPE_PRECISION (TREE_TYPE (expr)),
2072 need_unsigned);
2073 if (temp == NULL_TREE)
2074 {
2075 error ("No integer mode which matches expression's mode");
2076 return integer_zero_node;
2077 }
2078 temp = convert (temp, expr);
2079
2080 if (TREE_CONSTANT (temp))
2081 {
2082 if (tree_int_cst_lt (temp,
2083 TYPE_MIN_VALUE (TREE_TYPE (temp))))
2084 error ("NUM's parameter is below its mode range");
2085 if (tree_int_cst_lt (TYPE_MAX_VALUE (TREE_TYPE (temp)),
2086 temp))
2087 error ("NUM's parameter is above its mode range");
2088 }
2089 #if 0
2090 else
2091 {
2092 if (range_checking)
2093 cond_overflow_exception (temp,
2094 TYPE_MIN_VALUE (TREE_TYPE (temp)),
2095 TYPE_MAX_VALUE (TREE_TYPE (temp)));
2096 }
2097 #endif
2098
2099 /* NUM delivers the INT derived class */
2100 CH_DERIVED_FLAG (temp) = 1;
2101
2102 return temp;
2103 }
2104 return NULL_TREE;
2105 }
2106
2107
2108 static tree
2109 build_chill_pred_or_succ (expr, op)
2110 tree expr;
2111 enum tree_code op; /* PLUS_EXPR for SUCC; MINUS_EXPR for PRED. */
2112 {
2113 struct ch_class class;
2114 tree etype, cond;
2115
2116 if (pass == 1)
2117 return NULL_TREE;
2118
2119 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
2120 return error_mark_node;
2121
2122 /* disallow numbered SETs */
2123 if (TREE_CODE (TREE_TYPE (expr)) == ENUMERAL_TYPE
2124 && CH_ENUM_IS_NUMBERED (TREE_TYPE (expr)))
2125 {
2126 error ("Cannot take SUCC or PRED of a numbered SET");
2127 return error_mark_node;
2128 }
2129
2130 if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
2131 {
2132 if (TREE_TYPE (TREE_TYPE (expr)) == void_type_node)
2133 {
2134 error ("SUCC or PRED must not be done on a PTR.");
2135 return error_mark_node;
2136 }
2137 pedwarn ("SUCC or PRED for a reference type is not standard.");
2138 return fold (build (op, TREE_TYPE (expr),
2139 expr,
2140 size_in_bytes (TREE_TYPE (TREE_TYPE (expr)))));
2141 }
2142
2143 expr = convert_to_discrete (expr);
2144
2145 if (expr == NULL_TREE)
2146 {
2147 error ("SUCC or PRED argument must be a discrete mode");
2148 return error_mark_node;
2149 }
2150
2151 class = chill_expr_class (expr);
2152 if (class.mode)
2153 class.mode = CH_ROOT_MODE (class.mode);
2154 etype = class.mode;
2155 expr = convert (etype, expr);
2156
2157 /* Exception if expression is already at the
2158 min (PRED)/max(SUCC) valid value for its type. */
2159 cond = fold (build (op == PLUS_EXPR ? GE_EXPR : LE_EXPR,
2160 boolean_type_node,
2161 expr,
2162 convert (etype,
2163 op == PLUS_EXPR ? TYPE_MAX_VALUE (etype)
2164 : TYPE_MIN_VALUE (etype))));
2165 if (TREE_CODE (cond) == INTEGER_CST
2166 && tree_int_cst_equal (cond, integer_one_node))
2167 {
2168 error ("Taking the %s of a value already at its %s value",
2169 op == PLUS_EXPR ? "SUCC" : "PRED",
2170 op == PLUS_EXPR ? "maximum" : "minimum");
2171 return error_mark_node;
2172 }
2173
2174 if (range_checking)
2175 expr = check_expression (expr, cond,
2176 ridpointers[(int) RID_OVERFLOW]);
2177
2178 expr = fold (build (op, etype, expr,
2179 convert (etype, integer_one_node)));
2180 return convert_to_class (class, expr);
2181 }
2182 \f
2183 /* Compute the value of the CHILL `size' operator just
2184 * like the C 'sizeof' operator (code stolen from c-typeck.c)
2185 * TYPE may be a location or mode tree. In pass 1, we build
2186 * a function-call syntax tree; in pass 2, we evaluate it.
2187 */
2188 tree
2189 build_chill_sizeof (type)
2190 tree type;
2191 {
2192 if (pass == 2)
2193 {
2194 tree temp;
2195 struct ch_class class;
2196 enum tree_code code;
2197 tree signame = NULL_TREE;
2198
2199 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
2200 return error_mark_node;
2201
2202 if (TREE_CODE (type) == IDENTIFIER_NODE)
2203 type = lookup_name (type);
2204
2205 code = TREE_CODE (type);
2206 if (code == ERROR_MARK)
2207 return error_mark_node;
2208
2209 if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
2210 {
2211 if (TREE_CODE (type) == TYPE_DECL && CH_DECL_SIGNAL (type))
2212 signame = DECL_NAME (type);
2213 type = TREE_TYPE (type);
2214 }
2215
2216 if (code == FUNCTION_TYPE)
2217 {
2218 if (pedantic || warn_pointer_arith)
2219 pedwarn ("size applied to a function mode");
2220 return error_mark_node;
2221 }
2222 if (code == VOID_TYPE)
2223 {
2224 if (pedantic || warn_pointer_arith)
2225 pedwarn ("sizeof applied to a void mode");
2226 return error_mark_node;
2227 }
2228 if (TYPE_SIZE (type) == 0)
2229 {
2230 error ("sizeof applied to an incomplete mode");
2231 return error_mark_node;
2232 }
2233
2234 temp = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
2235 size_int (TYPE_PRECISION (char_type_node)));
2236 if (signame != NULL_TREE)
2237 {
2238 /* we have a signal definition. This signal may have no
2239 data items specified. The definition however says that
2240 there are data, cause we cannot build a structure without
2241 fields. In this case return 0. */
2242 if (IDENTIFIER_SIGNAL_DATA (signame) == 0)
2243 temp = integer_zero_node;
2244 }
2245
2246 /* FIXME: should call
2247 * cond_type_range_exception (temp);
2248 */
2249 class.kind = CH_DERIVED_CLASS;
2250 class.mode = integer_type_node;
2251 return convert_to_class (class, temp);
2252 }
2253 return NULL_TREE;
2254 }
2255 \f
2256 /* Compute the declared maximum value of the variable,
2257 * expression or declared type
2258 */
2259 tree
2260 build_chill_upper (what)
2261 tree what;
2262 {
2263 return build_chill_lower_or_upper (what, 1);
2264 }
2265 \f
2266 /*
2267 * Here at the site of a function/procedure call.. We need to build
2268 * temps for the INOUT and OUT parameters, and copy the actual parameters
2269 * into the temps. After the call, we 'copy back' the values from the
2270 * temps to the actual parameter variables. This somewhat verbose pol-
2271 * icy meets the requirement that the actual parameters are undisturbed
2272 * if the function/procedure causes an exception. They are updated only
2273 * upon a normal return from the function.
2274 *
2275 * Note: the expr_list, which collects all of the above assignments, etc,
2276 * is built in REVERSE execution order. The list is corrected by nreverse
2277 * inside the build_chill_compound_expr call.
2278 */
2279 tree
2280 build_chill_function_call (function, expr)
2281 tree function, expr;
2282 {
2283 register tree typetail, valtail, typelist;
2284 register tree temp, actual_args = NULL_TREE;
2285 tree name = NULL_TREE;
2286 tree function_call;
2287 tree fntype;
2288 int parmno = 1; /* parameter number for error message */
2289 int callee_raise_exception = 0;
2290
2291 /* list of assignments to run after the actual call,
2292 copying from the temps back to the user's variables. */
2293 tree copy_back = NULL_TREE;
2294
2295 /* list of expressions to run before the call, copying from
2296 the user's variable to the temps that are passed to the function */
2297 tree expr_list = NULL_TREE;
2298
2299 if (function == NULL_TREE || TREE_CODE (function) == ERROR_MARK)
2300 return error_mark_node;
2301
2302 if (expr != NULL_TREE && TREE_CODE (expr) == ERROR_MARK)
2303 return error_mark_node;
2304
2305 if (pass < 2)
2306 return error_mark_node;
2307
2308 fntype = TREE_TYPE (function);
2309 if (TREE_CODE (function) == FUNCTION_DECL)
2310 {
2311 callee_raise_exception = TYPE_RAISES_EXCEPTIONS (fntype) != NULL_TREE;
2312
2313 /* Differs from default_conversion by not setting TREE_ADDRESSABLE
2314 (because calling an inline function does not mean the function
2315 needs to be separately compiled). */
2316 fntype = build_type_variant (fntype,
2317 TREE_READONLY (function),
2318 TREE_THIS_VOLATILE (function));
2319 name = DECL_NAME (function);
2320
2321 /* check that function is not a PROCESS */
2322 if (CH_DECL_PROCESS (function))
2323 {
2324 error ("cannot call a PROCESS, you START a PROCESS");
2325 return error_mark_node;
2326 }
2327
2328 function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
2329 }
2330 else if (TREE_CODE (fntype) == POINTER_TYPE)
2331 {
2332 fntype = TREE_TYPE (fntype);
2333 callee_raise_exception = TYPE_RAISES_EXCEPTIONS (fntype) != NULL_TREE;
2334
2335 /* Z.200 6.7 Call Action:
2336 "A procedure call causes the EMPTY exception if the
2337 procedure primitive value delivers NULL. */
2338 if (TREE_CODE (function) != ADDR_EXPR
2339 || TREE_CODE (TREE_OPERAND (function, 0)) != FUNCTION_DECL)
2340 function = check_non_null (function);
2341 }
2342
2343 typelist = TYPE_ARG_TYPES (fntype);
2344 if (callee_raise_exception)
2345 {
2346 /* remove last two arguments from list for subsequent checking.
2347 They will get added automatically after checking */
2348 int len = list_length (typelist);
2349 int i;
2350 tree newtypelist = NULL_TREE;
2351 tree wrk = typelist;
2352
2353 for (i = 0; i < len - 3; i++)
2354 {
2355 newtypelist = tree_cons (TREE_PURPOSE (wrk), TREE_VALUE (wrk), newtypelist);
2356 wrk = TREE_CHAIN (wrk);
2357 }
2358 /* add the void_type_node */
2359 newtypelist = tree_cons (NULL_TREE, void_type_node, newtypelist);
2360 typelist = nreverse (newtypelist);
2361 }
2362
2363 /* Scan the given expressions and types, producing individual
2364 converted arguments and pushing them on ACTUAL_ARGS in
2365 reverse order. */
2366 for (valtail = expr, typetail = typelist;
2367 valtail != NULL_TREE && typetail != NULL_TREE; parmno++,
2368 valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail))
2369 {
2370 register tree actual = TREE_VALUE (valtail);
2371 register tree attr = TREE_PURPOSE (typetail)
2372 ? TREE_PURPOSE (typetail) : ridpointers[(int) RID_IN];
2373 register tree type = TREE_VALUE (typetail);
2374 char place[30];
2375 sprintf (place, "parameter %d", parmno);
2376
2377 /* if we have reached void_type_node in typelist we are at the
2378 end of formal parameters and then we have too many actual
2379 parameters */
2380 if (type == void_type_node)
2381 break;
2382
2383 /* check if actual is a TYPE_DECL. FIXME: what else ? */
2384 if (TREE_CODE (actual) == TYPE_DECL)
2385 {
2386 error ("invalid %s", place);
2387 actual = error_mark_node;
2388 }
2389 /* INOUT or OUT param to handle? */
2390 else if (attr == ridpointers[(int) RID_OUT]
2391 || attr == ridpointers[(int)RID_INOUT])
2392 {
2393 char temp_name[20];
2394 tree parmtmp;
2395 tree in_actual = NULL_TREE, out_actual;
2396
2397 /* actual parameter must be a location so we can
2398 build a reference to it */
2399 if (!CH_LOCATION_P (actual))
2400 {
2401 error ("%s parameter %d must be a location",
2402 (attr == ridpointers[(int) RID_OUT]) ?
2403 "OUT" : "INOUT", parmno);
2404 continue;
2405 }
2406 if (TYPE_READONLY_PROPERTY (TREE_TYPE (actual))
2407 || TREE_READONLY (actual))
2408 {
2409 error ("%s parameter %d is READ-only",
2410 (attr == ridpointers[(int) RID_OUT]) ?
2411 "OUT" : "INOUT", parmno);
2412 continue;
2413 }
2414
2415 sprintf (temp_name, "PARM_%d_%s", parmno,
2416 (attr == ridpointers[(int)RID_OUT]) ?
2417 "OUT" : "INOUT");
2418 parmtmp = decl_temp1 (get_unique_identifier (temp_name),
2419 TREE_TYPE (type), 0, NULL_TREE, 0, 0);
2420 /* this temp *must not* be optimized into a register */
2421 mark_addressable (parmtmp);
2422
2423 if (attr == ridpointers[(int)RID_INOUT])
2424 {
2425 tree in_actual = chill_convert_for_assignment (TREE_TYPE (type),
2426 actual, place);
2427 tree tmp = build_chill_modify_expr (parmtmp, in_actual);
2428 expr_list = tree_cons (NULL_TREE, tmp, expr_list);
2429 }
2430 if (in_actual != error_mark_node)
2431 {
2432 /* list of copy back assignments to perform, from the temp
2433 back to the actual parameter */
2434 out_actual = chill_convert_for_assignment (TREE_TYPE (actual),
2435 parmtmp, place);
2436 copy_back = tree_cons (NULL_TREE,
2437 build_chill_modify_expr (actual,
2438 out_actual),
2439 copy_back);
2440 }
2441 /* we can do this because build_chill_function_type
2442 turned these parameters into REFERENCE_TYPEs. */
2443 actual = build1 (ADDR_EXPR, type, parmtmp);
2444 }
2445 else if (attr == ridpointers[(int) RID_LOC])
2446 {
2447 int is_location = chill_location (actual);
2448 if (is_location)
2449 {
2450 if (is_location == 1)
2451 {
2452 error ("LOC actual parameter %d is a non-referable location",
2453 parmno);
2454 actual = error_mark_node;
2455 }
2456 else if (! CH_READ_COMPATIBLE (type, TREE_TYPE (actual)))
2457 {
2458 error ("mode mismatch in parameter %d", parmno);
2459 actual = error_mark_node;
2460 }
2461 else
2462 actual = convert (type, actual);
2463 }
2464 else
2465 {
2466 sprintf (place, "parameter_%d", parmno);
2467 actual = decl_temp1 (get_identifier (place),
2468 TREE_TYPE (type), 0, actual, 0, 0);
2469 actual = convert (type, actual);
2470 }
2471 mark_addressable (actual);
2472 }
2473 else
2474 actual = chill_convert_for_assignment (type, actual, place);
2475
2476 actual_args = tree_cons (NULL_TREE, actual, actual_args);
2477 }
2478
2479 if (valtail != 0 && TREE_VALUE (valtail) != void_type_node)
2480 {
2481 char *errstr = "too many arguments to procedure";
2482 if (name)
2483 error ("%s `%s'", errstr, IDENTIFIER_POINTER (name));
2484 else
2485 error (errstr);
2486 return error_mark_node;
2487 }
2488 else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
2489 {
2490 char *errstr = "too few arguments to procedure";
2491 if (name)
2492 error ("%s `%s'", errstr, IDENTIFIER_POINTER (name));
2493 else
2494 error (errstr);
2495 return error_mark_node;
2496 }
2497
2498 if (callee_raise_exception)
2499 {
2500 /* add linenumber and filename of the caller as arguments */
2501 actual_args = tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2502 actual_args);
2503 actual_args = tree_cons (NULL_TREE, get_chill_linenumber (), actual_args);
2504 }
2505
2506 function_call = build (CALL_EXPR, TREE_TYPE (fntype),
2507 function, nreverse (actual_args), NULL_TREE);
2508 TREE_SIDE_EFFECTS (function_call) = 1;
2509
2510 if (copy_back == NULL_TREE && expr_list == NULL_TREE)
2511 return function_call; /* no copying to do, either way */
2512 else
2513 {
2514 tree result_type = TREE_TYPE (fntype);
2515 tree result_tmp = NULL_TREE;
2516
2517 /* no result wanted from procedure call */
2518 if (result_type == NULL_TREE || result_type == void_type_node)
2519 expr_list = tree_cons (NULL_TREE, function_call, expr_list);
2520 else
2521 {
2522 /* create a temp for the function's result. this is so that we can
2523 evaluate this temp as the last expression in the list, which will
2524 make the function's return value the value of the whole list of
2525 expressions (by the C rules for compound expressions) */
2526 result_tmp = decl_temp1 (get_unique_identifier ("FUNC_RESULT"),
2527 result_type, 0, NULL_TREE, 0, 0);
2528 expr_list = tree_cons (NULL_TREE,
2529 build_chill_modify_expr (result_tmp, function_call),
2530 expr_list);
2531 }
2532
2533 expr_list = chainon (copy_back, expr_list);
2534
2535 /* last, but not least, the function's result */
2536 if (result_tmp != NULL_TREE)
2537 expr_list = tree_cons (NULL_TREE, result_tmp, expr_list);
2538 temp = build_chill_compound_expr (nreverse (expr_list));
2539 return temp;
2540 }
2541 }
2542 \f
2543 /* We saw something that looks like a function call,
2544 but if it's pass 1, we're not sure. */
2545
2546 tree
2547 build_generalized_call (func, args)
2548 tree func, args;
2549 {
2550 tree type = TREE_TYPE (func);
2551
2552 if (pass == 1)
2553 return build (CALL_EXPR, NULL_TREE, func, args, NULL_TREE);
2554
2555 /* Handle string repetition */
2556 if (TREE_CODE (func) == INTEGER_CST)
2557 {
2558 if (args == NULL_TREE || TREE_CHAIN (args) != NULL_TREE)
2559 {
2560 error ("syntax error (integer used as function)");
2561 return error_mark_node;
2562 }
2563 if (TREE_CODE (args) == TREE_LIST)
2564 args = TREE_VALUE (args);
2565 return build_chill_repetition_op (func, args);
2566 }
2567
2568 if (args != NULL_TREE)
2569 {
2570 if (TREE_CODE (args) == RANGE_EXPR)
2571 {
2572 tree lo = TREE_OPERAND (args, 0), hi = TREE_OPERAND (args, 1);
2573 if (TREE_CODE_CLASS (TREE_CODE (func)) == 't')
2574 return build_chill_range_type (func, lo, hi);
2575 else
2576 return build_chill_slice_with_range (func, lo, hi);
2577 }
2578 else if (TREE_CODE (args) != TREE_LIST)
2579 {
2580 error ("syntax error - missing operator, comma, or '('?");
2581 return error_mark_node;
2582 }
2583 }
2584
2585 if (TREE_CODE (func) == TYPE_DECL)
2586 {
2587 if (CH_DECL_SIGNAL (func))
2588 return build_signal_descriptor (func, args);
2589 func = TREE_TYPE (func);
2590 }
2591
2592 if (TREE_CODE_CLASS (TREE_CODE (func)) == 't'
2593 && args != NULL_TREE && TREE_CHAIN (args) == NULL_TREE)
2594 return build_chill_cast (func, TREE_VALUE (args));
2595
2596 if (TREE_CODE (type) == FUNCTION_TYPE
2597 || (TREE_CODE (type) == POINTER_TYPE
2598 && TREE_TYPE (type) != NULL_TREE
2599 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
2600 {
2601 /* Check for a built-in Chill function. */
2602 if (TREE_CODE (func) == FUNCTION_DECL
2603 && DECL_BUILT_IN (func)
2604 && DECL_FUNCTION_CODE (func) > END_BUILTINS)
2605 {
2606 tree fnname = DECL_NAME (func);
2607 switch ((enum chill_built_in_function)DECL_FUNCTION_CODE (func))
2608 {
2609 case BUILT_IN_CH_ABS:
2610 if (check_arglist_length (args, 1, 1, fnname) < 0)
2611 return error_mark_node;
2612 return build_chill_abs (TREE_VALUE (args));
2613 case BUILT_IN_ABSTIME:
2614 if (check_arglist_length (args, 0, 6, fnname) < 0)
2615 return error_mark_node;
2616 return build_chill_abstime (args);
2617 case BUILT_IN_ADDR:
2618 if (check_arglist_length (args, 1, 1, fnname) < 0)
2619 return error_mark_node;
2620 #if 0
2621 return build_chill_addr_expr (TREE_VALUE (args), (char *)0);
2622 #else
2623 return build_chill_arrow_expr (TREE_VALUE (args), 0);
2624 #endif
2625 case BUILT_IN_ALLOCATE_GLOBAL_MEMORY:
2626 if (check_arglist_length (args, 2, 2, fnname) < 0)
2627 return error_mark_node;
2628 return build_allocate_global_memory_call
2629 (TREE_VALUE (args),
2630 TREE_VALUE (TREE_CHAIN (args)));
2631 case BUILT_IN_ALLOCATE:
2632 if (check_arglist_length (args, 1, 2, fnname) < 0)
2633 return error_mark_node;
2634 return build_chill_allocate (TREE_VALUE (args),
2635 TREE_CHAIN (args) == NULL_TREE ? NULL_TREE : TREE_VALUE (TREE_CHAIN (args)));
2636 case BUILT_IN_ALLOCATE_MEMORY:
2637 if (check_arglist_length (args, 2, 2, fnname) < 0)
2638 return error_mark_node;
2639 return build_allocate_memory_call
2640 (TREE_VALUE (args),
2641 TREE_VALUE (TREE_CHAIN (args)));
2642 case BUILT_IN_ASSOCIATE:
2643 if (check_arglist_length (args, 2, 3, fnname) < 0)
2644 return error_mark_node;
2645 return build_chill_associate
2646 (TREE_VALUE (args),
2647 TREE_VALUE (TREE_CHAIN (args)),
2648 TREE_CHAIN (TREE_CHAIN (args)));
2649 case BUILT_IN_ARCCOS:
2650 if (check_arglist_length (args, 1, 1, fnname) < 0)
2651 return error_mark_node;
2652 return build_chill_floatcall (TREE_VALUE (args),
2653 IDENTIFIER_POINTER (fnname),
2654 "__acos");
2655 case BUILT_IN_ARCSIN:
2656 if (check_arglist_length (args, 1, 1, fnname) < 0)
2657 return error_mark_node;
2658 return build_chill_floatcall (TREE_VALUE (args),
2659 IDENTIFIER_POINTER (fnname),
2660 "__asin");
2661 case BUILT_IN_ARCTAN:
2662 if (check_arglist_length (args, 1, 1, fnname) < 0)
2663 return error_mark_node;
2664 return build_chill_floatcall (TREE_VALUE (args),
2665 IDENTIFIER_POINTER (fnname),
2666 "__atan");
2667 case BUILT_IN_CARD:
2668 if (check_arglist_length (args, 1, 1, fnname) < 0)
2669 return error_mark_node;
2670 return build_chill_card (TREE_VALUE (args));
2671 case BUILT_IN_CONNECT:
2672 if (check_arglist_length (args, 3, 5, fnname) < 0)
2673 return error_mark_node;
2674 return build_chill_connect
2675 (TREE_VALUE (args),
2676 TREE_VALUE (TREE_CHAIN (args)),
2677 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))),
2678 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args))));
2679 case BUILT_IN_COPY_NUMBER:
2680 if (check_arglist_length (args, 1, 1, fnname) < 0)
2681 return error_mark_node;
2682 return build_copy_number (TREE_VALUE (args));
2683 case BUILT_IN_CH_COS:
2684 if (check_arglist_length (args, 1, 1, fnname) < 0)
2685 return error_mark_node;
2686 return build_chill_floatcall (TREE_VALUE (args),
2687 IDENTIFIER_POINTER (fnname),
2688 "__cos");
2689 case BUILT_IN_CREATE:
2690 if (check_arglist_length (args, 1, 1, fnname) < 0)
2691 return error_mark_node;
2692 return build_chill_create (TREE_VALUE (args));
2693 case BUILT_IN_DAYS:
2694 if (check_arglist_length (args, 1, 1, fnname) < 0)
2695 return error_mark_node;
2696 return build_chill_duration (TREE_VALUE (args), DAYS_MULTIPLIER,
2697 fnname, DAYS_MAX);
2698 case BUILT_IN_CH_DELETE:
2699 if (check_arglist_length (args, 1, 1, fnname) < 0)
2700 return error_mark_node;
2701 return build_chill_delete (TREE_VALUE (args));
2702 case BUILT_IN_DESCR:
2703 if (check_arglist_length (args, 1, 1, fnname) < 0)
2704 return error_mark_node;
2705 return build_chill_descr (TREE_VALUE (args));
2706 case BUILT_IN_DISCONNECT:
2707 if (check_arglist_length (args, 1, 1, fnname) < 0)
2708 return error_mark_node;
2709 return build_chill_disconnect (TREE_VALUE (args));
2710 case BUILT_IN_DISSOCIATE:
2711 if (check_arglist_length (args, 1, 1, fnname) < 0)
2712 return error_mark_node;
2713 return build_chill_dissociate (TREE_VALUE (args));
2714 case BUILT_IN_EOLN:
2715 if (check_arglist_length (args, 1, 1, fnname) < 0)
2716 return error_mark_node;
2717 return build_chill_eoln (TREE_VALUE (args));
2718 case BUILT_IN_EXISTING:
2719 if (check_arglist_length (args, 1, 1, fnname) < 0)
2720 return error_mark_node;
2721 return build_chill_existing (TREE_VALUE (args));
2722 case BUILT_IN_EXP:
2723 if (check_arglist_length (args, 1, 1, fnname) < 0)
2724 return error_mark_node;
2725 return build_chill_floatcall (TREE_VALUE (args),
2726 IDENTIFIER_POINTER (fnname),
2727 "__exp");
2728 case BUILT_IN_GEN_CODE:
2729 if (check_arglist_length (args, 1, 1, fnname) < 0)
2730 return error_mark_node;
2731 return build_gen_code (TREE_VALUE (args));
2732 case BUILT_IN_GEN_INST:
2733 if (check_arglist_length (args, 2, 2, fnname) < 0)
2734 return error_mark_node;
2735 return build_gen_inst (TREE_VALUE (args),
2736 TREE_VALUE (TREE_CHAIN (args)));
2737 case BUILT_IN_GEN_PTYPE:
2738 if (check_arglist_length (args, 1, 1, fnname) < 0)
2739 return error_mark_node;
2740 return build_gen_ptype (TREE_VALUE (args));
2741 case BUILT_IN_GETASSOCIATION:
2742 if (check_arglist_length (args, 1, 1, fnname) < 0)
2743 return error_mark_node;
2744 return build_chill_getassociation (TREE_VALUE (args));
2745 case BUILT_IN_GETSTACK:
2746 if (check_arglist_length (args, 1, 2, fnname) < 0)
2747 return error_mark_node;
2748 return build_chill_getstack (TREE_VALUE (args),
2749 TREE_CHAIN (args) == NULL_TREE ? NULL_TREE : TREE_VALUE (TREE_CHAIN (args)));
2750 case BUILT_IN_GETTEXTACCESS:
2751 if (check_arglist_length (args, 1, 1, fnname) < 0)
2752 return error_mark_node;
2753 return build_chill_gettextaccess (TREE_VALUE (args));
2754 case BUILT_IN_GETTEXTINDEX:
2755 if (check_arglist_length (args, 1, 1, fnname) < 0)
2756 return error_mark_node;
2757 return build_chill_gettextindex (TREE_VALUE (args));
2758 case BUILT_IN_GETTEXTRECORD:
2759 if (check_arglist_length (args, 1, 1, fnname) < 0)
2760 return error_mark_node;
2761 return build_chill_gettextrecord (TREE_VALUE (args));
2762 case BUILT_IN_GETUSAGE:
2763 if (check_arglist_length (args, 1, 1, fnname) < 0)
2764 return error_mark_node;
2765 return build_chill_getusage (TREE_VALUE (args));
2766 case BUILT_IN_HOURS:
2767 if (check_arglist_length (args, 1, 1, fnname) < 0)
2768 return error_mark_node;
2769 return build_chill_duration (TREE_VALUE (args), HOURS_MULTIPLIER,
2770 fnname, HOURS_MAX);
2771 case BUILT_IN_INDEXABLE:
2772 if (check_arglist_length (args, 1, 1, fnname) < 0)
2773 return error_mark_node;
2774 return build_chill_indexable (TREE_VALUE (args));
2775 case BUILT_IN_INTTIME:
2776 if (check_arglist_length (args, 2, 7, fnname) < 0)
2777 return error_mark_node;
2778 return build_chill_inttime (TREE_VALUE (args),
2779 TREE_CHAIN (args));
2780 case BUILT_IN_ISASSOCIATED:
2781 if (check_arglist_length (args, 1, 1, fnname) < 0)
2782 return error_mark_node;
2783 return build_chill_isassociated (TREE_VALUE (args));
2784 case BUILT_IN_LENGTH:
2785 if (check_arglist_length (args, 1, 1, fnname) < 0)
2786 return error_mark_node;
2787 return build_chill_length (TREE_VALUE (args));
2788 case BUILT_IN_LN:
2789 if (check_arglist_length (args, 1, 1, fnname) < 0)
2790 return error_mark_node;
2791 return build_chill_floatcall (TREE_VALUE (args),
2792 IDENTIFIER_POINTER (fnname),
2793 "__log");
2794 case BUILT_IN_LOG:
2795 if (check_arglist_length (args, 1, 1, fnname) < 0)
2796 return error_mark_node;
2797 return build_chill_floatcall (TREE_VALUE (args),
2798 IDENTIFIER_POINTER (fnname),
2799 "__log10");
2800 case BUILT_IN_LOWER:
2801 if (check_arglist_length (args, 1, 1, fnname) < 0)
2802 return error_mark_node;
2803 return build_chill_lower (TREE_VALUE (args));
2804 case BUILT_IN_MAX:
2805 if (check_arglist_length (args, 1, 1, fnname) < 0)
2806 return error_mark_node;
2807 return build_chill_max (TREE_VALUE (args));
2808 case BUILT_IN_MILLISECS:
2809 if (check_arglist_length (args, 1, 1, fnname) < 0)
2810 return error_mark_node;
2811 return build_chill_duration (TREE_VALUE (args), MILLISECS_MULTIPLIER,
2812 fnname, MILLISECS_MAX);
2813 case BUILT_IN_MIN:
2814 if (check_arglist_length (args, 1, 1, fnname) < 0)
2815 return error_mark_node;
2816 return build_chill_min (TREE_VALUE (args));
2817 case BUILT_IN_MINUTES:
2818 if (check_arglist_length (args, 1, 1, fnname) < 0)
2819 return error_mark_node;
2820 return build_chill_duration (TREE_VALUE (args), MINUTES_MULTIPLIER,
2821 fnname, MINUTES_MAX);
2822 case BUILT_IN_MODIFY:
2823 if (check_arglist_length (args, 1, -1, fnname) < 0)
2824 return error_mark_node;
2825 return build_chill_modify (TREE_VALUE (args), TREE_CHAIN (args));
2826 case BUILT_IN_NUM:
2827 if (check_arglist_length (args, 1, 1, fnname) < 0)
2828 return error_mark_node;
2829 return build_chill_num (TREE_VALUE (args));
2830 case BUILT_IN_OUTOFFILE:
2831 if (check_arglist_length (args, 1, 1, fnname) < 0)
2832 return error_mark_node;
2833 return build_chill_outoffile (TREE_VALUE (args));
2834 case BUILT_IN_PRED:
2835 if (check_arglist_length (args, 1, 1, fnname) < 0)
2836 return error_mark_node;
2837 return build_chill_pred_or_succ (TREE_VALUE (args), MINUS_EXPR);
2838 case BUILT_IN_PROC_TYPE:
2839 if (check_arglist_length (args, 1, 1, fnname) < 0)
2840 return error_mark_node;
2841 return build_proc_type (TREE_VALUE (args));
2842 case BUILT_IN_QUEUE_LENGTH:
2843 if (check_arglist_length (args, 1, 1, fnname) < 0)
2844 return error_mark_node;
2845 return build_queue_length (TREE_VALUE (args));
2846 case BUILT_IN_READABLE:
2847 if (check_arglist_length (args, 1, 1, fnname) < 0)
2848 return error_mark_node;
2849 return build_chill_readable (TREE_VALUE (args));
2850 case BUILT_IN_READRECORD:
2851 if (check_arglist_length (args, 1, 3, fnname) < 0)
2852 return error_mark_node;
2853 return build_chill_readrecord (TREE_VALUE (args), TREE_CHAIN (args));
2854 case BUILT_IN_READTEXT:
2855 if (check_arglist_length (args, 2, -1, fnname) < 0)
2856 return error_mark_node;
2857 return build_chill_readtext (TREE_VALUE (args),
2858 TREE_CHAIN (args));
2859 case BUILT_IN_RETURN_MEMORY:
2860 if (check_arglist_length (args, 1, 1, fnname) < 0)
2861 return error_mark_node;
2862 return build_return_memory (TREE_VALUE (args));
2863 case BUILT_IN_SECS:
2864 if (check_arglist_length (args, 1, 1, fnname) < 0)
2865 return error_mark_node;
2866 return build_chill_duration (TREE_VALUE (args), SECS_MULTIPLIER,
2867 fnname, SECS_MAX);
2868 case BUILT_IN_SEQUENCIBLE:
2869 if (check_arglist_length (args, 1, 1, fnname) < 0)
2870 return error_mark_node;
2871 return build_chill_sequencible (TREE_VALUE (args));
2872 case BUILT_IN_SETTEXTACCESS:
2873 if (check_arglist_length (args, 2, 2, fnname) < 0)
2874 return error_mark_node;
2875 return build_chill_settextaccess (TREE_VALUE (args),
2876 TREE_VALUE (TREE_CHAIN (args)));
2877 case BUILT_IN_SETTEXTINDEX:
2878 if (check_arglist_length (args, 2, 2, fnname) < 0)
2879 return error_mark_node;
2880 return build_chill_settextindex (TREE_VALUE (args),
2881 TREE_VALUE (TREE_CHAIN (args)));
2882 case BUILT_IN_SETTEXTRECORD:
2883 if (check_arglist_length (args, 2, 2, fnname) < 0)
2884 return error_mark_node;
2885 return build_chill_settextrecord (TREE_VALUE (args),
2886 TREE_VALUE (TREE_CHAIN (args)));
2887 case BUILT_IN_CH_SIN:
2888 if (check_arglist_length (args, 1, 1, fnname) < 0)
2889 return error_mark_node;
2890 return build_chill_floatcall (TREE_VALUE (args),
2891 IDENTIFIER_POINTER (fnname),
2892 "__sin");
2893 case BUILT_IN_SIZE:
2894 if (check_arglist_length (args, 1, 1, fnname) < 0)
2895 return error_mark_node;
2896 return build_chill_sizeof (TREE_VALUE (args));
2897 case BUILT_IN_SQRT:
2898 if (check_arglist_length (args, 1, 1, fnname) < 0)
2899 return error_mark_node;
2900 return build_chill_floatcall (TREE_VALUE (args),
2901 IDENTIFIER_POINTER (fnname),
2902 "__sqrt");
2903 case BUILT_IN_SUCC:
2904 if (check_arglist_length (args, 1, 1, fnname) < 0)
2905 return error_mark_node;
2906 return build_chill_pred_or_succ (TREE_VALUE (args), PLUS_EXPR);
2907 case BUILT_IN_TAN:
2908 if (check_arglist_length (args, 1, 1, fnname) < 0)
2909 return error_mark_node;
2910 return build_chill_floatcall (TREE_VALUE (args),
2911 IDENTIFIER_POINTER (fnname),
2912 "__tan");
2913 case BUILT_IN_TERMINATE:
2914 if (check_arglist_length (args, 1, 1, fnname) < 0)
2915 return error_mark_node;
2916 return build_chill_terminate (TREE_VALUE (args));
2917 case BUILT_IN_UPPER:
2918 if (check_arglist_length (args, 1, 1, fnname) < 0)
2919 return error_mark_node;
2920 return build_chill_upper (TREE_VALUE (args));
2921 case BUILT_IN_VARIABLE:
2922 if (check_arglist_length (args, 1, 1, fnname) < 0)
2923 return error_mark_node;
2924 return build_chill_variable (TREE_VALUE (args));
2925 case BUILT_IN_WRITEABLE:
2926 if (check_arglist_length (args, 1, 1, fnname) < 0)
2927 return error_mark_node;
2928 return build_chill_writeable (TREE_VALUE (args));
2929 case BUILT_IN_WRITERECORD:
2930 if (check_arglist_length (args, 2, 3, fnname) < 0)
2931 return error_mark_node;
2932 return build_chill_writerecord (TREE_VALUE (args), TREE_CHAIN (args));
2933 case BUILT_IN_WRITETEXT:
2934 if (check_arglist_length (args, 2, -1, fnname) < 0)
2935 return error_mark_node;
2936 return build_chill_writetext (TREE_VALUE (args),
2937 TREE_CHAIN (args));
2938
2939 case BUILT_IN_EXPIRED:
2940 case BUILT_IN_WAIT:
2941 sorry ("unimplemented builtin function `%s'",
2942 IDENTIFIER_POINTER (fnname));
2943 break;
2944 default:
2945 error ("internal error - bad builtin function `%s'",
2946 IDENTIFIER_POINTER (fnname));
2947 }
2948 }
2949 return build_chill_function_call (func, args);
2950 }
2951
2952 if (chill_varying_type_p (TREE_TYPE (func)))
2953 type = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (type)));
2954
2955 if (CH_STRING_TYPE_P (type))
2956 {
2957 if (args == NULL_TREE)
2958 {
2959 error ("empty expression in string index");
2960 return error_mark_node;
2961 }
2962 if (TREE_CHAIN (args) != NULL)
2963 {
2964 error ("only one expression allowed in string index");
2965 return error_mark_node;
2966 }
2967 if (flag_old_strings)
2968 return build_chill_slice_with_length (func,
2969 TREE_VALUE (args),
2970 integer_one_node);
2971 else if (CH_BOOLS_TYPE_P (type))
2972 return build_chill_bitref (func, args);
2973 else
2974 return build_chill_array_ref (func, args);
2975 }
2976
2977 else if (TREE_CODE (type) == ARRAY_TYPE)
2978 return build_chill_array_ref (func, args);
2979
2980 if (TREE_CODE (func) != ERROR_MARK)
2981 error ("invalid: primval ( untyped_exprlist )");
2982 return error_mark_node;
2983 }
2984 \f
2985 /* Given a set stored as one bit per char (in BUFFER[0 .. BIT_SIZE-1]),
2986 return a CONTRUCTOR, of type TYPE (a SET_TYPE). */
2987 tree
2988 expand_packed_set (buffer, bit_size, type)
2989 char *buffer;
2990 int bit_size;
2991 tree type;
2992 {
2993 /* The ordinal number corresponding to the first stored bit. */
2994 HOST_WIDE_INT first_bit_no =
2995 TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type)));
2996 tree list = NULL_TREE;
2997 int i;
2998
2999 for (i = 0; i < bit_size; i++)
3000 if (buffer[i])
3001 {
3002 int next_0;
3003 for (next_0 = i + 1;
3004 next_0 < bit_size && buffer[next_0]; next_0++)
3005 ;
3006 if (next_0 == i + 1)
3007 list = tree_cons (NULL_TREE,
3008 build_int_2 (i + first_bit_no, 0), list);
3009 else
3010 {
3011 list = tree_cons (build_int_2 (i + first_bit_no, 0),
3012 build_int_2 (next_0 - 1 + first_bit_no, 0), list);
3013 /* advance i past the range of 1-bits */
3014 i = next_0;
3015 }
3016 }
3017 list = build (CONSTRUCTOR, type, NULL_TREE, nreverse (list));
3018 TREE_CONSTANT (list) = 1;
3019 return list;
3020 }
3021 \f
3022 /*
3023 * fold a set represented as a CONSTRUCTOR list.
3024 * An empty set has a NULL_TREE in its TREE_OPERAND (set, 1) slot.
3025 */
3026 static tree
3027 fold_set_expr (code, op0, op1)
3028 enum chill_tree_code code;
3029 tree op0, op1;
3030 {
3031 tree temp;
3032 char *buffer0, *buffer1, *bufferr;
3033 int i, size0, size1, first_unused_bit;
3034
3035 if (! TREE_CONSTANT (op0) || TREE_CODE (op0) != CONSTRUCTOR)
3036 return NULL_TREE;
3037
3038 if (op1
3039 && (! TREE_CONSTANT (op1) || TREE_CODE (op1) != CONSTRUCTOR))
3040 return NULL_TREE;
3041
3042 size0 = int_size_in_bytes (TREE_TYPE (op0)) * BITS_PER_UNIT;
3043 if (size0 < 0)
3044 {
3045 error ("operand is variable-size bitstring/power-set");
3046 return error_mark_node;
3047 }
3048 buffer0 = (char*) alloca (size0);
3049
3050 temp = get_set_constructor_bits (op0, buffer0, size0);
3051 if (temp)
3052 return NULL_TREE;
3053
3054 if (op0 && op1)
3055 {
3056 size1 = int_size_in_bytes (TREE_TYPE (op1)) * BITS_PER_UNIT;
3057 if (size1 < 0)
3058 {
3059 error ("operand is variable-size bitstring/power-set");
3060 return error_mark_node;
3061 }
3062 if (size0 != size1)
3063 return NULL_TREE;
3064 buffer1 = (char*) alloca (size1);
3065 temp = get_set_constructor_bits (op1, buffer1, size1);
3066 if (temp)
3067 return NULL_TREE;
3068 }
3069
3070 bufferr = (char*) alloca (size0); /* result buffer */
3071
3072 switch ((int)code)
3073 {
3074 case SET_NOT_EXPR:
3075 case BIT_NOT_EXPR:
3076 for (i = 0; i < size0; i++)
3077 bufferr[i] = 1 & ~buffer0[i];
3078 goto build_result;
3079 case SET_AND_EXPR:
3080 case BIT_AND_EXPR:
3081 for (i = 0; i < size0; i++)
3082 bufferr[i] = buffer0[i] & buffer1[i];
3083 goto build_result;
3084 case SET_IOR_EXPR:
3085 case BIT_IOR_EXPR:
3086 for (i = 0; i < size0; i++)
3087 bufferr[i] = buffer0[i] | buffer1[i];
3088 goto build_result;
3089 case SET_XOR_EXPR:
3090 case BIT_XOR_EXPR:
3091 for (i = 0; i < size0; i++)
3092 bufferr[i] = (buffer0[i] ^ buffer1[i]) & 1;
3093 goto build_result;
3094 case SET_DIFF_EXPR:
3095 case MINUS_EXPR:
3096 for (i = 0; i < size0; i++)
3097 bufferr[i] = buffer0[i] & ~buffer1[i];
3098 goto build_result;
3099 build_result:
3100 /* mask out unused bits. Same as runtime library does. */
3101 first_unused_bit = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (op0))))
3102 - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (op0)))) + 1;
3103 for (i = first_unused_bit; i < size0 ; i++)
3104 bufferr[i] = 0;
3105 return expand_packed_set (bufferr, size0, TREE_TYPE (op0));
3106 case EQ_EXPR:
3107 for (i = 0; i < size0; i++)
3108 if (buffer0[i] != buffer1[i])
3109 return boolean_false_node;
3110 return boolean_true_node;
3111
3112 case NE_EXPR:
3113 for (i = 0; i < size0; i++)
3114 if (buffer0[i] != buffer1[i])
3115 return boolean_true_node;
3116 return boolean_false_node;
3117
3118 default:
3119 return NULL_TREE;
3120 }
3121 }
3122 \f
3123 /*
3124 * build a set or bit-array expression. Type-checking is
3125 * done elsewhere.
3126 */
3127 static tree
3128 build_compare_set_expr (code, op0, op1)
3129 enum tree_code code;
3130 tree op0, op1;
3131 {
3132 tree result_type = NULL_TREE;
3133 char *fnname;
3134 tree x;
3135
3136 /* These conversions are needed if -fold-strings. */
3137 if (TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE)
3138 {
3139 if (CH_BOOLS_ONE_P (TREE_TYPE (op1)))
3140 return build_compare_discrete_expr (code,
3141 op0,
3142 convert (boolean_type_node, op1));
3143 else
3144 op0 = convert (bitstring_one_type_node, op0);
3145 }
3146 if (TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
3147 {
3148 if (CH_BOOLS_ONE_P (TREE_TYPE (op0)))
3149 return build_compare_discrete_expr (code,
3150 convert (boolean_type_node, op0),
3151 op1);
3152 else
3153 op1 = convert (bitstring_one_type_node, op1);
3154 }
3155
3156 switch ((int)code)
3157 {
3158 case EQ_EXPR:
3159 {
3160 tree temp = fold_set_expr (EQ_EXPR, op0, op1);
3161 if (temp)
3162 return temp;
3163 fnname = "__eqpowerset";
3164 goto compare_powerset;
3165 }
3166 break;
3167
3168 case GE_EXPR:
3169 /* switch operands and fall thru */
3170 x = op0;
3171 op0 = op1;
3172 op1 = x;
3173
3174 case LE_EXPR:
3175 fnname = "__lepowerset";
3176 goto compare_powerset;
3177
3178 case GT_EXPR:
3179 /* switch operands and fall thru */
3180 x = op0;
3181 op0 = op1;
3182 op1 = x;
3183
3184 case LT_EXPR:
3185 fnname = "__ltpowerset";
3186 goto compare_powerset;
3187
3188 case NE_EXPR:
3189 return invert_truthvalue (build_compare_set_expr (EQ_EXPR, op0, op1));
3190
3191 compare_powerset:
3192 {
3193 tree tsize = powersetlen (op0);
3194
3195 if (TREE_CODE (TREE_TYPE (op0)) != SET_TYPE)
3196 tsize = fold (build (MULT_EXPR, sizetype, tsize,
3197 size_int (BITS_PER_UNIT)));
3198
3199 return build_chill_function_call (lookup_name (get_identifier (fnname)),
3200 tree_cons (NULL_TREE, force_addr_of (op0),
3201 tree_cons (NULL_TREE, force_addr_of (op1),
3202 tree_cons (NULL_TREE, tsize, NULL_TREE))));
3203 }
3204 break;
3205
3206 default:
3207 if ((int) code >= (int)LAST_AND_UNUSED_TREE_CODE)
3208 {
3209 error ("tree code `%s' unhandled in build_compare_set_expr",
3210 tree_code_name[(int)code]);
3211 return error_mark_node;
3212 }
3213 break;
3214 }
3215
3216 return build ((enum tree_code)code, result_type,
3217 op0, op1);
3218 }
3219 \f
3220 /* Convert a varying string (or array) to dynamic non-varying string:
3221 EXP becomes EXP.var_data(0 UP EXP.var_length). */
3222
3223 tree
3224 varying_to_slice (exp)
3225 tree exp;
3226 {
3227 if (!chill_varying_type_p (TREE_TYPE (exp)))
3228 return exp;
3229 else
3230 { tree size, data, data_domain, min;
3231 tree novelty = CH_NOVELTY (TREE_TYPE (exp));
3232 exp = save_if_needed (exp);
3233 size = build_component_ref (exp, var_length_id);
3234 data = build_component_ref (exp, var_data_id);
3235 TREE_TYPE (data) = copy_novelty (novelty, TREE_TYPE (data));
3236 data_domain = TYPE_DOMAIN (TREE_TYPE (data));
3237 if (data_domain != NULL_TREE
3238 && TYPE_MIN_VALUE (data_domain) != NULL_TREE)
3239 min = TYPE_MIN_VALUE (data_domain);
3240 else
3241 min = integer_zero_node;
3242 return build_chill_slice (data, min, size);
3243 }
3244 }
3245
3246 /* Convert a scalar argument to a string or array type. This is a subroutine
3247 of `build_concat_expr'. */
3248
3249 static tree
3250 scalar_to_string (exp)
3251 tree exp;
3252 {
3253 tree type = TREE_TYPE (exp);
3254
3255 if (SCALAR_P (type))
3256 {
3257 int was_const = TREE_CONSTANT (exp);
3258 if (TREE_TYPE (exp) == char_type_node)
3259 exp = convert (string_one_type_node, exp);
3260 else if (TREE_TYPE (exp) == boolean_type_node)
3261 exp = convert (bitstring_one_type_node, exp);
3262 else
3263 exp = convert (build_array_type_for_scalar (type), exp);
3264 TREE_CONSTANT (exp) = was_const;
3265 return exp;
3266 }
3267 return varying_to_slice (exp);
3268 }
3269
3270 /* FIXME: Generalize this to general arrays (not just strings),
3271 at least for the compiler-generated case of padding fixed-length arrays. */
3272
3273 static tree
3274 build_concat_expr (op0, op1)
3275 tree op0, op1;
3276 {
3277 tree orig_op0 = op0, orig_op1 = op1;
3278 tree type0, type1, size0, size1, res;
3279
3280 op0 = scalar_to_string (op0);
3281 type0 = TREE_TYPE (op0);
3282 op1 = scalar_to_string (op1);
3283 type1 = TREE_TYPE (op1);
3284 size1 = size_in_bytes (type1);
3285
3286 /* try to fold constant string literals */
3287 if (TREE_CODE (op0) == STRING_CST
3288 && (TREE_CODE (op1) == STRING_CST
3289 || TREE_CODE (op1) == UNDEFINED_EXPR)
3290 && TREE_CODE (size1) == INTEGER_CST)
3291 {
3292 int len0 = TREE_STRING_LENGTH (op0);
3293 int len1 = TREE_INT_CST_LOW (size1);
3294 char *result = xmalloc (len0 + len1 + 1);
3295 memcpy (result, TREE_STRING_POINTER (op0), len0);
3296 if (TREE_CODE (op1) == UNDEFINED_EXPR)
3297 memset (&result[len0], '\0', len1);
3298 else
3299 memcpy (&result[len0], TREE_STRING_POINTER (op1), len1);
3300 return build_chill_string (len0 + len1, result);
3301 }
3302 else if (TREE_CODE (type0) == TREE_CODE (type1))
3303 {
3304 tree result_size;
3305 struct ch_class result_class;
3306 struct ch_class class0;
3307 struct ch_class class1;
3308
3309 class0 = chill_expr_class (orig_op0);
3310 class1 = chill_expr_class (orig_op1);
3311
3312 if (TREE_CODE (type0) == SET_TYPE)
3313 {
3314 result_size = size_binop (PLUS_EXPR,
3315 discrete_count (TYPE_DOMAIN (type0)),
3316 discrete_count (TYPE_DOMAIN (type1)));
3317 result_class.mode = build_bitstring_type (result_size);
3318 }
3319 else
3320 {
3321 tree max0 = TYPE_MAX_VALUE (type0);
3322 tree max1 = TYPE_MAX_VALUE (type1);
3323
3324 /* new array's dynamic size (in bytes). */
3325 size0 = size_in_bytes (type0);
3326 /* size1 was computed above. */
3327
3328 result_size = size_binop (PLUS_EXPR, size0, size1);
3329 /* new array's type. */
3330 result_class.mode = build_string_type (char_type_node, result_size);
3331
3332 if (max0 || max1)
3333 {
3334 max0 = max0 == 0 ? size0 : convert (sizetype, max0);
3335 max1 = max1 == 0 ? size1 : convert (sizetype, max1);
3336 TYPE_MAX_VALUE (result_class.mode)
3337 = size_binop (PLUS_EXPR, max0, max1);
3338 }
3339 }
3340
3341 if (class0.kind == CH_VALUE_CLASS || class1.kind == CH_VALUE_CLASS)
3342 {
3343 tree novelty0 = CH_NOVELTY (TREE_TYPE (orig_op0));
3344 result_class.kind = CH_VALUE_CLASS;
3345 if (class0.kind == CH_VALUE_CLASS && novelty0 != NULL_TREE)
3346 SET_CH_NOVELTY_NONNIL (result_class.mode, novelty0);
3347 else if (class1.kind == CH_VALUE_CLASS)
3348 SET_CH_NOVELTY (result_class.mode,
3349 CH_NOVELTY (TREE_TYPE (orig_op1)));
3350 }
3351 else
3352 result_class.kind = CH_DERIVED_CLASS;
3353
3354 if (TREE_CODE (result_class.mode) == SET_TYPE
3355 && TREE_CONSTANT (op0) && TREE_CONSTANT (op1)
3356 && TREE_CODE (op0) == CONSTRUCTOR && TREE_CODE (op1) == CONSTRUCTOR)
3357 {
3358 HOST_WIDE_INT size0, size1; char *buffer;
3359 size0 = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type0))) + 1;
3360 size1 = TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type1))) + 1;
3361 buffer = (char*) alloca (size0 + size1);
3362 if (size0 < 0 || size1 < 0
3363 || get_set_constructor_bits (op0, buffer, size0)
3364 || get_set_constructor_bits (op1, buffer + size0, size1))
3365 abort ();
3366 res = expand_packed_set (buffer, size0 + size1, result_class.mode);
3367 }
3368 else
3369 res = build (CONCAT_EXPR, result_class.mode, op0, op1);
3370 return convert_to_class (result_class, res);
3371 }
3372 else
3373 {
3374 error ("incompatible modes in concat expression");
3375 return error_mark_node;
3376 }
3377 }
3378
3379 /*
3380 * handle varying and fixed array compare operations
3381 */
3382 static tree
3383 build_compare_string_expr (code, op0, op1)
3384 enum tree_code code;
3385 tree op0, op1;
3386 {
3387 if (op0 == NULL_TREE || TREE_CODE (op0) == ERROR_MARK)
3388 return error_mark_node;
3389 if (op1 == NULL_TREE || TREE_CODE (op1) == ERROR_MARK)
3390 return error_mark_node;
3391
3392 if (tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (op0)),
3393 TYPE_SIZE (TREE_TYPE (op1)))
3394 && ! chill_varying_type_p (TREE_TYPE (op0))
3395 && ! chill_varying_type_p (TREE_TYPE (op1)))
3396 {
3397 tree size = size_in_bytes (TREE_TYPE (op0));
3398 tree temp = lookup_name (get_identifier ("memcmp"));
3399 temp = build_chill_function_call (temp,
3400 tree_cons (NULL_TREE, force_addr_of (op0),
3401 tree_cons (NULL_TREE, force_addr_of (op1),
3402 tree_cons (NULL_TREE, size, NULL_TREE))));
3403 return build_compare_discrete_expr (code, temp, integer_zero_node);
3404 }
3405
3406 switch ((int)code)
3407 {
3408 case EQ_EXPR:
3409 code = STRING_EQ_EXPR;
3410 break;
3411 case GE_EXPR:
3412 return invert_truthvalue (build_compare_string_expr (LT_EXPR, op0, op1));
3413 case LE_EXPR:
3414 return invert_truthvalue (build_compare_string_expr (LT_EXPR, op1, op0));
3415 case GT_EXPR:
3416 return build_compare_string_expr (LT_EXPR, op1, op0);
3417 case LT_EXPR:
3418 code = STRING_LT_EXPR;
3419 break;
3420 case NE_EXPR:
3421 return invert_truthvalue (build_compare_string_expr (EQ_EXPR, op0, op1));
3422 default:
3423 error ("Invalid operation on array of chars");
3424 return error_mark_node;
3425 }
3426
3427 return build (code, boolean_type_node, op0, op1);
3428 }
3429
3430 tree
3431 compare_records (exp0, exp1)
3432 tree exp0, exp1;
3433 {
3434 tree type = TREE_TYPE (exp0);
3435 tree field;
3436 int have_variants = 0;
3437
3438 tree result = boolean_true_node;
3439 extern int maximum_field_alignment;
3440
3441 if (TREE_CODE (type) != RECORD_TYPE)
3442 abort ();
3443
3444 exp0 = save_if_needed (exp0);
3445 exp1 = save_if_needed (exp1);
3446
3447 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
3448 {
3449 if (DECL_NAME (field) == NULL_TREE)
3450 {
3451 have_variants = 1;
3452 break;
3453 }
3454 }
3455
3456 /* in case of -fpack we always do a memcmp */
3457 if (maximum_field_alignment != 0)
3458 {
3459 tree memcmp_func = lookup_name (get_identifier ("memcmp"));
3460 tree arg1 = force_addr_of (exp0);
3461 tree arg2 = force_addr_of (exp1);
3462 tree arg3 = size_in_bytes (type);
3463 tree fcall = build_chill_function_call (memcmp_func,
3464 tree_cons (NULL_TREE, arg1,
3465 tree_cons (NULL_TREE, arg2,
3466 tree_cons (NULL_TREE, arg3, NULL_TREE))));
3467
3468 if (have_variants)
3469 warning ("comparison of variant structures is unsafe");
3470 result = build_chill_binary_op (EQ_EXPR, fcall, integer_zero_node);
3471 return result;
3472 }
3473
3474 if (have_variants)
3475 {
3476 sorry ("compare with variant records");
3477 return error_mark_node;
3478 }
3479
3480 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
3481 {
3482 tree exp0fld = build_component_ref (exp0, DECL_NAME (field));
3483 tree exp1fld = build_component_ref (exp1, DECL_NAME (field));
3484 tree eq_flds = build_chill_binary_op (EQ_EXPR, exp0fld, exp1fld);
3485 result = build_chill_binary_op (TRUTH_AND_EXPR, result, eq_flds);
3486 }
3487 return result;
3488 }
3489 \f
3490 int
3491 compare_int_csts (op, val1, val2)
3492 enum tree_code op;
3493 tree val1, val2;
3494 {
3495 int result;
3496 tree tmp;
3497 tree type1 = TREE_TYPE (val1);
3498 tree type2 = TREE_TYPE (val2);
3499 switch (op)
3500 {
3501 case GT_EXPR:
3502 case GE_EXPR:
3503 tmp = val1; val1 = val2; val2 = tmp;
3504 tmp = type1; type1 = type2; type2 = tmp;
3505 op = (op == GT_EXPR) ? LT_EXPR : LE_EXPR;
3506 /* ... fall through ... */
3507 case LT_EXPR:
3508 case LE_EXPR:
3509 if (!TREE_UNSIGNED (type1))
3510 {
3511 if (!TREE_UNSIGNED (type2))
3512 result = INT_CST_LT (val1, val2);
3513 else if (TREE_INT_CST_HIGH (val1) < 0)
3514 result = 1;
3515 else
3516 result = INT_CST_LT_UNSIGNED (val1, val2);
3517 }
3518 else
3519 {
3520 if (!TREE_UNSIGNED (type2) && TREE_INT_CST_HIGH (val2) < 0)
3521 result = 0;
3522 else
3523 result = INT_CST_LT_UNSIGNED (val1, val2);
3524 }
3525 if (op == LT_EXPR || result == 1)
3526 break;
3527 /* else fall through ... */
3528 case NE_EXPR:
3529 case EQ_EXPR:
3530 if (TREE_INT_CST_LOW (val1) == TREE_INT_CST_LOW (val2)
3531 && TREE_INT_CST_HIGH (val1) == TREE_INT_CST_HIGH (val2)
3532 /* They're bitwise equal.
3533 Check for one being negative and the other unsigned. */
3534 && (TREE_INT_CST_HIGH (val2) >= 0
3535 || TREE_UNSIGNED (TREE_TYPE (val1))
3536 == TREE_UNSIGNED (TREE_TYPE (val2))))
3537 result = 1;
3538 else
3539 result = 0;
3540 if (op == NE_EXPR)
3541 result = !result;
3542 break;
3543 default:
3544 abort();
3545 }
3546 return result;
3547 }
3548
3549 /* Build an expression to compare discrete values VAL1 and VAL2.
3550 This does not check that they are discrete, nor that they are
3551 compatible; if you need such checks use build_compare_expr. */
3552
3553 tree
3554 build_compare_discrete_expr (op, val1, val2)
3555 enum tree_code op;
3556 tree val1, val2;
3557 {
3558 tree type1 = TREE_TYPE (val1);
3559 tree type2 = TREE_TYPE (val2);
3560 tree tmp;
3561
3562 if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
3563 {
3564 if (compare_int_csts (op, val1, val2))
3565 return boolean_true_node;
3566 else
3567 return boolean_false_node;
3568 }
3569
3570 if (TREE_UNSIGNED (type1) != TREE_UNSIGNED (type2))
3571 {
3572 switch (op)
3573 {
3574 case GT_EXPR:
3575 case GE_EXPR:
3576 tmp = val1; val1 = val2; val2 = tmp;
3577 tmp = type1; type1 = type2; type2 = tmp;
3578 op = (op == GT_EXPR) ? LT_EXPR : LE_EXPR;
3579 /* ... fall through ... */
3580 case LT_EXPR:
3581 case LE_EXPR:
3582 if (TREE_UNSIGNED (type2))
3583 {
3584 tmp = build_int_2_wide (0, 0);
3585 TREE_TYPE (tmp) = type1;
3586 val1 = save_expr (val1);
3587 tmp = fold (build (LT_EXPR, boolean_type_node, val1, tmp));
3588 if (TYPE_PRECISION (type2) < TYPE_PRECISION (type1))
3589 {
3590 type2 = unsigned_type (type1);
3591 val2 = convert_to_integer (type2, val2);
3592 }
3593 val1 = convert_to_integer (type2, val1);
3594 return fold (build (TRUTH_OR_EXPR, boolean_type_node,
3595 tmp,
3596 fold (build (op, boolean_type_node,
3597 val1, val2))));
3598 }
3599 unsigned_vs_signed: /* val1 is unsigned, val2 is signed */
3600 tmp = build_int_2_wide (0, 0);
3601 TREE_TYPE (tmp) = type2;
3602 val2 = save_expr (val2);
3603 tmp = fold (build (GE_EXPR, boolean_type_node, val2, tmp));
3604 if (TYPE_PRECISION (type1) < TYPE_PRECISION (type2))
3605 {
3606 type1 = unsigned_type (type2);
3607 val1 = convert_to_integer (type1, val1);
3608 }
3609 val2 = convert_to_integer (type1, val2);
3610 return fold (build (TRUTH_AND_EXPR, boolean_type_node, tmp,
3611 fold (build (op, boolean_type_node,
3612 val1, val2))));
3613 case EQ_EXPR:
3614 if (TREE_UNSIGNED (val2))
3615 {
3616 tmp = val1; val1 = val2; val2 = tmp;
3617 tmp = type1; type1 = type2; type2 = tmp;
3618 }
3619 goto unsigned_vs_signed;
3620 case NE_EXPR:
3621 tmp = build_compare_expr (EQ_EXPR, val1, val2);
3622 return build_chill_unary_op (TRUTH_NOT_EXPR, tmp);
3623 default:
3624 abort();
3625 }
3626 }
3627 if (TYPE_PRECISION (type1) > TYPE_PRECISION (type2))
3628 val2 = convert (type1, val2);
3629 else if (TYPE_PRECISION (type1) < TYPE_PRECISION (type2))
3630 val1 = convert (type2, val1);
3631 return fold (build (op, boolean_type_node, val1, val2));
3632 }
3633
3634 tree
3635 build_compare_expr (op, val1, val2)
3636 enum tree_code op;
3637 tree val1, val2;
3638 {
3639 tree tmp;
3640 tree type1, type2;
3641 val1 = check_have_mode (val1, "relational expression");
3642 val2 = check_have_mode (val2, "relational expression");
3643 if (val1 == NULL_TREE || TREE_CODE (val1) == ERROR_MARK)
3644 return error_mark_node;
3645 if (val2 == NULL_TREE || TREE_CODE (val2) == ERROR_MARK)
3646 return error_mark_node;
3647
3648 if (pass == 1)
3649 return build (op, NULL_TREE, val1, val2);
3650
3651 if (!CH_COMPATIBLE_CLASSES (val1, val2))
3652 {
3653 error ("incompatible operands to %s", boolean_code_name [op]);
3654 return error_mark_node;
3655 }
3656
3657 tmp = CH_ROOT_MODE (TREE_TYPE (val1));
3658 if (tmp != TREE_TYPE (val1))
3659 val1 = convert (tmp, val1);
3660 tmp = CH_ROOT_MODE (TREE_TYPE (val2));
3661 if (tmp != TREE_TYPE (val2))
3662 val2 = convert (tmp, val2);
3663
3664 type1 = TREE_TYPE (val1);
3665 type2 = TREE_TYPE (val2);
3666
3667 if (TREE_CODE (type1) == SET_TYPE)
3668 tmp = build_compare_set_expr (op, val1, val2);
3669
3670 else if (discrete_type_p (type1))
3671 tmp = build_compare_discrete_expr (op, val1, val2);
3672
3673 else if (chill_varying_type_p (type1) || chill_varying_type_p (type2)
3674 || (TREE_CODE (type1) == ARRAY_TYPE
3675 && TREE_CODE (TREE_TYPE (type1)) == CHAR_TYPE)
3676 || (TREE_CODE (type2) == ARRAY_TYPE
3677 && TREE_CODE (TREE_TYPE (type2)) == CHAR_TYPE) )
3678 tmp = build_compare_string_expr (op, val1, val2);
3679
3680 else if ((TREE_CODE (type1) == RECORD_TYPE
3681 || TREE_CODE (type2) == RECORD_TYPE)
3682 && (op == EQ_EXPR || op == NE_EXPR))
3683 {
3684 /* This is for handling INSTANCEs being compared against NULL. */
3685 if (val1 == null_pointer_node)
3686 val1 = convert (type2, val1);
3687 if (val2 == null_pointer_node)
3688 val2 = convert (type1, val2);
3689
3690 tmp = compare_records (val1, val2);
3691 if (op == NE_EXPR)
3692 tmp = build_chill_unary_op (TRUTH_NOT_EXPR, tmp);
3693 }
3694
3695 else if (TREE_CODE (type1) == REAL_TYPE || TREE_CODE (type2) == REAL_TYPE
3696 || (op == EQ_EXPR || op == NE_EXPR))
3697 {
3698 tmp = build (op, boolean_type_node, val1, val2);
3699 CH_DERIVED_FLAG (tmp) = 1; /* Optimization to avoid copy_node. */
3700 tmp = fold (tmp);
3701 }
3702
3703 else
3704 {
3705 error ("relational operator not allowed for this mode");
3706 return error_mark_node;
3707 }
3708
3709 if (!CH_DERIVED_FLAG (tmp))
3710 {
3711 tmp = copy_node (tmp);
3712 CH_DERIVED_FLAG (tmp) = 1;
3713 }
3714 return tmp;
3715 }
3716 \f
3717 tree
3718 finish_chill_binary_op (node)
3719 tree node;
3720 {
3721 tree op0 = check_have_mode (TREE_OPERAND (node, 0), "binary expression");
3722 tree op1 = check_have_mode (TREE_OPERAND (node, 1), "binary expression");
3723 tree type0 = TREE_TYPE (op0);
3724 tree type1 = TREE_TYPE (op1);
3725 tree folded;
3726
3727 if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
3728 return error_mark_node;
3729
3730 if (UNSATISFIED (op0) || UNSATISFIED (op1))
3731 {
3732 UNSATISFIED_FLAG (node) = 1;
3733 return node;
3734 }
3735 #if 0
3736 /* assure that both operands have a type */
3737 if (! type0 && type1)
3738 {
3739 op0 = convert (type1, op0);
3740 type0 = TREE_TYPE (op0);
3741 }
3742 if (! type1 && type0)
3743 {
3744 op1 = convert (type0, op1);
3745 type1 = TREE_TYPE (op1);
3746 }
3747 #endif
3748 UNSATISFIED_FLAG (node) = 0;
3749 #if 0
3750
3751 { int op0f = TREE_CODE (op0) == FUNCTION_DECL;
3752 int op1f = TREE_CODE (op1) == FUNCTION_DECL;
3753 if (op0f)
3754 op0 = convert (build_pointer_type (TREE_TYPE (op0)), op0);
3755 if (op1f)
3756 op1 = convert (build_pointer_type (TREE_TYPE (op1)), op1);
3757 if ((op0f || op1f)
3758 && code != EQ_EXPR && code != NE_EXPR)
3759 error ("Cannot use %s operator on PROC mode variable",
3760 tree_code_name[(int)code]);
3761 }
3762
3763 if (invalid_left_operand (type0, code))
3764 {
3765 error ("invalid left operand of %s", tree_code_name[(int)code]);
3766 return error_mark_node;
3767 }
3768 if (invalid_right_operand (code, type1))
3769 {
3770 error ("invalid right operand of %s", tree_code_name[(int)code]);
3771 return error_mark_node;
3772 }
3773 #endif
3774
3775 switch (TREE_CODE (node))
3776 {
3777 case CONCAT_EXPR:
3778 return build_concat_expr (op0, op1);
3779
3780 case REPLICATE_EXPR:
3781 op0 = fold (op0);
3782 if (!TREE_CONSTANT (op0) || !TREE_CONSTANT (op1))
3783 {
3784 error ("repetition expression must be constant");
3785 return error_mark_node;
3786 }
3787 else
3788 return build_chill_repetition_op (op0, op1);
3789
3790 case FLOOR_MOD_EXPR:
3791 case TRUNC_MOD_EXPR:
3792 if (TREE_CODE (type0) != INTEGER_TYPE)
3793 {
3794 error ("left argument to MOD/REM operator must be integral");
3795 return error_mark_node;
3796 }
3797 if (TREE_CODE (type1) != INTEGER_TYPE)
3798 {
3799 error ("right argument to MOD/REM operator must be integral");
3800 return error_mark_node;
3801 }
3802 break;
3803
3804 case MINUS_EXPR:
3805 if (TREE_CODE (type1) == SET_TYPE)
3806 {
3807 tree temp = fold_set_expr (MINUS_EXPR, op0, op1);
3808
3809 if (temp)
3810 return temp;
3811 if (TYPE_MODE (type1) == BLKmode)
3812 TREE_SET_CODE (node, SET_DIFF_EXPR);
3813 else
3814 {
3815 op1 = build_chill_unary_op (BIT_NOT_EXPR, op1);
3816 TREE_OPERAND (node, 1) = op1;
3817 TREE_SET_CODE (node, BIT_AND_EXPR);
3818 }
3819 }
3820 break;
3821
3822 case TRUNC_DIV_EXPR:
3823 if (TREE_CODE (type0) == REAL_TYPE || TREE_CODE (type1) == REAL_TYPE)
3824 TREE_SET_CODE (node, RDIV_EXPR);
3825 break;
3826
3827 case BIT_AND_EXPR:
3828 if (TYPE_MODE (type1) == BLKmode)
3829 TREE_SET_CODE (node, SET_AND_EXPR);
3830 goto fold_set_binop;
3831 case BIT_IOR_EXPR:
3832 if (TYPE_MODE (type1) == BLKmode)
3833 TREE_SET_CODE (node, SET_IOR_EXPR);
3834 goto fold_set_binop;
3835 case BIT_XOR_EXPR:
3836 if (TYPE_MODE (type1) == BLKmode)
3837 TREE_SET_CODE (node, SET_XOR_EXPR);
3838 goto fold_set_binop;
3839 case SET_AND_EXPR:
3840 case SET_IOR_EXPR:
3841 case SET_XOR_EXPR:
3842 case SET_DIFF_EXPR:
3843 fold_set_binop:
3844 if (TREE_CODE (type0) == SET_TYPE)
3845 {
3846 tree temp = fold_set_expr (TREE_CODE (node), op0, op1);
3847
3848 if (temp)
3849 return temp;
3850 }
3851 break;
3852
3853 case SET_IN_EXPR:
3854 if (TREE_CODE (type1) != SET_TYPE || CH_BOOLS_TYPE_P (type1))
3855 {
3856 error ("right operand of IN is not a powerset");
3857 return error_mark_node;
3858 }
3859 if (!CH_COMPATIBLE (op0, TYPE_DOMAIN (type1)))
3860 {
3861 error ("left operand of IN incompatible with right operand");
3862 return error_mark_node;
3863 }
3864 type0 = CH_ROOT_MODE (type0);
3865 if (type0 != TREE_TYPE (op0))
3866 TREE_OPERAND (node, 0) = op0 = convert (type0, op0);
3867 TREE_TYPE (node) = boolean_type_node;
3868 CH_DERIVED_FLAG (node) = 1;
3869 node = fold (node);
3870 if (!CH_DERIVED_FLAG (node))
3871 {
3872 node = copy_node (node);
3873 CH_DERIVED_FLAG (node) = 1;
3874 }
3875 return node;
3876 case NE_EXPR:
3877 case EQ_EXPR:
3878 case GE_EXPR:
3879 case GT_EXPR:
3880 case LE_EXPR:
3881 case LT_EXPR:
3882 return build_compare_expr (TREE_CODE (node), op0, op1);
3883 default:
3884 ;
3885 }
3886
3887 if (!CH_COMPATIBLE_CLASSES (op0, op1))
3888 {
3889 error ("incompatible operands to %s", tree_code_name[(int) TREE_CODE (node)]);
3890 return error_mark_node;
3891 }
3892
3893 if (TREE_TYPE (node) == NULL_TREE)
3894 {
3895 struct ch_class class;
3896 class = CH_ROOT_RESULTING_CLASS (op0, op1);
3897 TREE_OPERAND (node, 0) = op0 = convert_to_class (class, op0);
3898 type0 = TREE_TYPE (op0);
3899 TREE_OPERAND (node, 1) = op1 = convert_to_class (class, op1);
3900 type1 = TREE_TYPE (op1);
3901 TREE_TYPE (node) = class.mode;
3902 folded = convert_to_class (class, fold (node));
3903 }
3904 else
3905 folded = fold (node);
3906 #if 0
3907 if (folded == node)
3908 TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
3909 #endif
3910 if (TREE_CODE (node) == TRUNC_DIV_EXPR)
3911 {
3912 if (TREE_CONSTANT (op1))
3913 {
3914 if (tree_int_cst_equal (op1, integer_zero_node))
3915 {
3916 error ("division by zero");
3917 return integer_zero_node;
3918 }
3919 }
3920 else if (range_checking)
3921 {
3922 #if 0
3923 tree test =
3924 build (EQ_EXPR, boolean_type_node, op1, integer_zero_node);
3925 /* Should this be overflow? */
3926 folded = check_expression (folded, test,
3927 ridpointers[(int) RID_RANGEFAIL]);
3928 #endif
3929 }
3930 }
3931 return folded;
3932 }
3933 \f
3934 /*
3935 * This implements the '->' operator, which, like the '&' in C,
3936 * returns a pointer to an object, which has the type of
3937 * pointer-to-that-object.
3938 *
3939 * FORCE is 0 when we're evaluating a user-level syntactic construct,
3940 * and 1 when we're calling from inside the compiler.
3941 */
3942 tree
3943 build_chill_arrow_expr (ref, force)
3944 tree ref;
3945 int force;
3946 {
3947 tree addr_type;
3948 tree result;
3949
3950 if (pass == 1)
3951 {
3952 error ("-> operator not allow in constant expression");
3953 return error_mark_node;
3954 }
3955
3956 if (ref == NULL_TREE || TREE_CODE (ref) == ERROR_MARK)
3957 return ref;
3958
3959 while (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
3960 ref = convert (TREE_TYPE (TREE_TYPE (ref)), ref);
3961
3962 if (!force && ! CH_LOCATION_P (ref))
3963 {
3964 if (TREE_CODE (ref) == STRING_CST)
3965 pedwarn ("taking the address of a string literal is non-standard");
3966 else if (TREE_CODE (TREE_TYPE (ref)) == FUNCTION_TYPE)
3967 pedwarn ("taking the address of a function is non-standard");
3968 else
3969 {
3970 error ("ADDR requires a LOCATION argument");
3971 return error_mark_node;
3972 }
3973 /* FIXME: Should we be sure that ref isn't a
3974 function if we're being pedantic? */
3975 }
3976
3977 addr_type = build_pointer_type (TREE_TYPE (ref));
3978
3979 #if 0
3980 /* This transformation makes chill_expr_class return CH_VALUE_CLASS
3981 when it should return CH_REFERENCE_CLASS. That could be fixed,
3982 but we probably don't want this transformation anyway. */
3983 if (TREE_CODE (ref) == NOP_EXPR) /* RETYPE_EXPR */
3984 {
3985 tree addr;
3986 while (TREE_CODE (ref) == NOP_EXPR) /* RETYPE_EXPR */
3987 ref = TREE_OPERAND (ref, 0);
3988 mark_addressable (ref);
3989 addr = build1 (ADDR_EXPR,
3990 build_pointer_type (TREE_TYPE (ref)), ref);
3991 return build1 (NOP_EXPR, /* RETYPE_EXPR */
3992 addr_type,
3993 addr);
3994 }
3995 else
3996 #endif
3997 {
3998 if (! mark_addressable (ref))
3999 {
4000 error ("-> expression is not addressable");
4001 return error_mark_node;
4002 }
4003 result = build1 (ADDR_EXPR, addr_type, ref);
4004 if (staticp (ref)
4005 && ! (TREE_CODE (ref) == FUNCTION_DECL
4006 && DECL_CONTEXT (ref) != 0))
4007 TREE_CONSTANT (result) = 1;
4008 return result;
4009 }
4010 }
4011 \f
4012 /*
4013 * This implements the ADDR builtin function, which returns a
4014 * free reference, analogous to the C 'void *'.
4015 */
4016 tree
4017 build_chill_addr_expr (ref, errormsg)
4018 tree ref;
4019 char *errormsg;
4020 {
4021 if (ref == error_mark_node)
4022 return ref;
4023
4024 if (! CH_LOCATION_P (ref)
4025 && TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE)
4026 {
4027 error ("ADDR parameter must be a LOCATION");
4028 return error_mark_node;
4029 }
4030 ref = build_chill_arrow_expr (ref, 1);
4031
4032 if (ref != NULL_TREE && TREE_CODE (ref) != ERROR_MARK)
4033 TREE_TYPE (ref) = ptr_type_node;
4034 else if (errormsg == NULL)
4035 {
4036 error ("possible internal error in build_chill_arrow_expr");
4037 return error_mark_node;
4038 }
4039 else
4040 {
4041 error ("%s is not addressable", errormsg);
4042 return error_mark_node;
4043 }
4044 return ref;
4045 }
4046 \f
4047 tree
4048 build_chill_binary_op (code, op0, op1)
4049 enum chill_tree_code code;
4050 tree op0, op1;
4051 {
4052 register tree result;
4053
4054 if (op0 == NULL_TREE || TREE_CODE (op0) == ERROR_MARK)
4055 return error_mark_node;
4056 if (op1 == NULL_TREE || TREE_CODE (op1) == ERROR_MARK)
4057 return error_mark_node;
4058
4059 result = build (code, NULL_TREE, op0, op1);
4060
4061 if (pass != 1)
4062 result = finish_chill_binary_op (result);
4063 return result;
4064 }
4065 \f
4066 /*
4067 * process a string repetition phrase '(' COUNT ')' STRING
4068 */
4069 tree
4070 string_char_rep (count, string)
4071 int count;
4072 tree string;
4073 {
4074 int slen, charindx, repcnt;
4075 char ch;
4076 char *temp;
4077 char *inp;
4078 char *outp;
4079 tree type;
4080
4081 if (string == NULL_TREE || TREE_CODE (string) == ERROR_MARK)
4082 return error_mark_node;
4083
4084 type = TREE_TYPE (string);
4085 slen = int_size_in_bytes (type);
4086 temp = xmalloc (slen * count);
4087 inp = &ch;
4088 outp = temp;
4089 if (TREE_CODE (string) == STRING_CST)
4090 inp = TREE_STRING_POINTER (string);
4091 else /* single character */
4092 ch = (char)TREE_INT_CST_LOW (string);
4093
4094 /* copy the string/char COUNT times into the output buffer */
4095 for (outp = temp, repcnt = 0; repcnt < count; repcnt++)
4096 for (charindx = 0; charindx < slen; charindx++)
4097 *outp++ = inp[charindx];
4098 return build_chill_string (slen * count, temp);
4099 }
4100 \f
4101 /* Build a bit-string constant containing with the given LENGTH
4102 containing all ones (if VALUE is true), or all zeros (if VALUE is false). */
4103
4104 tree
4105 build_boring_bitstring (length, value)
4106 long length;
4107 int value;
4108 {
4109 tree result;
4110 tree list; /* Value of CONSTRUCTOR_ELTS in the result. */
4111 if (value && length > 0)
4112 list = tree_cons (integer_zero_node, size_int (length - 1), NULL_TREE);
4113 else
4114 list = NULL_TREE;
4115
4116 result = build (CONSTRUCTOR,
4117 build_bitstring_type (size_int (length)),
4118 NULL_TREE,
4119 list);
4120 TREE_CONSTANT (result) = 1;
4121 CH_DERIVED_FLAG (result) = 1;
4122 return result;
4123 }
4124
4125 /*
4126 * handle a string repetition, with the syntax:
4127 * ( COUNT ) 'STRING'
4128 * COUNT is required to be constant, positive and folded.
4129 */
4130 tree
4131 build_chill_repetition_op (count_op, string)
4132 tree count_op;
4133 tree string;
4134 {
4135 int count;
4136 tree type = TREE_TYPE (string);
4137
4138 if (TREE_CODE (count_op) != INTEGER_CST)
4139 {
4140 error ("repetition count is not an integer constant");
4141 return error_mark_node;
4142 }
4143
4144 count = TREE_INT_CST_LOW (count_op);
4145
4146 if (count < 0)
4147 {
4148 error ("repetition count < 0");
4149 return error_mark_node;
4150 }
4151 if (! TREE_CONSTANT (string))
4152 {
4153 error ("repetition value not constant");
4154 return error_mark_node;
4155 }
4156
4157 if (TREE_CODE (string) == STRING_CST)
4158 return string_char_rep (count, string);
4159
4160 switch ((int)TREE_CODE (type))
4161 {
4162 case BOOLEAN_TYPE:
4163 if (TREE_CODE (string) == INTEGER_CST)
4164 return build_boring_bitstring (count, TREE_INT_CST_LOW (string));
4165 error ("bitstring repetition of non-constant boolean");
4166 return error_mark_node;
4167
4168 case CHAR_TYPE:
4169 return string_char_rep (count, string);
4170
4171 case SET_TYPE:
4172 { int i, tree_const = 1;
4173 tree new_list = NULL_TREE;
4174 tree vallist;
4175 tree result;
4176 tree domain = TYPE_DOMAIN (type);
4177 tree orig_length;
4178 HOST_WIDE_INT orig_len;
4179
4180 if (!CH_BOOLS_TYPE_P (type)) /* cannot replicate a powerset */
4181 break;
4182
4183 orig_length = discrete_count (domain);
4184
4185 if (TREE_CODE (string) != CONSTRUCTOR || !TREE_CONSTANT (string)
4186 || TREE_CODE (orig_length) != INTEGER_CST)
4187 {
4188 error ("string repetition operand is non-constant bitstring");
4189 return error_mark_node;
4190 }
4191
4192
4193 orig_len = TREE_INT_CST_LOW (orig_length);
4194
4195 /* if the set is empty, this is NULL */
4196 vallist = TREE_OPERAND (string, 1);
4197
4198 if (vallist == NULL_TREE) /* No bits are set. */
4199 return build_boring_bitstring (count * orig_len, 0);
4200 else if (TREE_CHAIN (vallist) == NULL_TREE
4201 && (TREE_PURPOSE (vallist) == NULL_TREE
4202 ? (orig_len == 1
4203 && tree_int_cst_equal (TYPE_MIN_VALUE (domain),
4204 TREE_VALUE (vallist)))
4205 : (tree_int_cst_equal (TYPE_MIN_VALUE (domain),
4206 TREE_PURPOSE (vallist))
4207 && tree_int_cst_equal (TYPE_MAX_VALUE (domain),
4208 TREE_VALUE (vallist)))))
4209 return build_boring_bitstring (count * orig_len, 1);
4210
4211 for (i = 0; i < count; i++)
4212 {
4213 tree origin = build_int_2 (i * orig_len, 0);
4214 tree temp;
4215
4216 /* scan down the given value list, building
4217 new bit-positions */
4218 for (temp = vallist; temp; temp = TREE_CHAIN (temp))
4219 {
4220 tree new_value
4221 = fold (size_binop (PLUS_EXPR, origin, TREE_VALUE (temp)));
4222 tree new_purpose = NULL_TREE;
4223 if (! TREE_CONSTANT (TREE_VALUE (temp)))
4224 tree_const = 0;
4225 if (TREE_PURPOSE (temp))
4226 {
4227 new_purpose = fold (size_binop (PLUS_EXPR,
4228 origin,
4229 TREE_PURPOSE (temp)));
4230 if (! TREE_CONSTANT (TREE_PURPOSE (temp)))
4231 tree_const = 0;
4232 }
4233
4234 new_list = tree_cons (new_purpose,
4235 new_value, new_list);
4236 }
4237 }
4238 result = build (CONSTRUCTOR,
4239 build_bitstring_type (size_int (count * orig_len)),
4240 NULL_TREE, nreverse (new_list));
4241 TREE_CONSTANT (result) = tree_const;
4242 CH_DERIVED_FLAG (result) = CH_DERIVED_FLAG (string);
4243 return result;
4244 }
4245
4246 default:
4247 error ("non-char, non-bit string repetition");
4248 return error_mark_node;
4249 }
4250 return error_mark_node;
4251 }
4252 \f
4253 tree
4254 finish_chill_unary_op (node)
4255 tree node;
4256 {
4257 enum chill_tree_code code = TREE_CODE (node);
4258 tree op0 = check_have_mode (TREE_OPERAND (node, 0), "unary expression");
4259 tree type0 = TREE_TYPE (op0);
4260 struct ch_class class;
4261
4262 if (TREE_CODE (op0) == ERROR_MARK)
4263 return error_mark_node;
4264 /* The expression codes of the data types of the arguments tell us
4265 whether the arguments are integers, floating, pointers, etc. */
4266
4267 if (TREE_CODE (type0) == REFERENCE_TYPE)
4268 {
4269 op0 = convert (TREE_TYPE (type0), op0);
4270 type0 = TREE_TYPE (op0);
4271 }
4272
4273 if (invalid_right_operand (code, type0))
4274 {
4275 error ("invalid operand of %s",
4276 tree_code_name[(int)code]);
4277 return error_mark_node;
4278 }
4279 switch ((int)TREE_CODE (type0))
4280 {
4281 case ARRAY_TYPE:
4282 if (TREE_CODE ( TREE_TYPE (type0)) == BOOLEAN_TYPE)
4283 code = SET_NOT_EXPR;
4284 else
4285 {
4286 error ("right operand of %s is not array of boolean",
4287 tree_code_name[(int)code]);
4288 return error_mark_node;
4289 }
4290 break;
4291 case BOOLEAN_TYPE:
4292 switch ((int)code)
4293 {
4294 case BIT_NOT_EXPR:
4295 case TRUTH_NOT_EXPR:
4296 return invert_truthvalue (truthvalue_conversion (op0));
4297
4298 default:
4299 error ("%s operator applied to boolean variable",
4300 tree_code_name[(int)code]);
4301 return error_mark_node;
4302 }
4303 break;
4304
4305 case SET_TYPE:
4306 switch ((int)code)
4307 {
4308 case BIT_NOT_EXPR:
4309 case NEGATE_EXPR:
4310 {
4311 tree temp = fold_set_expr (BIT_NOT_EXPR, op0, NULL_TREE);
4312
4313 if (temp)
4314 return temp;
4315
4316 code = SET_NOT_EXPR;
4317 }
4318 break;
4319
4320 default:
4321 error ("invalid right operand of %s", tree_code_name[(int)code]);
4322 return error_mark_node;
4323 }
4324
4325 }
4326
4327 class = chill_expr_class (op0);
4328 if (class.mode)
4329 class.mode = CH_ROOT_MODE (class.mode);
4330 TREE_SET_CODE (node, code);
4331 TREE_OPERAND (node, 0) = op0 = convert_to_class (class, op0);
4332 TREE_TYPE (node) = TREE_TYPE (op0);
4333
4334 node = convert_to_class (class, fold (node));
4335
4336 /* FIXME: should call
4337 * cond_type_range_exception (op0);
4338 */
4339 return node;
4340 }
4341
4342 /* op is TRUTH_NOT_EXPR, BIT_NOT_EXPR, or NEGATE_EXPR */
4343
4344 tree
4345 build_chill_unary_op (code, op0)
4346 enum chill_tree_code code;
4347 tree op0;
4348 {
4349 register tree result = NULL_TREE;
4350
4351 if (op0 == NULL_TREE || TREE_CODE (op0) == ERROR_MARK)
4352 return error_mark_node;
4353
4354 result = build1 (code, NULL_TREE, op0);
4355
4356 if (pass != 1)
4357 result = finish_chill_unary_op (result);
4358 return result;
4359 }
4360
4361 tree
4362 truthvalue_conversion (expr)
4363 tree expr;
4364 {
4365 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
4366 return error_mark_node;
4367
4368 #if 0 /* what about a LE_EXPR (integer_type, integer_type ) */
4369 if (TREE_CODE (TREE_TYPE (expr)) != BOOLEAN_TYPE)
4370 error ("non-boolean mode in conditional expression");
4371 #endif
4372
4373 switch ((int)TREE_CODE (expr))
4374 {
4375 /* It is simpler and generates better code to have only TRUTH_*_EXPR
4376 or comparison expressions as truth values at this level. */
4377 #if 0
4378 case COMPONENT_REF:
4379 /* A one-bit unsigned bit-field is already acceptable. */
4380 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
4381 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
4382 return expr;
4383 break;
4384 #endif
4385
4386 case EQ_EXPR:
4387 /* It is simpler and generates better code to have only TRUTH_*_EXPR
4388 or comparison expressions as truth values at this level. */
4389 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
4390 case TRUTH_ANDIF_EXPR:
4391 case TRUTH_ORIF_EXPR:
4392 case TRUTH_AND_EXPR:
4393 case TRUTH_OR_EXPR:
4394 case ERROR_MARK:
4395 return expr;
4396
4397 case INTEGER_CST:
4398 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
4399
4400 case REAL_CST:
4401 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
4402
4403 case ADDR_EXPR:
4404 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
4405 return build (COMPOUND_EXPR, boolean_type_node,
4406 TREE_OPERAND (expr, 0), boolean_true_node);
4407 else
4408 return boolean_true_node;
4409
4410 case NEGATE_EXPR:
4411 case ABS_EXPR:
4412 case FLOAT_EXPR:
4413 case FFS_EXPR:
4414 /* These don't change whether an object is non-zero or zero. */
4415 return truthvalue_conversion (TREE_OPERAND (expr, 0));
4416
4417 case LROTATE_EXPR:
4418 case RROTATE_EXPR:
4419 /* These don't change whether an object is zero or non-zero, but
4420 we can't ignore them if their second arg has side-effects. */
4421 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
4422 return build (COMPOUND_EXPR, boolean_type_node, TREE_OPERAND (expr, 1),
4423 truthvalue_conversion (TREE_OPERAND (expr, 0)));
4424 else
4425 return truthvalue_conversion (TREE_OPERAND (expr, 0));
4426
4427 case COND_EXPR:
4428 /* Distribute the conversion into the arms of a COND_EXPR. */
4429 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
4430 truthvalue_conversion (TREE_OPERAND (expr, 1)),
4431 truthvalue_conversion (TREE_OPERAND (expr, 2))));
4432
4433 case CONVERT_EXPR:
4434 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
4435 since that affects how `default_conversion' will behave. */
4436 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
4437 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
4438 break;
4439 /* fall through... */
4440 case NOP_EXPR:
4441 /* If this is widening the argument, we can ignore it. */
4442 if (TYPE_PRECISION (TREE_TYPE (expr))
4443 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
4444 return truthvalue_conversion (TREE_OPERAND (expr, 0));
4445 break;
4446
4447 case BIT_XOR_EXPR:
4448 case MINUS_EXPR:
4449 /* These can be changed into a comparison of the two objects. */
4450 if (TREE_TYPE (TREE_OPERAND (expr, 0))
4451 == TREE_TYPE (TREE_OPERAND (expr, 1)))
4452 return build_chill_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
4453 TREE_OPERAND (expr, 1));
4454 return build_chill_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
4455 fold (build1 (NOP_EXPR,
4456 TREE_TYPE (TREE_OPERAND (expr, 0)),
4457 TREE_OPERAND (expr, 1))));
4458 }
4459
4460 return build_chill_binary_op (NE_EXPR, expr, boolean_false_node);
4461 }
4462
4463
4464 /*
4465 * return a folded tree for the powerset's length in bits. If a
4466 * non-set is passed, we assume it's an array or boolean bytes.
4467 */
4468 tree
4469 powersetlen (powerset)
4470 tree powerset;
4471 {
4472 if (powerset == NULL_TREE || TREE_CODE (powerset) == ERROR_MARK)
4473 return error_mark_node;
4474
4475 return discrete_count (TYPE_DOMAIN (TREE_TYPE (powerset)));
4476 }
This page took 0.218443 seconds and 5 git commands to generate.