Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / type.c
1 /*
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".
4  */
5 /* $Id: type.c,v 3.12 1994/06/24 12:06:40 ceriel Exp $ */
6 /*      T Y P E   D E F I N I T I O N   M E C H A N I S M        */
7
8 #include        "nofloat.h"
9 #include        "nobitfield.h"
10 #include        "botch_free.h"
11 #include        <alloc.h>
12 #include        "Lpars.h"
13 #include        "arith.h"
14 #include        "type.h"
15 #include        "idf.h"
16 #include        "def.h"
17 #include        "sizes.h"
18 #include        "align.h"
19
20 struct type *function_of(), *array_of();
21 #ifndef NOBITFIELD
22 struct type *field_of();
23 #endif /* NOBITFIELD */
24
25 /*      To be created dynamically in main() from defaults or from command
26         line parameters.
27 */
28 struct type
29         *char_type, *uchar_type,
30         *short_type, *ushort_type,
31         *word_type, *uword_type,
32         *int_type, *uint_type,
33         *long_type, *ulong_type,
34 #ifndef NOFLOAT
35         *float_type, *double_type,
36 #endif /* NOFLOAT */
37         *void_type, *label_type,
38         *string_type, *funint_type, *error_type;
39
40 struct type *pa_type;   /* Pointer-Arithmetic type      */
41
42 struct type *
43 create_type(fund)
44         int fund;
45 {
46         /*      A brand new struct type is created, and its tp_fund set
47                 to fund.
48         */
49         register struct type *ntp = new_type();
50
51         ntp->tp_fund = fund;
52         ntp->tp_size = (arith)-1;
53
54         return ntp;
55 }
56
57 struct type *
58 construct_type(fund, tp, count)
59         register struct type *tp;
60         arith count; /* for fund == ARRAY only */
61 {
62         /*      fund must be a type constructor: FIELD, FUNCTION, POINTER or
63                 ARRAY. The pointer to the constructed type is returned.
64         */
65         register struct type *dtp;
66
67         switch (fund)   {
68 #ifndef NOBITFIELD
69         case FIELD:
70                 dtp = field_of(tp);
71                 break;
72 #endif /* NOBITFIELD */
73
74         case FUNCTION:
75                 if (tp->tp_fund == FUNCTION)    {
76                         error("function cannot yield function");
77                         return error_type;
78                 }
79                 if (tp->tp_fund == ARRAY)       {
80                         error("function cannot yield array");
81                         return error_type;
82                 }
83
84                 dtp = function_of(tp);
85                 break;
86         case POINTER:
87                 dtp = pointer_to(tp);
88                 break;
89         case ARRAY:
90                 if (count >= 0 && tp->tp_size < 0)      {
91                         error("cannot construct array of unknown type");
92                         count = (arith)-1;
93                 }
94                 else if (tp->tp_size == 0)      /* CJ */
95                         warning("array elements have size 0");
96                 if (count >= (arith)0)
97                         count *= tp->tp_size;
98                 dtp = array_of(tp, count);
99                 break;
100         default:
101                 crash("bad constructor in construct_type");
102                 /*NOTREACHED*/
103         }
104         return dtp;
105 }
106
107 struct type *
108 function_of(tp)
109         register struct type *tp;
110 {
111         register struct type *dtp = tp->tp_function;
112
113         if (!dtp)       {
114                 tp->tp_function = dtp = create_type(FUNCTION);
115                 dtp->tp_up = tp;
116                 dtp->tp_size = pointer_size;
117                 dtp->tp_align = pointer_align;
118         }
119         return dtp;
120 }
121
122 struct type *
123 pointer_to(tp)
124         register struct type *tp;
125 {
126         register struct type *dtp = tp->tp_pointer;
127
128         if (!dtp)       {
129                 tp->tp_pointer = dtp = create_type(POINTER);
130                 dtp->tp_unsigned = 1;
131                 dtp->tp_up = tp;
132                 dtp->tp_size = pointer_size;
133                 dtp->tp_align = pointer_align;
134         }
135         return dtp;
136 }
137
138 struct type *
139 array_of(tp, count)
140         register struct type *tp;
141         arith count;
142 {
143         register struct type *dtp = tp->tp_array;
144
145         /* look for a type with the right size */
146         while (dtp && dtp->tp_size != count)
147                 dtp = dtp->next;
148
149         if (!dtp)       {
150                 dtp = create_type(ARRAY);
151                 dtp->tp_up = tp;
152                 dtp->tp_size = count;
153                 dtp->tp_align = tp->tp_align;
154                 dtp->next = tp->tp_array;
155                 tp->tp_array = dtp;
156         }
157         return dtp;
158 }
159
160 #ifndef NOBITFIELD
161 struct type *
162 field_of(tp)
163         register struct type *tp;
164 {
165         register struct type *dtp = create_type(FIELD);
166
167         dtp->tp_up = tp;
168         dtp->tp_align = tp->tp_align;
169         dtp->tp_size = tp->tp_size;
170         return dtp;
171 }
172 #endif /* NOBITFIELD */
173
174 arith
175 size_of_type(tp, nm)
176         struct type *tp;
177         char nm[];
178 {
179         arith sz = tp->tp_size;
180
181         if (sz < 0)     {
182                 error("size of %s unknown", nm);
183                 return (arith)1;
184         }
185         return sz;
186 }
187
188 idf2type(idf, tpp)
189         struct idf *idf;
190         struct type **tpp;
191 {
192         /*      Decoding  a typedef-ed identifier: if the size is yet
193                 unknown we have to make copy of the type descriptor to
194                 prevent garbage at the initialisation of arrays with
195                 unknown size.
196         */
197         register struct type *tp = idf->id_def->df_type;
198
199         if (    tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) {
200                 *tpp = new_type();
201                 **tpp = *tp;
202                         /* this is really a structure assignment, AAGH!!! */
203         }
204         else    {
205                 *tpp = tp;
206         }
207 }
208
209 arith
210 align(pos, al)
211         arith pos;
212         int al;
213 {
214         return ((pos + al - 1) / al) * al;
215 }
216
217 struct type *
218 standard_type(fund, sgn, algn, sz)
219         int algn; arith sz;
220 {
221         register struct type *tp = create_type(fund);
222
223         tp->tp_unsigned = sgn;
224         tp->tp_align = algn;
225         tp->tp_size = sz;
226
227         return tp;
228 }