123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- /* $Id$ */
- /* Routines to create type structures */
- #include <alloc.h>
- #include <assert.h>
- #include "idf.h"
- #include "type.h"
- #include "symbol.h"
- #include "scope.h"
- #include "langdep.h"
- #include "expr.h"
- #include "misc.h"
- p_type int_type, char_type, short_type, long_type, bool_type;
- p_type uint_type, uchar_type, ushort_type, ulong_type;
- p_type void_type;
- p_type float_type, double_type;
- p_type string_type, address_type;
- long int_size = sizeof(int),
- char_size = 1,
- short_size = sizeof(short),
- long_size = sizeof(long),
- pointer_size = sizeof(char *);
- long float_size = sizeof(float),
- double_size = sizeof(double);
- struct bounds {
- long low, high;
- };
- static struct bounds ibounds[2] = {
- { -128, 127 },
- { -32768, 32767 }
- };
- static struct bounds ubounds[2] = {
- { 0, 255 },
- { 0, 65535 }
- };
- static long max_int[8], max_uns[8];
- struct integer_types {
- long maxval;
- p_type type;
- };
- static struct integer_types i_types[4];
- static struct integer_types u_types[4];
- #define ufit(n, nb) Xfit(n, nb, ubounds)
- #define ifit(n, nb) Xfit(n, nb, ibounds)
- #define Xfit(n, nb, b) ((n) >= (b)[(nb)-1].low && (n) <= (b)[(nb)-1].high)
- /* Create a subrange type, but is it really a subrange? */
- p_type
- subrange_type(A, base_index, c1, c2, result_index)
- int *base_index, *result_index;
- long c1, c2;
- {
- int itself = 0;
- register p_type p;
- p_type base_type;
- if (!A) {
- /* Subrange of itself is a special case ... */
- if (result_index &&
- result_index[0] == base_index[0] &&
- result_index[1] == base_index[1]) {
- /* c1 = 0 and c2 = 0 -> void */
- if (c1 == 0 && c2 == 0) {
- return void_type;
- }
- if ((c1 == 0 || c1 == -128) && c2 == 127) {
- return char_type;
- }
- if (c1 == 0 && c2 == 255) {
- return uchar_type;
- }
- itself = 1;
- }
- }
- if (itself) base_type = int_type; else base_type = *(tp_lookup(base_index));
- if (! A) {
- /* c2 = 0 and c1 > 0 -> real */
- if (c2 == 0 && c1 > 0) {
- if (c1 == float_size) return float_type;
- return double_type;
- }
- /* c1 = 0 and base_index indicates int_type or itself -> unsigned,
- c1 = -c2 - 1 and base_index indicates int_type or itself -> integer
- */
- if (itself || base_type == int_type) {
- register struct integer_types *ip = 0;
- if (c1 == 0) {
- ip = &u_types[0];
- }
- else if (c1 == -c2 - 1) {
- ip = &i_types[0];
- }
- if (ip) {
- while (ip->maxval != 0 && ip->maxval != c2) ip++;
- if (ip->maxval) return ip->type;
- }
- }
- }
- /* if we get here, it actually is a subrange type */
- p = new_type();
- p->ty_class = T_SUBRANGE;
- p->ty_low = c1;
- p->ty_up = c2;
- p->ty_base = base_type;
- p->ty_A = A;
- /* determine size of subrange type */
- p->ty_size = base_type->ty_size;
- if (!A && p->ty_base == uint_type) {
- if (ufit(p->ty_up, 1)) {
- p->ty_size = 1;
- }
- else if (ufit(p->ty_up, (int)short_size)) {
- p->ty_size = short_size;
- }
- }
- if (!A && p->ty_base == int_type) {
- if (ifit(p->ty_up, 1) && ifit(p->ty_low, 1)) {
- p->ty_size = 1;
- }
- else if (ifit(p->ty_up, (int)short_size) &&
- ifit(p->ty_low, (int)short_size)) {
- p->ty_size = short_size;
- }
- }
- return p;
- }
- static long
- nel(tp)
- register p_type tp;
- {
- switch(tp->ty_class) {
- case T_SUBRANGE:
- if (tp->ty_A) return 0;
- if (tp->ty_low <= tp->ty_up) return tp->ty_up - tp->ty_low + 1;
- return tp->ty_low - tp->ty_up + 1;
- case T_UNSIGNED:
- case T_INTEGER:
- if (tp->ty_size == 1) return 256;
- if (tp->ty_size == 2) return 65536L;
- assert(0);
- break;
- case T_ENUM:
- return tp->ty_nenums;
- default:
- assert(0);
- break;
- }
- return 0;
- }
- p_type
- array_type(bound_type, el_type)
- p_type bound_type, el_type;
- {
- register p_type tp = new_type();
- tp->ty_class = T_ARRAY;
- tp->ty_index = bound_type;
- switch(bound_type->ty_class) {
- case T_SUBRANGE:
- if (bound_type->ty_A) break;
- tp->ty_lb = bound_type->ty_low;
- tp->ty_hb = bound_type->ty_up;
- break;
- case T_ENUM:
- tp->ty_lb = 0;
- tp->ty_hb = bound_type->ty_nenums-1;
- break;
- case T_UNSIGNED:
- tp->ty_lb = 0;
- tp->ty_hb = bound_type->ty_size == 1 ? 255 : 65535L;
- break;
- case T_INTEGER:
- tp->ty_lb = bound_type->ty_size == 1 ? -128 : -32768;
- tp->ty_hb = bound_type->ty_size == 1 ? 127 : 32767;
- break;
- }
- tp->ty_elements = el_type;
- tp->ty_size = (*currlang->arrayelsize)(el_type->ty_size) * nel(bound_type);
- return tp;
- }
- p_type
- basic_type(fund, size)
- int fund;
- long size;
- {
- register p_type p = new_type();
- p->ty_class = fund;
- p->ty_size = size;
- return p;
- }
- set_bounds(tp)
- register p_type tp;
- {
- /* Determine the size and low of a set type */
- register p_type base = tp->ty_setbase;
- if (base->ty_class == T_SUBRANGE) {
- tp->ty_size = (base->ty_up - base->ty_low + 7) >> 3;
- tp->ty_setlow = base->ty_low;
- }
- else if (base->ty_class == T_INTEGER) {
- tp->ty_size = (max_int[(int)base->ty_size] + 1) >> 2;
- tp->ty_setlow = -max_int[(int)base->ty_size] - 1;
- }
- else {
- assert(base->ty_class == T_UNSIGNED);
- tp->ty_size = (max_uns[(int)base->ty_size] + 1) >> 3;
- tp->ty_setlow = 0;
- }
- }
- init_types()
- {
- register int i = 0;
- register long x = 0;
- while (x >= 0) {
- i++;
- x = (x << 8) + 0377;
- max_uns[i] = x;
- max_int[i] = x & ~(1L << (8*i - 1));
- }
- int_type = basic_type(T_INTEGER, int_size);
- long_type = basic_type(T_INTEGER, long_size);
- short_type = basic_type(T_INTEGER, short_size);
- char_type = basic_type(T_INTEGER, char_size);
- uint_type = basic_type(T_UNSIGNED, int_size);
- ulong_type = basic_type(T_UNSIGNED, long_size);
- ushort_type = basic_type(T_UNSIGNED, short_size);
- uchar_type = basic_type(T_UNSIGNED, char_size);
- string_type = basic_type(T_STRING, 0L);
- address_type = basic_type(T_POINTER, pointer_size);
- void_type = basic_type(T_VOID, 0L);
- float_type = basic_type(T_REAL, float_size);
- double_type = basic_type(T_REAL, double_size);
- i_types[0].maxval = max_int[(int)int_size]; i_types[0].type = int_type;
- i_types[1].maxval = max_int[(int)short_size]; i_types[1].type = short_type;
- i_types[2].maxval = max_int[(int)long_size]; i_types[2].type = long_type;
- u_types[0].maxval = max_uns[(int)int_size]; u_types[0].type = uint_type;
- u_types[1].maxval = max_uns[(int)short_size]; u_types[1].type = ushort_type;
- u_types[2].maxval = max_uns[(int)long_size]; u_types[2].type = ulong_type;
- }
- /*
- * Some code to handle type indices, which are pairs of integers.
- * What we need is a two-dimensional array, but we don't know how large
- * it is going to be, so we use a list of rows instead.
- */
- static struct tp_index {
- unsigned len;
- p_type **row;
- } *list_row;
- static unsigned list_len;
- #define NINCR 10
-
- p_type *
- tp_lookup(type_index)
- int *type_index;
- {
- register int i;
- register struct tp_index *p;
- while (type_index[0] >= list_len) {
- if (list_len) {
- list_row = (struct tp_index *) Realloc((char *) list_row,
- (list_len += NINCR) * sizeof(struct tp_index));
- }
- else list_row = (struct tp_index *)
- Malloc((list_len = NINCR) * sizeof(struct tp_index));
- for (i = NINCR; i > 0; i--) {
- list_row[list_len - i].len = 0;
- }
- }
- p = &list_row[type_index[0]];
- while (type_index[1] >= p->len) {
- int indx = p->len/NINCR;
- if (p->len) {
- p->row = (p_type **) Realloc((char *) p->row,
- (unsigned) (indx + 1) * sizeof(p_type *));
- }
- else p->row = (p_type **) Malloc(sizeof(p_type *));
- p->len += NINCR;
- p->row[indx] = (p_type *) Malloc(NINCR * sizeof(p_type));
- for (i = NINCR-1; i >= 0; i--) {
- p->row[indx][i] = 0;
- }
- }
- return &(p->row[type_index[1]/NINCR][type_index[1]%NINCR]);
- }
- clean_tp_tab()
- {
- if (list_len) {
- register int i = list_len;
- while (--i >= 0) {
- register int j = list_row[i].len;
- if (j) {
- while (--j > 0) {
- p_type p = list_row[i].row[j/NINCR][j%NINCR];
- if (p && p->ty_class == 0) {
- error("%s: incomplete type (%d,%d)",
- FileScope->sc_definedby->sy_idf->id_text,
- i,
- j);
- }
- }
- j = list_row[i].len;
- while (j > 0) {
- free((char *) list_row[i].row[j/NINCR-1]);
- j -= NINCR;
- }
- free((char *) list_row[i].row);
- }
- }
- free((char *) list_row);
- list_len = 0;
- list_row = 0;
- }
- }
- end_literal(tp, maxval)
- register p_type tp;
- long maxval;
- {
- tp->ty_literals = (struct literal *)
- Realloc((char *) tp->ty_literals,
- tp->ty_nenums * sizeof(struct literal));
- if (ufit(maxval, 1)) tp->ty_size = 1;
- else if (ufit(maxval, (int)short_size)) tp->ty_size = short_size;
- else tp->ty_size = int_size;
- if (! bool_type) bool_type = tp;
- }
- long
- param_size(t, v)
- int v;
- p_type t;
- {
- if (v == 'i' || v == 'v') {
- /* addresss; only exception is a conformant array, which also
- takes a descriptor.
- */
- if (currlang == m2_dep &&
- t->ty_class == T_ARRAY &&
- t->ty_index->ty_class == T_SUBRANGE &&
- t->ty_index->ty_A) {
- return pointer_size + 3 * int_size;
- }
- return pointer_size;
- }
- return ((t->ty_size + int_size - 1) / int_size) * int_size;
- }
- add_param_type(v, s)
- int v; /* 'v' or 'i' for address, 'p' for value */
- p_symbol s; /* parameter itself */
- {
- register p_scope sc = base_scope(s->sy_scope);
- register p_type prc_type;
- if (! sc) return;
- prc_type = sc->sc_definedby->sy_type;
- assert(prc_type->ty_class == T_PROCEDURE);
- if (v == 'Z') {
- prc_type->ty_nbparams += 3 * int_size;
- return;
- }
- prc_type->ty_nparams++;
- prc_type->ty_params = (struct param *) Realloc((char *) prc_type->ty_params,
- (unsigned)prc_type->ty_nparams * sizeof(struct param));
- prc_type->ty_params[prc_type->ty_nparams - 1].par_type = s->sy_type;
- prc_type->ty_params[prc_type->ty_nparams - 1].par_kind = v;
- prc_type->ty_params[prc_type->ty_nparams - 1].par_off = s->sy_name.nm_value;
- prc_type->ty_nbparams += param_size(s->sy_type, v);
- }
- /* Compute the size of a parameter of dynamic size
- */
- long
- compute_size(tp, AB)
- p_type tp;
- char *AB;
- {
- long low, high;
- assert(tp->ty_class == T_ARRAY);
- assert(tp->ty_index->ty_class == T_SUBRANGE);
- assert(tp->ty_index->ty_A != 0);
- if (tp->ty_index->ty_A & 1) {
- low = get_int(AB+tp->ty_index->ty_low, int_size, T_INTEGER);
- } else low = tp->ty_index->ty_low;
- tp->ty_lb = low;
- if (tp->ty_index->ty_A & 2) {
- high = get_int(AB+tp->ty_index->ty_up, int_size, T_INTEGER);
- } else if (tp->ty_index->ty_A & 0200) {
- high = get_int(AB+tp->ty_index->ty_up, int_size, T_INTEGER);
- high += get_int(AB+tp->ty_index->ty_up+int_size, int_size, T_INTEGER);
- } else high = tp->ty_index->ty_up;
- tp->ty_hb = high;
- return (high - low + 1) * tp->ty_elements->ty_size;
- }
|