2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 * Author: Ceriel J.H. Jacobs
8 /* T Y P E D E F I N I T I O N M E C H A N I S M */
10 /* $Id: type.c,v 1.102 1996/08/14 07:42:38 ceriel Exp $ */
31 #include "uns_arith.h"
34 #include "target_sizes.h"
37 short_align = AL_SHORT,
40 float_align = AL_FLOAT,
41 double_align = AL_DOUBLE,
42 pointer_align = AL_POINTER,
43 struct_align = AL_STRUCT;
47 dword_size = 2 * SZ_WORD,
49 short_size = SZ_SHORT,
51 float_size = SZ_FLOAT,
52 double_size = SZ_DOUBLE,
53 pointer_size = SZ_POINTER;
56 #define arith_sign ((arith) (1L << (sizeof(arith) * 8 - 1)))
80 construct_type(fund, tp)
84 /* fund must be a type constructor.
85 The pointer to the constructed type is returned.
87 register t_type *dtp = new_type();
89 switch (dtp->tp_fund = fund) {
93 dtp->tp_align = pointer_align;
94 dtp->tp_size = pointer_size;
98 dtp->tp_align = word_align;
102 dtp->tp_value.tp_arr = new_array();
103 dtp->tp_align = struct_align;
108 dtp->tp_value.tp_subrange = new_subrange();
109 dtp->tp_align = tp->tp_align;
110 dtp->tp_size = tp->tp_size;
114 crash("funny type constructor");
128 if (i) return pos + (al - i);
133 standard_type(fund, algn, size)
138 register t_type *tp = new_type();
143 if (fund == T_ENUMERATION || fund == T_CHAR) {
144 tp->tp_value.tp_enum = new_enume();
152 /* Initialize the predefined types
156 /* first, do some checking
158 if ((int) int_size != (int) word_size) {
159 fatal("integer size not equal to word size");
162 if ((int) long_size < (int) int_size) {
163 fatal("long integer size smaller than integer size");
166 if ((int) double_size < (int) float_size) {
167 fatal("long real size smaller than real size");
170 ret_area_size = (int) double_size > ((int) pointer_size << 1) ?
171 double_size : (pointer_size << 1);
175 char_type = standard_type(T_CHAR, 1, (arith) 1);
176 char_type->enm_ncst = 256;
180 bool_type = standard_type(T_ENUMERATION, 1, (arith) 1);
181 bool_type->enm_ncst = 2;
183 /* integer types, also a "intorcard", for integer constants between
186 int_type = standard_type(T_INTEGER, int_align, int_size);
187 longint_type = standard_type(T_INTEGER, long_align, long_size);
188 longcard_type = standard_type(T_CARDINAL, long_align, long_size);
189 card_type = standard_type(T_CARDINAL, int_align, int_size);
190 intorcard_type = standard_type(T_INTORCARD, int_align, int_size);
191 longintorcard_type = standard_type(T_INTORCARD, long_align, long_size);
195 real_type = standard_type(T_REAL, float_align, float_size);
196 longreal_type = standard_type(T_REAL, double_align, double_size);
200 word_type = standard_type(T_WORD, word_align, word_size);
201 byte_type = standard_type(T_WORD, 1, (arith) 1);
202 address_type = construct_type(T_POINTER, word_type);
204 /* create BITSET type
205 TYPE BITSET = SET OF [0..W-1];
206 The subrange is a subrange of type cardinal, because the lower bound
207 is a non-negative integer (See Rep. 6.3)
209 tp = construct_type(T_SUBRANGE, card_type);
211 tp->sub_ub = (int) word_size * 8 - 1;
212 bitset_type = set_type(tp);
214 /* a unique type for standard procedures and functions
216 std_type = construct_type(T_PROCEDURE, NULLTYPE);
218 /* a unique type indicating an error
220 error_type = new_type();
221 *error_type = *char_type;
222 void_type = error_type;
229 return ((sz) + ((arith)0x80<<(((nbytes)-1)*8)) & ~full_mask[(nbytes)]) == 0;
241 else if (ufit(n, (int)short_size)) {
242 tp->tp_size = short_size;
243 tp->tp_align = short_align;
251 register t_type *tp =
252 standard_type(T_ENUMERATION, int_align, int_size);
254 EnterEnumList(EnumList, tp);
255 if (! fit(tp->enm_ncst, (int) int_size)) {
256 node_error(EnumList, "too many enumeration literals");
258 u_small(tp, (arith) (tp->enm_ncst-1));
268 if (ChkDesig(pnd, D_USED)) {
269 register t_node *nd = *pnd;
270 if (nd->nd_class != Def) {
271 node_error(nd, "type expected");
277 if (df->df_kind&(D_ISTYPE|D_FORWARD|D_FORWTYPE|D_ERROR)) {
279 node_error(nd,"type \"%s\" not (yet) declared", df->df_idf->id_text);
284 if (df->df_kind == D_FORWTYPE) {
285 /* Here, df->df_type was already set,
286 so there is an actual definition in the
287 surrounding scope, which is now used.
289 ForceForwardTypeDef(df);
293 node_error(nd, "identifier \"%s\" is not a type", df->df_idf->id_text);
301 chk_bounds(l1, l2, fund)
304 /* compare to arith's, but be careful. They might be unsigned
306 if (fund == T_INTEGER) {
309 #ifdef UNSIGNED_ARITH
310 return (UNSIGNED_ARITH) l2 >= (UNSIGNED_ARITH) l1;
312 return (l2 & arith_sign ?
313 (l1 & arith_sign ? l2 >= l1 : 1) :
314 (l1 & arith_sign ? 0 : l2 >= l1)
324 /* Check that the value i fits in the subrange or enumeration
325 type tp. Return 1 if so, 0 otherwise
328 switch(tp->tp_fund) {
331 return i >= 0 && i < tp->enm_ncst;
334 return chk_bounds(i, tp->sub_ub, SubBaseType(tp)->tp_fund) &&
335 chk_bounds(tp->sub_lb, i, SubBaseType(tp)->tp_fund);
342 subr_type(lb, ub, base)
347 /* Construct a subrange type from the constant expressions
348 indicated by "lb" and "ub", but first perform some
349 checks. "base" is either a user-specified base-type, or NULL.
351 register t_type *tp = BaseType(lb->nd_type);
352 register t_type *res;
354 if (tp == intorcard_type) {
355 /* Lower bound >= 0; in this case, the base type is CARDINAL,
356 according to the language definition, par. 6.3.
357 But what if the upper-bound is of type INTEGER (f.i.
358 MAX(INTEGER)? The Report does not answer this. Fix this
359 for the time being, by making it an INTEGER subrange.
362 assert(lb->nd_INT >= 0);
363 if (BaseType(ub->nd_type) == int_type ||
364 (base && BaseType(base) == int_type)) tp = int_type;
368 if (!ChkCompat(&ub, tp, "subrange bounds")) {
374 if (! (tp->tp_fund & T_DISCRETE)) {
375 node_error(lb, "illegal base type for subrange");
379 /* Now construct resulting type
381 res = construct_type(T_SUBRANGE, tp);
382 res->sub_lb = lb->nd_INT;
383 res->sub_ub = ub->nd_INT;
387 if (! chk_bounds(lb->nd_INT, ub->nd_INT, tp->tp_fund)) {
388 node_error(lb, "lower bound exceeds upper bound");
389 ub->nd_INT = lb->nd_INT;
390 res->sub_ub = res->sub_lb;
393 if (tp == card_type) {
394 u_small(res, res->sub_ub);
396 else if (tp == int_type) {
397 if (fit(res->sub_lb, 1) && fit(res->sub_ub, 1)) {
401 else if (fit(res->sub_lb, (int)short_size) &&
402 fit(res->sub_ub, (int)short_size)) {
403 res->tp_size = short_size;
404 res->tp_align = short_align;
409 if (base->tp_fund == T_SUBRANGE) {
410 /* Check that the bounds of "res" fall within the range
413 if (! in_range(res->sub_lb, base) ||
414 ! in_range(res->sub_ub, base)) {
415 error("base type has insufficient range");
417 base = base->tp_next;
419 if ((base->tp_fund & (T_ENUMERATION|T_CHAR)) ||
421 if (res->tp_next != base) {
422 error("specified basetype for subrange not compatible with bounds");
425 else if (base == int_type) {
426 if (res->tp_next == card_type &&
427 ! chk_bounds(res->sub_ub,
428 max_int[(int)int_size],
430 error("upperbound too large for type INTEGER");
433 else error("illegal base for a subrange");
440 proc_type(result_type, parameters, n_bytes_params)
443 arith n_bytes_params;
445 register t_type *tp = construct_type(T_PROCEDURE, result_type);
447 tp->prc_params = parameters;
448 tp->prc_nbpar = n_bytes_params;
449 if (! fit(n_bytes_params, (int) word_size)) {
450 error("maximum parameter byte count exceeded");
452 if (result_type && ! fit(WA(result_type->tp_size), (int) word_size)) {
453 error("maximum return value size exceeded");
461 /* generate a range check descriptor for type "tp" when
462 neccessary. Return its label.
466 arith size = tp->tp_size;
467 extern char *long2str();
468 register t_type *btp = BaseType(tp);
470 if (size < word_size) size = word_size;
471 getbounds(tp, &lb, &ub);
473 if (tp->tp_fund == T_SUBRANGE) {
474 if (!(ol = tp->sub_rck)) {
475 tp->sub_rck = ++data_label;
478 else if (!(ol = tp->enm_rck)) {
479 tp->enm_rck = ++data_label;
482 C_df_dlb(ol = data_label);
483 C_rom_icon(long2str((long)lb,10), size);
484 C_rom_icon(long2str((long)ub,10), size);
487 if (size <= word_size) {
488 CAL(btp->tp_fund == T_INTEGER ? "rcki" : "rcku", (int) pointer_size);
491 CAL(btp->tp_fund == T_INTEGER ? "rckil" : "rckul", (int) pointer_size);
495 getbounds(tp, plo, phi)
499 /* Get the bounds of a bounded type
504 if (tp->tp_fund == T_SUBRANGE) {
510 *phi = tp->enm_ncst - 1;
518 /* Construct a set type with base type "tp", but first
521 arith lb, ub, diff, alloc_size;
523 if (! bounded(tp) || tp->tp_size > word_size) {
524 error("illegal base type for set");
528 getbounds(tp, &lb, &ub);
532 warning(W_STRICT, "base type of set has negative lower bound");
538 error("set type limits exceeded");
542 tp = construct_type(T_SET, tp);
543 tp->tp_size = WA((diff + 7) >> 3);
544 alloc_size = (tp->tp_size / word_size + 1) * sizeof(arith);
545 tp->set_sz = alloc_size;
546 if (tp->set_sz != alloc_size) {
547 error("set size too large");
557 /* Align element size to alignment requirement of element type.
558 Also make sure that its size is either a dividor of the word_size,
562 register t_type *elem_type = tp->arr_elem;
564 if (elem_type->tp_fund == T_ARRAY) ArraySizes(elem_type);
565 algn = align(elem_type->tp_size, elem_type->tp_align);
566 if (word_size % algn != 0) {
567 /* algn is not a dividor of the word size, so make sure it
572 if (! fit(algn, (int) word_size)) {
573 error("element size of array too large");
575 tp->arr_elsize = algn;
576 if (tp->tp_align < elem_type->tp_align) {
577 tp->tp_align = elem_type->tp_align;
584 /* Assign sizes to an array type, and check index type
586 register t_type *index_type = IndexType(tp);
593 if (index_type->tp_size > word_size || ! bounded(index_type)) {
594 error("illegal index type");
595 tp->tp_size = tp->arr_elsize;
599 getbounds(index_type, &(tp->arr_low), &(tp->arr_high));
600 diff = tp->arr_high - tp->arr_low;
602 if (diff < 0 || ! fit(diff, (int) int_size)) {
603 error("too many elements in array");
606 tp->tp_size = align((diff + 1) * tp->arr_elsize, tp->tp_align);
607 /* ??? check overflow ??? */
608 if (! ufit(tp->tp_size, (int) pointer_size)) {
609 error("array too large");
612 /* generate descriptor and remember label.
614 tp->arr_descr = ++data_label;
615 C_df_dlb(tp->arr_descr);
616 C_rom_cst((arith) 0);
618 C_rom_cst(tp->arr_elsize);
624 /* Release type structures indicated by "tp".
625 This procedure is only called for types, constructed with
628 register t_param *pr, *pr1;
630 assert(tp->tp_fund == T_PROCEDURE);
636 free_def(pr1->par_def);
643 DeclareType(nd, df, tp)
648 /* A type with type-description "tp" is declared and must
649 be bound to definition "df".
650 This routine also handles the case that the type-field of
651 "df" is already bound. In that case, it is either an opaque
652 type, or an error message was given when "df" was created.
654 register t_type *df_tp = df->df_type;
656 if (df_tp && df_tp->tp_fund == T_HIDDEN) {
657 if (! (tp->tp_fund & (T_POINTER|T_HIDDEN|T_EQUAL))) {
659 "opaque type \"%s\" is not a pointer type",
660 df->df_idf->id_text);
663 df_tp->tp_fund = T_EQUAL;
664 while (tp != df_tp && tp->tp_fund == T_EQUAL) {
668 /* Circular definition! */
670 "opaque type \"%s\" has a circular definition",
671 df->df_idf->id_text);
672 tp->tp_next = error_type;
677 if (BaseType(tp)->tp_fund == T_ENUMERATION) {
682 if (options['g']) stb_string(df, D_TYPE);
685 SolveForwardTypeRefs(df);
688 SolveForwardTypeRefs(df)
693 if (df->df_kind == D_FORWTYPE) {
694 nd = df->df_forw_node;
696 df->df_kind = D_TYPE;
698 nd->nd_type->tp_next = df->df_type;
700 if (options['g'] && nd->nd_type->tp_dbindex < 0) {
701 stb_addtp("(forward_type)", nd->nd_type);
706 FreeNode(df->df_forw_node);
711 ForceForwardTypeDef(df)
714 register t_def *df1 = df, *df2;
715 register t_node *nd = df->df_forw_node;
717 while (df && df->df_kind == D_FORWTYPE) {
718 RemoveFromIdList(df);
719 if ((df2 = df->df_scope->sc_def) == df) {
720 df->df_scope->sc_def = df->df_nextinscope;
723 while (df2->df_nextinscope != df) {
724 df2 = df2->df_nextinscope;
726 df2->df_nextinscope = df->df_nextinscope;
728 df = df->df_forw_def;
730 while (nd->nd_class == Link) {
733 df = lookfor(nd, CurrVis, 1, 0);
734 if (! df->df_kind & (D_ERROR|D_TYPE)) {
735 node_error(nd, "\"%s\" is not a type", df1->df_idf->id_text);
737 while (df1 && df1->df_kind == D_FORWTYPE) {
738 df2 = df1->df_forw_def;
739 df1->df_type = df->df_type;
740 SolveForwardTypeRefs(df1);
748 register t_type *tpx;
751 if (tpx) while (tpx->tp_fund == T_EQUAL) tpx = tpx->tp_next;
759 /* POINTER TO IDENTIFIER construction. The IDENTIFIER resides
760 in "dot". This routine handles the different cases.
763 register t_def *df, *df1;
765 if ((df1 = lookup(dot.TOK_IDF, CurrentScope, D_IMPORTED, D_USED))) {
766 /* Either a Module or a Type, but in both cases defined
767 in this scope, so this is the correct identification
769 switch(df1->df_kind) {
771 FreeNode(df1->for_node);
772 df1->df_kind = D_FORWTYPE;
773 df1->df_forw_node = 0;
776 nd = dot2node(Link, NULLNODE, df1->df_forw_node);
777 df1->df_forw_node = nd;
785 if ((df1 = lookfor(nd, CurrVis, 0, D_USED))->df_kind == D_MODULE) {
786 /* A Modulename in one of the enclosing scopes.
787 It is not clear from the language definition that
788 it is correct to handle these like this, but
789 existing compilers do it like this, and the
790 alternative is difficult with a lookahead of only
792 This path should actually only be taken if the next token
799 /* Enter a forward reference into a list belonging to the
800 current scope. This is used for POINTER declarations, which
801 may have forward references that must howewer be declared in the
804 df = define(nd->nd_IDF, CurrentScope, D_FORWTYPE);
805 assert(df->df_kind == D_FORWTYPE);
806 df->df_flags |= D_USED | D_DEFINED;
808 df->df_forw_node = nd;
809 if (df != df1 && (df1->df_kind & (D_TYPE | D_FORWTYPE))) {
810 /* "df1" refers to a possible identification, but
811 we cannot be sure at this point. For the time
812 being, however, we use this one.
814 df->df_type = df1->df_type;
815 df->df_forw_def = df1;
824 /* Greatest Common Divisor
840 /* Least Common Multiple
842 return m * (n / gcd(m, n));
846 intorcard(left, right)
847 register t_type *left, *right;
849 if (left->tp_fund == T_INTORCARD) {
854 if (right->tp_fund == T_INTORCARD) {
855 if (left->tp_fund == T_INTEGER || left->tp_fund == T_CARDINAL) {
868 print("align:%d; size:%ld;", tp->tp_align, (long) tp->tp_size);
871 switch(tp->tp_fund) {
876 print("ENUMERATION; ncst:%d", tp->enm_ncst); break;
878 print("INTEGER"); break;
880 print("CARDINAL"); break;
882 print("REAL"); break;
884 print("HIDDEN"); break;
886 print("EQUAL"); break;
888 print("POINTER"); break;
890 print("CHAR"); break;
892 print("WORD"); break;
896 print("SUBRANGE %ld-%ld", (long) tp->sub_lb, (long) tp->sub_ub);
900 register t_param *par = ParamList(tp);
906 if (IsVarParam(par)) print("VAR ");
907 DumpType(TypeOfParam(par));
916 DumpType(tp->arr_elem);
918 DumpType(tp->tp_next);
922 print("STRING"); break;
924 print("INTORCARD"); break;
928 if (tp->tp_next && tp->tp_fund != T_POINTER) {
929 /* Avoid printing recursive types!
932 DumpType(tp->tp_next);