Changed implementation of tr module.
[libfirm] / ir / tr / type.c
1 /****h* libfirm/type.c
2  *
3  * NAME
4  *   file type.c - implementation of the datastructure to hold
5  *   type information.
6  * COPYRIGHT
7  *  (C) 2001 by Universitaet Karlsruhe
8  * AUTHORS
9  *  Martin Trapp, Christian Schaefer, Goetz Lindenmaier
10  *
11  * NOTES
12  *  This module supplies a datastructure to represent all types
13  *  known in the compiled program.  This includes types specified
14  *  in the program as well as types defined by the language.  In the
15  *  view of the intermediate representation there is no difference
16  *  between these types.
17  *
18  *  There exist several kinds of types, arranged by the structure of
19  *  the type.  A type is described by a set of attributes.  Some of
20  *  these attributes are common to all types, others depend on the
21  *  kind of the type.
22  *
23  *  Types are different from the modes defined in irmode:  Types are
24  *  on the level of the programming language, modes at the level of
25  *  the target processor.
26  *
27  * SEE ALSO
28  *   type_t.h type tpop
29  *****
30  */
31 # include <stdlib.h>
32 # include <stddef.h>
33 # include "type_t.h"
34 # include "tpop_t.h"
35 # include "array.h"
36
37 /*******************************************************************/
38 /** TYPE                                                          **/
39 /*******************************************************************/
40
41 unsigned long type_visited;
42
43 inline type *
44 new_type(tp_op *type_op, ir_mode *mode, ident* name) {
45   type *res;
46
47   int node_size = offsetof (type, attr) +  type_op->attr_size;
48   res = (type *) xmalloc (node_size);
49   add_irp_type(res);   /* Remember the new type global. */
50
51   res->kind = k_type;
52   res->type_op = type_op;
53   res->mode = mode;
54   res->name = name;
55   res->size = -1;
56   res->visit = 0;
57
58   return res;
59 }
60
61 tp_op*      get_type_tpop(type *tp) {
62   assert(tp);
63   return tp->type_op;
64 }
65
66 ident*      get_type_tpop_nameid(type *tp) {
67   assert(tp);
68   return tp->type_op->name;
69 }
70 const char* get_type_tpop_name(type *tp) {
71   assert(tp);
72   return id_to_str(tp->type_op->name);
73 }
74 tp_opcode    get_type_tpop_code(type *tp) {
75   assert(tp);
76   return tp->type_op->code;
77 }
78 ir_mode*    get_type_mode(type *tp) {
79   assert(tp);
80   return tp->mode;
81 }
82 void        set_type_mode(type *tp, ir_mode* m) {
83   assert(tp);
84   tp->mode = m;
85 }
86 ident*      get_type_nameid(type *tp) {
87   assert(tp);
88   return tp->name;
89 }
90 void        set_type_nameid(type *tp, ident* id) {
91   assert(tp);
92   tp->name = id;
93 }
94 const char* get_type_name(type *tp) {
95   assert(tp);
96   return id_to_str(tp->name);
97 }
98 int         get_type_size(type *tp) {
99   assert(tp);
100   return tp->size;
101 }
102 void        set_type_size(type *tp, int size) {
103   assert(tp);
104   tp->size = size;
105 }
106 unsigned long get_type_visited(type *tp) {
107   assert(tp);
108   return tp->visit;
109 }
110 void        set_type_visited(type *tp, unsigned long num) {
111   assert(tp);
112   tp->visit = num;
113 }
114 /* Sets visited field in type to type_visited. */
115 void        mark_type_visited(type *tp) {
116   assert(tp);
117   assert(tp->visit < type_visited);
118   tp->visit = type_visited;
119 }
120
121 int is_type            (void *thing) {
122   assert(thing);
123   if (get_kind(thing) == k_type)
124     return 1;
125   else
126     return 0;
127 }
128
129 /*******************************************************************/
130 /** TYPE_CLASS                                                    **/
131 /*******************************************************************/
132
133 /* create a new class type */
134 type   *new_type_class (ident *name) {
135   type *res;
136
137   res = new_type(type_class, NULL, name);
138
139   res->attr.ca.members    = NEW_ARR_F (entity *, 1);
140   res->attr.ca.subtypes   = NEW_ARR_F (type *, 1);
141   res->attr.ca.supertypes = NEW_ARR_F (type *, 1);
142
143   return res;
144 }
145 /* manipulate private fields of class type  */
146 void    add_class_member   (type *clss, entity *member) {
147   assert(clss && (clss->type_op == type_class));
148   ARR_APP1 (entity *, clss->attr.ca.members, member);
149 }
150 int     get_class_n_member (type *clss) {
151   assert(clss && (clss->type_op == type_class));
152   return (ARR_LEN (clss->attr.ca.members))-1;
153 }
154 entity *get_class_member   (type *clss, int pos) {
155   assert(clss && (clss->type_op == type_class));
156   return clss->attr.ca.members[pos+1];
157 }
158 void    set_class_member   (type *clss, entity *member, int pos) {
159   assert(clss && (clss->type_op == type_class));
160   clss->attr.ca.members[pos+1] = member;
161 }
162
163 void    add_class_subtype   (type *clss, type *subtype) {
164   assert(clss && (clss->type_op == type_class));
165   ARR_APP1 (type *, clss->attr.ca.subtypes, subtype);
166 }
167 int     get_class_n_subtype (type *clss) {
168   assert(clss && (clss->type_op == type_class));
169   return (ARR_LEN (clss->attr.ca.subtypes))-1;
170 }
171 type   *get_class_subtype   (type *clss, int pos) {
172   assert(clss && (clss->type_op == type_class));
173   return clss->attr.ca.subtypes[pos+1];
174 }
175 void    set_class_subtype   (type *clss, type *subtype, int pos) {
176   assert(clss && (clss->type_op == type_class));
177   clss->attr.ca.subtypes[pos+1] = subtype;
178 }
179
180 void    add_class_supertype   (type *clss, type *supertype) {
181   assert(clss && (clss->type_op == type_class));
182   ARR_APP1 (type *, clss->attr.ca.supertypes, supertype);
183 }
184 int     get_class_n_supertype (type *clss) {
185   assert(clss && (clss->type_op == type_class));
186   return (ARR_LEN (clss->attr.ca.supertypes))-1;
187 }
188 type   *get_class_supertype   (type *clss, int pos) {
189   assert(clss && (clss->type_op == type_class));
190   return clss->attr.ca.supertypes[pos+1];
191 }
192 void    set_class_supertype   (type *clss, type *supertype, int pos) {
193   assert(clss && (clss->type_op == type_class));
194   clss->attr.ca.supertypes[pos+1] = supertype;
195 }
196 /* typecheck */
197 bool    is_class_type(type *clss) {
198   assert(clss);
199   if (clss->type_op == type_class) return 1; else return 0;
200 }
201
202 /*******************************************************************/
203 /** TYPE_STRUCT                                                   **/
204 /*******************************************************************/
205
206 /* create a new type struct */
207 type   *new_type_struct (ident *name) {
208   type *res;
209   res = new_type(type_struct, NULL, name);
210   res->attr.sa.members = NEW_ARR_F (entity *, 1);
211   return res;
212 }
213 /* manipulate private fields of struct */
214 void    add_struct_member   (type *strct, entity *member) {
215   assert(strct && (strct->type_op == type_struct));
216   ARR_APP1 (entity *, strct->attr.sa.members, member);
217 }
218 int     get_struct_n_member (type *strct) {
219   assert(strct && (strct->type_op == type_struct));
220   return (ARR_LEN (strct->attr.sa.members))-1;
221 }
222 entity *get_struct_member   (type *strct, int pos) {
223   assert(strct && (strct->type_op == type_struct));
224   return strct->attr.sa.members[pos+1];
225 }
226 void    set_struct_member   (type *strct, int pos, entity *member) {
227   assert(strct && (strct->type_op == type_struct));
228   strct->attr.sa.members[pos+1] = member;
229 }
230 /* typecheck */
231 bool    is_struct_type(type *strct) {
232   assert(strct);
233   if (strct->type_op == type_struct) return 1; else return 0;
234 }
235
236 /*******************************************************************/
237 /** TYPE_METHOD                                                   **/
238 /*******************************************************************/
239
240 /* Create a new method type.
241    N_param is the number of parameters, n_res the number of results.  */
242 type *new_type_method (ident *name, int n_param, int n_res) {
243   type *res;
244   res = new_type(type_method, NULL, name);
245   res->attr.ma.n_params   = n_param;
246   res->attr.ma.param_type = (type **) xmalloc (sizeof (type *) * n_param);
247   res->attr.ma.n_res      = n_res;
248   res->attr.ma.res_type   = (type **) xmalloc (sizeof (type *) * n_res);
249   return res;
250 }
251
252 /* manipulate private fields of method. */
253 int   get_method_n_params  (type *method) {
254   assert(method && (method->type_op == type_method));
255   return method->attr.ma.n_params;
256 }
257 type *get_method_param_type(type *method, int pos) {
258   assert(method && (method->type_op == type_method));
259   return method->attr.ma.param_type[pos];
260 }
261 void  set_method_param_type(type *method, int pos, type* type) {
262   assert(method && (method->type_op == type_method));
263   method->attr.ma.param_type[pos] = type;
264 }
265
266 int   get_method_n_res   (type *method) {
267   assert(method && (method->type_op == type_method));
268   return method->attr.ma.n_res;
269 }
270 type *get_method_res_type(type *method, int pos) {
271   assert(method && (method->type_op == type_method));
272   return method->attr.ma.res_type[pos];
273 }
274 void  set_method_res_type(type *method, int pos, type* type) {
275   assert(method && (method->type_op == type_method));
276   method->attr.ma.res_type[pos] = type;
277 }
278 /* typecheck */
279 bool  is_method_type     (type *method) {
280   assert(method);
281   if (method->type_op == type_method) return 1; else return 0;
282 }
283 /*****/
284
285 /*******************************************************************/
286 /** TYPE_UNION                                                    **/
287 /*******************************************************************/
288
289 /* create a new type uni */
290 type  *new_type_uni (ident *name, int n_types) {
291   type *res;
292   res = new_type(type_union, NULL, name);
293   res->attr.ua.n_types = n_types;
294   res->attr.ua.unioned_type = (type **)  xmalloc (sizeof (type *)  * n_types);
295   res->attr.ua.delim_names  = (ident **) xmalloc (sizeof (ident *) * n_types);
296   return res;
297 }
298 /* manipulate private fields of struct */
299 int    get_union_n_types      (type *uni) {
300   assert(uni && (uni->type_op == type_union));
301   return uni->attr.ua.n_types;
302 }
303 type  *get_union_unioned_type (type *uni, int pos) {
304   assert(uni && (uni->type_op == type_union));
305   return uni->attr.ua.unioned_type[pos];
306 }
307 void   set_union_unioned_type (type *uni, int pos, type *type) {
308   assert(uni && (uni->type_op == type_union));
309   uni->attr.ua.unioned_type[pos] = type;
310 }
311 ident *get_union_delim_nameid (type *uni, int pos) {
312   assert(uni && (uni->type_op == type_union));
313   return uni->attr.ua.delim_names[pos];
314 }
315 const char *get_union_delim_name (type *uni, int pos) {
316   assert(uni && (uni->type_op == type_union));
317   return id_to_str(uni->attr.ua.delim_names[pos]);
318 }
319 void   set_union_delim_nameid (type *uni, int pos, ident *id) {
320   assert(uni && (uni->type_op == type_union));
321   uni->attr.ua.delim_names[pos] = id;
322 }
323
324 /* typecheck */
325 bool   is_union_type         (type *uni) {
326   assert(uni);
327   if (uni->type_op == type_union) return 1; else return 0;
328 }
329
330 /*******************************************************************/
331 /** TYPE_ARRAY                                                    **/
332 /*******************************************************************/
333
334
335 /* create a new type array -- set dimension sizes independently */
336 type *new_type_array         (ident *name, int n_dimensions) {
337   type *res;
338   res = new_type(type_array, NULL, name);
339   res->attr.aa.n_dimensions = n_dimensions;
340   res->attr.aa.lower_bound  = (int *) xmalloc (sizeof (int) * n_dimensions);
341   res->attr.aa.upper_bound  = (int *) xmalloc (sizeof (int) * n_dimensions);
342   return res;
343 }
344 /* manipulate private fields of array type */
345 int   get_array_n_dimensions (type *array) {
346   assert(array && (array->type_op == type_array));
347   return array->attr.aa.n_dimensions;
348 }
349 void  set_array_bounds       (type *array, int dimension, int lower_bound,
350                                                           int upper_bound) {
351   assert(array && (array->type_op == type_array));
352   array->attr.aa.lower_bound[dimension] = lower_bound;
353   array->attr.aa.upper_bound[dimension] = upper_bound;
354 }
355 void  set_array_lower_bound  (type *array, int dimension, int lower_bound) {
356   assert(array && (array->type_op == type_array));
357   array->attr.aa.lower_bound[dimension] = lower_bound;
358 }
359 void  set_array_upper_bound  (type *array, int dimension, int upper_bound) {
360   assert(array && (array->type_op == type_array));
361   array->attr.aa.upper_bound[dimension] = upper_bound;
362 }
363 int   get_array_lower_bound  (type *array, int dimension) {
364   assert(array && (array->type_op == type_array));
365   return array->attr.aa.lower_bound[dimension];
366 }
367 int   get_array_upper_bound  (type *array, int dimension) {
368   assert(array && (array->type_op == type_array));
369   return array->attr.aa.upper_bound[dimension];
370 }
371 void  set_array_element_type (type *array, type *type) {
372   assert(array && (array->type_op == type_array));
373   array->attr.aa.element_type = type;
374 }
375 type *get_array_element_type (type *array) {
376   assert(array && (array->type_op == type_array));
377   return array->attr.aa.element_type;
378 }
379 /* typecheck */
380 bool   is_array_type         (type *array) {
381   assert(array);
382   if (array->type_op == type_array) return 1; else return 0;
383 }
384
385 /*******************************************************************/
386 /** TYPE_ENUMERATION                                              **/
387 /*******************************************************************/
388
389 /* create a new type enumeration -- set the enumerators independently */
390 type   *new_type_enumeration    (ident *name, int n_enums) {
391   type *res;
392   res = new_type(type_enumeration, NULL, name);
393   res->attr.ea.n_enums     = n_enums;
394   res->attr.ea.enumer      = (tarval **) xmalloc (sizeof (tarval *) * n_enums);
395   res->attr.ea.enum_nameid = (ident  **) xmalloc (sizeof (ident  *) * n_enums);
396   return res;
397 }
398
399 /* manipulate fields of enumeration type. */
400 int     get_enumeration_n_enums (type *enumeration) {
401   assert(enumeration && (enumeration->type_op == type_enumeration));
402   return enumeration->attr.ea.n_enums;
403 }
404 void    set_enumeration_enum    (type *enumeration, int pos, tarval *con) {
405   assert(enumeration && (enumeration->type_op == type_enumeration));
406   enumeration->attr.ea.enumer[pos] = con;
407 }
408 tarval *get_enumeration_enum    (type *enumeration, int pos) {
409   assert(enumeration && (enumeration->type_op == type_enumeration));
410   return enumeration->attr.ea.enumer[pos];
411 }
412 void    set_enumeration_nameid  (type *enumeration, int pos, ident *id) {
413   assert(enumeration && (enumeration->type_op == type_enumeration));
414   enumeration->attr.ea.enum_nameid[pos] = id;
415 }
416 ident  *get_enumeration_nameid  (type *enumeration, int pos) {
417   assert(enumeration && (enumeration->type_op == type_enumeration));
418   return enumeration->attr.ea.enum_nameid[pos];
419 }
420 const char *get_enumeration_name(type *enumeration, int pos) {
421   assert(enumeration && (enumeration->type_op == type_enumeration));
422   return id_to_str(enumeration->attr.ea.enum_nameid[pos]);
423 }
424
425 /* typecheck */
426 bool    is_enumeration_type     (type *enumeration) {
427   assert(enumeration);
428   if (enumeration->type_op == type_enumeration) return 1; else return 0;
429 }
430
431 /*******************************************************************/
432 /** TYPE_POINTER                                                  **/
433 /*******************************************************************/
434
435 /* Create a new type pointer */
436 type *new_type_pointer           (ident *name, type *points_to) {
437   type *res;
438   res = new_type(type_pointer, mode_p, name);
439   res->attr.pa.points_to = points_to;
440   return res;
441 }
442 /* manipulate fields of type_pointer */
443 void  set_pointer_points_to_type (type *pointer, type *type) {
444   assert(pointer && (pointer->type_op == type_pointer));
445   pointer->attr.pa.points_to = type;
446 }
447 type *get_pointer_points_to_type (type *pointer) {
448   assert(pointer && (pointer->type_op == type_pointer));
449   return pointer->attr.pa.points_to;
450 }
451
452 /* typecheck */
453 bool  is_pointer_type            (type *pointer) {
454   assert(pointer);
455   if (pointer->type_op == type_pointer) return 1; else return 0;
456 }
457
458
459 /*******************************************************************/
460 /** TYPE_PRIMITIVE                                                **/
461 /*******************************************************************/
462
463 /* create a new type primitive */
464 type *new_type_primitive (ident *name, ir_mode *mode) {
465   type *res;
466   res = new_type(type_primitive, mode_p, name);
467   return res;
468 }
469
470 /* typecheck */
471 bool  is_primitive_type  (type *primitive) {
472   assert(primitive);
473   if (primitive->type_op == type_primitive) return 1; else return 0;
474 }