Rimproved interface to type array.
[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   /* For pointer and primitive size depends on the mode. */
86   if ((tp->type_op == type_pointer) || (tp->type_op == type_primitive))
87     tp->size == get_mode_size(m);
88 }
89 ident*      get_type_nameid(type *tp) {
90   assert(tp);
91   return tp->name;
92 }
93 void        set_type_nameid(type *tp, ident* id) {
94   assert(tp);
95   tp->name = id;
96 }
97 const char* get_type_name(type *tp) {
98   assert(tp);
99   return id_to_str(tp->name);
100 }
101 int         get_type_size(type *tp) {
102   assert(tp);
103   return tp->size;
104 }
105 void        set_type_size(type *tp, int size) {
106   assert(tp);
107   /* For pointer and primitive size depends on the mode. */
108   assert((tp->type_op != type_pointer) && (tp->type_op != type_primitive));
109   tp->size = size;
110 }
111 unsigned long get_type_visited(type *tp) {
112   assert(tp);
113   return tp->visit;
114 }
115 void        set_type_visited(type *tp, unsigned long num) {
116   assert(tp);
117   tp->visit = num;
118 }
119 /* Sets visited field in type to type_visited. */
120 void        mark_type_visited(type *tp) {
121   assert(tp);
122   assert(tp->visit < type_visited);
123   tp->visit = type_visited;
124 }
125
126 int is_type            (void *thing) {
127   assert(thing);
128   if (get_kind(thing) == k_type)
129     return 1;
130   else
131     return 0;
132 }
133
134 /*******************************************************************/
135 /** TYPE_CLASS                                                    **/
136 /*******************************************************************/
137
138 /* create a new class type */
139 type   *new_type_class (ident *name) {
140   type *res;
141
142   res = new_type(type_class, NULL, name);
143
144   res->attr.ca.members    = NEW_ARR_F (entity *, 1);
145   res->attr.ca.subtypes   = NEW_ARR_F (type *, 1);
146   res->attr.ca.supertypes = NEW_ARR_F (type *, 1);
147
148   return res;
149 }
150 /* manipulate private fields of class type  */
151 void    add_class_member   (type *clss, entity *member) {
152   assert(clss && (clss->type_op == type_class));
153   ARR_APP1 (entity *, clss->attr.ca.members, member);
154 }
155 int     get_class_n_member (type *clss) {
156   assert(clss && (clss->type_op == type_class));
157   return (ARR_LEN (clss->attr.ca.members))-1;
158 }
159 entity *get_class_member   (type *clss, int pos) {
160   assert(clss && (clss->type_op == type_class));
161   return clss->attr.ca.members[pos+1];
162 }
163 void    set_class_member   (type *clss, entity *member, int pos) {
164   assert(clss && (clss->type_op == type_class));
165   clss->attr.ca.members[pos+1] = member;
166 }
167
168 void    add_class_subtype   (type *clss, type *subtype) {
169   assert(clss && (clss->type_op == type_class));
170   ARR_APP1 (type *, clss->attr.ca.subtypes, subtype);
171 }
172 int     get_class_n_subtype (type *clss) {
173   assert(clss && (clss->type_op == type_class));
174   return (ARR_LEN (clss->attr.ca.subtypes))-1;
175 }
176 type   *get_class_subtype   (type *clss, int pos) {
177   assert(clss && (clss->type_op == type_class));
178   return clss->attr.ca.subtypes[pos+1];
179 }
180 void    set_class_subtype   (type *clss, type *subtype, int pos) {
181   assert(clss && (clss->type_op == type_class));
182   clss->attr.ca.subtypes[pos+1] = subtype;
183 }
184
185 void    add_class_supertype   (type *clss, type *supertype) {
186   assert(clss && (clss->type_op == type_class));
187   ARR_APP1 (type *, clss->attr.ca.supertypes, supertype);
188 }
189 int     get_class_n_supertype (type *clss) {
190   assert(clss && (clss->type_op == type_class));
191   return (ARR_LEN (clss->attr.ca.supertypes))-1;
192 }
193 type   *get_class_supertype   (type *clss, int pos) {
194   assert(clss && (clss->type_op == type_class));
195   return clss->attr.ca.supertypes[pos+1];
196 }
197 void    set_class_supertype   (type *clss, type *supertype, int pos) {
198   assert(clss && (clss->type_op == type_class));
199   clss->attr.ca.supertypes[pos+1] = supertype;
200 }
201 /* typecheck */
202 bool    is_class_type(type *clss) {
203   assert(clss);
204   if (clss->type_op == type_class) return 1; else return 0;
205 }
206
207 /*******************************************************************/
208 /** TYPE_STRUCT                                                   **/
209 /*******************************************************************/
210
211 /* create a new type struct */
212 type   *new_type_struct (ident *name) {
213   type *res;
214   res = new_type(type_struct, NULL, name);
215   res->attr.sa.members = NEW_ARR_F (entity *, 1);
216   return res;
217 }
218 /* manipulate private fields of struct */
219 void    add_struct_member   (type *strct, entity *member) {
220   assert(strct && (strct->type_op == type_struct));
221   ARR_APP1 (entity *, strct->attr.sa.members, member);
222 }
223 int     get_struct_n_member (type *strct) {
224   assert(strct && (strct->type_op == type_struct));
225   return (ARR_LEN (strct->attr.sa.members))-1;
226 }
227 entity *get_struct_member   (type *strct, int pos) {
228   assert(strct && (strct->type_op == type_struct));
229   return strct->attr.sa.members[pos+1];
230 }
231 void    set_struct_member   (type *strct, int pos, entity *member) {
232   assert(strct && (strct->type_op == type_struct));
233   strct->attr.sa.members[pos+1] = member;
234 }
235 /* typecheck */
236 bool    is_struct_type(type *strct) {
237   assert(strct);
238   if (strct->type_op == type_struct) return 1; else return 0;
239 }
240
241 /*******************************************************************/
242 /** TYPE_METHOD                                                   **/
243 /*******************************************************************/
244
245 /* Create a new method type.
246    N_param is the number of parameters, n_res the number of results.  */
247 type *new_type_method (ident *name, int n_param, int n_res) {
248   type *res;
249   res = new_type(type_method, NULL, name);
250   res->attr.ma.n_params   = n_param;
251   res->attr.ma.param_type = (type **) xmalloc (sizeof (type *) * n_param);
252   res->attr.ma.n_res      = n_res;
253   res->attr.ma.res_type   = (type **) xmalloc (sizeof (type *) * n_res);
254   return res;
255 }
256
257 /* manipulate private fields of method. */
258 int   get_method_n_params  (type *method) {
259   assert(method && (method->type_op == type_method));
260   return method->attr.ma.n_params;
261 }
262 type *get_method_param_type(type *method, int pos) {
263   assert(method && (method->type_op == type_method));
264   return method->attr.ma.param_type[pos];
265 }
266 void  set_method_param_type(type *method, int pos, type* type) {
267   assert(method && (method->type_op == type_method));
268   method->attr.ma.param_type[pos] = type;
269 }
270
271 int   get_method_n_res   (type *method) {
272   assert(method && (method->type_op == type_method));
273   return method->attr.ma.n_res;
274 }
275 type *get_method_res_type(type *method, int pos) {
276   assert(method && (method->type_op == type_method));
277   return method->attr.ma.res_type[pos];
278 }
279 void  set_method_res_type(type *method, int pos, type* type) {
280   assert(method && (method->type_op == type_method));
281   method->attr.ma.res_type[pos] = type;
282 }
283
284 /* typecheck */
285 bool  is_method_type     (type *method) {
286   assert(method);
287   if (method->type_op == type_method) return 1; else return 0;
288 }
289 /*****/
290
291 /*******************************************************************/
292 /** TYPE_UNION                                                    **/
293 /*******************************************************************/
294
295 /* create a new type uni */
296 type  *new_type_uni (ident *name) {
297   type *res;
298   res = new_type(type_union, NULL, name);
299   /*res->attr.ua.unioned_type = (type **)  xmalloc (sizeof (type *)  * n_types);
300     res->attr.ua.delim_names  = (ident **) xmalloc (sizeof (ident *) * n_types); */
301   res->attr.ua.members = NEW_ARR_F (entity *, 1);
302   return res;
303 }
304 /* manipulate private fields of struct */
305 #if 0
306 int    get_union_n_types      (type *uni) {
307   assert(uni && (uni->type_op == type_union));
308   return uni->attr.ua.n_types;
309 }
310 type  *get_union_unioned_type (type *uni, int pos) {
311   assert(uni && (uni->type_op == type_union));
312   return uni->attr.ua.unioned_type[pos];
313 }
314 void   set_union_unioned_type (type *uni, int pos, type *type) {
315   assert(uni && (uni->type_op == type_union));
316   uni->attr.ua.unioned_type[pos] = type;
317 }
318 ident *get_union_delim_nameid (type *uni, int pos) {
319   assert(uni && (uni->type_op == type_union));
320   return uni->attr.ua.delim_names[pos];
321 }
322 const char *get_union_delim_name (type *uni, int pos) {
323   assert(uni && (uni->type_op == type_union));
324   return id_to_str(uni->attr.ua.delim_names[pos]);
325 }
326 void   set_union_delim_nameid (type *uni, int pos, ident *id) {
327   assert(uni && (uni->type_op == type_union));
328   uni->attr.ua.delim_names[pos] = id;
329 }
330 #endif
331 int    get_union_n_members      (type *uni) {
332   assert(uni && (uni->type_op == type_union));
333   return (ARR_LEN (uni->attr.ua.members))-1;
334 }
335 void    add_union_member   (type *uni, entity *member) {
336   assert(uni && (uni->type_op == type_union));
337   ARR_APP1 (entity *, uni->attr.ua.members, member);
338 }
339 entity  *get_union_member (type *uni, int pos) {
340   assert(uni && (uni->type_op == type_union));
341   return uni->attr.ua.members[pos+1];
342 }
343 void   set_union_member (type *uni, int pos, entity *member) {
344   assert(uni && (uni->type_op == type_union));
345   uni->attr.ua.members[pos+1] = member;
346 }
347
348 /* typecheck */
349 bool   is_union_type         (type *uni) {
350   assert(uni);
351   if (uni->type_op == type_union) return 1; else return 0;
352 }
353
354 /*******************************************************************/
355 /** TYPE_ARRAY                                                    **/
356 /*******************************************************************/
357
358
359 /* create a new type array -- set dimension sizes independently */
360 type *new_type_array         (ident *name, int n_dimensions,
361                               type *element_type) {
362   type *res;
363   res = new_type(type_array, NULL, name);
364   res->attr.aa.n_dimensions = n_dimensions;
365   res->attr.aa.lower_bound  = (int *) xmalloc (sizeof (int) * n_dimensions);
366   res->attr.aa.upper_bound  = (int *) xmalloc (sizeof (int) * n_dimensions);
367   res->attr.aa.element_type = element_type;
368   new_entity(res, name, element_type);
369   return res;
370 }
371
372 /* manipulate private fields of array type */
373 int   get_array_n_dimensions (type *array) {
374   assert(array && (array->type_op == type_array));
375   return array->attr.aa.n_dimensions;
376 }
377 void  set_array_bounds       (type *array, int dimension, int lower_bound,
378                                                           int upper_bound) {
379   assert(array && (array->type_op == type_array));
380   array->attr.aa.lower_bound[dimension] = lower_bound;
381   array->attr.aa.upper_bound[dimension] = upper_bound;
382 }
383 void  set_array_lower_bound  (type *array, int dimension, int lower_bound) {
384   assert(array && (array->type_op == type_array));
385   array->attr.aa.lower_bound[dimension] = lower_bound;
386 }
387 void  set_array_upper_bound  (type *array, int dimension, int upper_bound) {
388   assert(array && (array->type_op == type_array));
389   array->attr.aa.upper_bound[dimension] = upper_bound;
390 }
391 int   get_array_lower_bound  (type *array, int dimension) {
392   assert(array && (array->type_op == type_array));
393   return array->attr.aa.lower_bound[dimension];
394 }
395 int   get_array_upper_bound  (type *array, int dimension) {
396   assert(array && (array->type_op == type_array));
397   return array->attr.aa.upper_bound[dimension];
398 }
399 void  set_array_element_type (type *array, type *type) {
400   assert(array && (array->type_op == type_array));
401   array->attr.aa.element_type = type;
402 }
403 type *get_array_element_type (type *array) {
404   assert(array && (array->type_op == type_array));
405   return array->attr.aa.element_type;
406 }
407 void  set_array_element_entity (type *array, entity *ent) {
408   assert(array && (array->type_op == type_array));
409   array->attr.aa.element_ent = ent;
410 }
411 entity *get_array_element_entity (type *array) {
412   assert(array && (array->type_op == type_array));
413   return array->attr.aa.element_ent;
414 }
415
416 /* typecheck */
417 bool   is_array_type         (type *array) {
418   assert(array);
419   if (array->type_op == type_array) return 1; else return 0;
420 }
421
422 /*******************************************************************/
423 /** TYPE_ENUMERATION                                              **/
424 /*******************************************************************/
425
426 /* create a new type enumeration -- set the enumerators independently */
427 type   *new_type_enumeration    (ident *name, int n_enums) {
428   type *res;
429   res = new_type(type_enumeration, NULL, name);
430   res->attr.ea.n_enums     = n_enums;
431   res->attr.ea.enumer      = (tarval **) xmalloc (sizeof (tarval *) * n_enums);
432   res->attr.ea.enum_nameid = (ident  **) xmalloc (sizeof (ident  *) * n_enums);
433   return res;
434 }
435
436 /* manipulate fields of enumeration type. */
437 int     get_enumeration_n_enums (type *enumeration) {
438   assert(enumeration && (enumeration->type_op == type_enumeration));
439   return enumeration->attr.ea.n_enums;
440 }
441 void    set_enumeration_enum    (type *enumeration, int pos, tarval *con) {
442   assert(enumeration && (enumeration->type_op == type_enumeration));
443   enumeration->attr.ea.enumer[pos] = con;
444 }
445 tarval *get_enumeration_enum    (type *enumeration, int pos) {
446   assert(enumeration && (enumeration->type_op == type_enumeration));
447   return enumeration->attr.ea.enumer[pos];
448 }
449 void    set_enumeration_nameid  (type *enumeration, int pos, ident *id) {
450   assert(enumeration && (enumeration->type_op == type_enumeration));
451   enumeration->attr.ea.enum_nameid[pos] = id;
452 }
453 ident  *get_enumeration_nameid  (type *enumeration, int pos) {
454   assert(enumeration && (enumeration->type_op == type_enumeration));
455   return enumeration->attr.ea.enum_nameid[pos];
456 }
457 const char *get_enumeration_name(type *enumeration, int pos) {
458   assert(enumeration && (enumeration->type_op == type_enumeration));
459   return id_to_str(enumeration->attr.ea.enum_nameid[pos]);
460 }
461
462 /* typecheck */
463 bool    is_enumeration_type     (type *enumeration) {
464   assert(enumeration);
465   if (enumeration->type_op == type_enumeration) return 1; else return 0;
466 }
467
468 /*******************************************************************/
469 /** TYPE_POINTER                                                  **/
470 /*******************************************************************/
471
472 /* Create a new type pointer */
473 type *new_type_pointer           (ident *name, type *points_to) {
474   type *res;
475   res = new_type(type_pointer, mode_p, name);
476   res->attr.pa.points_to = points_to;
477   res->size = get_mode_size(res->mode);
478   return res;
479 }
480 /* manipulate fields of type_pointer */
481 void  set_pointer_points_to_type (type *pointer, type *type) {
482   assert(pointer && (pointer->type_op == type_pointer));
483   pointer->attr.pa.points_to = type;
484 }
485 type *get_pointer_points_to_type (type *pointer) {
486   assert(pointer && (pointer->type_op == type_pointer));
487   return pointer->attr.pa.points_to;
488 }
489
490 /* typecheck */
491 bool  is_pointer_type            (type *pointer) {
492   assert(pointer);
493   if (pointer->type_op == type_pointer) return 1; else return 0;
494 }
495
496
497 /*******************************************************************/
498 /** TYPE_PRIMITIVE                                                **/
499 /*******************************************************************/
500
501 /* create a new type primitive */
502 type *new_type_primitive (ident *name, ir_mode *mode) {
503   type *res;
504   res = new_type(type_primitive, mode, name);
505   res->size = get_mode_size(mode);
506   return res;
507 }
508
509 /* typecheck */
510 bool  is_primitive_type  (type *primitive) {
511   assert(primitive);
512   if (primitive->type_op == type_primitive) return 1; else return 0;
513 }