]> gcc.gnu.org Git - gcc.git/blob - gcc/ch/inout.c
Warning fixes:
[gcc.git] / gcc / ch / inout.c
1 /* Implement I/O-related actions for CHILL.
2 Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "tree.h"
23 #include "ch-tree.h"
24 #include "rtl.h"
25 #include "lex.h"
26 #include "flags.h"
27 #include "input.h"
28 #include "assert.h"
29 #include "toplev.h"
30
31 /* set non-zero if input text is forced to lowercase */
32 extern int ignore_case;
33
34 /* set non-zero if special words are to be entered in uppercase */
35 extern int special_UC;
36
37 static int intsize_of_charsexpr PROTO((tree));
38
39 /* association mode */
40 tree association_type_node;
41 /* initialzier for association mode */
42 tree association_init_value;
43
44 /* NOTE: should be same as in runtime/chillrt0.c */
45 #define STDIO_TEXT_LENGTH 1024
46 /* mode of stdout, stdin, stderr*/
47 static tree stdio_type_node;
48
49 /* usage- and where modes */
50 tree usage_type_node;
51 tree where_type_node;
52
53 /* we have to distinguish between io-list-type for WRITETEXT
54 and for READTEXT. WRITETEXT does not process ranges and
55 READTEXT must get pointers to the variables.
56 */
57 /* variable to hold the type of the io_list */
58 static tree chill_io_list_type = NULL_TREE;
59
60 /* the type for the enum tables */
61 static tree enum_table_type = NULL_TREE;
62
63 /* structure to save enums for later use in compilation */
64 typedef struct save_enum_names
65 {
66 struct save_enum_names *forward;
67 tree name;
68 tree decl;
69 } SAVE_ENUM_NAMES;
70
71 static SAVE_ENUM_NAMES *used_enum_names = (SAVE_ENUM_NAMES *)0;
72
73 typedef struct save_enum_values
74 {
75 long val;
76 struct save_enum_names *name;
77 } SAVE_ENUM_VALUES;
78
79 typedef struct save_enums
80 {
81 struct save_enums *forward;
82 tree context;
83 tree type;
84 tree ptrdecl;
85 long num_vals;
86 struct save_enum_values *vals;
87 } SAVE_ENUMS;
88
89 static SAVE_ENUMS *used_enums = (SAVE_ENUMS *)0;
90
91 \f
92 /* Function collects all enums are necessary to collect, makes a copy of
93 the value and returns a VAR_DECL external to current function describing
94 the pointer to a name table, which will be generated at the end of
95 compilation
96 */
97
98 static tree add_enum_to_list (type, context)
99 tree type;
100 tree context;
101 {
102 tree tmp;
103 SAVE_ENUMS *wrk = used_enums;
104 SAVE_ENUM_VALUES *vals;
105 SAVE_ENUM_NAMES *names;
106
107 while (wrk != (SAVE_ENUMS *)0)
108 {
109 /* search for this enum already in use */
110 if (wrk->context == context && wrk->type == type)
111 {
112 /* yes, found. look if the ptrdecl is valid in this scope */
113 char *name = IDENTIFIER_POINTER (DECL_NAME (wrk->ptrdecl));
114 tree var = get_identifier (name);
115 tree decl = lookup_name (var);
116
117 if (decl == NULL_TREE)
118 {
119 /* no, not valid in this context, declare it */
120 decl = decl_temp1 (var, build_pointer_type (TREE_TYPE (enum_table_type)),
121 0, NULL_TREE, 1, 0);
122 }
123 return decl;
124 }
125
126 /* next one */
127 wrk = wrk->forward;
128 }
129
130 /* not yet found -- generate an entry */
131 wrk = (SAVE_ENUMS *)xmalloc (sizeof (SAVE_ENUMS));
132 wrk->forward = used_enums;
133 used_enums = wrk;
134
135 /* generate the pointer decl */
136 wrk->ptrdecl = get_unique_identifier ("ENUMTABPTR");
137 wrk->ptrdecl = decl_temp1 (wrk->ptrdecl, build_pointer_type (TREE_TYPE (enum_table_type)),
138 0, NULL_TREE, 1, 0);
139
140 /* save information for later use */
141 wrk->context = context;
142 wrk->type = type;
143
144 /* insert the names and values */
145 tmp = TYPE_FIELDS (type);
146 wrk->num_vals = list_length (tmp);
147 vals = (SAVE_ENUM_VALUES *)xmalloc (sizeof (SAVE_ENUM_VALUES) * wrk->num_vals);
148 wrk->vals = vals;
149
150 while (tmp != NULL_TREE)
151 {
152 /* search if name is already in use */
153 names = used_enum_names;
154 while (names != (SAVE_ENUM_NAMES *)0)
155 {
156 if (names->name == TREE_PURPOSE (tmp))
157 break;
158 names = names->forward;
159 }
160 if (names == (SAVE_ENUM_NAMES *)0)
161 {
162 /* we have to insert one */
163 names = (SAVE_ENUM_NAMES *)xmalloc (sizeof (SAVE_ENUM_NAMES));
164 names->forward = used_enum_names;
165 used_enum_names = names;
166 names->decl = NULL_TREE;
167 names->name = TREE_PURPOSE (tmp);
168 }
169 vals->name = names;
170 vals->val = TREE_INT_CST_LOW (TREE_VALUE (tmp));
171
172 /* next entry in enum */
173 vals++;
174 tmp = TREE_CHAIN (tmp);
175 }
176
177 /* return the generated decl */
178 return wrk->ptrdecl;
179 }
180
181 \f
182 static void
183 build_chill_io_list_type ()
184 {
185 tree list = NULL_TREE;
186 tree result, enum1, listbase;
187 tree io_descriptor;
188 tree decl1, decl2;
189 tree forcharstring, forset_W, forset_R, forboolrange;
190
191 tree forintrange, intunion, forsetrange, forcharrange;
192 tree long_type, ulong_type, union_type;
193
194 long_type = long_integer_type_node;
195 ulong_type = long_unsigned_type_node;
196
197 if (chill_io_list_type != NULL_TREE)
198 /* already done */
199 return;
200
201 /* first build the enum for the desriptor */
202 enum1 = start_enum (NULL_TREE);
203 result = build_enumerator (get_identifier ("__IO_UNUSED"),
204 NULL_TREE);
205 list = chainon (result, list);
206
207 result = build_enumerator (get_identifier ("__IO_ByteVal"),
208 NULL_TREE);
209 list = chainon (result, list);
210
211 result = build_enumerator (get_identifier ("__IO_UByteVal"),
212 NULL_TREE);
213 list = chainon (result, list);
214
215 result = build_enumerator (get_identifier ("__IO_IntVal"),
216 NULL_TREE);
217 list = chainon (result, list);
218
219 result = build_enumerator (get_identifier ("__IO_UIntVal"),
220 NULL_TREE);
221 list = chainon (result, list);
222
223 result = build_enumerator (get_identifier ("__IO_LongVal"),
224 NULL_TREE);
225 list = chainon (result, list);
226
227 result = build_enumerator (get_identifier ("__IO_ULongVal"),
228 NULL_TREE);
229 list = chainon (result, list);
230
231 result = build_enumerator (get_identifier ("__IO_ByteLoc"),
232 NULL_TREE);
233 list = chainon (result, list);
234
235 result = build_enumerator (get_identifier ("__IO_UByteLoc"),
236 NULL_TREE);
237 list = chainon (result, list);
238
239 result = build_enumerator (get_identifier ("__IO_IntLoc"),
240 NULL_TREE);
241 list = chainon (result, list);
242
243 result = build_enumerator (get_identifier ("__IO_UIntLoc"),
244 NULL_TREE);
245 list = chainon (result, list);
246
247 result = build_enumerator (get_identifier ("__IO_LongLoc"),
248 NULL_TREE);
249 list = chainon (result, list);
250
251 result = build_enumerator (get_identifier ("__IO_ULongLoc"),
252 NULL_TREE);
253 list = chainon (result, list);
254
255 result = build_enumerator (get_identifier ("__IO_ByteRangeLoc"),
256 NULL_TREE);
257 list = chainon (result, list);
258
259 result = build_enumerator (get_identifier ("__IO_UByteRangeLoc"),
260 NULL_TREE);
261 list = chainon (result, list);
262
263 result = build_enumerator (get_identifier ("__IO_IntRangeLoc"),
264 NULL_TREE);
265 list = chainon (result, list);
266
267 result = build_enumerator (get_identifier ("__IO_UIntRangeLoc"),
268 NULL_TREE);
269 list = chainon (result, list);
270
271 result = build_enumerator (get_identifier ("__IO_LongRangeLoc"),
272 NULL_TREE);
273 list = chainon (result, list);
274
275 result = build_enumerator (get_identifier ("__IO_ULongRangeLoc"),
276 NULL_TREE);
277 list = chainon (result, list);
278
279 result = build_enumerator (get_identifier ("__IO_BoolVal"),
280 NULL_TREE);
281 list = chainon (result, list);
282
283 result = build_enumerator (get_identifier ("__IO_BoolLoc"),
284 NULL_TREE);
285 list = chainon (result, list);
286
287 result = build_enumerator (get_identifier ("__IO_BoolRangeLoc"),
288 NULL_TREE);
289 list = chainon (result, list);
290
291 result = build_enumerator (get_identifier ("__IO_SetVal"),
292 NULL_TREE);
293 list = chainon (result, list);
294
295 result = build_enumerator (get_identifier ("__IO_SetLoc"),
296 NULL_TREE);
297 list = chainon (result, list);
298
299 result = build_enumerator (get_identifier ("__IO_SetRangeLoc"),
300 NULL_TREE);
301 list = chainon (result, list);
302
303 result = build_enumerator (get_identifier ("__IO_CharVal"),
304 NULL_TREE);
305 list = chainon (result, list);
306
307 result = build_enumerator (get_identifier ("__IO_CharLoc"),
308 NULL_TREE);
309 list = chainon (result, list);
310
311 result = build_enumerator (get_identifier ("__IO_CharRangeLoc"),
312 NULL_TREE);
313 list = chainon (result, list);
314
315 result = build_enumerator (get_identifier ("__IO_CharStrLoc"),
316 NULL_TREE);
317 list = chainon (result, list);
318
319 result = build_enumerator (get_identifier ("__IO_CharVaryingLoc"),
320 NULL_TREE);
321 list = chainon (result, list);
322
323 result = build_enumerator (get_identifier ("__IO_BitStrLoc"),
324 NULL_TREE);
325 list = chainon (result, list);
326
327 result = build_enumerator (get_identifier ("__IO_RealVal"),
328 NULL_TREE);
329 list = chainon (result, list);
330
331 result = build_enumerator (get_identifier ("__IO_RealLoc"),
332 NULL_TREE);
333 list = chainon (result, list);
334
335 result = build_enumerator (get_identifier ("__IO_LongRealVal"),
336 NULL_TREE);
337 list = chainon (result, list);
338
339 result = build_enumerator (get_identifier ("__IO_LongRealLoc"),
340 NULL_TREE);
341 list = chainon (result, list);
342 #if 0
343 result = build_enumerator (get_identifier ("_IO_Pointer"),
344 NULL_TREE);
345 list = chainon (result, list);
346 #endif
347
348 result = finish_enum (enum1, list);
349 pushdecl (io_descriptor = build_decl (TYPE_DECL,
350 get_identifier ("__tmp_IO_enum"),
351 result));
352 /* prevent seizing/granting of the decl */
353 DECL_SOURCE_LINE (io_descriptor) = 0;
354 satisfy_decl (io_descriptor, 0);
355
356 /* build type for enum_tables */
357 decl1 = build_decl (FIELD_DECL, get_identifier ("value"),
358 long_type);
359 DECL_INITIAL (decl1) = NULL_TREE;
360 decl2 = build_decl (FIELD_DECL, get_identifier ("name"),
361 build_pointer_type (char_type_node));
362 DECL_INITIAL (decl2) = NULL_TREE;
363 TREE_CHAIN (decl1) = decl2;
364 TREE_CHAIN (decl2) = NULL_TREE;
365 result = build_chill_struct_type (decl1);
366 pushdecl (enum_table_type = build_decl (TYPE_DECL,
367 get_identifier ("__tmp_IO_enum_table_type"),
368 result));
369 DECL_SOURCE_LINE (enum_table_type) = 0;
370 satisfy_decl (enum_table_type, 0);
371
372 /* build type for writing a set mode */
373 decl1 = build_decl (FIELD_DECL, get_identifier ("value"),
374 long_type);
375 DECL_INITIAL (decl1) = NULL_TREE;
376 listbase = decl1;
377
378 decl2 = build_decl (FIELD_DECL, get_identifier ("name_table"),
379 build_pointer_type (TREE_TYPE (enum_table_type)));
380 DECL_INITIAL (decl2) = NULL_TREE;
381 TREE_CHAIN (decl1) = decl2;
382 decl1 = decl2;
383 TREE_CHAIN (decl2) = NULL_TREE;
384
385 result = build_chill_struct_type (listbase);
386 pushdecl (forset_W = build_decl (TYPE_DECL,
387 get_identifier ("__tmp_WIO_set"),
388 result));
389 DECL_SOURCE_LINE (forset_W) = 0;
390 satisfy_decl (forset_W, 0);
391
392 /* build type for charrange */
393 decl1 = build_decl (FIELD_DECL, get_identifier ("ptr"),
394 build_pointer_type (char_type_node));
395 DECL_INITIAL (decl1) = NULL_TREE;
396 listbase = decl1;
397
398 decl2 = build_decl (FIELD_DECL, get_identifier ("lower"),
399 long_type);
400 DECL_INITIAL (decl2) = NULL_TREE;
401 TREE_CHAIN (decl1) = decl2;
402 decl1 = decl2;
403
404 decl2 = build_decl (FIELD_DECL, get_identifier ("upper"),
405 long_type);
406 DECL_INITIAL (decl2) = NULL_TREE;
407 TREE_CHAIN (decl1) = decl2;
408 TREE_CHAIN (decl2) = NULL_TREE;
409
410 result = build_chill_struct_type (listbase);
411 pushdecl (forcharrange = build_decl (TYPE_DECL,
412 get_identifier ("__tmp_IO_charrange"),
413 result));
414 DECL_SOURCE_LINE (forcharrange) = 0;
415 satisfy_decl (forcharrange, 0);
416
417 /* type for integer range */
418 decl1 = build_tree_list (NULL_TREE,
419 build_decl (FIELD_DECL,
420 get_identifier ("_slong"),
421 long_type));
422 listbase = decl1;
423
424 decl2 = build_tree_list (NULL_TREE,
425 build_decl (FIELD_DECL,
426 get_identifier ("_ulong"),
427 ulong_type));
428 TREE_CHAIN (decl1) = decl2;
429 TREE_CHAIN (decl2) = NULL_TREE;
430
431 decl1 = grok_chill_variantdefs (NULL_TREE, listbase, NULL_TREE);
432 TREE_CHAIN (decl1) = NULL_TREE;
433 result = build_chill_struct_type (decl1);
434 pushdecl (intunion = build_decl (TYPE_DECL,
435 get_identifier ("__tmp_IO_long"),
436 result));
437 DECL_SOURCE_LINE (intunion) = 0;
438 satisfy_decl (intunion, 0);
439
440 decl1 = build_decl (FIELD_DECL,
441 get_identifier ("ptr"),
442 ptr_type_node);
443 listbase = decl1;
444
445 decl2 = build_decl (FIELD_DECL,
446 get_identifier ("lower"),
447 TREE_TYPE (intunion));
448 TREE_CHAIN (decl1) = decl2;
449 decl1 = decl2;
450
451 decl2 = build_decl (FIELD_DECL,
452 get_identifier ("upper"),
453 TREE_TYPE (intunion));
454 TREE_CHAIN (decl1) = decl2;
455 TREE_CHAIN (decl2) = NULL_TREE;
456
457 result = build_chill_struct_type (listbase);
458 pushdecl (forintrange = build_decl (TYPE_DECL,
459 get_identifier ("__tmp_IO_intrange"),
460 result));
461 DECL_SOURCE_LINE (forintrange) = 0;
462 satisfy_decl (forintrange, 0);
463
464 /* build structure for bool range */
465 decl1 = build_decl (FIELD_DECL,
466 get_identifier ("ptr"),
467 ptr_type_node);
468 DECL_INITIAL (decl1) = NULL_TREE;
469 listbase = decl1;
470
471 decl2 = build_decl (FIELD_DECL,
472 get_identifier ("lower"),
473 ulong_type);
474 DECL_INITIAL (decl2) = NULL_TREE;
475 TREE_CHAIN (decl1) = decl2;
476 decl1 = decl2;
477
478 decl2 = build_decl (FIELD_DECL,
479 get_identifier ("upper"),
480 ulong_type);
481 DECL_INITIAL (decl2) = NULL_TREE;
482 TREE_CHAIN (decl1) = decl2;
483 TREE_CHAIN (decl2) = NULL_TREE;
484
485 result = build_chill_struct_type (listbase);
486 pushdecl (forboolrange = build_decl (TYPE_DECL,
487 get_identifier ("__tmp_RIO_boolrange"),
488 result));
489 DECL_SOURCE_LINE (forboolrange) = 0;
490 satisfy_decl (forboolrange, 0);
491
492 /* build type for reading a set */
493 decl1 = build_decl (FIELD_DECL, get_identifier ("ptr"),
494 ptr_type_node);
495 DECL_INITIAL (decl1) = NULL_TREE;
496 listbase = decl1;
497
498 decl2 = build_decl (FIELD_DECL, get_identifier ("length"),
499 long_type);
500 DECL_INITIAL (decl2) = NULL_TREE;
501 TREE_CHAIN (decl1) = decl2;
502 decl1 = decl2;
503
504 decl2 = build_decl (FIELD_DECL, get_identifier ("name_table"),
505 build_pointer_type (TREE_TYPE (enum_table_type)));
506 DECL_INITIAL (decl2) = NULL_TREE;
507 TREE_CHAIN (decl1) = decl2;
508 TREE_CHAIN (decl2) = NULL_TREE;
509
510 result = build_chill_struct_type (listbase);
511 pushdecl (forset_R = build_decl (TYPE_DECL,
512 get_identifier ("__tmp_RIO_set"),
513 result));
514 DECL_SOURCE_LINE (forset_R) = 0;
515 satisfy_decl (forset_R, 0);
516
517 /* build type for setrange */
518 decl1 = build_decl (FIELD_DECL, get_identifier ("ptr"),
519 ptr_type_node);
520 DECL_INITIAL (decl1) = NULL_TREE;
521 listbase = decl1;
522
523 decl2 = build_decl (FIELD_DECL, get_identifier ("length"),
524 long_type);
525 DECL_INITIAL (decl2) = NULL_TREE;
526 TREE_CHAIN (decl1) = decl2;
527 decl1 = decl2;
528
529 decl2 = build_decl (FIELD_DECL, get_identifier ("name_table"),
530 build_pointer_type (TREE_TYPE (enum_table_type)));
531 DECL_INITIAL (decl2) = NULL_TREE;
532 TREE_CHAIN (decl1) = decl2;
533 decl1 = decl2;
534
535 decl2 = build_decl (FIELD_DECL, get_identifier ("lower"),
536 long_type);
537 DECL_INITIAL (decl2) = NULL_TREE;
538 TREE_CHAIN (decl1) = decl2;
539 decl1 = decl2;
540
541 decl2 = build_decl (FIELD_DECL, get_identifier ("upper"),
542 long_type);
543 DECL_INITIAL (decl2) = NULL_TREE;
544 TREE_CHAIN (decl1) = decl2;
545 TREE_CHAIN (decl2) = NULL_TREE;
546
547 result = build_chill_struct_type (listbase);
548 pushdecl (forsetrange = build_decl (TYPE_DECL,
549 get_identifier ("__tmp_RIO_setrange"),
550 result));
551 DECL_SOURCE_LINE (forsetrange) = 0;
552 satisfy_decl (forsetrange, 0);
553
554 /* build structure for character string */
555 decl1 = build_decl (FIELD_DECL,
556 get_identifier ("string"),
557 build_pointer_type (char_type_node));
558 DECL_INITIAL (decl1) = NULL_TREE;
559 listbase = decl1;
560
561 decl2 = build_decl (FIELD_DECL,
562 get_identifier ("string_length"),
563 ulong_type);
564 DECL_INITIAL (decl2) = NULL_TREE;
565 TREE_CHAIN (decl1) = decl2;
566 decl1 = decl2;
567 TREE_CHAIN (decl2) = NULL_TREE;
568
569 result = build_chill_struct_type (listbase);
570 pushdecl (forcharstring = build_decl (TYPE_DECL,
571 get_identifier ("__tmp_IO_forcharstring"), result));
572 DECL_SOURCE_LINE (forcharstring) = 0;
573 satisfy_decl (forcharstring, 0);
574
575 /* build the union */
576 decl1 = build_tree_list (NULL_TREE,
577 build_decl (FIELD_DECL,
578 get_identifier ("__valbyte"),
579 signed_char_type_node));
580 listbase = decl1;
581
582 decl2 = build_tree_list (NULL_TREE,
583 build_decl (FIELD_DECL,
584 get_identifier ("__valubyte"),
585 unsigned_char_type_node));
586 TREE_CHAIN (decl1) = decl2;
587 decl1 = decl2;
588
589 decl2 = build_tree_list (NULL_TREE,
590 build_decl (FIELD_DECL,
591 get_identifier ("__valint"),
592 chill_integer_type_node));
593 TREE_CHAIN (decl1) = decl2;
594 decl1 = decl2;
595
596 decl2 = build_tree_list (NULL_TREE,
597 build_decl (FIELD_DECL,
598 get_identifier ("__valuint"),
599 chill_unsigned_type_node));
600 TREE_CHAIN (decl1) = decl2;
601 decl1 = decl2;
602
603 decl2 = build_tree_list (NULL_TREE,
604 build_decl (FIELD_DECL,
605 get_identifier ("__vallong"),
606 long_type));
607 TREE_CHAIN (decl1) = decl2;
608 decl1 = decl2;
609
610 decl2 = build_tree_list (NULL_TREE,
611 build_decl (FIELD_DECL,
612 get_identifier ("__valulong"),
613 ulong_type));
614 TREE_CHAIN (decl1) = decl2;
615 decl1 = decl2;
616
617 decl2 = build_tree_list (NULL_TREE,
618 build_decl (FIELD_DECL,
619 get_identifier ("__locint"),
620 ptr_type_node));
621 TREE_CHAIN (decl1) = decl2;
622 decl1 = decl2;
623
624 decl2 = build_tree_list (NULL_TREE,
625 build_decl (FIELD_DECL,
626 get_identifier ("__locintrange"),
627 TREE_TYPE (forintrange)));
628 TREE_CHAIN (decl1) = decl2;
629 decl1 = decl2;
630
631 decl2 = build_tree_list (NULL_TREE,
632 build_decl (FIELD_DECL,
633 get_identifier ("__valbool"),
634 boolean_type_node));
635 TREE_CHAIN (decl1) = decl2;
636 decl1 = decl2;
637
638 decl2 = build_tree_list (NULL_TREE,
639 build_decl (FIELD_DECL,
640 get_identifier ("__locbool"),
641 build_pointer_type (boolean_type_node)));
642 TREE_CHAIN (decl1) = decl2;
643 decl1 = decl2;
644
645 decl2 = build_tree_list (NULL_TREE,
646 build_decl (FIELD_DECL,
647 get_identifier ("__locboolrange"),
648 TREE_TYPE (forboolrange)));
649 TREE_CHAIN (decl1) = decl2;
650 decl1 = decl2;
651
652 decl2 = build_tree_list (NULL_TREE,
653 build_decl (FIELD_DECL,
654 get_identifier ("__valset"),
655 TREE_TYPE (forset_W)));
656 TREE_CHAIN (decl1) = decl2;
657 decl1 = decl2;
658
659 decl2 = build_tree_list (NULL_TREE,
660 build_decl (FIELD_DECL,
661 get_identifier ("__locset"),
662 TREE_TYPE (forset_R)));
663 TREE_CHAIN (decl1) = decl2;
664 decl1 = decl2;
665
666 decl2 = build_tree_list (NULL_TREE,
667 build_decl (FIELD_DECL,
668 get_identifier ("__locsetrange"),
669 TREE_TYPE (forsetrange)));
670 TREE_CHAIN (decl1) = decl2;
671 decl1 = decl2;
672
673 decl2 = build_tree_list (NULL_TREE,
674 build_decl (FIELD_DECL,
675 get_identifier ("__valchar"),
676 char_type_node));
677 TREE_CHAIN (decl1) = decl2;
678 decl1 = decl2;
679
680 decl2 = build_tree_list (NULL_TREE,
681 build_decl (FIELD_DECL,
682 get_identifier ("__locchar"),
683 build_pointer_type (char_type_node)));
684 TREE_CHAIN (decl1) = decl2;
685 decl1 = decl2;
686
687 decl2 = build_tree_list (NULL_TREE,
688 build_decl (FIELD_DECL,
689 get_identifier ("__loccharrange"),
690 TREE_TYPE (forcharrange)));
691 TREE_CHAIN (decl1) = decl2;
692 decl1 = decl2;
693
694 decl2 = build_tree_list (NULL_TREE,
695 build_decl (FIELD_DECL,
696 get_identifier ("__loccharstring"),
697 TREE_TYPE (forcharstring)));
698 TREE_CHAIN (decl1) = decl2;
699 decl1 = decl2;
700
701 decl2 = build_tree_list (NULL_TREE,
702 build_decl (FIELD_DECL,
703 get_identifier ("__valreal"),
704 float_type_node));
705 TREE_CHAIN (decl1) = decl2;
706 decl1 = decl2;
707
708 decl2 = build_tree_list (NULL_TREE,
709 build_decl (FIELD_DECL,
710 get_identifier ("__locreal"),
711 build_pointer_type (float_type_node)));
712 TREE_CHAIN (decl1) = decl2;
713 decl1 = decl2;
714
715 decl2 = build_tree_list (NULL_TREE,
716 build_decl (FIELD_DECL,
717 get_identifier ("__vallongreal"),
718 double_type_node));
719 TREE_CHAIN (decl1) = decl2;
720 decl1 = decl2;
721
722 decl2 = build_tree_list (NULL_TREE,
723 build_decl (FIELD_DECL,
724 get_identifier ("__loclongreal"),
725 build_pointer_type (double_type_node)));
726 TREE_CHAIN (decl1) = decl2;
727 decl1 = decl2;
728
729 #if 0
730 decl2 = build_tree_list (NULL_TREE,
731 build_decl (FIELD_DECL,
732 get_identifier ("__forpointer"),
733 ptr_type_node));
734 TREE_CHAIN (decl1) = decl2;
735 decl1 = decl2;
736 #endif
737
738 TREE_CHAIN (decl2) = NULL_TREE;
739
740 decl1 = grok_chill_variantdefs (NULL_TREE, listbase, NULL_TREE);
741 TREE_CHAIN (decl1) = NULL_TREE;
742 result = build_chill_struct_type (decl1);
743 pushdecl (union_type = build_decl (TYPE_DECL,
744 get_identifier ("__tmp_WIO_union"),
745 result));
746 DECL_SOURCE_LINE (union_type) = 0;
747 satisfy_decl (union_type, 0);
748
749 /* now build the final structure */
750 decl1 = build_decl (FIELD_DECL, get_identifier ("__t"),
751 TREE_TYPE (union_type));
752 DECL_INITIAL (decl1) = NULL_TREE;
753 listbase = decl1;
754
755 decl2 = build_decl (FIELD_DECL, get_identifier ("__descr"),
756 long_type);
757
758 TREE_CHAIN (decl1) = decl2;
759 TREE_CHAIN (decl2) = NULL_TREE;
760
761 result = build_chill_struct_type (listbase);
762 pushdecl (chill_io_list_type = build_decl (TYPE_DECL,
763 get_identifier ("__tmp_IO_list"),
764 result));
765 DECL_SOURCE_LINE (chill_io_list_type) = 0;
766 satisfy_decl (chill_io_list_type, 0);
767 }
768 \f
769 /* build the ASSOCIATION, ACCESS and TEXT mode types */
770 static void
771 build_io_types ()
772 {
773 tree listbase, decl1, decl2, result, association;
774 tree acc, txt, tloc;
775 tree enum1, tmp;
776
777 /* the association mode */
778 listbase = build_decl (FIELD_DECL,
779 get_identifier ("flags"),
780 long_unsigned_type_node);
781 DECL_INITIAL (listbase) = NULL_TREE;
782 decl1 = listbase;
783
784 decl2 = build_decl (FIELD_DECL,
785 get_identifier ("pathname"),
786 ptr_type_node);
787 DECL_INITIAL (decl2) = NULL_TREE;
788 TREE_CHAIN (decl1) = decl2;
789 decl1 = decl2;
790
791 decl2 = build_decl (FIELD_DECL,
792 get_identifier ("access"),
793 ptr_type_node);
794 DECL_INITIAL (decl2) = NULL_TREE;
795 TREE_CHAIN (decl1) = decl2;
796 decl1 = decl2;
797
798 decl2 = build_decl (FIELD_DECL,
799 get_identifier ("handle"),
800 integer_type_node);
801 DECL_INITIAL (decl2) = NULL_TREE;
802 TREE_CHAIN (decl1) = decl2;
803 decl1 = decl2;
804
805 decl2 = build_decl (FIELD_DECL,
806 get_identifier ("bufptr"),
807 ptr_type_node);
808 DECL_INITIAL (decl2) = NULL_TREE;
809 TREE_CHAIN (decl1) = decl2;
810 decl1 = decl2;
811
812 decl2 = build_decl (FIELD_DECL,
813 get_identifier ("syserrno"),
814 long_integer_type_node);
815 DECL_INITIAL (decl2) = NULL_TREE;
816 TREE_CHAIN (decl1) = decl2;
817 decl1 = decl2;
818
819 decl2 = build_decl (FIELD_DECL,
820 get_identifier ("usage"),
821 char_type_node);
822 DECL_INITIAL (decl2) = NULL_TREE;
823 TREE_CHAIN (decl1) = decl2;
824 decl1 = decl2;
825
826 decl2 = build_decl (FIELD_DECL,
827 get_identifier ("ctl_pre"),
828 char_type_node);
829 DECL_INITIAL (decl2) = NULL_TREE;
830 TREE_CHAIN (decl1) = decl2;
831 decl1 = decl2;
832
833 decl2 = build_decl (FIELD_DECL,
834 get_identifier ("ctl_post"),
835 char_type_node);
836 DECL_INITIAL (decl2) = NULL_TREE;
837 TREE_CHAIN (decl1) = decl2;
838 TREE_CHAIN (decl2) = NULL_TREE;
839
840 result = build_chill_struct_type (listbase);
841 pushdecl (association = build_decl (TYPE_DECL,
842 ridpointers[(int)RID_ASSOCIATION],
843 result));
844 DECL_SOURCE_LINE (association) = 0;
845 satisfy_decl (association, 0);
846 association_type_node = TREE_TYPE (association);
847 TYPE_NAME (association_type_node) = association;
848 CH_NOVELTY (association_type_node) = association;
849 CH_TYPE_NONVALUE_P(association_type_node) = 1;
850 CH_TYPE_NONVALUE_P(association) = 1;
851
852 /* initialiser for association type */
853 tmp = convert (char_type_node, integer_zero_node);
854 association_init_value =
855 build_nt (CONSTRUCTOR, NULL_TREE,
856 tree_cons (NULL_TREE, integer_zero_node, /* flags */
857 tree_cons (NULL_TREE, null_pointer_node, /* pathname */
858 tree_cons (NULL_TREE, null_pointer_node, /* access */
859 tree_cons (NULL_TREE, integer_minus_one_node, /* handle */
860 tree_cons (NULL_TREE, null_pointer_node, /* bufptr */
861 tree_cons (NULL_TREE, integer_zero_node, /* syserrno */
862 tree_cons (NULL_TREE, tmp, /* usage */
863 tree_cons (NULL_TREE, tmp, /* ctl_pre */
864 tree_cons (NULL_TREE, tmp, /* ctl_post */
865 NULL_TREE))))))))));
866
867 /* the type for stdin, stdout, stderr */
868 /* text part */
869 decl1 = build_decl (FIELD_DECL,
870 get_identifier ("flags"),
871 long_unsigned_type_node);
872 DECL_INITIAL (decl1) = NULL_TREE;
873 listbase = decl1;
874
875 decl2 = build_decl (FIELD_DECL,
876 get_identifier ("text_record"),
877 ptr_type_node);
878 DECL_INITIAL (decl2) = NULL_TREE;
879 TREE_CHAIN (decl1) = decl2;
880 decl1 = decl2;
881
882 decl2 = build_decl (FIELD_DECL,
883 get_identifier ("access_sub"),
884 ptr_type_node);
885 DECL_INITIAL (decl2) = NULL_TREE;
886 TREE_CHAIN (decl1) = decl2;
887 decl1 = decl2;
888
889 decl2 = build_decl (FIELD_DECL,
890 get_identifier ("actual_index"),
891 long_unsigned_type_node);
892 DECL_INITIAL (decl2) = NULL_TREE;
893 TREE_CHAIN (decl1) = decl2;
894 TREE_CHAIN (decl2) = NULL_TREE;
895 txt = build_chill_struct_type (listbase);
896
897 /* access part */
898 decl1 = build_decl (FIELD_DECL,
899 get_identifier ("flags"),
900 long_unsigned_type_node);
901 DECL_INITIAL (decl1) = NULL_TREE;
902 listbase = decl1;
903
904 decl2 = build_decl (FIELD_DECL,
905 get_identifier ("reclength"),
906 long_unsigned_type_node);
907 DECL_INITIAL (decl2) = NULL_TREE;
908 TREE_CHAIN (decl1) = decl2;
909 decl1 = decl2;
910
911 decl2 = build_decl (FIELD_DECL,
912 get_identifier ("lowindex"),
913 long_integer_type_node);
914 DECL_INITIAL (decl2) = NULL_TREE;
915 TREE_CHAIN (decl1) = decl2;
916 decl1 = decl2;
917
918 decl2 = build_decl (FIELD_DECL,
919 get_identifier ("highindex"),
920 long_integer_type_node);
921 DECL_INITIAL (decl2) = NULL_TREE;
922 TREE_CHAIN (decl1) = decl2;
923 decl2 = decl1;
924
925 decl2 = build_decl (FIELD_DECL,
926 get_identifier ("association"),
927 ptr_type_node);
928 DECL_INITIAL (decl2) = NULL_TREE;
929 TREE_CHAIN (decl1) = decl2;
930 decl1 = decl2;
931
932 decl2 = build_decl (FIELD_DECL,
933 get_identifier ("base"),
934 long_unsigned_type_node);
935 DECL_INITIAL (decl2) = NULL_TREE;
936 TREE_CHAIN (decl1) = decl2;
937 decl1 = decl2;
938
939 decl2 = build_decl (FIELD_DECL,
940 get_identifier ("storelocptr"),
941 ptr_type_node);
942 DECL_INITIAL (decl2) = NULL_TREE;
943 TREE_CHAIN (decl1) = decl2;
944 decl1 = decl2;
945
946 decl2 = build_decl (FIELD_DECL,
947 get_identifier ("rectype"),
948 long_integer_type_node);
949 DECL_INITIAL (decl2) = NULL_TREE;
950 TREE_CHAIN (decl1) = decl2;
951 TREE_CHAIN (decl2) = NULL_TREE;
952 acc = build_chill_struct_type (listbase);
953
954 /* the location */
955 tmp = build_string_type (char_type_node, build_int_2 (STDIO_TEXT_LENGTH, 0));
956 tloc = build_varying_struct (tmp);
957
958 /* now the final mode */
959 decl1 = build_decl (FIELD_DECL, get_identifier ("txt"), txt);
960 listbase = decl1;
961
962 decl2 = build_decl (FIELD_DECL, get_identifier ("acc"), acc);
963 TREE_CHAIN (decl1) = decl2;
964 decl1 = decl2;
965
966 decl2 = build_decl (FIELD_DECL, get_identifier ("tloc"), tloc);
967 TREE_CHAIN (decl1) = decl2;
968 decl1 = decl2;
969
970 decl2 = build_lang_decl (TYPE_DECL, get_identifier ("__indexmode"),
971 void_type_node);
972 TREE_CHAIN (decl1) = decl2;
973 decl1 = decl2;
974
975 decl2 = build_decl (CONST_DECL, get_identifier ("__textlength"),
976 integer_type_node);
977 DECL_INITIAL (decl2) = build_int_2 (STDIO_TEXT_LENGTH, 0);
978 TREE_CHAIN (decl1) = decl2;
979 decl1 = decl2;
980
981 decl2 = build_decl (CONST_DECL, get_identifier ("__dynamic"),
982 integer_type_node);
983 DECL_INITIAL (decl2) = integer_zero_node;
984 TREE_CHAIN (decl1) = decl2;
985 TREE_CHAIN (decl2) = NULL_TREE;
986
987 result = build_chill_struct_type (listbase);
988 pushdecl (tmp = build_decl (TYPE_DECL,
989 get_identifier ("__stdio_text"),
990 result));
991 DECL_SOURCE_LINE (tmp) = 0;
992 satisfy_decl (tmp, 0);
993 stdio_type_node = TREE_TYPE (tmp);
994 CH_IS_TEXT_MODE (stdio_type_node) = 1;
995
996 /* predefined usage mode */
997 enum1 = start_enum (NULL_TREE);
998 listbase = NULL_TREE;
999 result = build_enumerator (
1000 get_identifier ((ignore_case || ! special_UC) ? "readonly" : "READONLY"),
1001 NULL_TREE);
1002 listbase = chainon (result, listbase);
1003 result = build_enumerator (
1004 get_identifier ((ignore_case || ! special_UC) ? "writeonly" : "WRITEONLY"),
1005 NULL_TREE);
1006 listbase = chainon (result, listbase);
1007 result = build_enumerator (
1008 get_identifier ((ignore_case || ! special_UC) ? "readwrite" : "READWRITE"),
1009 NULL_TREE);
1010 listbase = chainon (result, listbase);
1011 result = finish_enum (enum1, listbase);
1012 pushdecl (tmp = build_decl (TYPE_DECL,
1013 get_identifier ((ignore_case || ! special_UC) ? "usage" : "USAGE"),
1014 result));
1015 DECL_SOURCE_LINE (tmp) = 0;
1016 satisfy_decl (tmp, 0);
1017 usage_type_node = TREE_TYPE (tmp);
1018 TYPE_NAME (usage_type_node) = tmp;
1019 CH_NOVELTY (usage_type_node) = tmp;
1020
1021 /* predefined where mode */
1022 enum1 = start_enum (NULL_TREE);
1023 listbase = NULL_TREE;
1024 result = build_enumerator (
1025 get_identifier ((ignore_case || ! special_UC) ? "first" : "FIRST"),
1026 NULL_TREE);
1027 listbase = chainon (result, listbase);
1028 result = build_enumerator (
1029 get_identifier ((ignore_case || ! special_UC) ? "same" : "SAME"),
1030 NULL_TREE);
1031 listbase = chainon (result, listbase);
1032 result = build_enumerator (
1033 get_identifier ((ignore_case || ! special_UC) ? "last" : "LAST"),
1034 NULL_TREE);
1035 listbase = chainon (result, listbase);
1036 result = finish_enum (enum1, listbase);
1037 pushdecl (tmp = build_decl (TYPE_DECL,
1038 get_identifier ((ignore_case || ! special_UC) ? "where" : "WHERE"),
1039 result));
1040 DECL_SOURCE_LINE (tmp) = 0;
1041 satisfy_decl (tmp, 0);
1042 where_type_node = TREE_TYPE (tmp);
1043 TYPE_NAME (where_type_node) = tmp;
1044 CH_NOVELTY (where_type_node) = tmp;
1045 }
1046 \f
1047 static void
1048 declare_predefined_file (name, assembler_name)
1049 char *name;
1050 char* assembler_name;
1051 {
1052 tree decl = build_lang_decl (VAR_DECL, get_identifier (name),
1053 stdio_type_node);
1054 DECL_ASSEMBLER_NAME (decl) = get_identifier(assembler_name);
1055 TREE_STATIC (decl) = 1;
1056 TREE_PUBLIC (decl) = 1;
1057 DECL_EXTERNAL (decl) = 1;
1058 DECL_IN_SYSTEM_HEADER (decl) = 1;
1059 make_decl_rtl (decl, 0, 1);
1060 pushdecl (decl);
1061 }
1062 \f
1063
1064 /* initialisation of all IO/related functions, types, etc. */
1065 void
1066 inout_init ()
1067 {
1068 /* We temporarily reset the maximum_field_alignment to zero so the
1069 compiler's init data structures can be compatible with the
1070 run-time system, even when we're compiling with -fpack. */
1071 extern int maximum_field_alignment;
1072 int save_maximum_field_alignment = maximum_field_alignment;
1073
1074 extern tree chill_predefined_function_type;
1075 tree endlink = void_list_node;
1076 tree bool_ftype_ptr_ptr_int;
1077 tree ptr_ftype_ptr_ptr_int;
1078 tree luns_ftype_ptr_ptr_int;
1079 tree int_ftype_ptr_ptr_int;
1080 tree ptr_ftype_ptr_ptr_int_ptr_int_ptr_int;
1081 tree void_ftype_ptr_ptr_int_ptr_int_ptr_int;
1082 tree void_ftype_ptr_ptr_int;
1083 tree void_ftype_ptr_ptr_int_int_int_long_ptr_int;
1084 tree ptr_ftype_ptr_int_ptr_ptr_int;
1085 tree void_ftype_ptr_int_ptr_luns_ptr_int;
1086 tree void_ftype_ptr_ptr_ptr_int;
1087 tree void_ftype_ptr_int_ptr_int;
1088 tree void_ftype_ptr_int_ptr_int_ptr_int_ptr_int;
1089
1090 maximum_field_alignment = 0;
1091
1092 builtin_function ((ignore_case || ! special_UC) ? "associate" : "ASSOCIATE",
1093 chill_predefined_function_type,
1094 BUILT_IN_ASSOCIATE, NULL_PTR);
1095 builtin_function ((ignore_case || ! special_UC) ? "connect" : "CONNECT",
1096 chill_predefined_function_type,
1097 BUILT_IN_CONNECT, NULL_PTR);
1098 builtin_function ((ignore_case || ! special_UC) ? "create" : "CREATE",
1099 chill_predefined_function_type,
1100 BUILT_IN_CREATE, NULL_PTR);
1101 builtin_function ((ignore_case || ! special_UC) ? "delete" : "DELETE",
1102 chill_predefined_function_type,
1103 BUILT_IN_CH_DELETE, NULL_PTR);
1104 builtin_function ((ignore_case || ! special_UC) ? "disconnect" : "DISCONNECT",
1105 chill_predefined_function_type,
1106 BUILT_IN_DISCONNECT, NULL_PTR);
1107 builtin_function ((ignore_case || ! special_UC) ? "dissociate" : "DISSOCIATE",
1108 chill_predefined_function_type,
1109 BUILT_IN_DISSOCIATE, NULL_PTR);
1110 builtin_function ((ignore_case || ! special_UC) ? "eoln" : "EOLN",
1111 chill_predefined_function_type,
1112 BUILT_IN_EOLN, NULL_PTR);
1113 builtin_function ((ignore_case || ! special_UC) ? "existing" : "EXISTING",
1114 chill_predefined_function_type,
1115 BUILT_IN_EXISTING, NULL_PTR);
1116 builtin_function ((ignore_case || ! special_UC) ? "getassociation" : "GETASSOCIATION",
1117 chill_predefined_function_type,
1118 BUILT_IN_GETASSOCIATION, NULL_PTR);
1119 builtin_function ((ignore_case || ! special_UC) ? "gettextaccess" : "GETTEXTASSCESS",
1120 chill_predefined_function_type,
1121 BUILT_IN_GETTEXTACCESS, NULL_PTR);
1122 builtin_function ((ignore_case || ! special_UC) ? "gettextindex" : "GETTEXTINDEX",
1123 chill_predefined_function_type,
1124 BUILT_IN_GETTEXTINDEX, NULL_PTR);
1125 builtin_function ((ignore_case || ! special_UC) ? "gettextrecord" : "GETTEXTRECORD",
1126 chill_predefined_function_type,
1127 BUILT_IN_GETTEXTRECORD, NULL_PTR);
1128 builtin_function ((ignore_case || ! special_UC) ? "getusage" : "GETUSAGE",
1129 chill_predefined_function_type,
1130 BUILT_IN_GETUSAGE, NULL_PTR);
1131 builtin_function ((ignore_case || ! special_UC) ? "indexable" : "INDEXABLE",
1132 chill_predefined_function_type,
1133 BUILT_IN_INDEXABLE, NULL_PTR);
1134 builtin_function ((ignore_case || ! special_UC) ? "isassociated" : "ISASSOCIATED",
1135 chill_predefined_function_type,
1136 BUILT_IN_ISASSOCIATED, NULL_PTR);
1137 builtin_function ((ignore_case || ! special_UC) ? "modify" : "MODIFY",
1138 chill_predefined_function_type,
1139 BUILT_IN_MODIFY, NULL_PTR);
1140 builtin_function ((ignore_case || ! special_UC) ? "outoffile" : "OUTOFFILE",
1141 chill_predefined_function_type,
1142 BUILT_IN_OUTOFFILE, NULL_PTR);
1143 builtin_function ((ignore_case || ! special_UC) ? "readable" : "READABLE",
1144 chill_predefined_function_type,
1145 BUILT_IN_READABLE, NULL_PTR);
1146 builtin_function ((ignore_case || ! special_UC) ? "readrecord" : "READRECORD",
1147 chill_predefined_function_type,
1148 BUILT_IN_READRECORD, NULL_PTR);
1149 builtin_function ((ignore_case || ! special_UC) ? "readtext" : "READTEXT",
1150 chill_predefined_function_type,
1151 BUILT_IN_READTEXT, NULL_PTR);
1152 builtin_function ((ignore_case || ! special_UC) ? "sequencible" : "SEQUENCIBLE",
1153 chill_predefined_function_type,
1154 BUILT_IN_SEQUENCIBLE, NULL_PTR);
1155 builtin_function ((ignore_case || ! special_UC) ? "settextaccess" : "SETTEXTACCESS",
1156 chill_predefined_function_type,
1157 BUILT_IN_SETTEXTACCESS, NULL_PTR);
1158 builtin_function ((ignore_case || ! special_UC) ? "settextindex" : "SETTEXTINDEX",
1159 chill_predefined_function_type,
1160 BUILT_IN_SETTEXTINDEX, NULL_PTR);
1161 builtin_function ((ignore_case || ! special_UC) ? "settextrecord" : "SETTEXTRECORD",
1162 chill_predefined_function_type,
1163 BUILT_IN_SETTEXTRECORD, NULL_PTR);
1164 builtin_function ((ignore_case || ! special_UC) ? "variable" : "VARIABLE",
1165 chill_predefined_function_type,
1166 BUILT_IN_VARIABLE, NULL_PTR);
1167 builtin_function ((ignore_case || ! special_UC) ? "writeable" : "WRITEABLE",
1168 chill_predefined_function_type,
1169 BUILT_IN_WRITEABLE, NULL_PTR);
1170 builtin_function ((ignore_case || ! special_UC) ? "writerecord" : "WRITERECORD",
1171 chill_predefined_function_type,
1172 BUILT_IN_WRITERECORD, NULL_PTR);
1173 builtin_function ((ignore_case || ! special_UC) ? "writetext" : "WRITETEXT",
1174 chill_predefined_function_type,
1175 BUILT_IN_WRITETEXT, NULL_PTR);
1176
1177 /* build function prototypes */
1178 bool_ftype_ptr_ptr_int =
1179 build_function_type (boolean_type_node,
1180 tree_cons (NULL_TREE, ptr_type_node,
1181 tree_cons (NULL_TREE, ptr_type_node,
1182 tree_cons (NULL_TREE, integer_type_node,
1183 endlink))));
1184 ptr_ftype_ptr_ptr_int_ptr_int_ptr_int =
1185 build_function_type (ptr_type_node,
1186 tree_cons (NULL_TREE, ptr_type_node,
1187 tree_cons (NULL_TREE, ptr_type_node,
1188 tree_cons (NULL_TREE, integer_type_node,
1189 tree_cons (NULL_TREE, ptr_type_node,
1190 tree_cons (NULL_TREE, integer_type_node,
1191 tree_cons (NULL_TREE, ptr_type_node,
1192 tree_cons (NULL_TREE, integer_type_node,
1193 endlink))))))));
1194 void_ftype_ptr_ptr_int =
1195 build_function_type (void_type_node,
1196 tree_cons (NULL_TREE, ptr_type_node,
1197 tree_cons (NULL_TREE, ptr_type_node,
1198 tree_cons (NULL_TREE, integer_type_node,
1199 endlink))));
1200 void_ftype_ptr_ptr_int_ptr_int_ptr_int =
1201 build_function_type (void_type_node,
1202 tree_cons (NULL_TREE, ptr_type_node,
1203 tree_cons (NULL_TREE, ptr_type_node,
1204 tree_cons (NULL_TREE, integer_type_node,
1205 tree_cons (NULL_TREE, ptr_type_node,
1206 tree_cons (NULL_TREE, integer_type_node,
1207 tree_cons (NULL_TREE, ptr_type_node,
1208 tree_cons (NULL_TREE, integer_type_node,
1209 endlink))))))));
1210 void_ftype_ptr_ptr_int_int_int_long_ptr_int =
1211 build_function_type (void_type_node,
1212 tree_cons (NULL_TREE, ptr_type_node,
1213 tree_cons (NULL_TREE, ptr_type_node,
1214 tree_cons (NULL_TREE, integer_type_node,
1215 tree_cons (NULL_TREE, integer_type_node,
1216 tree_cons (NULL_TREE, integer_type_node,
1217 tree_cons (NULL_TREE, long_integer_type_node,
1218 tree_cons (NULL_TREE, ptr_type_node,
1219 tree_cons (NULL_TREE, integer_type_node,
1220 endlink)))))))));
1221 ptr_ftype_ptr_ptr_int =
1222 build_function_type (ptr_type_node,
1223 tree_cons (NULL_TREE, ptr_type_node,
1224 tree_cons (NULL_TREE, ptr_type_node,
1225 tree_cons (NULL_TREE, integer_type_node,
1226 endlink))));
1227 int_ftype_ptr_ptr_int =
1228 build_function_type (integer_type_node,
1229 tree_cons (NULL_TREE, ptr_type_node,
1230 tree_cons (NULL_TREE, ptr_type_node,
1231 tree_cons (NULL_TREE, integer_type_node,
1232 endlink))));
1233 ptr_ftype_ptr_int_ptr_ptr_int =
1234 build_function_type (ptr_type_node,
1235 tree_cons (NULL_TREE, ptr_type_node,
1236 tree_cons (NULL_TREE, integer_type_node,
1237 tree_cons (NULL_TREE, ptr_type_node,
1238 tree_cons (NULL_TREE, ptr_type_node,
1239 tree_cons (NULL_TREE, integer_type_node,
1240 endlink))))));
1241 void_ftype_ptr_int_ptr_luns_ptr_int =
1242 build_function_type (void_type_node,
1243 tree_cons (NULL_TREE, ptr_type_node,
1244 tree_cons (NULL_TREE, integer_type_node,
1245 tree_cons (NULL_TREE, ptr_type_node,
1246 tree_cons (NULL_TREE, long_unsigned_type_node,
1247 tree_cons (NULL_TREE, ptr_type_node,
1248 tree_cons (NULL_TREE, integer_type_node,
1249 endlink)))))));
1250 luns_ftype_ptr_ptr_int =
1251 build_function_type (long_unsigned_type_node,
1252 tree_cons (NULL_TREE, ptr_type_node,
1253 tree_cons (NULL_TREE, ptr_type_node,
1254 tree_cons (NULL_TREE, integer_type_node,
1255 endlink))));
1256 void_ftype_ptr_ptr_ptr_int =
1257 build_function_type (void_type_node,
1258 tree_cons (NULL_TREE, ptr_type_node,
1259 tree_cons (NULL_TREE, ptr_type_node,
1260 tree_cons (NULL_TREE, ptr_type_node,
1261 tree_cons (NULL_TREE, integer_type_node,
1262 endlink)))));
1263 void_ftype_ptr_int_ptr_int =
1264 build_function_type (void_type_node,
1265 tree_cons (NULL_TREE, ptr_type_node,
1266 tree_cons (NULL_TREE, integer_type_node,
1267 tree_cons (NULL_TREE, ptr_type_node,
1268 tree_cons (NULL_TREE, integer_type_node,
1269 endlink)))));
1270 void_ftype_ptr_int_ptr_int_ptr_int_ptr_int =
1271 build_function_type (void_type_node,
1272 tree_cons (NULL_TREE, ptr_type_node,
1273 tree_cons (NULL_TREE, integer_type_node,
1274 tree_cons (NULL_TREE, ptr_type_node,
1275 tree_cons (NULL_TREE, integer_type_node,
1276 tree_cons (NULL_TREE, ptr_type_node,
1277 tree_cons (NULL_TREE, integer_type_node,
1278 tree_cons (NULL_TREE, ptr_type_node,
1279 tree_cons (NULL_TREE, integer_type_node,
1280 endlink)))))))));
1281
1282 builtin_function ("__associate", ptr_ftype_ptr_ptr_int_ptr_int_ptr_int,
1283 NOT_BUILT_IN, NULL_PTR);
1284 builtin_function ("__connect", void_ftype_ptr_ptr_int_int_int_long_ptr_int,
1285 NOT_BUILT_IN, NULL_PTR);
1286 builtin_function ("__create", void_ftype_ptr_ptr_int,
1287 NOT_BUILT_IN, NULL_PTR);
1288 builtin_function ("__delete", void_ftype_ptr_ptr_int,
1289 NOT_BUILT_IN, NULL_PTR);
1290 builtin_function ("__disconnect", void_ftype_ptr_ptr_int,
1291 NOT_BUILT_IN, NULL_PTR);
1292 builtin_function ("__dissociate", void_ftype_ptr_ptr_int,
1293 NOT_BUILT_IN, NULL_PTR);
1294 builtin_function ("__eoln", bool_ftype_ptr_ptr_int,
1295 NOT_BUILT_IN, NULL_PTR);
1296 builtin_function ("__existing", bool_ftype_ptr_ptr_int,
1297 NOT_BUILT_IN, NULL_PTR);
1298 builtin_function ("__getassociation", ptr_ftype_ptr_ptr_int,
1299 NOT_BUILT_IN, NULL_PTR);
1300 builtin_function ("__gettextaccess", ptr_ftype_ptr_ptr_int,
1301 NOT_BUILT_IN, NULL_PTR);
1302 builtin_function ("__gettextindex", luns_ftype_ptr_ptr_int,
1303 NOT_BUILT_IN, NULL_PTR);
1304 builtin_function ("__gettextrecord", ptr_ftype_ptr_ptr_int,
1305 NOT_BUILT_IN, NULL_PTR);
1306 builtin_function ("__getusage", int_ftype_ptr_ptr_int,
1307 NOT_BUILT_IN, NULL_PTR);
1308 builtin_function ("__indexable", bool_ftype_ptr_ptr_int,
1309 NOT_BUILT_IN, NULL_PTR);
1310 builtin_function ("__isassociated", bool_ftype_ptr_ptr_int,
1311 NOT_BUILT_IN, NULL_PTR);
1312 builtin_function ("__modify", void_ftype_ptr_ptr_int_ptr_int_ptr_int,
1313 NOT_BUILT_IN, NULL_PTR);
1314 builtin_function ("__outoffile", bool_ftype_ptr_ptr_int,
1315 NOT_BUILT_IN, NULL_PTR);
1316 builtin_function ("__readable", bool_ftype_ptr_ptr_int,
1317 NOT_BUILT_IN, NULL_PTR);
1318 builtin_function ("__readrecord", ptr_ftype_ptr_int_ptr_ptr_int,
1319 NOT_BUILT_IN, NULL_PTR);
1320 builtin_function ("__readtext_f", void_ftype_ptr_int_ptr_int_ptr_int_ptr_int,
1321 NOT_BUILT_IN, NULL_PTR);
1322 builtin_function ("__readtext_s", void_ftype_ptr_int_ptr_int_ptr_int_ptr_int,
1323 NOT_BUILT_IN, NULL_PTR);
1324 builtin_function ("__sequencible", bool_ftype_ptr_ptr_int,
1325 NOT_BUILT_IN, NULL_PTR);
1326 builtin_function ("__settextaccess", void_ftype_ptr_ptr_ptr_int,
1327 NOT_BUILT_IN, NULL_PTR);
1328 builtin_function ("__settextindex", void_ftype_ptr_int_ptr_int,
1329 NOT_BUILT_IN, NULL_PTR);
1330 builtin_function ("__settextrecord", void_ftype_ptr_ptr_ptr_int,
1331 NOT_BUILT_IN, NULL_PTR);
1332 builtin_function ("__variable", bool_ftype_ptr_ptr_int,
1333 NOT_BUILT_IN, NULL_PTR);
1334 builtin_function ("__writeable", bool_ftype_ptr_ptr_int,
1335 NOT_BUILT_IN, NULL_PTR);
1336 builtin_function ("__writerecord", void_ftype_ptr_int_ptr_luns_ptr_int,
1337 NOT_BUILT_IN, NULL_PTR);
1338 builtin_function ("__writetext_f", void_ftype_ptr_int_ptr_int_ptr_int_ptr_int,
1339 NOT_BUILT_IN, NULL_PTR);
1340 builtin_function ("__writetext_s", void_ftype_ptr_int_ptr_int_ptr_int_ptr_int,
1341 NOT_BUILT_IN, NULL_PTR);
1342
1343 /* declare ASSOCIATION, ACCESS, and TEXT modes */
1344 build_io_types ();
1345
1346 /* declare the predefined text locations */
1347 declare_predefined_file ((ignore_case || ! special_UC) ? "stdin" : "STDIN",
1348 "chill_stdin");
1349 declare_predefined_file ((ignore_case || ! special_UC) ? "stdout" : "STDOUT",
1350 "chill_stdout");
1351 declare_predefined_file ((ignore_case || ! special_UC) ? "stderr" : "STDERR",
1352 "chill_stderr");
1353
1354 /* last, but not least, build the chill IO-list type */
1355 build_chill_io_list_type ();
1356
1357 maximum_field_alignment = save_maximum_field_alignment;
1358 }
1359 \f
1360 /* function returns the recordmode of an ACCESS */
1361 tree
1362 access_recordmode (access)
1363 tree access;
1364 {
1365 tree field;
1366
1367 if (access == NULL_TREE || TREE_CODE (access) == ERROR_MARK)
1368 return NULL_TREE;
1369 if (! CH_IS_ACCESS_MODE (access))
1370 return NULL_TREE;
1371
1372 field = TYPE_FIELDS (access);
1373 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1374 {
1375 if (TREE_CODE (field) == TYPE_DECL &&
1376 DECL_NAME (field) == get_identifier ("__recordmode"))
1377 return TREE_TYPE (field);
1378 }
1379 return void_type_node;
1380 }
1381
1382 /* function invalidates the recordmode of an ACCESS */
1383 void
1384 invalidate_access_recordmode (access)
1385 tree access;
1386 {
1387 tree field;
1388
1389 if (access == NULL_TREE || TREE_CODE (access) == ERROR_MARK)
1390 return;
1391 if (! CH_IS_ACCESS_MODE (access))
1392 return;
1393
1394 field = TYPE_FIELDS (access);
1395 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1396 {
1397 if (TREE_CODE (field) == TYPE_DECL &&
1398 DECL_NAME (field) == get_identifier ("__recordmode"))
1399 {
1400 TREE_TYPE (field) = error_mark_node;
1401 return;
1402 }
1403 }
1404 }
1405
1406 /* function returns the index mode of an ACCESS if there is one,
1407 otherwise NULL_TREE */
1408 tree
1409 access_indexmode (access)
1410 tree access;
1411 {
1412 tree field;
1413
1414 if (access == NULL_TREE || TREE_CODE (access) == ERROR_MARK)
1415 return NULL_TREE;
1416 if (! CH_IS_ACCESS_MODE (access))
1417 return NULL_TREE;
1418
1419 field = TYPE_FIELDS (access);
1420 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1421 {
1422 if (TREE_CODE (field) == TYPE_DECL &&
1423 DECL_NAME (field) == get_identifier ("__indexmode"))
1424 return TREE_TYPE (field);
1425 }
1426 return void_type_node;
1427 }
1428
1429 /* function returns one if an ACCESS was specified DYNAMIC, otherwise zero */
1430 tree
1431 access_dynamic (access)
1432 tree access;
1433 {
1434 tree field;
1435
1436 if (access == NULL_TREE || TREE_CODE (access) == ERROR_MARK)
1437 return NULL_TREE;
1438 if (! CH_IS_ACCESS_MODE (access))
1439 return NULL_TREE;
1440
1441 field = TYPE_FIELDS (access);
1442 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1443 {
1444 if (TREE_CODE (field) == CONST_DECL)
1445 return DECL_INITIAL (field);
1446 }
1447 return integer_zero_node;
1448 }
1449
1450 #if 0
1451 returns a structure like
1452 STRUCT (data STRUCT (flags ULONG,
1453 reclength ULONG,
1454 lowindex LONG,
1455 highindex LONG,
1456 association PTR,
1457 base ULONG,
1458 store_loc PTR,
1459 rectype LONG),
1460 this is followed by a
1461 TYPE_DECL __recordmode recordmode ? recordmode : void_type_node
1462 TYPE_DECL __indexmode indexmode ? indexmode : void_type_node
1463 CONST_DECL __dynamic dynamic ? integer_one_node : integer_zero_node
1464 #endif
1465
1466 static tree
1467 build_access_part ()
1468 {
1469 tree listbase, decl;
1470
1471 listbase = build_decl (FIELD_DECL, get_identifier ("flags"),
1472 long_unsigned_type_node);
1473 decl = build_decl (FIELD_DECL, get_identifier ("reclength"),
1474 long_unsigned_type_node);
1475 listbase = chainon (listbase, decl);
1476 decl = build_decl (FIELD_DECL, get_identifier ("lowindex"),
1477 long_unsigned_type_node);
1478 listbase = chainon (listbase, decl);
1479 decl = build_decl (FIELD_DECL, get_identifier ("highindex"),
1480 long_integer_type_node);
1481 listbase = chainon (listbase, decl);
1482 decl = build_decl (FIELD_DECL, get_identifier ("association"),
1483 ptr_type_node);
1484 listbase = chainon (listbase, decl);
1485 decl = build_decl (FIELD_DECL, get_identifier ("base"),
1486 long_unsigned_type_node);
1487 listbase = chainon (listbase, decl);
1488 decl = build_decl (FIELD_DECL, get_identifier ("storelocptr"),
1489 ptr_type_node);
1490 listbase = chainon (listbase, decl);
1491 decl = build_decl (FIELD_DECL, get_identifier ("rectype"),
1492 long_integer_type_node);
1493 listbase = chainon (listbase, decl);
1494 return build_chill_struct_type (listbase);
1495 }
1496
1497 tree
1498 build_access_mode (indexmode, recordmode, dynamic)
1499 tree indexmode;
1500 tree recordmode;
1501 int dynamic;
1502 {
1503 tree type, listbase, decl, datamode;
1504
1505 if (indexmode != NULL_TREE && TREE_CODE (indexmode) == ERROR_MARK)
1506 return error_mark_node;
1507 if (recordmode != NULL_TREE && TREE_CODE (recordmode) == ERROR_MARK)
1508 return error_mark_node;
1509
1510 datamode = build_access_part ();
1511
1512 type = make_node (RECORD_TYPE);
1513 listbase = build_decl (FIELD_DECL, get_identifier ("data"),
1514 datamode);
1515 TYPE_FIELDS (type) = listbase;
1516 decl = build_lang_decl (TYPE_DECL, get_identifier ("__recordmode"),
1517 recordmode == NULL_TREE ? void_type_node : recordmode);
1518 chainon (listbase, decl);
1519 decl = build_lang_decl (TYPE_DECL, get_identifier ("__indexmode"),
1520 indexmode == NULL_TREE ? void_type_node : indexmode);
1521 chainon (listbase, decl);
1522 decl = build_decl (CONST_DECL, get_identifier ("__dynamic"),
1523 integer_type_node);
1524 DECL_INITIAL (decl) = dynamic ? integer_one_node : integer_zero_node;
1525 chainon (listbase, decl);
1526 CH_IS_ACCESS_MODE (type) = 1;
1527 CH_TYPE_NONVALUE_P (type) = 1;
1528 return type;
1529 }
1530 \f
1531 #if 0
1532 returns a structure like:
1533 STRUCT (txt STRUCT (flags ULONG,
1534 text_record PTR,
1535 access_sub PTR,
1536 actual_index LONG),
1537 acc STRUCT (flags ULONG,
1538 reclength ULONG,
1539 lowindex LONG,
1540 highindex LONG,
1541 association PTR,
1542 base ULONG,
1543 store_loc PTR,
1544 rectype LONG),
1545 tloc CHARS(textlength) VARYING;
1546 )
1547 followed by
1548 TYPE_DECL __indexmode indexmode ? indexmode : void_type_node
1549 CONST_DECL __text_length
1550 CONST_DECL __dynamic dynamic ? integer_one_node : integer_zero_node
1551 #endif
1552 tree
1553 build_text_mode (textlength, indexmode, dynamic)
1554 tree textlength;
1555 tree indexmode;
1556 int dynamic;
1557 {
1558 tree txt, acc, listbase, decl, type, tltype;
1559 tree savedlength = textlength;
1560
1561 if (indexmode != NULL_TREE && TREE_CODE (indexmode) == ERROR_MARK)
1562 return error_mark_node;
1563 if (textlength == NULL_TREE || TREE_CODE (textlength) == ERROR_MARK)
1564 return error_mark_node;
1565
1566 /* build the structure */
1567 listbase = build_decl (FIELD_DECL, get_identifier ("flags"),
1568 long_unsigned_type_node);
1569 decl = build_decl (FIELD_DECL, get_identifier ("text_record"),
1570 ptr_type_node);
1571 listbase = chainon (listbase, decl);
1572 decl = build_decl (FIELD_DECL, get_identifier ("access_sub"),
1573 ptr_type_node);
1574 listbase = chainon (listbase, decl);
1575 decl = build_decl (FIELD_DECL, get_identifier ("actual_index"),
1576 long_integer_type_node);
1577 listbase = chainon (listbase, decl);
1578 txt = build_chill_struct_type (listbase);
1579
1580 acc = build_access_part ();
1581
1582 type = make_node (RECORD_TYPE);
1583 listbase = build_decl (FIELD_DECL, get_identifier ("txt"), txt);
1584 TYPE_FIELDS (type) = listbase;
1585 decl = build_decl (FIELD_DECL, get_identifier ("acc"), acc);
1586 chainon (listbase, decl);
1587 /* the text location */
1588 tltype = build_string_type (char_type_node, textlength);
1589 tltype = build_varying_struct (tltype);
1590 decl = build_decl (FIELD_DECL, get_identifier ("tloc"),
1591 tltype);
1592 chainon (listbase, decl);
1593 /* the index mode */
1594 decl = build_lang_decl (TYPE_DECL, get_identifier ("__indexmode"),
1595 indexmode == NULL_TREE ? void_type_node : indexmode);
1596 chainon (listbase, decl);
1597 /* save dynamic */
1598 decl = build_decl (CONST_DECL, get_identifier ("__textlength"),
1599 integer_type_node);
1600 if (TREE_CODE (textlength) == COMPONENT_REF)
1601 /* FIXME: we cannot use one and the same COMPONENT_REF twice, so build
1602 another one */
1603 savedlength = build_component_ref (TREE_OPERAND (textlength, 0),
1604 TREE_OPERAND (textlength, 1));
1605 DECL_INITIAL (decl) = savedlength;
1606 chainon (listbase, decl);
1607 /* save dynamic */
1608 decl = build_decl (CONST_DECL, get_identifier ("__dynamic"),
1609 integer_type_node);
1610 DECL_INITIAL (decl) = dynamic ? integer_one_node : integer_zero_node;
1611 chainon (listbase, decl);
1612 CH_IS_TEXT_MODE (type) = 1;
1613 CH_TYPE_NONVALUE_P (type) = 1;
1614 return type;
1615 }
1616
1617 tree
1618 check_text_length (length)
1619 tree length;
1620 {
1621 if (length == NULL_TREE || TREE_CODE (length) == ERROR_MARK)
1622 return length;
1623 if (TREE_TYPE (length) == NULL_TREE
1624 || !CH_SIMILAR (TREE_TYPE (length), integer_type_node))
1625 {
1626 error ("non-integral text length");
1627 return integer_one_node;
1628 }
1629 if (TREE_CODE (length) != INTEGER_CST)
1630 {
1631 error ("non-constant text length");
1632 return integer_one_node;
1633 }
1634 if (compare_int_csts (LE_EXPR, length, integer_zero_node))
1635 {
1636 error ("text length must be greater then 0");
1637 return integer_one_node;
1638 }
1639 return length;
1640 }
1641
1642 tree
1643 text_indexmode (text)
1644 tree text;
1645 {
1646 tree field;
1647
1648 if (text == NULL_TREE || TREE_CODE (text) == ERROR_MARK)
1649 return NULL_TREE;
1650 if (! CH_IS_TEXT_MODE (text))
1651 return NULL_TREE;
1652
1653 field = TYPE_FIELDS (text);
1654 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1655 {
1656 if (TREE_CODE (field) == TYPE_DECL)
1657 return TREE_TYPE (field);
1658 }
1659 return void_type_node;
1660 }
1661
1662 tree
1663 text_dynamic (text)
1664 tree text;
1665 {
1666 tree field;
1667
1668 if (text == NULL_TREE || TREE_CODE (text) == ERROR_MARK)
1669 return NULL_TREE;
1670 if (! CH_IS_TEXT_MODE (text))
1671 return NULL_TREE;
1672
1673 field = TYPE_FIELDS (text);
1674 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1675 {
1676 if (TREE_CODE (field) == CONST_DECL &&
1677 DECL_NAME (field) == get_identifier ("__dynamic"))
1678 return DECL_INITIAL (field);
1679 }
1680 return integer_zero_node;
1681 }
1682
1683 tree
1684 text_length (text)
1685 tree text;
1686 {
1687 tree field;
1688
1689 if (text == NULL_TREE || TREE_CODE (text) == ERROR_MARK)
1690 return NULL_TREE;
1691 if (! CH_IS_TEXT_MODE (text))
1692 return NULL_TREE;
1693
1694 field = TYPE_FIELDS (text);
1695 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1696 {
1697 if (TREE_CODE (field) == CONST_DECL &&
1698 DECL_NAME (field) == get_identifier ("__textlength"))
1699 return DECL_INITIAL (field);
1700 }
1701 return integer_zero_node;
1702 }
1703
1704 static tree
1705 textlocation_mode (text)
1706 tree text;
1707 {
1708 tree field;
1709
1710 if (text == NULL_TREE || TREE_CODE (text) == ERROR_MARK)
1711 return NULL_TREE;
1712 if (! CH_IS_TEXT_MODE (text))
1713 return NULL_TREE;
1714
1715 field = TYPE_FIELDS (text);
1716 for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
1717 {
1718 if (TREE_CODE (field) == FIELD_DECL &&
1719 DECL_NAME (field) == get_identifier ("tloc"))
1720 return TREE_TYPE (field);
1721 }
1722 return NULL_TREE;
1723 }
1724 \f
1725 static int
1726 check_assoc (assoc, argnum, errmsg)
1727 tree assoc;
1728 int argnum;
1729 char *errmsg;
1730 {
1731 if (assoc == NULL_TREE || TREE_CODE (assoc) == ERROR_MARK)
1732 return 0;
1733
1734 if (! CH_IS_ASSOCIATION_MODE (TREE_TYPE (assoc)))
1735 {
1736 error ("argument %d of %s must be of mode ASSOCIATION", argnum, errmsg);
1737 return 0;
1738 }
1739 if (! CH_LOCATION_P (assoc))
1740 {
1741 error ("argument %d of %s must be a location", argnum, errmsg);
1742 return 0;
1743 }
1744 return 1;
1745 }
1746
1747 tree
1748 build_chill_associate (assoc, fname, attr)
1749 tree assoc;
1750 tree fname;
1751 tree attr;
1752 {
1753 tree arg1 = NULL_TREE, arg2 = NULL_TREE, arg3 = NULL_TREE, arg4 = NULL_TREE,
1754 arg5 = NULL_TREE, arg6, arg7;
1755 int had_errors = 0;
1756 tree result;
1757
1758 /* make some checks */
1759 if (fname == NULL_TREE || TREE_CODE (fname) == ERROR_MARK)
1760 return error_mark_node;
1761
1762 /* check the association */
1763 if (! check_assoc (assoc, 1, "ASSOCIATION"))
1764 had_errors = 1;
1765 else
1766 /* build a pointer to the association */
1767 arg1 = force_addr_of (assoc);
1768
1769 /* check the filename, must be a string */
1770 if (CH_CHARS_TYPE_P (TREE_TYPE (fname)) ||
1771 (flag_old_strings && TREE_CODE (fname) == INTEGER_CST &&
1772 TREE_CODE (TREE_TYPE (fname)) == CHAR_TYPE))
1773 {
1774 if (int_size_in_bytes (TREE_TYPE (fname)) == 0)
1775 {
1776 error ("argument 2 of ASSOCIATE must not be an empty string");
1777 had_errors = 1;
1778 }
1779 else
1780 {
1781 arg2 = force_addr_of (fname);
1782 arg3 = size_in_bytes (TREE_TYPE (fname));
1783 }
1784 }
1785 else if (chill_varying_string_type_p (TREE_TYPE (fname)))
1786 {
1787 arg2 = force_addr_of (build_component_ref (fname, var_data_id));
1788 arg3 = build_component_ref (fname, var_length_id);
1789 }
1790 else
1791 {
1792 error ("argument 2 to ASSOCIATE must be a string");
1793 had_errors = 1;
1794 }
1795
1796 /* check attr argument, must be a string too */
1797 if (attr == NULL_TREE)
1798 {
1799 arg4 = null_pointer_node;
1800 arg5 = integer_zero_node;
1801 }
1802 else
1803 {
1804 attr = TREE_VALUE (attr);
1805 if (attr == NULL_TREE || TREE_CODE (attr) == ERROR_MARK)
1806 had_errors = 1;
1807 else
1808 {
1809 if (CH_CHARS_TYPE_P (TREE_TYPE (attr)) ||
1810 (flag_old_strings && TREE_CODE (attr) == INTEGER_CST &&
1811 TREE_CODE (TREE_TYPE (attr)) == CHAR_TYPE))
1812 {
1813 if (int_size_in_bytes (TREE_TYPE (attr)) == 0)
1814 {
1815 arg4 = null_pointer_node;
1816 arg5 = integer_zero_node;
1817 }
1818 else
1819 {
1820 arg4 = force_addr_of (attr);
1821 arg5 = size_in_bytes (TREE_TYPE (attr));
1822 }
1823 }
1824 else if (chill_varying_string_type_p (TREE_TYPE (attr)))
1825 {
1826 arg4 = force_addr_of (build_component_ref (attr, var_data_id));
1827 arg5 = build_component_ref (attr, var_length_id);
1828 }
1829 else
1830 {
1831 error ("argument 3 to ASSOCIATE must be a string");
1832 had_errors = 1;
1833 }
1834 }
1835 }
1836
1837 if (had_errors)
1838 return error_mark_node;
1839
1840 /* other arguments */
1841 arg6 = force_addr_of (get_chill_filename ());
1842 arg7 = get_chill_linenumber ();
1843
1844 result = build_chill_function_call (
1845 lookup_name (get_identifier ("__associate")),
1846 tree_cons (NULL_TREE, arg1,
1847 tree_cons (NULL_TREE, arg2,
1848 tree_cons (NULL_TREE, arg3,
1849 tree_cons (NULL_TREE, arg4,
1850 tree_cons (NULL_TREE, arg5,
1851 tree_cons (NULL_TREE, arg6,
1852 tree_cons (NULL_TREE, arg7, NULL_TREE))))))));
1853
1854 TREE_TYPE (result) = build_chill_pointer_type (TREE_TYPE (assoc));
1855 return result;
1856 }
1857
1858 static tree
1859 assoc_call (assoc, func, name)
1860 tree assoc;
1861 tree func;
1862 char *name;
1863 {
1864 tree arg1, arg2, arg3;
1865 tree result;
1866
1867 if (! check_assoc (assoc, 1, name))
1868 return error_mark_node;
1869
1870 arg1 = force_addr_of (assoc);
1871 arg2 = force_addr_of (get_chill_filename ());
1872 arg3 = get_chill_linenumber ();
1873
1874 result = build_chill_function_call (func,
1875 tree_cons (NULL_TREE, arg1,
1876 tree_cons (NULL_TREE, arg2,
1877 tree_cons (NULL_TREE, arg3, NULL_TREE))));
1878 return result;
1879 }
1880
1881 tree
1882 build_chill_isassociated (assoc)
1883 tree assoc;
1884 {
1885 tree result = assoc_call (assoc,
1886 lookup_name (get_identifier ("__isassociated")),
1887 "ISASSOCIATED");
1888 return result;
1889 }
1890
1891 tree
1892 build_chill_existing (assoc)
1893 tree assoc;
1894 {
1895 tree result = assoc_call (assoc,
1896 lookup_name (get_identifier ("__existing")),
1897 "EXISTING");
1898 return result;
1899 }
1900
1901 tree
1902 build_chill_readable (assoc)
1903 tree assoc;
1904 {
1905 tree result = assoc_call (assoc,
1906 lookup_name (get_identifier ("__readable")),
1907 "READABLE");
1908 return result;
1909 }
1910
1911 tree
1912 build_chill_writeable (assoc)
1913 tree assoc;
1914 {
1915 tree result = assoc_call (assoc,
1916 lookup_name (get_identifier ("__writeable")),
1917 "WRITEABLE");
1918 return result;
1919 }
1920
1921 tree
1922 build_chill_sequencible (assoc)
1923 tree assoc;
1924 {
1925 tree result = assoc_call (assoc,
1926 lookup_name (get_identifier ("__sequencible")),
1927 "SEQUENCIBLE");
1928 return result;
1929 }
1930
1931 tree
1932 build_chill_variable (assoc)
1933 tree assoc;
1934 {
1935 tree result = assoc_call (assoc,
1936 lookup_name (get_identifier ("__variable")),
1937 "VARIABLE");
1938 return result;
1939 }
1940
1941 tree
1942 build_chill_indexable (assoc)
1943 tree assoc;
1944 {
1945 tree result = assoc_call (assoc,
1946 lookup_name (get_identifier ("__indexable")),
1947 "INDEXABLE");
1948 return result;
1949 }
1950
1951 tree
1952 build_chill_dissociate (assoc)
1953 tree assoc;
1954 {
1955 tree result = assoc_call (assoc,
1956 lookup_name (get_identifier ("__dissociate")),
1957 "DISSOCIATE");
1958 return result;
1959 }
1960
1961 tree
1962 build_chill_create (assoc)
1963 tree assoc;
1964 {
1965 tree result = assoc_call (assoc,
1966 lookup_name (get_identifier ("__create")),
1967 "CREATE");
1968 return result;
1969 }
1970
1971 tree
1972 build_chill_delete (assoc)
1973 tree assoc;
1974 {
1975 tree result = assoc_call (assoc,
1976 lookup_name (get_identifier ("__delete")),
1977 "DELETE");
1978 return result;
1979 }
1980
1981 tree
1982 build_chill_modify (assoc, list)
1983 tree assoc;
1984 tree list;
1985 {
1986 tree arg1 = NULL_TREE, arg2 = NULL_TREE, arg3 = NULL_TREE, arg4 = NULL_TREE,
1987 arg5 = NULL_TREE, arg6, arg7;
1988 int had_errors = 0, numargs;
1989 tree fname = NULL_TREE, attr = NULL_TREE;
1990 tree result;
1991
1992 /* check the association */
1993 if (! check_assoc (assoc, 1, "MODIFY"))
1994 had_errors = 1;
1995 else
1996 arg1 = force_addr_of (assoc);
1997
1998 /* look how much arguments we have got */
1999 numargs = list_length (list);
2000 switch (numargs)
2001 {
2002 case 0:
2003 break;
2004 case 1:
2005 fname = TREE_VALUE (list);
2006 break;
2007 case 2:
2008 fname = TREE_VALUE (list);
2009 attr = TREE_VALUE (TREE_CHAIN (list));
2010 break;
2011 default:
2012 error ("Too many arguments in call to MODIFY");
2013 had_errors = 1;
2014 break;
2015 }
2016
2017 if (fname != NULL_TREE && fname != null_pointer_node)
2018 {
2019 if (CH_CHARS_TYPE_P (TREE_TYPE (fname)) ||
2020 (flag_old_strings && TREE_CODE (fname) == INTEGER_CST &&
2021 TREE_CODE (TREE_TYPE (fname)) == CHAR_TYPE))
2022 {
2023 if (int_size_in_bytes (TREE_TYPE (fname)) == 0)
2024 {
2025 error ("argument 2 of MODIFY must not be an empty string");
2026 had_errors = 1;
2027 }
2028 else
2029 {
2030 arg2 = force_addr_of (fname);
2031 arg3 = size_in_bytes (TREE_TYPE (fname));
2032 }
2033 }
2034 else if (chill_varying_string_type_p (TREE_TYPE (fname)))
2035 {
2036 arg2 = force_addr_of (build_component_ref (fname, var_data_id));
2037 arg3 = build_component_ref (fname, var_length_id);
2038 }
2039 else
2040 {
2041 error ("argument 2 to MODIFY must be a string");
2042 had_errors = 1;
2043 }
2044 }
2045 else
2046 {
2047 arg2 = null_pointer_node;
2048 arg3 = integer_zero_node;
2049 }
2050
2051 if (attr != NULL_TREE && attr != null_pointer_node)
2052 {
2053 if (CH_CHARS_TYPE_P (TREE_TYPE (attr)) ||
2054 (flag_old_strings && TREE_CODE (attr) == INTEGER_CST &&
2055 TREE_CODE (TREE_TYPE (attr)) == CHAR_TYPE))
2056 {
2057 if (int_size_in_bytes (TREE_TYPE (attr)) == 0)
2058 {
2059 arg4 = null_pointer_node;
2060 arg5 = integer_zero_node;
2061 }
2062 else
2063 {
2064 arg4 = force_addr_of (attr);
2065 arg5 = size_in_bytes (TREE_TYPE (attr));
2066 }
2067 }
2068 else if (chill_varying_string_type_p (TREE_TYPE (attr)))
2069 {
2070 arg4 = force_addr_of (build_component_ref (attr, var_data_id));
2071 arg5 = build_component_ref (attr, var_length_id);
2072 }
2073 else
2074 {
2075 error ("argument 3 to MODIFY must be a string");
2076 had_errors = 1;
2077 }
2078 }
2079 else
2080 {
2081 arg4 = null_pointer_node;
2082 arg5 = integer_zero_node;
2083 }
2084
2085 if (had_errors)
2086 return error_mark_node;
2087
2088 /* other arguments */
2089 arg6 = force_addr_of (get_chill_filename ());
2090 arg7 = get_chill_linenumber ();
2091
2092 result = build_chill_function_call (
2093 lookup_name (get_identifier ("__modify")),
2094 tree_cons (NULL_TREE, arg1,
2095 tree_cons (NULL_TREE, arg2,
2096 tree_cons (NULL_TREE, arg3,
2097 tree_cons (NULL_TREE, arg4,
2098 tree_cons (NULL_TREE, arg5,
2099 tree_cons (NULL_TREE, arg6,
2100 tree_cons (NULL_TREE, arg7, NULL_TREE))))))));
2101
2102 return result;
2103 }
2104 \f
2105 static int
2106 check_transfer (transfer, argnum, errmsg)
2107 tree transfer;
2108 int argnum;
2109 char *errmsg;
2110 {
2111 int result = 0;
2112
2113 if (transfer == NULL_TREE || TREE_CODE (transfer) == ERROR_MARK)
2114 return 0;
2115
2116 if (CH_IS_ACCESS_MODE (TREE_TYPE (transfer)))
2117 result = 1;
2118 else if (CH_IS_TEXT_MODE (TREE_TYPE (transfer)))
2119 result = 2;
2120 else
2121 {
2122 error ("argument %d of %s must be an ACCESS or TEXT mode", argnum, errmsg);
2123 return 0;
2124 }
2125 if (! CH_LOCATION_P (transfer))
2126 {
2127 error ("argument %d of %s must be a location", argnum, errmsg);
2128 return 0;
2129 }
2130 return result;
2131 }
2132
2133 /* define bits in an access/text flag word.
2134 NOTE: this must be consistent with runtime/iomodes.h */
2135 #define IO_TEXTLOCATION 0x80000000
2136 #define IO_INDEXED 0x00000001
2137 #define IO_TEXTIO 0x00000002
2138 #define IO_OUTOFFILE 0x00010000
2139 \f
2140 /* generated initialisation code for ACCESS and TEXT.
2141 functions gets called from do_decl. */
2142 void init_access_location (decl, type)
2143 tree decl;
2144 tree type;
2145 {
2146 tree recordmode = access_recordmode (type);
2147 tree indexmode = access_indexmode (type);
2148 int flags_init = 0;
2149 tree data = build_component_ref (decl, get_identifier ("data"));
2150 tree lowindex = integer_zero_node;
2151 tree highindex = integer_zero_node;
2152 tree rectype, reclen;
2153
2154 /* flag word */
2155 if (indexmode != NULL_TREE && indexmode != void_type_node)
2156 {
2157 flags_init |= IO_INDEXED;
2158 lowindex = convert (integer_type_node, TYPE_MIN_VALUE (indexmode));
2159 highindex = convert (integer_type_node, TYPE_MAX_VALUE (indexmode));
2160 }
2161
2162 expand_expr_stmt (
2163 build_chill_modify_expr (
2164 build_component_ref (data, get_identifier ("flags")),
2165 build_int_2 (flags_init, 0)));
2166
2167 /* record length */
2168 if (recordmode == NULL_TREE || recordmode == void_type_node)
2169 {
2170 reclen = integer_zero_node;
2171 rectype = integer_zero_node;
2172 }
2173 else if (chill_varying_string_type_p (recordmode))
2174 {
2175 tree fields = TYPE_FIELDS (recordmode);
2176 tree len1, len2;
2177
2178 /* don't count any padding bytes at end of varying */
2179 len1 = size_in_bytes (TREE_TYPE (fields));
2180 fields = TREE_CHAIN (fields);
2181 len2 = size_in_bytes (TREE_TYPE (fields));
2182 reclen = fold (build (PLUS_EXPR, long_integer_type_node, len1, len2));
2183 rectype = build_int_2 (2, 0);
2184 }
2185 else
2186 {
2187 reclen = size_in_bytes (recordmode);
2188 rectype = integer_one_node;
2189 }
2190 expand_expr_stmt (
2191 build_chill_modify_expr (
2192 build_component_ref (data, get_identifier ("reclength")), reclen));
2193
2194 /* record type */
2195 expand_expr_stmt (
2196 build_chill_modify_expr (
2197 build_component_ref (data, get_identifier ("rectype")), rectype));
2198
2199 /* the index */
2200 expand_expr_stmt (
2201 build_chill_modify_expr (
2202 build_component_ref (data, get_identifier ("lowindex")), lowindex));
2203 expand_expr_stmt (
2204 build_chill_modify_expr (
2205 build_component_ref (data, get_identifier ("highindex")), highindex));
2206
2207 /* association */
2208 expand_expr_stmt (
2209 build_chill_modify_expr (
2210 build_chill_component_ref (data, get_identifier ("association")),
2211 null_pointer_node));
2212
2213 /* storelocptr */
2214 expand_expr_stmt (
2215 build_chill_modify_expr (
2216 build_component_ref (data, get_identifier ("storelocptr")), null_pointer_node));
2217 }
2218
2219 void init_text_location (decl, type)
2220 tree decl;
2221 tree type;
2222 {
2223 tree indexmode = text_indexmode (type);
2224 unsigned long accessflags = 0;
2225 unsigned long textflags = IO_TEXTLOCATION;
2226 tree lowindex = integer_zero_node;
2227 tree highindex = integer_zero_node;
2228 tree data, tloc, tlocfields, len1, len2, reclen;
2229
2230 if (indexmode != NULL_TREE && indexmode != void_type_node)
2231 {
2232 accessflags |= IO_INDEXED;
2233 lowindex = convert (integer_type_node, TYPE_MIN_VALUE (indexmode));
2234 highindex = convert (integer_type_node, TYPE_MAX_VALUE (indexmode));
2235 }
2236
2237 tloc = build_component_ref (decl, get_identifier ("tloc"));
2238 /* fill access part of text location */
2239 data = build_component_ref (decl, get_identifier ("acc"));
2240 /* flag word */
2241 expand_expr_stmt (
2242 build_chill_modify_expr (
2243 build_component_ref (data, get_identifier ("flags")),
2244 build_int_2 (accessflags, 0)));
2245
2246 /* record length, don't count any padding bytes at end of varying */
2247 tlocfields = TYPE_FIELDS (TREE_TYPE (tloc));
2248 len1 = size_in_bytes (TREE_TYPE (tlocfields));
2249 tlocfields = TREE_CHAIN (tlocfields);
2250 len2 = size_in_bytes (TREE_TYPE (tlocfields));
2251 reclen = fold (build (PLUS_EXPR, long_integer_type_node, len1, len2));
2252 expand_expr_stmt (
2253 build_chill_modify_expr (
2254 build_component_ref (data, get_identifier ("reclength")),
2255 reclen));
2256
2257 /* the index */
2258 expand_expr_stmt (
2259 build_chill_modify_expr (
2260 build_component_ref (data, get_identifier ("lowindex")), lowindex));
2261 expand_expr_stmt (
2262 build_chill_modify_expr (
2263 build_component_ref (data, get_identifier ("highindex")), highindex));
2264
2265 /* association */
2266 expand_expr_stmt (
2267 build_chill_modify_expr (
2268 build_chill_component_ref (data, get_identifier ("association")),
2269 null_pointer_node));
2270
2271 /* storelocptr */
2272 expand_expr_stmt (
2273 build_chill_modify_expr (
2274 build_component_ref (data, get_identifier ("storelocptr")),
2275 null_pointer_node));
2276
2277 /* record type */
2278 expand_expr_stmt (
2279 build_chill_modify_expr (
2280 build_component_ref (data, get_identifier ("rectype")),
2281 build_int_2 (2, 0))); /* VaryingChars */
2282
2283 /* fill text part */
2284 data = build_component_ref (decl, get_identifier ("txt"));
2285 /* flag word */
2286 expand_expr_stmt (
2287 build_chill_modify_expr (
2288 build_component_ref (data, get_identifier ("flags")),
2289 build_int_2 (textflags, 0)));
2290
2291 /* pointer to text record */
2292 expand_expr_stmt (
2293 build_chill_modify_expr (
2294 build_component_ref (data, get_identifier ("text_record")),
2295 force_addr_of (tloc)));
2296
2297 /* pointer to the access */
2298 expand_expr_stmt (
2299 build_chill_modify_expr (
2300 build_component_ref (data, get_identifier ("access_sub")),
2301 force_addr_of (build_component_ref (decl, get_identifier ("acc")))));
2302
2303 /* actual length */
2304 expand_expr_stmt (
2305 build_chill_modify_expr (
2306 build_component_ref (data, get_identifier ("actual_index")),
2307 integer_zero_node));
2308
2309 /* length of text record */
2310 expand_expr_stmt (
2311 build_chill_modify_expr (
2312 build_component_ref (tloc, get_identifier (VAR_LENGTH)),
2313 integer_zero_node));
2314 }
2315 \f
2316 static int
2317 connect_process_optionals (optionals, whereptr, indexptr, indexmode)
2318 tree optionals;
2319 tree *whereptr;
2320 tree *indexptr;
2321 tree indexmode;
2322 {
2323 tree where = NULL_TREE, theindex = NULL_TREE;
2324 int had_errors = 0;
2325
2326 if (optionals != NULL_TREE)
2327 {
2328 /* get the where expression */
2329 where = TREE_VALUE (optionals);
2330 if (where == NULL_TREE || TREE_CODE (where) == ERROR_MARK)
2331 had_errors = 1;
2332 else
2333 {
2334 if (! CH_IS_WHERE_MODE (TREE_TYPE (where)))
2335 {
2336 error ("argument 4 of CONNECT must be of mode WHERE");
2337 had_errors = 1;
2338 }
2339 where = convert (integer_type_node, where);
2340 }
2341 optionals = TREE_CHAIN (optionals);
2342 }
2343 if (optionals != NULL_TREE)
2344 {
2345 theindex = TREE_VALUE (optionals);
2346 if (theindex == NULL_TREE || TREE_CODE (theindex) == ERROR_MARK)
2347 had_errors = 1;
2348 else
2349 {
2350 if (indexmode == void_type_node)
2351 {
2352 error ("index expression for ACCESS without index");
2353 had_errors = 1;
2354 }
2355 else if (! CH_COMPATIBLE (theindex, indexmode))
2356 {
2357 error ("incompatible index mode");
2358 had_errors = 1;
2359 }
2360 }
2361 }
2362 if (had_errors)
2363 return 0;
2364
2365 *whereptr = where;
2366 *indexptr = theindex;
2367 return 1;
2368 }
2369
2370 static tree
2371 connect_text (assoc, text, usage, optionals)
2372 tree assoc;
2373 tree text;
2374 tree usage;
2375 tree optionals;
2376 {
2377 tree where = NULL_TREE, theindex = NULL_TREE;
2378 tree indexmode = text_indexmode (TREE_TYPE (text));
2379 tree result, what_where, have_index, what_index;
2380
2381 /* process optionals */
2382 if (!connect_process_optionals (optionals, &where, &theindex, indexmode))
2383 return error_mark_node;
2384
2385 what_where = where == NULL_TREE ? integer_zero_node : where;
2386 have_index = theindex == NULL_TREE ? integer_zero_node
2387 : integer_one_node;
2388 what_index = theindex == NULL_TREE ? integer_zero_node
2389 : convert (integer_type_node, theindex);
2390 result = build_chill_function_call (
2391 lookup_name (get_identifier ("__connect")),
2392 tree_cons (NULL_TREE, force_addr_of (text),
2393 tree_cons (NULL_TREE, force_addr_of (assoc),
2394 tree_cons (NULL_TREE, convert (integer_type_node, usage),
2395 tree_cons (NULL_TREE, what_where,
2396 tree_cons (NULL_TREE, have_index,
2397 tree_cons (NULL_TREE, what_index,
2398 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2399 tree_cons (NULL_TREE, get_chill_linenumber (),
2400 NULL_TREE)))))))));
2401 return result;
2402 }
2403
2404 static tree
2405 connect_access (assoc, transfer, usage, optionals)
2406 tree assoc;
2407 tree transfer;
2408 tree usage;
2409 tree optionals;
2410 {
2411 tree where = NULL_TREE, theindex = NULL_TREE;
2412 tree indexmode = access_indexmode (TREE_TYPE (transfer));
2413 tree result, what_where, have_index, what_index;
2414
2415 /* process the optionals */
2416 if (! connect_process_optionals (optionals, &where, &theindex, indexmode))
2417 return error_mark_node;
2418
2419 /* now the call */
2420 what_where = where == NULL_TREE ? integer_zero_node : where;
2421 have_index = theindex == NULL_TREE ? integer_zero_node : integer_one_node;
2422 what_index = theindex == NULL_TREE ? integer_zero_node : convert (integer_type_node, theindex);
2423 result = build_chill_function_call (
2424 lookup_name (get_identifier ("__connect")),
2425 tree_cons (NULL_TREE, force_addr_of (transfer),
2426 tree_cons (NULL_TREE, force_addr_of (assoc),
2427 tree_cons (NULL_TREE, convert (integer_type_node, usage),
2428 tree_cons (NULL_TREE, what_where,
2429 tree_cons (NULL_TREE, have_index,
2430 tree_cons (NULL_TREE, what_index,
2431 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2432 tree_cons (NULL_TREE, get_chill_linenumber (),
2433 NULL_TREE)))))))));
2434 return result;
2435 }
2436
2437 tree
2438 build_chill_connect (transfer, assoc, usage, optionals)
2439 tree transfer;
2440 tree assoc;
2441 tree usage;
2442 tree optionals;
2443 {
2444 int had_errors = 0;
2445 int what = 0;
2446 tree result = error_mark_node;
2447
2448 if (! check_assoc (assoc, 2, "CONNECT"))
2449 had_errors = 1;
2450
2451 /* check usage */
2452 if (usage == NULL_TREE || TREE_CODE (usage) == ERROR_MARK)
2453 return error_mark_node;
2454
2455 if (! CH_IS_USAGE_MODE (TREE_TYPE (usage)))
2456 {
2457 error ("argument 3 to CONNECT must be of mode USAGE");
2458 had_errors = 1;
2459 }
2460 if (had_errors)
2461 return error_mark_node;
2462
2463 /* look what we have got */
2464 what = check_transfer (transfer, 1, "CONNECT");
2465 switch (what)
2466 {
2467 case 1:
2468 /* we have an ACCESS */
2469 result = connect_access (assoc, transfer, usage, optionals);
2470 break;
2471 case 2:
2472 /* we have a TEXT */
2473 result = connect_text (assoc, transfer, usage, optionals);
2474 break;
2475 default:
2476 result = error_mark_node;
2477 }
2478 return result;
2479 }
2480
2481 static int
2482 check_access (access, argnum, errmsg)
2483 tree access;
2484 int argnum;
2485 char *errmsg;
2486 {
2487 if (access == NULL_TREE || TREE_CODE (access) == ERROR_MARK)
2488 return 1;
2489
2490 if (! CH_IS_ACCESS_MODE (TREE_TYPE (access)))
2491 {
2492 error ("argument %d of %s must be of mode ACCESS", argnum, errmsg);
2493 return 0;
2494 }
2495 if (! CH_LOCATION_P (access))
2496 {
2497 error ("argument %d of %s must be a location", argnum, errmsg);
2498 return 0;
2499 }
2500 return 1;
2501 }
2502
2503 tree
2504 build_chill_readrecord (access, optionals)
2505 tree access;
2506 tree optionals;
2507 {
2508 int len;
2509 tree recordmode, indexmode, dynamic, result;
2510 tree index = NULL_TREE, location = NULL_TREE;
2511
2512 if (! check_access (access, 1, "READRECORD"))
2513 return error_mark_node;
2514
2515 recordmode = access_recordmode (TREE_TYPE (access));
2516 indexmode = access_indexmode (TREE_TYPE (access));
2517 dynamic = access_dynamic (TREE_TYPE (access));
2518
2519 /* process the optionals */
2520 len = list_length (optionals);
2521 if (indexmode != void_type_node)
2522 {
2523 /* we must have an index */
2524 if (!len)
2525 {
2526 error ("Too few arguments in call to `readrecord'");
2527 return error_mark_node;
2528 }
2529 index = TREE_VALUE (optionals);
2530 if (index == NULL_TREE || TREE_CODE (index) == ERROR_MARK)
2531 return error_mark_node;
2532 optionals = TREE_CHAIN (optionals);
2533 if (! CH_COMPATIBLE (index, indexmode))
2534 {
2535 error ("incompatible index mode");
2536 return error_mark_node;
2537 }
2538 }
2539
2540 /* check the record mode, if one */
2541 if (optionals != NULL_TREE)
2542 {
2543 location = TREE_VALUE (optionals);
2544 if (location == NULL_TREE || TREE_CODE (location) == ERROR_MARK)
2545 return error_mark_node;
2546 if (recordmode != void_type_node &&
2547 ! CH_COMPATIBLE (location, recordmode))
2548 {
2549
2550 error ("incompatible record mode");
2551 return error_mark_node;
2552 }
2553 if (TYPE_READONLY_PROPERTY (TREE_TYPE (location)))
2554 {
2555 error ("store location must not be READonly");
2556 return error_mark_node;
2557 }
2558 location = force_addr_of (location);
2559 }
2560 else
2561 location = null_pointer_node;
2562
2563 index = index == NULL_TREE ? integer_zero_node : convert (integer_type_node, index);
2564 result = build_chill_function_call (
2565 lookup_name (get_identifier ("__readrecord")),
2566 tree_cons (NULL_TREE, force_addr_of (access),
2567 tree_cons (NULL_TREE, index,
2568 tree_cons (NULL_TREE, location,
2569 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2570 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))))));
2571
2572 TREE_TYPE (result) = build_chill_pointer_type (recordmode);
2573 return result;
2574 }
2575
2576 tree
2577 build_chill_writerecord (access, optionals)
2578 tree access;
2579 tree optionals;
2580 {
2581 int had_errors = 0, len;
2582 tree recordmode, indexmode, dynamic;
2583 tree index = NULL_TREE, location = NULL_TREE;
2584 tree result;
2585
2586 if (! check_access (access, 1, "WRITERECORD"))
2587 return error_mark_node;
2588
2589 recordmode = access_recordmode (TREE_TYPE (access));
2590 indexmode = access_indexmode (TREE_TYPE (access));
2591 dynamic = access_dynamic (TREE_TYPE (access));
2592
2593 /* process the optionals */
2594 len = list_length (optionals);
2595 if (indexmode != void_type_node && len != 2)
2596 {
2597 error ("Too few arguments in call to `writerecord'");
2598 return error_mark_node;
2599 }
2600 if (indexmode != void_type_node)
2601 {
2602 index = TREE_VALUE (optionals);
2603 if (index == NULL_TREE || TREE_CODE (index) == ERROR_MARK)
2604 return error_mark_node;
2605 location = TREE_VALUE (TREE_CHAIN (optionals));
2606 if (location == NULL_TREE || TREE_CODE (location) == ERROR_MARK)
2607 return error_mark_node;
2608 }
2609 else
2610 location = TREE_VALUE (optionals);
2611
2612 /* check the index */
2613 if (indexmode != void_type_node)
2614 {
2615 if (! CH_COMPATIBLE (index, indexmode))
2616 {
2617 error ("incompatible index mode");
2618 had_errors = 1;
2619 }
2620 }
2621 /* check the record mode */
2622 if (recordmode == void_type_node)
2623 {
2624 error ("transfer to ACCESS without record mode");
2625 had_errors = 1;
2626 }
2627 else if (! CH_COMPATIBLE (location, recordmode))
2628 {
2629 error ("incompatible record mode");
2630 had_errors = 1;
2631 }
2632 if (had_errors)
2633 return error_mark_node;
2634
2635 index = index == NULL_TREE ? integer_zero_node : convert (integer_type_node, index);
2636
2637 result = build_chill_function_call (
2638 lookup_name (get_identifier ("__writerecord")),
2639 tree_cons (NULL_TREE, force_addr_of (access),
2640 tree_cons (NULL_TREE, index,
2641 tree_cons (NULL_TREE, force_addr_of (location),
2642 tree_cons (NULL_TREE, size_in_bytes (TREE_TYPE (location)),
2643 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2644 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE)))))));
2645 return result;
2646 }
2647
2648 tree
2649 build_chill_disconnect (transfer)
2650 tree transfer;
2651 {
2652 tree result;
2653
2654 if (! check_transfer (transfer, 1, "DISCONNECT"))
2655 return error_mark_node;
2656 result = build_chill_function_call (
2657 lookup_name (get_identifier ("__disconnect")),
2658 tree_cons (NULL_TREE, force_addr_of (transfer),
2659 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2660 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2661 return result;
2662 }
2663
2664 tree
2665 build_chill_getassociation (transfer)
2666 tree transfer;
2667 {
2668 tree result;
2669
2670 if (! check_transfer (transfer, 1, "GETASSOCIATION"))
2671 return error_mark_node;
2672
2673 result = build_chill_function_call (
2674 lookup_name (get_identifier ("__getassociation")),
2675 tree_cons (NULL_TREE, force_addr_of (transfer),
2676 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2677 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2678 TREE_TYPE (result) = build_chill_pointer_type (association_type_node);
2679 return result;
2680 }
2681
2682 tree
2683 build_chill_getusage (transfer)
2684 tree transfer;
2685 {
2686 tree result;
2687
2688 if (! check_transfer (transfer, 1, "GETUSAGE"))
2689 return error_mark_node;
2690
2691 result = build_chill_function_call (
2692 lookup_name (get_identifier ("__getusage")),
2693 tree_cons (NULL_TREE, force_addr_of (transfer),
2694 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2695 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2696 TREE_TYPE (result) = usage_type_node;
2697 return result;
2698 }
2699
2700 tree
2701 build_chill_outoffile (transfer)
2702 tree transfer;
2703 {
2704 tree result;
2705
2706 if (! check_transfer (transfer, 1, "OUTOFFILE"))
2707 return error_mark_node;
2708
2709 result = build_chill_function_call (
2710 lookup_name (get_identifier ("__outoffile")),
2711 tree_cons (NULL_TREE, force_addr_of (transfer),
2712 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2713 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2714 return result;
2715 }
2716 \f
2717 static int
2718 check_text (text, argnum, errmsg)
2719 tree text;
2720 int argnum;
2721 char *errmsg;
2722 {
2723 if (text == NULL_TREE || TREE_CODE (text) == ERROR_MARK)
2724 return 0;
2725 if (! CH_IS_TEXT_MODE (TREE_TYPE (text)))
2726 {
2727 error ("argument %d of %s must be of mode TEXT", argnum, errmsg);
2728 return 0;
2729 }
2730 if (! CH_LOCATION_P (text))
2731 {
2732 error ("argument %d of %s must be a location", argnum, errmsg);
2733 return 0;
2734 }
2735 return 1;
2736 }
2737
2738 tree
2739 build_chill_eoln (text)
2740 tree text;
2741 {
2742 tree result;
2743
2744 if (! check_text (text, 1, "EOLN"))
2745 return error_mark_node;
2746
2747 result = build_chill_function_call (
2748 lookup_name (get_identifier ("__eoln")),
2749 tree_cons (NULL_TREE, force_addr_of (text),
2750 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2751 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2752 return result;
2753 }
2754
2755 tree
2756 build_chill_gettextindex (text)
2757 tree text;
2758 {
2759 tree result;
2760
2761 if (! check_text (text, 1, "GETTEXTINDEX"))
2762 return error_mark_node;
2763
2764 result = build_chill_function_call (
2765 lookup_name (get_identifier ("__gettextindex")),
2766 tree_cons (NULL_TREE, force_addr_of (text),
2767 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2768 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2769 return result;
2770 }
2771
2772 tree
2773 build_chill_gettextrecord (text)
2774 tree text;
2775 {
2776 tree textmode, result;
2777
2778 if (! check_text (text, 1, "GETTEXTRECORD"))
2779 return error_mark_node;
2780
2781 textmode = textlocation_mode (TREE_TYPE (text));
2782 if (textmode == NULL_TREE)
2783 {
2784 error ("TEXT doesn't have a location"); /* FIXME */
2785 return error_mark_node;
2786 }
2787 result = build_chill_function_call (
2788 lookup_name (get_identifier ("__gettextrecord")),
2789 tree_cons (NULL_TREE, force_addr_of (text),
2790 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2791 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2792 TREE_TYPE (result) = build_chill_pointer_type (textmode);
2793 CH_DERIVED_FLAG (result) = 1;
2794 return result;
2795 }
2796
2797 tree
2798 build_chill_gettextaccess (text)
2799 tree text;
2800 {
2801 tree access, refaccess, acc, decl, listbase;
2802 tree tlocmode, indexmode, dynamic;
2803 tree result;
2804 extern int maximum_field_alignment;
2805 int save_maximum_field_alignment = maximum_field_alignment;
2806
2807 if (! check_text (text, 1, "GETTEXTACCESS"))
2808 return error_mark_node;
2809
2810 tlocmode = textlocation_mode (TREE_TYPE (text));
2811 indexmode = text_indexmode (TREE_TYPE (text));
2812 dynamic = text_dynamic (TREE_TYPE (text));
2813
2814 /* we have to build a type for the access */
2815 acc = build_access_part ();
2816 access = make_node (RECORD_TYPE);
2817 listbase = build_decl (FIELD_DECL, get_identifier ("data"), acc);
2818 TYPE_FIELDS (access) = listbase;
2819 decl = build_lang_decl (TYPE_DECL, get_identifier ("__recordmode"),
2820 tlocmode);
2821 chainon (listbase, decl);
2822 decl = build_lang_decl (TYPE_DECL, get_identifier ("__indexmode"),
2823 indexmode);
2824 chainon (listbase, decl);
2825 decl = build_decl (CONST_DECL, get_identifier ("__dynamic"),
2826 integer_type_node);
2827 DECL_INITIAL (decl) = dynamic;
2828 chainon (listbase, decl);
2829 maximum_field_alignment = 0;
2830 layout_chill_struct_type (access);
2831 maximum_field_alignment = save_maximum_field_alignment;
2832 CH_IS_ACCESS_MODE (access) = 1;
2833 CH_TYPE_NONVALUE_P (access) = 1;
2834
2835 refaccess = build_chill_pointer_type (access);
2836
2837 result = build_chill_function_call (
2838 lookup_name (get_identifier ("__gettextaccess")),
2839 tree_cons (NULL_TREE, force_addr_of (text),
2840 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2841 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE))));
2842 TREE_TYPE (result) = refaccess;
2843 CH_DERIVED_FLAG (result) = 1;
2844 return result;
2845 }
2846
2847 tree
2848 build_chill_settextindex (text, expr)
2849 tree text;
2850 tree expr;
2851 {
2852 tree result;
2853
2854 if (! check_text (text, 1, "SETTEXTINDEX"))
2855 return error_mark_node;
2856 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
2857 return error_mark_node;
2858 result = build_chill_function_call (
2859 lookup_name (get_identifier ("__settextindex")),
2860 tree_cons (NULL_TREE, force_addr_of (text),
2861 tree_cons (NULL_TREE, expr,
2862 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2863 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE)))));
2864 return result;
2865 }
2866
2867 tree
2868 build_chill_settextaccess (text, access)
2869 tree text;
2870 tree access;
2871 {
2872 tree result;
2873 tree textindexmode, accessindexmode;
2874 tree textrecordmode, accessrecordmode;
2875
2876 if (! check_text (text, 1, "SETTEXTACCESS"))
2877 return error_mark_node;
2878 if (! check_access (access, 2, "SETTEXTACCESS"))
2879 return error_mark_node;
2880
2881 textindexmode = text_indexmode (TREE_TYPE (text));
2882 accessindexmode = access_indexmode (TREE_TYPE (access));
2883 if (textindexmode != accessindexmode)
2884 {
2885 if (! chill_read_compatible (textindexmode, accessindexmode))
2886 {
2887 error ("incompatible index mode for SETETEXTACCESS");
2888 return error_mark_node;
2889 }
2890 }
2891 textrecordmode = textlocation_mode (TREE_TYPE (text));
2892 accessrecordmode = access_recordmode (TREE_TYPE (access));
2893 if (textrecordmode != accessrecordmode)
2894 {
2895 if (! chill_read_compatible (textrecordmode, accessrecordmode))
2896 {
2897 error ("incompatible record mode for SETTEXTACCESS");
2898 return error_mark_node;
2899 }
2900 }
2901 result = build_chill_function_call (
2902 lookup_name (get_identifier ("__settextaccess")),
2903 tree_cons (NULL_TREE, force_addr_of (text),
2904 tree_cons (NULL_TREE, force_addr_of (access),
2905 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2906 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE)))));
2907 return result;
2908 }
2909
2910 tree
2911 build_chill_settextrecord (text, charloc)
2912 tree text;
2913 tree charloc;
2914 {
2915 tree result;
2916 int had_errors = 0;
2917 tree tlocmode;
2918
2919 if (! check_text (text, 1, "SETTEXTRECORD"))
2920 return error_mark_node;
2921 if (charloc == NULL_TREE || TREE_CODE (charloc) == ERROR_MARK)
2922 return error_mark_node;
2923
2924 /* check the location */
2925 if (! CH_LOCATION_P (charloc))
2926 {
2927 error ("parameter 2 must be a location");
2928 return error_mark_node;
2929 }
2930 tlocmode = textlocation_mode (TREE_TYPE (text));
2931 if (! chill_varying_string_type_p (TREE_TYPE (charloc)))
2932 had_errors = 1;
2933 else if (int_size_in_bytes (tlocmode) != int_size_in_bytes (TREE_TYPE (charloc)))
2934 had_errors = 1;
2935 if (had_errors)
2936 {
2937 error ("incompatible modes in parameter 2");
2938 return error_mark_node;
2939 }
2940 result = build_chill_function_call (
2941 lookup_name (get_identifier ("__settextrecord")),
2942 tree_cons (NULL_TREE, force_addr_of (text),
2943 tree_cons (NULL_TREE, force_addr_of (charloc),
2944 tree_cons (NULL_TREE, force_addr_of (get_chill_filename ()),
2945 tree_cons (NULL_TREE, get_chill_linenumber (), NULL_TREE)))));
2946 return result;
2947 }
2948 \f
2949 /* process iolist for READ- and WRITETEXT */
2950
2951 /* function walks through types as long as they are ranges,
2952 returns the type and min- and max-value form starting type.
2953 */
2954
2955 static tree
2956 get_final_type_and_range (item, low, high)
2957 tree item;
2958 tree *low;
2959 tree *high;
2960 {
2961 tree wrk = item;
2962
2963 *low = TYPE_MIN_VALUE (wrk);
2964 *high = TYPE_MAX_VALUE (wrk);
2965 while (TREE_CODE (wrk) == INTEGER_TYPE &&
2966 TREE_TYPE (wrk) != NULL_TREE &&
2967 TREE_CODE (TREE_TYPE (wrk)) == INTEGER_TYPE &&
2968 TREE_TYPE (TREE_TYPE (wrk)) != NULL_TREE)
2969 wrk = TREE_TYPE (wrk);
2970
2971 return (TREE_TYPE (wrk));
2972 }
2973
2974 static void
2975 process_io_list (exprlist, iolist_addr, iolist_length, iolist_rtx, do_read,
2976 argoffset)
2977 tree exprlist;
2978 tree *iolist_addr;
2979 tree *iolist_length;
2980 rtx *iolist_rtx;
2981 int do_read;
2982 int argoffset;
2983 {
2984 tree idxlist;
2985 int idxcnt;
2986 int iolen;
2987 tree iolisttype, iolist;
2988
2989 if (exprlist == NULL_TREE)
2990 return;
2991
2992 iolen = list_length (exprlist);
2993
2994 /* build indexlist for the io list */
2995 idxlist = build_tree_list (NULL_TREE,
2996 build_chill_range_type (NULL_TREE,
2997 integer_one_node,
2998 build_int_2 (iolen, 0)));
2999
3000 /* build the io-list type */
3001 iolisttype = build_chill_array_type (TREE_TYPE (chill_io_list_type),
3002 idxlist, 0, NULL_TREE);
3003
3004 /* declare the iolist */
3005 iolist = build_decl (VAR_DECL, get_unique_identifier (do_read ? "RDTEXT" : "WRTEXT"),
3006 iolisttype);
3007
3008 /* we want to get a variable which gets marked unused after
3009 the function call, This is a little bit tricky cause the
3010 address of this variable will be taken and therefor the variable
3011 gets moved out one level. However, we REALLY don't need this
3012 variable again. Solution: push 2 levels and do pop and free
3013 twice at the end. */
3014 push_temp_slots ();
3015 push_temp_slots ();
3016 *iolist_rtx = assign_temp (TREE_TYPE (iolist), 0, 1, 0);
3017 DECL_RTL (iolist) = *iolist_rtx;
3018
3019 /* process the exprlist */
3020 idxcnt = 1;
3021 while (exprlist != NULL_TREE)
3022 {
3023 tree item = TREE_VALUE (exprlist);
3024 tree idx = build_int_2 (idxcnt++, 0);
3025 char *fieldname = 0;
3026 char *enumname = 0;
3027 tree array_ref = build_chill_array_ref_1 (iolist, idx);
3028 tree item_type;
3029 tree range_low = NULL_TREE, range_high = NULL_TREE;
3030 int have_range = 0;
3031 tree item_addr = null_pointer_node;
3032 int referable = 0;
3033 int readonly = 0;
3034
3035 /* next value in exprlist */
3036 exprlist = TREE_CHAIN (exprlist);
3037 if (item == NULL_TREE || TREE_CODE (item) == ERROR_MARK)
3038 continue;
3039
3040 item_type = TREE_TYPE (item);
3041 if (item_type == NULL_TREE)
3042 {
3043 if (TREE_CODE (item) == COND_EXPR || TREE_CODE (item) == CASE_EXPR)
3044 error ("conditional expression not allowed in this context");
3045 else
3046 error ("untyped expression as argument %d", idxcnt + 1 + argoffset);
3047 continue;
3048 }
3049 else if (TREE_CODE (item_type) == ERROR_MARK)
3050 continue;
3051
3052 if (TREE_CODE (item_type) == REFERENCE_TYPE)
3053 {
3054 item_type = TREE_TYPE (item_type);
3055 item = convert (item_type, item);
3056 }
3057
3058 /* check for a range */
3059 if (TREE_CODE (item_type) == INTEGER_TYPE &&
3060 TREE_TYPE (item_type) != NULL_TREE)
3061 {
3062 /* we have a range. NOTE, however, on writetext we don't process ranges */
3063 item_type = get_final_type_and_range (item_type,
3064 &range_low, &range_high);
3065 have_range = 1;
3066 }
3067
3068 readonly = TYPE_READONLY_PROPERTY (item_type);
3069 referable = CH_REFERABLE (item);
3070 if (referable)
3071 item_addr = force_addr_of (item);
3072 /* if we are in read and have readonly we can't do this */
3073 if (readonly && do_read)
3074 {
3075 item_addr = null_pointer_node;
3076 referable = 0;
3077 }
3078
3079 /* process different types */
3080 if (TREE_CODE (item_type) == INTEGER_TYPE)
3081 {
3082 int type_size = TREE_INT_CST_LOW (TYPE_SIZE (item_type));
3083 tree to_assign = NULL_TREE;
3084
3085 if (do_read && referable)
3086 {
3087 /* process an integer in case of READTEXT and expression is
3088 referable and not READONLY */
3089 to_assign = item_addr;
3090 if (have_range)
3091 {
3092 /* do it for a range */
3093 tree t, __forxx, __ptr, __low, __high;
3094 tree what_upper, what_lower;
3095
3096 /* determine the name in the union of lower and upper */
3097 if (TREE_UNSIGNED (item_type))
3098 fieldname = "_ulong";
3099 else
3100 fieldname = "_slong";
3101
3102 switch (type_size)
3103 {
3104 case 8:
3105 if (TREE_UNSIGNED (item_type))
3106 enumname = "__IO_UByteRangeLoc";
3107 else
3108 enumname = "__IO_ByteRangeLoc";
3109 break;
3110 case 16:
3111 if (TREE_UNSIGNED (item_type))
3112 enumname = "__IO_UIntRangeLoc";
3113 else
3114 enumname = "__IO_IntRangeLoc";
3115 break;
3116 case 32:
3117 if (TREE_UNSIGNED (item_type))
3118 enumname = "__IO_ULongRangeLoc";
3119 else
3120 enumname = "__IO_LongRangeLoc";
3121 break;
3122 default:
3123 error ("Cannot process %d bits integer for READTEXT argument %d.",
3124 type_size, idxcnt + 1 + argoffset);
3125 continue;
3126 }
3127
3128 /* set up access to structure */
3129 t = build_component_ref (array_ref,
3130 get_identifier ("__t"));
3131 __forxx = build_component_ref (t, get_identifier ("__locintrange"));
3132 __ptr = build_component_ref (__forxx, get_identifier ("ptr"));
3133 __low = build_component_ref (__forxx, get_identifier ("lower"));
3134 what_lower = build_component_ref (__low, get_identifier (fieldname));
3135 __high = build_component_ref (__forxx, get_identifier ("upper"));
3136 what_upper = build_component_ref (__high, get_identifier (fieldname));
3137
3138 /* do the assignments */
3139 expand_assignment (__ptr, item_addr, 0, 0);
3140 expand_assignment (what_lower, range_low, 0, 0);
3141 expand_assignment (what_upper, range_high, 0, 0);
3142 fieldname = 0;
3143 }
3144 else
3145 {
3146 /* no range */
3147 fieldname = "__locint";
3148 switch (type_size)
3149 {
3150 case 8:
3151 if (TREE_UNSIGNED (item_type))
3152 enumname = "__IO_UByteLoc";
3153 else
3154 enumname = "__IO_ByteLoc";
3155 break;
3156 case 16:
3157 if (TREE_UNSIGNED (item_type))
3158 enumname = "__IO_UIntLoc";
3159 else
3160 enumname = "__IO_IntLoc";
3161 break;
3162 case 32:
3163 if (TREE_UNSIGNED (item_type))
3164 enumname = "__IO_ULongLoc";
3165 else
3166 enumname = "__IO_LongLoc";
3167 break;
3168 default:
3169 error ("Cannot process %d bits integer for READTEXT argument %d.",
3170 type_size, idxcnt + 1 + argoffset);
3171 continue;
3172 }
3173 }
3174 }
3175 else
3176 {
3177 /* process an integer in case of WRITETEXT */
3178 to_assign = item;
3179 switch (type_size)
3180 {
3181 case 8:
3182 if (TREE_UNSIGNED (item_type))
3183 {
3184 enumname = "__IO_UByteVal";
3185 fieldname = "__valubyte";
3186 }
3187 else
3188 {
3189 enumname = "__IO_ByteVal";
3190 fieldname = "__valbyte";
3191 }
3192 break;
3193 case 16:
3194 if (TREE_UNSIGNED (item_type))
3195 {
3196 enumname = "__IO_UIntVal";
3197 fieldname = "__valuint";
3198 }
3199 else
3200 {
3201 enumname = "__IO_IntVal";
3202 fieldname = "__valint";
3203 }
3204 break;
3205 case 32:
3206 try_long:
3207 if (TREE_UNSIGNED (item_type))
3208 {
3209 enumname = "__IO_ULongVal";
3210 fieldname = "__valulong";
3211 }
3212 else
3213 {
3214 enumname = "__IO_LongVal";
3215 fieldname = "__vallong";
3216 }
3217 break;
3218 case 64:
3219 /* convert it back to {unsigned}long. */
3220 if (TREE_UNSIGNED (item_type))
3221 item_type = long_unsigned_type_node;
3222 else
3223 item_type = long_integer_type_node;
3224 item = convert (item_type, item);
3225 goto try_long;
3226 default:
3227 /* This kludge is because the lexer gives literals
3228 the type long_long_{integer,unsigned}_type_node. */
3229 if (TREE_CODE (item) == INTEGER_CST)
3230 {
3231 if (int_fits_type_p (item, long_integer_type_node))
3232 {
3233 item_type = long_integer_type_node;
3234 item = convert (item_type, item);
3235 goto try_long;
3236 }
3237 if (int_fits_type_p (item, long_unsigned_type_node))
3238 {
3239 item_type = long_unsigned_type_node;
3240 item = convert (item_type, item);
3241 goto try_long;
3242 }
3243 }
3244 error ("Cannot process %d bits integer WRITETEXT argument %d.",
3245 type_size, idxcnt + 1 + argoffset);
3246 continue;
3247 }
3248 }
3249 if (fieldname)
3250 {
3251 tree t, __forxx;
3252
3253 t = build_component_ref (array_ref,
3254 get_identifier ("__t"));
3255 __forxx = build_component_ref (t, get_identifier (fieldname));
3256 expand_assignment (__forxx, to_assign, 0, 0);
3257 }
3258 }
3259 else if (TREE_CODE (item_type) == CHAR_TYPE)
3260 {
3261 tree to_assign = NULL_TREE;
3262
3263 if (do_read && readonly)
3264 {
3265 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3266 continue;
3267 }
3268 if (do_read)
3269 {
3270 if (! referable)
3271 {
3272 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3273 continue;
3274 }
3275 if (have_range)
3276 {
3277 tree t, forxx, ptr, lower, upper;
3278
3279 t = build_component_ref (array_ref, get_identifier ("__t"));
3280 forxx = build_component_ref (t, get_identifier ("__loccharrange"));
3281 ptr = build_component_ref (forxx, get_identifier ("ptr"));
3282 lower = build_component_ref (forxx, get_identifier ("lower"));
3283 upper = build_component_ref (forxx, get_identifier ("upper"));
3284 expand_assignment (ptr, item_addr, 0, 0);
3285 expand_assignment (lower, range_low, 0, 0);
3286 expand_assignment (upper, range_high, 0, 0);
3287
3288 fieldname = 0;
3289 enumname = "__IO_CharRangeLoc";
3290 }
3291 else
3292 {
3293 to_assign = item_addr;
3294 fieldname = "__locchar";
3295 enumname = "__IO_CharLoc";
3296 }
3297 }
3298 else
3299 {
3300 to_assign = item;
3301 enumname = "__IO_CharVal";
3302 fieldname = "__valchar";
3303 }
3304
3305 if (fieldname)
3306 {
3307 tree t, forxx;
3308
3309 t = build_component_ref (array_ref, get_identifier ("__t"));
3310 forxx = build_component_ref (t, get_identifier (fieldname));
3311 expand_assignment (forxx, to_assign, 0, 0);
3312 }
3313 }
3314 else if (TREE_CODE (item_type) == BOOLEAN_TYPE)
3315 {
3316 tree to_assign;
3317
3318 if (do_read && readonly)
3319 {
3320 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3321 continue;
3322 }
3323 if (do_read)
3324 {
3325 if (! referable)
3326 {
3327 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3328 continue;
3329 }
3330 if (have_range)
3331 {
3332 tree t, forxx, ptr, lower, upper;
3333
3334 t = build_component_ref (array_ref, get_identifier ("__t"));
3335 forxx = build_component_ref (t, get_identifier ("__locboolrange"));
3336 ptr = build_component_ref (forxx, get_identifier ("ptr"));
3337 lower = build_component_ref (forxx, get_identifier ("lower"));
3338 upper = build_component_ref (forxx, get_identifier ("upper"));
3339 expand_assignment (ptr, item_addr, 0, 0);
3340 expand_assignment (lower, range_low, 0, 0);
3341 expand_assignment (upper, range_high, 0, 0);
3342
3343 fieldname = 0;
3344 enumname = "__IO_BoolRangeLoc";
3345 }
3346 else
3347 {
3348 to_assign = item_addr;
3349 fieldname = "__locbool";
3350 enumname = "__IO_BoolLoc";
3351 }
3352 }
3353 else
3354 {
3355 to_assign = item;
3356 enumname = "__IO_BoolVal";
3357 fieldname = "__valbool";
3358 }
3359 if (fieldname)
3360 {
3361 tree t, forxx;
3362
3363 t = build_component_ref (array_ref, get_identifier ("__t"));
3364 forxx = build_component_ref (t, get_identifier (fieldname));
3365 expand_assignment (forxx, to_assign, 0, 0);
3366 }
3367 }
3368 else if (TREE_CODE (item_type) == ENUMERAL_TYPE)
3369 {
3370 /* process an enum */
3371 tree table_name;
3372 tree context_of_type;
3373 tree t;
3374
3375 /* determine the context of the type.
3376 if TYPE_NAME (item_type) == NULL_TREE
3377 if TREE_CODE (item) == INTEGER_CST
3378 context = NULL_TREE -- this is wrong but should work for now
3379 else
3380 context = DECL_CONTEXT (item)
3381 else
3382 context = DECL_CONTEXT (TYPE_NAME (item_type)) */
3383
3384 if (TYPE_NAME (item_type) == NULL_TREE)
3385 {
3386 if (TREE_CODE (item) == INTEGER_CST)
3387 context_of_type = NULL_TREE;
3388 else
3389 context_of_type = DECL_CONTEXT (item);
3390 }
3391 else
3392 context_of_type = DECL_CONTEXT (TYPE_NAME (item_type));
3393
3394 table_name = add_enum_to_list (item_type, context_of_type);
3395 t = build_component_ref (array_ref, get_identifier ("__t"));
3396
3397 if (do_read && readonly)
3398 {
3399 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3400 continue;
3401 }
3402 if (do_read)
3403 {
3404 if (! referable)
3405 {
3406 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3407 continue;
3408 }
3409 if (have_range)
3410 {
3411 tree forxx, ptr, len, nametable, lower, upper;
3412
3413 forxx = build_component_ref (t, get_identifier ("__locsetrange"));
3414 ptr = build_component_ref (forxx, get_identifier ("ptr"));
3415 len = build_component_ref (forxx, get_identifier ("length"));
3416 nametable = build_component_ref (forxx, get_identifier ("name_table"));
3417 lower = build_component_ref (forxx, get_identifier ("lower"));
3418 upper = build_component_ref (forxx, get_identifier ("upper"));
3419 expand_assignment (ptr, item_addr, 0, 0);
3420 expand_assignment (len, size_in_bytes (item_type), 0, 0);
3421 expand_assignment (nametable, table_name, 0, 0);
3422 expand_assignment (lower, range_low, 0, 0);
3423 expand_assignment (upper, range_high, 0, 0);
3424
3425 enumname = "__IO_SetRangeLoc";
3426 }
3427 else
3428 {
3429 tree forxx, ptr, len, nametable;
3430
3431 forxx = build_component_ref (t, get_identifier ("__locset"));
3432 ptr = build_component_ref (forxx, get_identifier ("ptr"));
3433 len = build_component_ref (forxx, get_identifier ("length"));
3434 nametable = build_component_ref (forxx, get_identifier ("name_table"));
3435 expand_assignment (ptr, item_addr, 0, 0);
3436 expand_assignment (len, size_in_bytes (item_type), 0, 0);
3437 expand_assignment (nametable, table_name, 0, 0);
3438
3439 enumname = "__IO_SetLoc";
3440 }
3441 }
3442 else
3443 {
3444 tree forxx, value, nametable;
3445
3446 forxx = build_component_ref (t, get_identifier ("__valset"));
3447 value = build_component_ref (forxx, get_identifier ("value"));
3448 nametable = build_component_ref (forxx, get_identifier ("name_table"));
3449 expand_assignment (value, item, 0, 0);
3450 expand_assignment (nametable, table_name, 0, 0);
3451
3452 enumname = "__IO_SetVal";
3453 }
3454 }
3455 else if (chill_varying_string_type_p (item_type))
3456 {
3457 /* varying char string */
3458 tree t = build_component_ref (array_ref, get_identifier ("__t"));
3459 tree forxx = build_component_ref (t, get_identifier ("__loccharstring"));
3460 tree string = build_component_ref (forxx, get_identifier ("string"));
3461 tree length = build_component_ref (forxx, get_identifier ("string_length"));
3462
3463 if (do_read && readonly)
3464 {
3465 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3466 continue;
3467 }
3468 if (do_read)
3469 {
3470 /* in this read case the argument must be referable */
3471 if (! referable)
3472 {
3473 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3474 continue;
3475 }
3476 }
3477 else if (! referable)
3478 {
3479 /* in the write case we create a temporary if not referable */
3480 rtx t;
3481 tree loc = build_decl (VAR_DECL,
3482 get_unique_identifier ("WRTEXTVS"),
3483 item_type);
3484 t = assign_temp (item_type, 0, 1, 0);
3485 DECL_RTL (loc) = t;
3486 expand_assignment (loc, item, 0, 0);
3487 item_addr = force_addr_of (loc);
3488 item = loc;
3489 }
3490
3491 expand_assignment (string, item_addr, 0, 0);
3492 if (do_read)
3493 /* we must pass the maximum length of the varying */
3494 expand_assignment (length,
3495 size_in_bytes (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (item_type)))),
3496 0, 0);
3497 else
3498 /* we pass the actual length of the string */
3499 expand_assignment (length,
3500 build_component_ref (item, var_length_id),
3501 0, 0);
3502
3503 enumname = "__IO_CharVaryingLoc";
3504 }
3505 else if (CH_CHARS_TYPE_P (item_type))
3506 {
3507 /* fixed character string */
3508 tree the_size;
3509 tree t = build_component_ref (array_ref, get_identifier ("__t"));
3510 tree forxx = build_component_ref (t, get_identifier ("__loccharstring"));
3511 tree string = build_component_ref (forxx, get_identifier ("string"));
3512 tree length = build_component_ref (forxx, get_identifier ("string_length"));
3513
3514 if (do_read && readonly)
3515 {
3516 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3517 continue;
3518 }
3519 if (do_read)
3520 {
3521 /* in this read case the argument must be referable */
3522 if (! CH_REFERABLE (item))
3523 {
3524 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3525 continue;
3526 }
3527 else
3528 item_addr = force_addr_of (item);
3529 the_size = size_in_bytes (item_type);
3530 enumname = "__IO_CharStrLoc";
3531 }
3532 else
3533 {
3534 if (! CH_REFERABLE (item))
3535 {
3536 /* in the write case we create a temporary if not referable */
3537 rtx t;
3538 int howmuchbytes;
3539
3540 howmuchbytes = int_size_in_bytes (item_type);
3541 if (howmuchbytes != -1)
3542 {
3543 /* fixed size */
3544 tree loc = build_decl (VAR_DECL,
3545 get_unique_identifier ("WRTEXTVS"),
3546 item_type);
3547 t = assign_temp (item_type, 0, 1, 0);
3548 DECL_RTL (loc) = t;
3549 expand_assignment (loc, item, 0, 0);
3550 item_addr = force_addr_of (loc);
3551 the_size = size_in_bytes (item_type);
3552 enumname = "__IO_CharStrLoc";
3553 }
3554 else
3555 {
3556 tree type, string, exp, loc;
3557
3558 if ((howmuchbytes = intsize_of_charsexpr (item)) == -1)
3559 {
3560 error ("cannot process argument %d of WRITETEXT, unknown size",
3561 idxcnt + 1 + argoffset);
3562 continue;
3563 }
3564 string = build_string_type (char_type_node,
3565 build_int_2 (howmuchbytes, 0));
3566 type = build_varying_struct (string);
3567 loc = build_decl (VAR_DECL,
3568 get_unique_identifier ("WRTEXTCS"),
3569 type);
3570 t = assign_temp (type, 0, 1, 0);
3571 DECL_RTL (loc) = t;
3572 exp = chill_convert_for_assignment (type, item, 0);
3573 expand_assignment (loc, exp, 0, 0);
3574 item_addr = force_addr_of (loc);
3575 the_size = integer_zero_node;
3576 enumname = "__IO_CharVaryingLoc";
3577 }
3578 }
3579 else
3580 {
3581 item_addr = force_addr_of (item);
3582 the_size = size_in_bytes (item_type);
3583 enumname = "__IO_CharStrLoc";
3584 }
3585 }
3586
3587 expand_assignment (string, item_addr, 0, 0);
3588 expand_assignment (length, size_in_bytes (item_type), 0, 0);
3589
3590 }
3591 else if (CH_BOOLS_TYPE_P (item_type))
3592 {
3593 /* we have a bitstring */
3594 tree t = build_component_ref (array_ref, get_identifier ("__t"));
3595 tree forxx = build_component_ref (t, get_identifier ("__loccharstring"));
3596 tree string = build_component_ref (forxx, get_identifier ("string"));
3597 tree length = build_component_ref (forxx, get_identifier ("string_length"));
3598
3599 if (do_read && readonly)
3600 {
3601 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3602 continue;
3603 }
3604 if (do_read)
3605 {
3606 /* in this read case the argument must be referable */
3607 if (! referable)
3608 {
3609 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3610 continue;
3611 }
3612 }
3613 else if (! referable)
3614 {
3615 /* in the write case we create a temporary if not referable */
3616 tree loc = build_decl (VAR_DECL,
3617 get_unique_identifier ("WRTEXTVS"),
3618 item_type);
3619 DECL_RTL (loc) = assign_temp (item_type, 0, 1, 0);
3620 expand_assignment (loc, item, 0, 0);
3621 item_addr = force_addr_of (loc);
3622 }
3623
3624 expand_assignment (string, item_addr, 0, 0);
3625 expand_assignment (length, build_chill_length (item), 0, 0);
3626
3627 enumname = "__IO_BitStrLoc";
3628 }
3629 else if (TREE_CODE (item_type) == REAL_TYPE)
3630 {
3631 /* process a (long_)real */
3632 tree t, forxx, to_assign;
3633
3634 if (do_read && readonly)
3635 {
3636 error ("argument %d is READonly", idxcnt + 1 + argoffset);
3637 continue;
3638 }
3639 if (do_read && ! referable)
3640 {
3641 error ("argument %d must be referable", idxcnt + 1 + argoffset);
3642 continue;
3643 }
3644
3645 if (lookup_name (ridpointers[RID_FLOAT]) == TYPE_NAME (item_type))
3646 {
3647 /* we have a real */
3648 if (do_read)
3649 {
3650 enumname = "__IO_RealLoc";
3651 fieldname = "__locreal";
3652 to_assign = item_addr;
3653 }
3654 else
3655 {
3656 enumname = "__IO_RealVal";
3657 fieldname = "__valreal";
3658 to_assign = item;
3659 }
3660 }
3661 else
3662 {
3663 /* we have a long_real */
3664 if (do_read)
3665 {
3666 enumname = "__IO_LongRealLoc";
3667 fieldname = "__loclongreal";
3668 to_assign = item_addr;
3669 }
3670 else
3671 {
3672 enumname = "__IO_LongRealVal";
3673 fieldname = "__vallongreal";
3674 to_assign = item;
3675 }
3676 }
3677 t = build_component_ref (array_ref, get_identifier ("__t"));
3678 forxx = build_component_ref (t, get_identifier (fieldname));
3679 expand_assignment (forxx, to_assign, 0, 0);
3680 }
3681 #if 0
3682 /* don't process them for now */
3683 else if (TREE_CODE (item_type) == POINTER_TYPE)
3684 {
3685 /* we have a pointer */
3686 tree __t, __forxx;
3687
3688 __t = build_component_ref (array_ref, get_identifier ("__t"));
3689 __forxx = build_component_ref (__t, get_identifier ("__forpointer"));
3690 expand_assignment (__forxx, item, 0, 0);
3691 enumname = "_IO_Pointer";
3692 }
3693 else if (item_type == instance_type_node)
3694 {
3695 /* we have an INSTANCE */
3696 tree __t, __forxx;
3697
3698 __t = build_component_ref (array_ref, get_identifier ("__t"));
3699 __forxx = build_component_ref (__t, get_identifier ("__forinstance"));
3700 expand_assignment (__forxx, item, 0, 0);
3701 enumname = "_IO_Instance";
3702 }
3703 #endif
3704 else
3705 {
3706 /* datatype is not yet implemented, issue a warning */
3707 error ("cannot process mode of argument %d for %sTEXT.", idxcnt + 1 + argoffset,
3708 do_read ? "READ" : "WRITE");
3709 enumname = "__IO_UNUSED";
3710 }
3711
3712 /* do assignment of the enum */
3713 if (enumname)
3714 {
3715 tree descr = build_component_ref (array_ref,
3716 get_identifier ("__descr"));
3717 expand_assignment (descr,
3718 lookup_name (get_identifier (enumname)), 0, 0);
3719 }
3720 }
3721
3722 /* set up address and length of iolist */
3723 *iolist_addr = build_chill_addr_expr (iolist, (char *)0);
3724 *iolist_length = build_int_2 (iolen, 0);
3725 }
3726 \f
3727 /* check the format string */
3728 #define LET 0x0001
3729 #define BIN 0x0002
3730 #define DEC 0x0004
3731 #define OCT 0x0008
3732 #define HEX 0x0010
3733 #define USC 0x0020
3734 #define BIL 0x0040
3735 #define SPC 0x0080
3736 #define SCS 0x0100
3737 #define IOC 0x0200
3738 #define EDC 0x0400
3739 #define CVC 0x0800
3740
3741 #define isDEC(c) ( chartab[(c)] & DEC )
3742 #define isCVC(c) ( chartab[(c)] & CVC )
3743 #define isEDC(c) ( chartab[(c)] & EDC )
3744 #define isIOC(c) ( chartab[(c)] & IOC )
3745 #define isUSC(c)
3746 #define isXXX(c,XXX) ( chartab[(c)] & XXX )
3747
3748 static
3749 short int chartab[256] = {
3750 0, 0, 0, 0, 0, 0, 0, 0,
3751 0, SPC, SPC, SPC, SPC, SPC, 0, 0,
3752
3753 0, 0, 0, 0, 0, 0, 0, 0,
3754 0, 0, 0, 0, 0, 0, 0, 0,
3755
3756 SPC, IOC, 0, 0, 0, 0, 0, 0,
3757 SCS, SCS, SCS, SCS+IOC, SCS, SCS+IOC, SCS, SCS+IOC,
3758 BIN+OCT+DEC+HEX, BIN+OCT+DEC+HEX, OCT+DEC+HEX, OCT+DEC+HEX, OCT+DEC+HEX,
3759 OCT+DEC+HEX, OCT+DEC+HEX, OCT+DEC+HEX,
3760 DEC+HEX, DEC+HEX, SCS, SCS, SCS+EDC, SCS+IOC, SCS+EDC, IOC,
3761
3762 0, LET+HEX+BIL, LET+HEX+BIL+CVC, LET+HEX+BIL+CVC, LET+HEX+BIL, LET+HEX,
3763 LET+HEX+CVC, LET,
3764 LET+BIL+CVC, LET, LET, LET, LET, LET, LET, LET+CVC,
3765
3766 LET, LET, LET, LET, LET+EDC, LET, LET, LET,
3767 LET+EDC, LET, LET, SCS, 0, SCS, 0, USC,
3768
3769 0, LET+HEX, LET+HEX, LET+HEX, LET+HEX, LET+HEX, LET+HEX, LET,
3770 LET, LET, LET, LET, LET, LET, LET, LET,
3771
3772 LET, LET, LET, LET, LET, LET, LET, LET,
3773 LET, LET, LET, 0, 0, 0, 0, 0
3774 };
3775
3776 typedef enum
3777 {
3778 FormatText, FirstPercent, RepFact, ConvClause, EditClause, ClauseEnd,
3779 AfterWidth, FractWidth, FractWidthCont, ExpoWidth, ExpoWidthCont,
3780 ClauseWidth, CatchPadding, LastPercent
3781 } fcsstate_t;
3782
3783 #define CONVERSIONCODES "CHOBF"
3784 typedef enum
3785 {
3786 DefaultConv, HexConv, OctalConv, BinaryConv, ScientConv
3787 } convcode_t;
3788 static convcode_t convcode;
3789
3790 typedef enum
3791 {
3792 False, True,
3793 } Boolean;
3794
3795 static unsigned long fractionwidth;
3796
3797 #define IOCODES "/+-?!="
3798 typedef enum {
3799 NextRecord, NextPage, CurrentLine, Prompt, Emit, EndPage
3800 } iocode_t;
3801 static iocode_t iocode;
3802
3803 #define EDITCODES "X<>T"
3804 typedef enum {
3805 SpaceSkip, SkipLeft, SkipRight, Tabulation
3806 } editcode_t;
3807 static editcode_t editcode;
3808
3809 static unsigned long clausewidth;
3810 static Boolean leftadjust;
3811 static Boolean overflowev;
3812 static Boolean dynamicwid;
3813 static Boolean paddingdef;
3814 static char paddingchar;
3815 static Boolean fractiondef;
3816 static Boolean exponentdef;
3817 static unsigned long exponentwidth;
3818 static unsigned long repetition;
3819
3820 typedef enum {
3821 NormalEnd, EndAtParen, TextFailEnd
3822 } formatexit_t;
3823
3824 /* NOTE: varibale have to be set to False before calling check_format_string */
3825 static Boolean empty_printed;
3826
3827 static int formstroffset;
3828
3829 static tree
3830 check_exprlist (code, exprlist, argnum, repetition)
3831 convcode_t code;
3832 tree exprlist;
3833 int argnum;
3834 unsigned long repetition;
3835 {
3836 tree expr, type, result;
3837
3838 while (repetition--)
3839 {
3840 if (exprlist == NULL_TREE)
3841 {
3842 if (empty_printed == False)
3843 {
3844 warning ("too few arguments for this format string");
3845 empty_printed = True;
3846 }
3847 return NULL_TREE;
3848 }
3849 expr = TREE_VALUE (exprlist);
3850 result = exprlist = TREE_CHAIN (exprlist);
3851 if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
3852 return result;
3853 type = TREE_TYPE (expr);
3854 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
3855 return result;
3856 if (TREE_CODE (type) == REFERENCE_TYPE)
3857 type = TREE_TYPE (type);
3858 if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
3859 return result;
3860
3861 switch (code)
3862 {
3863 case DefaultConv:
3864 /* %C, everything is allowed. Not know types are flaged later. */
3865 break;
3866 case ScientConv:
3867 /* %F, must be a REAL */
3868 if (TREE_CODE (type) != REAL_TYPE)
3869 warning ("type of argument %d invalid for conversion code at offset %d",
3870 argnum, formstroffset);
3871 break;
3872 case HexConv:
3873 case OctalConv:
3874 case BinaryConv:
3875 case -1:
3876 /* %H, %O, %B, and V as clause width */
3877 if (TREE_CODE (type) != INTEGER_TYPE)
3878 warning ("type of argument %d invalid for conversion code at offset %d",
3879 argnum, formstroffset);
3880 break;
3881 default:
3882 /* there is an invalid conversion code */
3883 break;
3884 }
3885 }
3886 return result;
3887 }
3888
3889 static formatexit_t
3890 scanformcont (fcs, len, fcsptr, lenptr, exprlist, exprptr,
3891 firstargnum, nextargnum)
3892 char *fcs;
3893 int len;
3894 char **fcsptr;
3895 int *lenptr;
3896 tree exprlist;
3897 tree *exprptr;
3898 int firstargnum;
3899 int *nextargnum;
3900 {
3901 fcsstate_t state = FormatText;
3902 unsigned char curr;
3903 int dig;
3904
3905 while (len--)
3906 {
3907 curr = *fcs++;
3908 formstroffset++;
3909 switch (state)
3910 {
3911 case FormatText:
3912 if (curr == '%')
3913 state = FirstPercent;
3914 break;
3915
3916 after_first_percent: ;
3917 case FirstPercent:
3918 if (curr == '%')
3919 {
3920 state = FormatText;
3921 break;
3922 }
3923 if (curr == ')')
3924 {
3925 *lenptr = len;
3926 *fcsptr = fcs;
3927 *exprptr = exprlist;
3928 *nextargnum = firstargnum;
3929 return EndAtParen;
3930 }
3931 if (isDEC (curr))
3932 {
3933 state = RepFact;
3934 repetition = curr - '0';
3935 break;
3936 }
3937
3938 repetition = 1;
3939
3940 test_for_control_codes: ;
3941 if (isCVC (curr))
3942 {
3943 state = ConvClause;
3944 convcode = strchr (CONVERSIONCODES, curr) - CONVERSIONCODES;
3945 leftadjust = False;
3946 overflowev = False;
3947 dynamicwid = False;
3948 paddingdef = False;
3949 paddingchar = ' ';
3950 fractiondef = False;
3951 /* fractionwidth = 0; default depends on mode ! */
3952 exponentdef = False;
3953 exponentwidth = 3;
3954 clausewidth = 0;
3955 /* check the argument */
3956 exprlist = check_exprlist (convcode, exprlist, firstargnum, repetition);
3957 firstargnum++;
3958 break;
3959 }
3960 if (isEDC (curr))
3961 {
3962 state = EditClause;
3963 editcode = strchr (EDITCODES, curr) - EDITCODES;
3964 dynamicwid = False;
3965 clausewidth = editcode == Tabulation ? 0 : 1;
3966 break;
3967 }
3968 if (isIOC (curr))
3969 {
3970 state = ClauseEnd;
3971 iocode = strchr (IOCODES, curr) - IOCODES;
3972 break;
3973 }
3974 if (curr == '(')
3975 {
3976 unsigned long times = repetition;
3977 int cntlen;
3978 char* cntfcs;
3979 tree cntexprlist;
3980 int nextarg;
3981
3982 while (times--)
3983 {
3984 if (scanformcont (fcs, len, &cntfcs, &cntlen,
3985 exprlist, &cntexprlist,
3986 firstargnum, &nextarg) != EndAtParen )
3987 {
3988 warning ("unmatched open paren");
3989 break;
3990 }
3991 exprlist = cntexprlist;
3992 }
3993 fcs = cntfcs;
3994 len = cntlen;
3995 if (len < 0)
3996 len = 0;
3997 exprlist = cntexprlist;
3998 firstargnum = nextarg;
3999 state = FormatText;
4000 break;
4001 }
4002 warning ("bad format specification character (offset %d)", formstroffset);
4003 state = FormatText;
4004 /* skip one argument */
4005 if (exprlist != NULL_TREE)
4006 exprlist = TREE_CHAIN (exprlist);
4007 break;
4008
4009 case RepFact:
4010 if (isDEC (curr))
4011 {
4012 dig = curr - '0';
4013 if (repetition > (ULONG_MAX - dig)/10)
4014 {
4015 warning ("repetition factor overflow (offset %d)", formstroffset);
4016 return TextFailEnd;
4017 }
4018 repetition = repetition*10 + dig;
4019 break;
4020 }
4021 goto test_for_control_codes;
4022
4023 case ConvClause:
4024 if (isDEC (curr))
4025 {
4026 state = ClauseWidth;
4027 clausewidth = curr - '0';
4028 break;
4029 }
4030 if (curr == 'L')
4031 {
4032 if (leftadjust)
4033 warning ("duplicate qualifier (offset %d)", formstroffset);
4034 leftadjust = True;
4035 break;
4036 }
4037 if (curr == 'E')
4038 {
4039 if (overflowev)
4040 warning ("duplicate qualifier (offset %d)", formstroffset);
4041 overflowev = True;
4042 break;
4043 }
4044 if (curr == 'P')
4045 {
4046 if (paddingdef)
4047 warning ("duplicate qualifier (offset %d)", formstroffset);
4048 paddingdef = True;
4049 state = CatchPadding;
4050 break;
4051 }
4052
4053 test_for_variable_width: ;
4054 if (curr == 'V')
4055 {
4056 dynamicwid = True;
4057 state = AfterWidth;
4058 exprlist = check_exprlist (-1, exprlist, firstargnum, 1);
4059 firstargnum++;
4060 break;
4061 }
4062 goto test_for_fraction_width;
4063
4064 case ClauseWidth:
4065 if (isDEC (curr))
4066 {
4067 dig = curr - '0';
4068 if (clausewidth > (ULONG_MAX - dig)/10)
4069 warning ("clause width overflow (offset %d)", formstroffset);
4070 else
4071 clausewidth = clausewidth*10 + dig;
4072 break;
4073 }
4074 /* fall through */
4075
4076 test_for_fraction_width: ;
4077 case AfterWidth:
4078 if (curr == '.')
4079 {
4080 if (convcode != DefaultConv && convcode != ScientConv)
4081 {
4082 warning ("no fraction (offset %d)", formstroffset);
4083 state = FormatText;
4084 break;
4085 }
4086 fractiondef = True;
4087 state = FractWidth;
4088 break;
4089 }
4090 goto test_for_exponent_width;
4091
4092 case FractWidth:
4093 if (isDEC (curr))
4094 {
4095 state = FractWidthCont;
4096 fractionwidth = curr - '0';
4097 break;
4098 }
4099 else
4100 warning ("no fraction width (offset %d)", formstroffset);
4101
4102 case FractWidthCont:
4103 if (isDEC (curr))
4104 {
4105 dig = curr - '0';
4106 if (fractionwidth > (ULONG_MAX - dig)/10)
4107 warning ("fraction width overflow (offset %d)", formstroffset);
4108 else
4109 fractionwidth = fractionwidth*10 + dig;
4110 break;
4111 }
4112
4113 test_for_exponent_width: ;
4114 if (curr == ':')
4115 {
4116 if (convcode != ScientConv)
4117 {
4118 warning ("no exponent (offset %d)", formstroffset);
4119 state = FormatText;
4120 break;
4121 }
4122 exponentdef = True;
4123 state = ExpoWidth;
4124 break;
4125 }
4126 goto test_for_final_percent;
4127
4128 case ExpoWidth:
4129 if (isDEC (curr))
4130 {
4131 state = ExpoWidthCont;
4132 exponentwidth = curr - '0';
4133 break;
4134 }
4135 else
4136 warning ("no exponent width (offset %d)", formstroffset);
4137
4138 case ExpoWidthCont:
4139 if (isDEC (curr))
4140 {
4141 dig = curr - '0';
4142 if (exponentwidth > (ULONG_MAX - dig)/10)
4143 warning ("exponent width overflow (offset %d)", formstroffset);
4144 else
4145 exponentwidth = exponentwidth*10 + dig;
4146 break;
4147 }
4148 /* fall through */
4149
4150 test_for_final_percent: ;
4151 case ClauseEnd:
4152 if (curr == '%')
4153 {
4154 state = LastPercent;
4155 break;
4156 }
4157
4158 state = FormatText;
4159 break;
4160
4161 case CatchPadding:
4162 paddingchar = curr;
4163 state = ConvClause;
4164 break;
4165
4166 case EditClause:
4167 if (isDEC (curr))
4168 {
4169 state = ClauseWidth;
4170 clausewidth = curr - '0';
4171 break;
4172 }
4173 goto test_for_variable_width;
4174
4175 case LastPercent:
4176 if (curr == '.')
4177 {
4178 state = FormatText;
4179 break;
4180 }
4181 goto after_first_percent;
4182
4183 default:
4184 error ("internal error in check_format_string");
4185 }
4186 }
4187
4188 switch (state)
4189 {
4190 case FormatText:
4191 break;
4192 case FirstPercent:
4193 case LastPercent:
4194 case RepFact:
4195 case FractWidth:
4196 case ExpoWidth:
4197 warning ("bad format specification character (offset %d)", formstroffset);
4198 break;
4199 case CatchPadding:
4200 warning ("no padding character (offset %d)", formstroffset);
4201 break;
4202 default:
4203 break;
4204 }
4205 *fcsptr = fcs;
4206 *lenptr = len;
4207 *exprptr = exprlist;
4208 *nextargnum = firstargnum;
4209 return NormalEnd;
4210 }
4211 static void
4212 check_format_string (format_str, exprlist, firstargnum)
4213 tree format_str;
4214 tree exprlist;
4215 int firstargnum;
4216 {
4217 char *x;
4218 int y, yy;
4219 tree z = NULL_TREE;
4220
4221 if (TREE_CODE (format_str) != STRING_CST)
4222 /* do nothing if we don't have a string constant */
4223 return;
4224
4225 formstroffset = -1;
4226 scanformcont (TREE_STRING_POINTER (format_str),
4227 TREE_STRING_LENGTH (format_str), &x, &y,
4228 exprlist, &z,
4229 firstargnum, &yy);
4230 if (z != NULL_TREE)
4231 /* too may arguments for format string */
4232 warning ("too many arguments for this format string");
4233 }
4234 \f
4235 static int
4236 get_max_size (expr)
4237 tree expr;
4238 {
4239 if (TREE_CODE (expr) == INDIRECT_REF)
4240 {
4241 tree x = TREE_OPERAND (expr, 0);
4242 tree y = TREE_OPERAND (x, 0);
4243 return int_size_in_bytes (TREE_TYPE (y));
4244 }
4245 else if (TREE_CODE (expr) == CONCAT_EXPR)
4246 return intsize_of_charsexpr (expr);
4247 else
4248 return int_size_in_bytes (TREE_TYPE (expr));
4249 }
4250
4251 static int
4252 intsize_of_charsexpr (expr)
4253 tree expr;
4254 {
4255 int op0size, op1size;
4256
4257 if (TREE_CODE (expr) != CONCAT_EXPR)
4258 return -1;
4259
4260 /* find maximum length of CONCAT_EXPR, this is the worst case */
4261 op0size = get_max_size (TREE_OPERAND (expr, 0));
4262 op1size = get_max_size (TREE_OPERAND (expr, 1));
4263 if (op0size == -1 || op1size == -1)
4264 return -1;
4265 return op0size + op1size;
4266 }
4267
4268 tree
4269 build_chill_writetext (text_arg, exprlist)
4270 tree text_arg, exprlist;
4271 {
4272 tree iolist_addr = null_pointer_node;
4273 tree iolist_length = integer_zero_node;
4274 tree fstr_addr;
4275 tree fstr_length;
4276 tree outstr_addr;
4277 tree outstr_length;
4278 tree fstrtype;
4279 tree outfunction;
4280 tree filename, linenumber;
4281 tree format_str = NULL_TREE, indexexpr = NULL_TREE;
4282 rtx iolist_rtx = NULL_RTX;
4283 int argoffset = 0;
4284
4285 /* make some checks */
4286 if (text_arg == NULL_TREE || TREE_CODE (text_arg) == ERROR_MARK)
4287 return error_mark_node;
4288
4289 if (exprlist != NULL_TREE)
4290 {
4291 if (TREE_CODE (exprlist) != TREE_LIST)
4292 return error_mark_node;
4293 }
4294
4295 /* check the text argument */
4296 if (chill_varying_string_type_p (TREE_TYPE (text_arg)))
4297 {
4298 /* build outstr-addr and outstr-length assuming that this is a CHAR (n) VARYING */
4299 outstr_addr = force_addr_of (text_arg);
4300 outstr_length = size_in_bytes (CH_VARYING_ARRAY_TYPE (TREE_TYPE (text_arg)));
4301 outfunction = lookup_name (get_identifier ("__writetext_s"));
4302 format_str = TREE_VALUE (exprlist);
4303 exprlist = TREE_CHAIN (exprlist);
4304 }
4305 else if (CH_IS_TEXT_MODE (TREE_TYPE (text_arg)))
4306 {
4307 /* we have a text mode */
4308 tree indexmode;
4309
4310 if (! check_text (text_arg, 1, "WRITETEXT"))
4311 return error_mark_node;
4312 indexmode = text_indexmode (TREE_TYPE (text_arg));
4313 if (indexmode == void_type_node)
4314 {
4315 /* no index */
4316 format_str = TREE_VALUE (exprlist);
4317 exprlist = TREE_CHAIN (exprlist);
4318 }
4319 else
4320 {
4321 /* we have an index. there must be an index argument before format string */
4322 indexexpr = TREE_VALUE (exprlist);
4323 exprlist = TREE_CHAIN (exprlist);
4324 if (! CH_COMPATIBLE (indexexpr, indexmode))
4325 {
4326 if (chill_varying_string_type_p (TREE_TYPE (indexexpr)) ||
4327 (CH_CHARS_TYPE_P (TREE_TYPE (indexexpr)) ||
4328 (flag_old_strings && TREE_CODE (indexexpr) == INTEGER_CST &&
4329 TREE_CODE (TREE_TYPE (indexexpr)) == CHAR_TYPE)))
4330 error ("missing index expression");
4331 else
4332 error ("incompatible index mode");
4333 return error_mark_node;
4334 }
4335 if (exprlist == NULL_TREE)
4336 {
4337 error ("Too few arguments in call to `writetext'");
4338 return error_mark_node;
4339 }
4340 format_str = TREE_VALUE (exprlist);
4341 exprlist = TREE_CHAIN (exprlist);
4342 argoffset = 1;
4343 }
4344 outstr_addr = force_addr_of (text_arg);
4345 outstr_length = convert (integer_type_node, indexexpr);
4346 outfunction = lookup_name (get_identifier ("__writetext_f"));
4347 }
4348 else
4349 {
4350 error ("argument 1 for WRITETEXT must be a TEXT or CHARS(n) VARYING location");
4351 return error_mark_node;
4352 }
4353
4354 /* check the format string */
4355 fstrtype = TREE_TYPE (format_str);
4356 if (CH_CHARS_TYPE_P (fstrtype) ||
4357 (flag_old_strings && TREE_CODE (format_str) == INTEGER_CST &&
4358 TREE_CODE (fstrtype) == CHAR_TYPE))
4359 {
4360 /* we have a character string */
4361 fstr_addr = force_addr_of (format_str);
4362 fstr_length = size_in_bytes (fstrtype);
4363 }
4364 else if (chill_varying_string_type_p (TREE_TYPE (format_str)))
4365 {
4366 /* we have a varying char string */
4367 fstr_addr
4368 = force_addr_of (build_component_ref (format_str, var_data_id));
4369 fstr_length = build_component_ref (format_str, var_length_id);
4370 }
4371 else
4372 {
4373 error ("`format string' for WRITETEXT must be a CHARACTER string");
4374 return error_mark_node;
4375 }
4376
4377 empty_printed = False;
4378 check_format_string (format_str, exprlist, argoffset + 3);
4379 process_io_list (exprlist, &iolist_addr, &iolist_length, &iolist_rtx, 0, argoffset);
4380
4381 /* tree to call the function */
4382
4383 filename = force_addr_of (get_chill_filename ());
4384 linenumber = get_chill_linenumber ();
4385
4386 expand_expr_stmt (
4387 build_chill_function_call (outfunction,
4388 tree_cons (NULL_TREE, outstr_addr,
4389 tree_cons (NULL_TREE, outstr_length,
4390 tree_cons (NULL_TREE, fstr_addr,
4391 tree_cons (NULL_TREE, fstr_length,
4392 tree_cons (NULL_TREE, iolist_addr,
4393 tree_cons (NULL_TREE, iolist_length,
4394 tree_cons (NULL_TREE, filename,
4395 tree_cons (NULL_TREE, linenumber,
4396 NULL_TREE))))))))));
4397
4398 /* get rid of the iolist variable, if we have one */
4399 if (iolist_rtx != NULL_RTX)
4400 {
4401 free_temp_slots ();
4402 pop_temp_slots ();
4403 free_temp_slots ();
4404 pop_temp_slots ();
4405 }
4406
4407 /* return something the rest of the machinery can work with,
4408 i.e. (void)0 */
4409 return build1 (CONVERT_EXPR, void_type_node, integer_zero_node);
4410 }
4411
4412 tree
4413 build_chill_readtext (text_arg, exprlist)
4414 tree text_arg, exprlist;
4415 {
4416 tree instr_addr, instr_length, infunction;
4417 tree fstr_addr, fstr_length, fstrtype;
4418 tree iolist_addr = null_pointer_node;
4419 tree iolist_length = integer_zero_node;
4420 tree filename, linenumber;
4421 tree format_str = NULL_TREE, indexexpr = NULL_TREE;
4422 rtx iolist_rtx = NULL_RTX;
4423 int argoffset = 0;
4424
4425 /* make some checks */
4426 if (text_arg == NULL_TREE || TREE_CODE (text_arg) == ERROR_MARK)
4427 return error_mark_node;
4428
4429 if (exprlist != NULL_TREE)
4430 {
4431 if (TREE_CODE (exprlist) != TREE_LIST)
4432 return error_mark_node;
4433 }
4434
4435 /* check the text argument */
4436 if (CH_CHARS_TYPE_P (TREE_TYPE (text_arg)))
4437 {
4438 instr_addr = force_addr_of (text_arg);
4439 instr_length = size_in_bytes (TREE_TYPE (text_arg));
4440 infunction = lookup_name (get_identifier ("__readtext_s"));
4441 format_str = TREE_VALUE (exprlist);
4442 exprlist = TREE_CHAIN (exprlist);
4443 }
4444 else if (chill_varying_string_type_p (TREE_TYPE (text_arg)))
4445 {
4446 instr_addr
4447 = force_addr_of (build_component_ref (text_arg, var_data_id));
4448 instr_length = build_component_ref (text_arg, var_length_id);
4449 infunction = lookup_name (get_identifier ("__readtext_s"));
4450 format_str = TREE_VALUE (exprlist);
4451 exprlist = TREE_CHAIN (exprlist);
4452 }
4453 else if (CH_IS_TEXT_MODE (TREE_TYPE (text_arg)))
4454 {
4455 /* we have a text mode */
4456 tree indexmode;
4457
4458 if (! check_text (text_arg, 1, "READTEXT"))
4459 return error_mark_node;
4460 indexmode = text_indexmode (TREE_TYPE (text_arg));
4461 if (indexmode == void_type_node)
4462 {
4463 /* no index */
4464 format_str = TREE_VALUE (exprlist);
4465 exprlist = TREE_CHAIN (exprlist);
4466 }
4467 else
4468 {
4469 /* we have an index. there must be an index argument before format string */
4470 indexexpr = TREE_VALUE (exprlist);
4471 exprlist = TREE_CHAIN (exprlist);
4472 if (! CH_COMPATIBLE (indexexpr, indexmode))
4473 {
4474 if (chill_varying_string_type_p (TREE_TYPE (indexexpr)) ||
4475 (CH_CHARS_TYPE_P (TREE_TYPE (indexexpr)) ||
4476 (flag_old_strings && TREE_CODE (indexexpr) == INTEGER_CST &&
4477 TREE_CODE (TREE_TYPE (indexexpr)) == CHAR_TYPE)))
4478 error ("missing index expression");
4479 else
4480 error ("incompatible index mode");
4481 return error_mark_node;
4482 }
4483 if (exprlist == NULL_TREE)
4484 {
4485 error ("Too few arguments in call to `readtext'");
4486 return error_mark_node;
4487 }
4488 format_str = TREE_VALUE (exprlist);
4489 exprlist = TREE_CHAIN (exprlist);
4490 argoffset = 1;
4491 }
4492 instr_addr = force_addr_of (text_arg);
4493 instr_length = convert (integer_type_node, indexexpr);
4494 infunction = lookup_name (get_identifier ("__readtext_f"));
4495 }
4496 else
4497 {
4498 error ("argument 1 for READTEXT must be a TEXT location or CHARS(n) [ VARYING ] expression");
4499 return error_mark_node;
4500 }
4501
4502 /* check the format string */
4503 fstrtype = TREE_TYPE (format_str);
4504 if (CH_CHARS_TYPE_P (fstrtype))
4505 {
4506 /* we have a character string */
4507 fstr_addr = force_addr_of (format_str);
4508 fstr_length = size_in_bytes (fstrtype);
4509 }
4510 else if (chill_varying_string_type_p (fstrtype))
4511 {
4512 /* we have a CHARS(n) VARYING */
4513 fstr_addr
4514 = force_addr_of (build_component_ref (format_str, var_data_id));
4515 fstr_length = build_component_ref (format_str, var_length_id);
4516 }
4517 else
4518 {
4519 error ("`format string' for READTEXT must be a CHARACTER string");
4520 return error_mark_node;
4521 }
4522
4523 empty_printed = False;
4524 check_format_string (format_str, exprlist, argoffset + 3);
4525 process_io_list (exprlist, &iolist_addr, &iolist_length, &iolist_rtx, 1, argoffset);
4526
4527 /* build the function call */
4528 filename = force_addr_of (get_chill_filename ());
4529 linenumber = get_chill_linenumber ();
4530 expand_expr_stmt (
4531 build_chill_function_call (infunction,
4532 tree_cons (NULL_TREE, instr_addr,
4533 tree_cons (NULL_TREE, instr_length,
4534 tree_cons (NULL_TREE, fstr_addr,
4535 tree_cons (NULL_TREE, fstr_length,
4536 tree_cons (NULL_TREE, iolist_addr,
4537 tree_cons (NULL_TREE, iolist_length,
4538 tree_cons (NULL_TREE, filename,
4539 tree_cons (NULL_TREE, linenumber,
4540 NULL_TREE))))))))));
4541
4542 /* get rid of the iolist variable, if we have one */
4543 if (iolist_rtx != NULL_RTX)
4544 {
4545 free_temp_slots ();
4546 pop_temp_slots ();
4547 free_temp_slots ();
4548 pop_temp_slots ();
4549 }
4550
4551 /* return something the rest of the machinery can work with,
4552 i.e. (void)0 */
4553 return build1 (CONVERT_EXPR, void_type_node, integer_zero_node);
4554 }
4555
4556 /* this function build all neccesary enum-tables used for
4557 WRITETEXT or READTEXT of an enum */
4558
4559 void build_enum_tables ()
4560 {
4561 SAVE_ENUM_NAMES *names;
4562 SAVE_ENUMS *wrk;
4563 void *saveptr;
4564 /* We temporarily reset the maximum_field_alignment to zero so the
4565 compiler's init data structures can be compatible with the
4566 run-time system, even when we're compiling with -fpack. */
4567 extern int maximum_field_alignment;
4568 int save_maximum_field_alignment;
4569
4570 if (pass == 1)
4571 return;
4572
4573 save_maximum_field_alignment = maximum_field_alignment;
4574 maximum_field_alignment = 0;
4575
4576 /* output all names */
4577 names = used_enum_names;
4578
4579 while (names != (SAVE_ENUM_NAMES *)0)
4580 {
4581 tree var = get_unique_identifier ("ENUMNAME");
4582 tree type;
4583
4584 type = build_string_type (char_type_node,
4585 build_int_2 (IDENTIFIER_LENGTH (names->name) + 1, 0));
4586 names->decl = decl_temp1 (var, type, 1,
4587 build_chill_string (IDENTIFIER_LENGTH (names->name) + 1,
4588 IDENTIFIER_POINTER (names->name)),
4589 0, 0);
4590 names = names->forward;
4591 }
4592
4593 /* output the tables and pointers to tables */
4594 wrk = used_enums;
4595 while (wrk != (SAVE_ENUMS *)0)
4596 {
4597 tree varptr = wrk->ptrdecl;
4598 tree table_addr = null_pointer_node;
4599 tree init = NULL_TREE, one_entry;
4600 tree table, idxlist, tabletype, addr;
4601 SAVE_ENUM_VALUES *vals;
4602 int i;
4603
4604 vals = wrk->vals;
4605 for (i = 0; i < wrk->num_vals; i++)
4606 {
4607 tree decl = vals->name->decl;
4608 addr = build1 (ADDR_EXPR,
4609 build_pointer_type (char_type_node),
4610 decl);
4611 TREE_CONSTANT (addr) = 1;
4612 one_entry = tree_cons (NULL_TREE, build_int_2 (vals->val, 0),
4613 tree_cons (NULL_TREE, addr, NULL_TREE));
4614 one_entry = build_nt (CONSTRUCTOR, NULL_TREE, one_entry);
4615 init = tree_cons (NULL_TREE, one_entry, init);
4616 vals++;
4617 }
4618
4619 /* add the terminator (name = null_pointer_node) to constructor */
4620 one_entry = tree_cons (NULL_TREE, integer_zero_node,
4621 tree_cons (NULL_TREE, null_pointer_node, NULL_TREE));
4622 one_entry = build_nt (CONSTRUCTOR, NULL_TREE, one_entry);
4623 init = tree_cons (NULL_TREE, one_entry, init);
4624 init = nreverse (init);
4625 init = build_nt (CONSTRUCTOR, NULL_TREE, init);
4626 TREE_CONSTANT (init) = 1;
4627
4628 /* generate table */
4629 idxlist = build_tree_list (NULL_TREE,
4630 build_chill_range_type (NULL_TREE,
4631 integer_zero_node,
4632 build_int_2 (wrk->num_vals, 0)));
4633 tabletype = build_chill_array_type (TREE_TYPE (enum_table_type),
4634 idxlist, 0, NULL_TREE);
4635 table = decl_temp1 (get_unique_identifier ("ENUMTAB"), tabletype,
4636 1, init, 0, 0);
4637 table_addr = build1 (ADDR_EXPR,
4638 build_pointer_type (TREE_TYPE (enum_table_type)),
4639 table);
4640 TREE_CONSTANT (table_addr) = 1;
4641
4642 /* generate pointer to table */
4643 decl_temp1 (DECL_NAME (varptr), TREE_TYPE (table_addr),
4644 1, table_addr, 0, 0);
4645
4646 /* free that stuff */
4647 saveptr = wrk->forward;
4648
4649 free (wrk->vals);
4650 free (wrk);
4651
4652 /* next enum */
4653 wrk = saveptr;
4654 }
4655
4656 /* free all the names */
4657 names = used_enum_names;
4658 while (names != (SAVE_ENUM_NAMES *)0)
4659 {
4660 saveptr = names->forward;
4661 free (names);
4662 names = saveptr;
4663 }
4664
4665 used_enums = (SAVE_ENUMS *)0;
4666 used_enum_names = (SAVE_ENUM_NAMES *)0;
4667 maximum_field_alignment = save_maximum_field_alignment;
4668 }
This page took 0.248166 seconds and 5 git commands to generate.