1 /* $Id: type.c,v 1.13 1994/06/24 11:01:39 ceriel Exp $ */
3 /* Routines to create type structures */
16 p_type int_type, char_type, short_type, long_type, bool_type;
17 p_type uint_type, uchar_type, ushort_type, ulong_type;
19 p_type float_type, double_type;
20 p_type string_type, address_type;
22 long int_size = sizeof(int),
24 short_size = sizeof(short),
25 long_size = sizeof(long),
26 pointer_size = sizeof(char *);
28 long float_size = sizeof(float),
29 double_size = sizeof(double);
35 static struct bounds ibounds[2] = {
40 static struct bounds ubounds[2] = {
45 static long max_int[8], max_uns[8];
47 struct integer_types {
52 static struct integer_types i_types[4];
53 static struct integer_types u_types[4];
55 #define ufit(n, nb) Xfit(n, nb, ubounds)
56 #define ifit(n, nb) Xfit(n, nb, ibounds)
57 #define Xfit(n, nb, b) ((n) >= (b)[(nb)-1].low && (n) <= (b)[(nb)-1].high)
59 /* Create a subrange type, but is it really a subrange? */
61 subrange_type(A, base_index, c1, c2, result_index)
62 int *base_index, *result_index;
70 /* Subrange of itself is a special case ... */
72 result_index[0] == base_index[0] &&
73 result_index[1] == base_index[1]) {
75 /* c1 = 0 and c2 = 0 -> void */
76 if (c1 == 0 && c2 == 0) {
80 if ((c1 == 0 || c1 == -128) && c2 == 127) {
84 if (c1 == 0 && c2 == 255) {
92 if (itself) base_type = int_type; else base_type = *(tp_lookup(base_index));
95 /* c2 = 0 and c1 > 0 -> real */
96 if (c2 == 0 && c1 > 0) {
97 if (c1 == float_size) return float_type;
101 /* c1 = 0 and base_index indicates int_type or itself -> unsigned,
102 c1 = -c2 - 1 and base_index indicates int_type or itself -> integer
104 if (itself || base_type == int_type) {
105 register struct integer_types *ip = 0;
109 else if (c1 == -c2 - 1) {
113 while (ip->maxval != 0 && ip->maxval != c2) ip++;
114 if (ip->maxval) return ip->type;
118 /* if we get here, it actually is a subrange type */
120 p->ty_class = T_SUBRANGE;
123 p->ty_base = base_type;
126 /* determine size of subrange type */
127 p->ty_size = base_type->ty_size;
128 if (!A && p->ty_base == uint_type) {
129 if (ufit(p->ty_up, 1)) {
132 else if (ufit(p->ty_up, (int)short_size)) {
133 p->ty_size = short_size;
136 if (!A && p->ty_base == int_type) {
137 if (ifit(p->ty_up, 1) && ifit(p->ty_low, 1)) {
140 else if (ifit(p->ty_up, (int)short_size) &&
141 ifit(p->ty_low, (int)short_size)) {
142 p->ty_size = short_size;
153 switch(tp->ty_class) {
155 if (tp->ty_A) return 0;
156 if (tp->ty_low <= tp->ty_up) return tp->ty_up - tp->ty_low + 1;
157 return tp->ty_low - tp->ty_up + 1;
160 if (tp->ty_size == 1) return 256;
161 if (tp->ty_size == 2) return 65536L;
165 return tp->ty_nenums;
174 array_type(bound_type, el_type)
175 p_type bound_type, el_type;
177 register p_type tp = new_type();
179 tp->ty_class = T_ARRAY;
180 tp->ty_index = bound_type;
181 switch(bound_type->ty_class) {
183 if (bound_type->ty_A) break;
184 tp->ty_lb = bound_type->ty_low;
185 tp->ty_hb = bound_type->ty_up;
189 tp->ty_hb = bound_type->ty_nenums-1;
193 tp->ty_hb = bound_type->ty_size == 1 ? 255 : 65535L;
196 tp->ty_lb = bound_type->ty_size == 1 ? -128 : -32768;
197 tp->ty_hb = bound_type->ty_size == 1 ? 127 : 32767;
200 tp->ty_elements = el_type;
201 tp->ty_size = (*currlang->arrayelsize)(el_type->ty_size) * nel(bound_type);
206 basic_type(fund, size)
210 register p_type p = new_type();
220 /* Determine the size and low of a set type */
221 register p_type base = tp->ty_setbase;
223 if (base->ty_class == T_SUBRANGE) {
224 tp->ty_size = (base->ty_up - base->ty_low + 7) >> 3;
225 tp->ty_setlow = base->ty_low;
227 else if (base->ty_class == T_INTEGER) {
228 tp->ty_size = (max_int[(int)base->ty_size] + 1) >> 2;
229 tp->ty_setlow = -max_int[(int)base->ty_size] - 1;
232 assert(base->ty_class == T_UNSIGNED);
233 tp->ty_size = (max_uns[(int)base->ty_size] + 1) >> 3;
247 max_int[i] = x & ~(1L << (8*i - 1));
249 int_type = basic_type(T_INTEGER, int_size);
250 long_type = basic_type(T_INTEGER, long_size);
251 short_type = basic_type(T_INTEGER, short_size);
252 char_type = basic_type(T_INTEGER, char_size);
253 uint_type = basic_type(T_UNSIGNED, int_size);
254 ulong_type = basic_type(T_UNSIGNED, long_size);
255 ushort_type = basic_type(T_UNSIGNED, short_size);
256 uchar_type = basic_type(T_UNSIGNED, char_size);
257 string_type = basic_type(T_STRING, 0L);
258 address_type = basic_type(T_POINTER, pointer_size);
259 void_type = basic_type(T_VOID, 0L);
260 float_type = basic_type(T_REAL, float_size);
261 double_type = basic_type(T_REAL, double_size);
263 i_types[0].maxval = max_int[(int)int_size]; i_types[0].type = int_type;
264 i_types[1].maxval = max_int[(int)short_size]; i_types[1].type = short_type;
265 i_types[2].maxval = max_int[(int)long_size]; i_types[2].type = long_type;
266 u_types[0].maxval = max_uns[(int)int_size]; u_types[0].type = uint_type;
267 u_types[1].maxval = max_uns[(int)short_size]; u_types[1].type = ushort_type;
268 u_types[2].maxval = max_uns[(int)long_size]; u_types[2].type = ulong_type;
272 * Some code to handle type indices, which are pairs of integers.
273 * What we need is a two-dimensional array, but we don't know how large
274 * it is going to be, so we use a list of rows instead.
276 static struct tp_index {
280 static unsigned list_len;
285 tp_lookup(type_index)
289 register struct tp_index *p;
291 while (type_index[0] >= list_len) {
293 list_row = (struct tp_index *) Realloc((char *) list_row,
294 (list_len += NINCR) * sizeof(struct tp_index));
296 else list_row = (struct tp_index *)
297 Malloc((list_len = NINCR) * sizeof(struct tp_index));
298 for (i = NINCR; i > 0; i--) {
299 list_row[list_len - i].len = 0;
302 p = &list_row[type_index[0]];
303 while (type_index[1] >= p->len) {
304 int indx = p->len/NINCR;
306 p->row = (p_type **) Realloc((char *) p->row,
307 (unsigned) (indx + 1) * sizeof(p_type *));
309 else p->row = (p_type **) Malloc(sizeof(p_type *));
311 p->row[indx] = (p_type *) Malloc(NINCR * sizeof(p_type));
312 for (i = NINCR-1; i >= 0; i--) {
316 return &(p->row[type_index[1]/NINCR][type_index[1]%NINCR]);
322 register int i = list_len;
325 register int j = list_row[i].len;
328 p_type p = list_row[i].row[j/NINCR][j%NINCR];
329 if (p && p->ty_class == 0) {
330 error("%s: incomplete type (%d,%d)",
331 FileScope->sc_definedby->sy_idf->id_text,
338 free((char *) list_row[i].row[j/NINCR-1]);
341 free((char *) list_row[i].row);
344 free((char *) list_row);
350 end_literal(tp, maxval)
354 tp->ty_literals = (struct literal *)
355 Realloc((char *) tp->ty_literals,
356 tp->ty_nenums * sizeof(struct literal));
357 if (ufit(maxval, 1)) tp->ty_size = 1;
358 else if (ufit(maxval, (int)short_size)) tp->ty_size = short_size;
359 else tp->ty_size = int_size;
360 if (! bool_type) bool_type = tp;
368 if (v == 'i' || v == 'v') {
369 /* addresss; only exception is a conformant array, which also
372 if (currlang == m2_dep &&
373 t->ty_class == T_ARRAY &&
374 t->ty_index->ty_class == T_SUBRANGE &&
376 return pointer_size + 3 * int_size;
380 return ((t->ty_size + int_size - 1) / int_size) * int_size;
384 int v; /* 'v' or 'i' for address, 'p' for value */
385 p_symbol s; /* parameter itself */
387 register p_scope sc = base_scope(s->sy_scope);
388 register p_type prc_type;
391 prc_type = sc->sc_definedby->sy_type;
392 assert(prc_type->ty_class == T_PROCEDURE);
395 prc_type->ty_nbparams += 3 * int_size;
398 prc_type->ty_nparams++;
399 prc_type->ty_params = (struct param *) Realloc((char *) prc_type->ty_params,
400 (unsigned)prc_type->ty_nparams * sizeof(struct param));
401 prc_type->ty_params[prc_type->ty_nparams - 1].par_type = s->sy_type;
402 prc_type->ty_params[prc_type->ty_nparams - 1].par_kind = v;
403 prc_type->ty_params[prc_type->ty_nparams - 1].par_off = s->sy_name.nm_value;
404 prc_type->ty_nbparams += param_size(s->sy_type, v);
407 /* Compute the size of a parameter of dynamic size
417 assert(tp->ty_class == T_ARRAY);
418 assert(tp->ty_index->ty_class == T_SUBRANGE);
419 assert(tp->ty_index->ty_A != 0);
421 if (tp->ty_index->ty_A & 1) {
422 low = get_int(AB+tp->ty_index->ty_low, int_size, T_INTEGER);
423 } else low = tp->ty_index->ty_low;
425 if (tp->ty_index->ty_A & 2) {
426 high = get_int(AB+tp->ty_index->ty_up, int_size, T_INTEGER);
427 } else if (tp->ty_index->ty_A & 0200) {
428 high = get_int(AB+tp->ty_index->ty_up, int_size, T_INTEGER);
429 high += get_int(AB+tp->ty_index->ty_up+int_size, int_size, T_INTEGER);
430 } else high = tp->ty_index->ty_up;
432 return (high - low + 1) * tp->ty_elements->ty_size;