1 /* T Y P E D E F I N I T I O N M E C H A N I S M */
21 #include "target_sizes.h"
26 pointer_align = AL_POINTER,
28 struct_align = AL_STRUCT;
34 pointer_size = SZ_POINTER,
56 /* first, do some checking
58 if( int_size != word_size )
59 fatal("integer size not equal to word size");
60 if( word_size != 2 && word_size != 4 )
61 fatal("illegal wordsize");
62 if( pointer_size != 2 && pointer_size != 4 )
63 fatal("illegal pointersize");
65 if( long_size < int_size )
66 fatal("longsize should be at least the integersize");
67 if( long_size > 2 * int_size)
68 fatal("longsize should be at most twice the integersize");
70 if( pointer_size < word_size )
71 fatal("pointersize should be at least the wordsize");
72 if( real_size != 4 && real_size != 8 )
73 fatal("illegal realsize");
78 /* First check the sizes of some basic EM-types
89 /* Initialize the predefined types
94 char_type = standard_type(T_CHAR, 1, (arith) 1);
95 char_type->enm_ncst = 128; /* only 7 bits ASCII characters */
99 bool_type = standard_type(T_ENUMERATION, 1, (arith) 1);
100 bool_type->enm_ncst = 2;
104 int_type = standard_type(T_INTEGER, int_align, int_size);
108 real_type = standard_type(T_REAL, real_align, real_size);
113 long_type = standard_type(T_LONG, long_align, long_size);
118 string_type = standard_type(T_STRING, pointer_align, pointer_size);
120 /* an unique type for standard procedures and functions
122 std_type = construct_type(T_PROCEDURE, NULLTYPE);
124 /* text (file of char) type
126 text_type = construct_type(T_FILE, char_type);
127 text_type->tp_flags |= T_HASFILE;
129 /* an unique type indicating an error
131 error_type = standard_type(T_ERROR, 1, (arith) 1);
132 void_type = error_type;
134 /* the nilvalue has an unique type
136 nil_type = construct_type(T_POINTER, error_type);
138 /* the type of an empty set is generic
140 emptyset_type = construct_type(T_SET, error_type);
141 emptyset_type->tp_size = word_size;
142 emptyset_type->tp_align = word_align;
149 return ((sz) + ((arith)0x80<<(((nbytes)-1)*8)) & ~full_mask[(nbytes)]) == 0;
153 standard_type(fund, algn, size)
156 register struct type *tp = new_type();
159 tp->tp_palign = algn ? algn : 1;
161 tp->tp_align = word_align;
162 tp->tp_size = WA(size);
168 construct_type(fund, tp)
169 register struct type *tp;
171 /* fund must be a type constructor.
172 * The pointer to the constructed type is returned.
174 register struct type *dtp = new_type();
176 switch( dtp->tp_fund = fund ) {
179 dtp->tp_align = pointer_align;
180 dtp->tp_size = 2 * pointer_size;
184 dtp->tp_align = dtp->tp_palign = pointer_align;
185 dtp->tp_size = dtp->tp_psize = pointer_size;
193 dtp->tp_align = dtp->tp_palign = word_align;
194 dtp->tp_size = dtp->tp_psize = sizeof(struct file);
199 dtp->tp_align = tp->tp_align;
200 dtp->tp_size = tp->tp_size;
201 dtp->tp_palign = tp->tp_palign;
202 dtp->tp_psize = tp->tp_psize;
206 crash("funny type constructor");
214 proc_type(parameters, n_bytes_params)
215 struct paramlist *parameters;
216 arith n_bytes_params;
218 register struct type *tp = construct_type(T_PROCEDURE, NULLTYPE);
220 tp->prc_params = parameters;
221 tp->prc_nbpar = n_bytes_params;
226 func_type(parameters, n_bytes_params, resulttype)
227 struct paramlist *parameters;
228 arith n_bytes_params;
229 struct type *resulttype;
231 register struct type *tp = construct_type(T_FUNCTION, resulttype);
233 tp->prc_params = parameters;
234 tp->prc_nbpar = n_bytes_params;
239 register struct type **ptp;
240 register struct node *nd;
242 register struct def *df;
245 if( ChkLinkOrName(nd) ) {
246 if( nd->nd_class != Def )
247 node_error(nd, "type expected");
249 /* register struct def *df = nd->nd_def; */
252 df->df_flags |= D_USED;
253 if( df->df_kind & (D_TYPE | D_FTYPE | D_ERROR) ) {
255 node_error(nd, "type \"%s\" not declared",
256 df->df_idf->id_text);
261 node_error(nd,"identifier \"%s\" is not a type",
262 df->df_idf->id_text);
269 register struct node *lb, *ub;
271 /* Construct a subrange type from the constant expressions
272 indicated by "lb" and "ub", but first perform some checks
275 register struct type *tp = lb->nd_type, *res;
277 if( !TstTypeEquiv(lb->nd_type, ub->nd_type) ) {
278 node_error(ub, "types of subrange bounds not equal");
284 if( !(tp->tp_fund & T_ORDINAL) ) {
285 node_error(ub, "illegal base type for subrange");
291 if( lb->nd_INT > ub->nd_INT )
292 node_error(ub, "lower bound exceeds upper bound");
294 /* Now construct resulting type
296 res = construct_type(T_SUBRANGE, tp);
297 res->sub_lb = lb->nd_INT;
298 res->sub_ub = ub->nd_INT;
299 if (res->sub_lb >= 0) {
300 if (ufit(res->sub_ub, 1)) {
304 else if (ufit(res->sub_ub, 2)) {
306 res->tp_palign = 2 < word_align ? 2 : word_align;
310 if (fit(res->sub_lb, 1) && fit(res->sub_ub, 1)) {
314 else if (fit(res->sub_lb, 2) && fit(res->sub_ub, 2)) {
316 res->tp_palign = 2 < word_align ? 2 : word_align;
323 getbounds(tp, plo, phi)
324 register struct type *tp;
327 /* Get the bounds of a bounded type
332 if( tp->tp_fund & T_SUBRANGE ) {
336 else if( tp->tp_fund & T_INTEGER ) {
342 *phi = tp->enm_ncst - 1;
348 register struct type *tp;
349 unsigned short packed;
351 /* Construct a set type with base type "tp", but first
354 struct type *basetype;
355 static struct type *int_set = 0;
358 if( tp == int_type ) {
361 struct node *lbn = new_node();
362 struct node *ubn = new_node();
364 lbn->nd_type = ubn->nd_type = int_type;
365 /* the bounds are implicit */
367 ubn->nd_INT = max_intset;
369 int_set = subr_type(lbn, ubn);
376 /* SET OF subrange/enumeration/char */
378 error("illegal base type of set");
382 basetype = BaseType(tp);
383 if( basetype == int_type ) {
384 /* subrange of integers */
385 getbounds(tp, &lb, &ub);
386 if( lb < 0 || ub > max_intset ) {
387 error("illegal integer base type of set");
393 else getbounds(basetype, &lb, &ub);
397 /* at this point lb and ub denote the bounds of the host-type of the
398 * base-type of the set
401 tp = construct_type(T_SET, tp);
402 tp->tp_flags |= packed;
404 tp->tp_psize = (ub - lb + 8) >> 3;
405 tp->tp_size = WA(tp->tp_psize);
406 tp->tp_align = word_align;
407 if( !packed || word_size % tp->tp_psize != 0 ) {
408 tp->tp_psize = tp->tp_size;
409 tp->tp_palign = word_align;
411 else tp->tp_palign = tp->tp_psize;
417 ArrayElSize(tp, packed)
418 register struct type *tp;
420 /* Align element size to alignment requirement of element type.
421 Also make sure that its size is either a dividor of the word_size,
426 if( tp->tp_fund & T_ARRAY && !(tp->tp_flags & T_CHECKED) )
432 algn = align(tp->tp_psize, tp->tp_palign);
433 if( word_size % algn != 0 ) {
434 /* algn is not a dividor of the word size, so make sure it
439 if( !fit(algn, (int) word_size) ) {
440 error("element of array too large");
446 register struct type *tp;
448 /* Assign sizes to an array type, and check index type
450 register struct type *index_type = IndexType(tp);
451 register struct type *elem_type = tp->arr_elem;
454 tp->tp_flags |= T_CHECKED;
455 tp->arr_elsize = ArrayElSize(elem_type,(int) IsPacked(tp));
459 if( !bounded(index_type) ) {
460 error("illegal index type");
461 tp->tp_psize = tp->tp_size = tp->arr_elsize;
462 tp->tp_palign = tp->tp_align = elem_type->tp_align;
463 tp->next = error_type;
467 getbounds(index_type, &lo, &hi);
470 if( diff < 0 || !fit(diff, (int) word_size) ) {
471 error("too many elements in array");
474 if( (unsigned long)full_mask[(int) pointer_size]/(diff + 1) <
476 error("array too large");
478 tp->tp_psize = (diff + 1) * tp->arr_elsize;
479 tp->tp_palign = (word_size % tp->tp_psize) ? word_align : tp->tp_psize;
480 tp->tp_size = WA(tp->tp_psize);
481 tp->tp_align = word_align;
483 /* generate descriptor and remember label.
485 tp->arr_ardescr = ++data_label;
486 C_df_dlb(data_label);
489 C_rom_cst(tp->arr_elsize);
492 FreeForward(for_type)
493 register struct forwtype *for_type;
495 if( !for_type ) return;
497 FreeForward(for_type->f_next);
498 free_node(for_type->f_node);
499 free_forwtype(for_type);
504 /* check all forward references (in pointer types) */
506 register struct def *df = CurrentScope->sc_def;
507 register struct def *ldf = NULLDEF;
511 if( df->df_kind & (D_FORWTYPE | D_FTYPE) ) {
512 register struct forwtype *fw_type = df->df_fortype;
514 if( df->df_kind == D_FORWTYPE ) {
515 /* forward type not in this scope declared */
516 register struct scopelist *scl = nextvisible(CurrVis);
520 /* look in enclosing scopes */
521 df1 = lookup(df->df_fortype->f_node->nd_IDF,
522 scl->sc_scope, D_INUSE);
524 scl = nextvisible( scl );
527 if( !df1 || df1->df_kind != D_TYPE ) {
528 /* bad forward type */
534 /* remove the def struct in the current scope */
536 CurrentScope->sc_def = df->df_nextinscope;
538 ldf->df_nextinscope = df->df_nextinscope;
540 /* remove the def struct from symbol-table */
544 else /* forward type was resolved */
548 if( tp == error_type )
549 node_error(fw_type->f_node,
550 "identifier \"%s\" is not a type",
551 df->df_idf->id_text);
552 fw_type->f_type->next = tp;
555 stb_addtp("(forward_type)", fw_type->f_type);
558 fw_type = fw_type->f_next;
561 FreeForward( df->df_fortype );
562 df->df_flags |= D_USED;
563 if( tp == error_type )
564 df->df_kind = D_ERROR;
566 df->df_kind = D_TYPE;
569 df = df->df_nextinscope;
573 TstCaseConstants(nd, sel, sel1)
574 register struct node *nd;
575 register struct selector *sel, *sel1;
577 /* Insert selector of nested variant (sel1) in tagvalue-table of
578 current selector (sel).
581 if( !TstCompat(nd->nd_type, sel->sel_type) )
582 node_error(nd, "type incompatibility in caselabel");
583 else if( sel->sel_ptrs ) {
584 arith i = nd->nd_INT - sel->sel_lb;
586 if( i < 0 || i >= sel->sel_ncst )
587 node_error(nd, "case constant: out of bounds");
588 else if( sel->sel_ptrs[i] != sel )
590 "record variant: multiple defined caselabel");
592 sel->sel_ptrs[i] = sel1;
605 return pos + ((i = pos % al) ? al - i : 0);
612 /* Greatest Common Divisor
628 /* Least Common Multiple
630 return m * (n / gcd(m, n));
635 register struct type *tp;
639 print("align:%d; size:%ld;", tp->tp_align, (long) tp->tp_size);
642 switch( tp->tp_fund ) {
644 print("ENUMERATION; ncst:%d", tp->enm_ncst); break;
646 print("INTEGER"); break;
648 print("LONG"); break;
650 print("REAL"); break;
652 print("CHAR"); break;
654 print("STRING"); break;
658 register struct paramlist *par = ParamList(tp);
660 if( tp->tp_fund == T_PROCEDURE )
667 if( IsVarParam(par) ) print("VAR ");
668 DumpType(TypeOfParam(par));
675 print("FILE"); break;
677 print("STRINGCONST"); break;
679 print("SUBRANGE %ld-%ld", (long) tp->sub_lb, (long) tp->sub_ub);
686 DumpType(tp->arr_elem);
692 print("RECORD"); break;
694 print("POINTER"); break;
698 if( tp->next && tp->tp_fund != T_POINTER ) {
699 /* Avoid printing recursive types!