d1d6dc44f7a0acf4d3669c2ca213ea21d92ee201
[libfirm] / ir / tr / type.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Martin Trapp, Christian Schaefer &
5 **          Goetz Lindenmaier
6 **
7 ** type.c: datastructures to hold type information.
8 */
9
10 # include "type.h"
11 # include "irprog.h"  /* So that constructors can add the type to global
12                          data structure. */
13 # include "array.h"
14 # include "ident_t.h"
15
16 unsigned long type_visited = 0;
17
18 void
19 init (void)
20 {
21 }
22
23 /*******************************************************************/
24 /** TYPE_CLASS                                                    **/
25 /*******************************************************************/
26
27 type_class *
28 new_type_class (ident *name)//, int members)
29 {
30   type_class *res;
31
32   res = (type_class *) xmalloc (sizeof (type_class));
33   add_irp_type((type *) res);   /* Remember the new type global. */
34   res->kind = k_type_class;
35   res->name = name;
36
37   res->members = NEW_ARR_F (entity *, 1);
38   res->subtypes = NEW_ARR_F (type_class *, 1);
39   res->supertypes = NEW_ARR_F (type_class *, 1);
40
41   res->visit = 0;
42
43   return res;
44 }
45
46 /* manipulate fields of type_class */
47 const char *
48 get_class_name  (type_class *class) {
49   assert(class);
50   return id_to_str(class->name);
51 }
52
53 /* field: ident */
54 ident *
55 get_class_ident (type_class *class) {
56   assert(class);
57   return class->name;
58 }
59
60 /*
61 void   set_class_name  (type_class *class, char *name);
62 void   set_class_ident (type_class *class, ident* ident);
63 */
64
65 /* field: member */
66 void
67 add_class_member (type_class *class, entity *member)
68 {
69   ARR_APP1 (entity *, class->members, member);
70 }
71
72 entity *
73 get_class_member (type_class *class, int pos)
74 {
75   assert (class);
76   return class->members[pos+1];
77 }
78
79 void
80 set_class_member (type_class *class, entity *member, int pos)
81 {
82   class->members[pos+1] = member;
83 }
84
85 int
86 get_class_n_member (type_class *class)
87 {
88   int res;
89
90   assert(class);
91   res = (ARR_LEN (class->members))-1;
92   return res;
93 }
94
95 /* field: subtype */
96 void
97 add_class_subtype (type_class *class,  type_class *subtype)
98 {
99   ARR_APP1 (type_class *, class->subtypes, subtype);
100 }
101
102 type_class *
103 get_class_subtype (type_class *class, int pos)
104 {
105   assert (class);
106   return class->subtypes[pos+1];
107 }
108
109 void
110 set_class_subtype (type_class *class, type_class *subtype, int pos)
111 {
112   class->subtypes[pos+1] = subtype;
113 }
114
115 int
116 get_class_n_subtype (type_class *class)
117 {
118   assert(class);
119   return (ARR_LEN (class->subtypes))-1;
120 }
121
122 /* field: supertype */
123 void
124 add_class_supertype (type_class *class, type_class *supertype)
125 {
126   ARR_APP1 (type_class *, class->supertypes, supertype);
127 }
128
129 type_class *
130 get_class_supertype (type_class *class, int pos)
131 {
132   assert (class);
133   return class->supertypes[pos+1];
134 }
135
136 void
137 set_class_supertype (type_class *class, type_class *supertype, int pos)
138 {
139   class->supertypes[pos+1] = supertype;
140 }
141
142 int
143 get_class_n_supertype (type_class *class)
144 {
145   assert(class);
146   return (ARR_LEN (class->supertypes))-1;
147 }
148
149 /*******************************************************************/
150 /** TYPE_STRCT                                                   **/
151 /*******************************************************************/
152
153 type_strct *
154 new_type_strct (ident *name)//, int members)
155 {
156   type_strct *res;
157
158   res = (type_strct *) xmalloc (sizeof (type_strct));
159   add_irp_type((type *) res);   /* Remember the new type global. */
160   res->kind = k_type_strct;
161   res->name = name;
162
163   res->members = NEW_ARR_F (entity *, 1);
164   res->visit = 0;
165
166   return res;
167 }
168
169 /* manipulate fields of type_strct */
170
171 const char *
172 get_strct_name  (type_strct *strct) {
173   assert(strct);
174   return ID_TO_STR(strct->name);
175 }
176
177
178 ident *
179 get_strct_ident (type_strct *strct) {
180   assert(strct);
181   return strct->name;
182 }
183
184 int
185 get_strct_n_member (type_strct *strct)
186 {
187   int res;
188
189   assert(strct);
190   res = (ARR_LEN (strct->members))-1;
191   return res;
192 }
193
194 void
195 add_strct_member (type_strct *strct, entity *member)
196 {
197   ARR_APP1 (type_strct *, strct->members, member);
198 }
199
200 entity *
201 get_strct_member (type_strct *strct, int pos)
202 {
203   assert (strct);
204   return strct->members[pos+1];
205 }
206
207 void
208 set_strct_member (type_strct *strct, int pos, entity *member)
209 {
210   strct->members[pos+1] = member;
211 }
212
213 /*
214 void   set_strct_name  (type_strct *strct, char *name);
215 void   set_strct_ident (type_strct *strct, ident* ident);
216 */
217
218
219 /*******************************************************************/
220 /** TYPE_METHOD                                                   **/
221 /*******************************************************************/
222
223 /* create a new type_method */
224 type_method *
225 new_type_method (ident *name, int arity, int n_res)
226 {
227   type_method *res;
228
229   res = (type_method *) xmalloc (sizeof (type_method));
230   add_irp_type((type *) res);   /* Remember the new type global. */
231   res->kind = k_type_method;
232   res->name = name;   // do I need the name, or is the name in entity sufficient?
233   res->arity = arity;
234   res->param_type = (type **) xmalloc (sizeof (type *) * arity);
235   res->n_res  = n_res;
236   res->res_type = (type **) xmalloc (sizeof (type *) * n_res);
237
238   res->visit = 0;
239
240   return res;
241 }
242
243 /* manipulate fields of type_method */
244 const char *
245 get_method_name  (type_method *method) {
246   assert(method);
247   return ID_TO_STR(method->name);
248 }
249
250 ident *
251 get_method_ident (type_method *method) {
252   assert(method);
253   return method->name;
254 }
255
256 /*
257 void   set_method_name  (type_method *method, char *name);
258 void   set_method_ident (type_method *method, ident* ident);
259 */
260
261
262 inline int
263 get_method_n_params (type_method *method) {
264   return method->arity;
265 }
266
267 inline int
268 get_method_arity (type_method *method) {
269   return method->arity;
270 }
271
272 /*
273 inline void
274 set_method_arity (type_method *method, int arity) {
275   method->arity = arity;
276   / change array size, somehow copy.  *
277 }
278 */
279
280 inline type *
281 get_method_param_type(type_method *method, int pos) {
282   return method->param_type[pos];
283 }
284
285 inline void
286 set_method_param_type(type_method *method, int pos, type* type) {
287   method->param_type[pos] = type;
288 }
289
290
291 inline int
292 get_method_n_res (type_method *method) {
293   return method->n_res;
294 }
295
296 /*
297 inline void
298 set_method_n_res (type_method *method, int n_res) {
299   method->n_res = n_res;
300 }
301 */
302
303 inline type *
304 get_method_res_type(type_method *method, int pos) {
305   return method->res_type[pos];
306 }
307
308 inline void
309 set_method_res_type(type_method *method, int pos, type* type) {
310   method->res_type[pos] = type;
311 }
312
313
314 /*******************************************************************/
315 /** TYPE_UNION                                                    **/
316 /*******************************************************************/
317
318 /* create a new type_union -- set unioned types by hand. */
319 type_union *
320 new_type_union (ident *name, int n_types)
321 {
322   type_union *res;
323
324   res = (type_union *) xmalloc (sizeof (type_union));
325   add_irp_type((type *) res);   /* Remember the new type global. */
326   res->kind = k_type_union;
327   res->name = name;   // do I need a name?
328   res->n_types = n_types;
329   /*
330   res->unioned_type = (int *) xmalloc (sizeof (int) * n_types);
331   */
332
333   res->visit = 0;
334
335   return res;
336 }
337
338 /* manipulate fields of type_union */
339 /*
340 char *
341 get_union_name  (type_union *uni) {
342   assert(uni);
343   return ID_TO_STR(uni->name);
344 }
345 */
346
347 ident *
348 get_union_ident (type_union *uni) {
349   assert(uni);
350   return uni->name;
351 }
352
353 /*
354 void   set_union_name  (type_union *union, char *name);
355 void   set_union_ident (type_union *union, ident* ident);
356 */
357 /*
358 int    get_union_n_types (type_union *union);
359 void   set_union_n_types (type_union *union, int n);
360 type  *get_union_unioned_type (type_union *union, int pos);
361 void   set_union_unioned_type (type_union *union, int pos, type *type);
362 */
363
364 /*******************************************************************/
365 /** TYPE_ARRAY                                                    **/
366 /*******************************************************************/
367
368 /* create a new type_array */
369 inline type_array *
370 new_type_array (ident *name, int n_dimensions)
371 {
372   type_array *res;
373
374   res = (type_array *) xmalloc (sizeof (type_array));
375   add_irp_type((type *) res);   /* Remember the new type global. */
376   res->kind = k_type_array;
377   res->name = name;
378   res->n_dimensions = n_dimensions;
379   res->lower_bound = (int *) xmalloc (sizeof (int) * n_dimensions);
380   res->upper_bound = (int *) xmalloc (sizeof (int) * n_dimensions);
381
382   res->visit = 0;
383
384   return res;
385 }
386
387 /* manipulate fields of type_array */
388 /*
389 char *
390 get_array_name  (type_array *array) {
391   assert(array);
392   return ID_TO_STR(array->name);
393 }
394 */
395
396 ident *
397 get_array_ident (type_array *array) {
398   assert(array);
399   return array->name;
400 }
401
402 /*
403 void   set_array_name  (type_array *array, char *name);
404 void   set_array_ident (type_array *array, ident* ident);
405 */
406
407 inline void
408 set_array_dimensions (type_array* array, int n) {
409   array->n_dimensions = n;
410 }
411
412 inline int
413 get_array_dimensions (type_array* array) {
414   return array->n_dimensions;
415 }
416
417 inline void
418 set_array_bounds (type_array* array, int dimension, int lower_bound,
419                   int upper_bound) {
420   array->lower_bound[dimension-1] = lower_bound;
421   array->upper_bound[dimension-1] = upper_bound;
422 }
423
424 inline void
425 set_array_lower_bound (type_array* array, int dimension, int lower_bound) {
426   array->lower_bound[dimension-1] = lower_bound;
427 }
428
429 inline void
430 set_array_upper_bound (type_array* array, int dimension, int upper_bound) {
431   array->upper_bound[dimension-1] = upper_bound;
432 }
433
434 inline int
435 get_array_lower_bound (type_array* array, int dimension) {
436   return array->lower_bound[dimension-1];
437 }
438
439 inline int
440 get_array_upper_bound (type_array* array, int dimension) {
441   return array->upper_bound[dimension-1];
442 }
443
444 inline void set_array_element_type (type_array *array, type *type) {
445   array->element_type = type;
446 }
447
448 inline type *
449 get_array_element_type (type_array *array) {
450   return array->element_type;
451 }
452
453
454 /*******************************************************************/
455 /** TYPE_ENUMERATION                                              **/
456 /*******************************************************************/
457
458 /* create a new type enumeration -- set the enumerators independently */
459 type_enumeration *
460 new_type_enumeration (ident *name /* , int n_enums */)
461 {
462   type_enumeration *res;
463
464   res = (type_enumeration *) xmalloc (sizeof (type_enumeration));
465   add_irp_type((type *) res);   /* Remember the new type global. */
466   res->kind = k_type_enumeration;
467   res->name = name;
468   /*
469   res->n_enums = n_enums;
470   res->enum = (int *) xmalloc (sizeof (int) * n_enums);
471   */
472
473   res->visit = 0;
474
475   return res;
476 }
477
478 /* manipulate fields of type_enumeration */
479 /*
480 char *
481 get_enumeration_name  (type_enumeration *enumeration) {
482   assert(enumeration);
483   return ID_TO_STR(enumeration->name);
484 }
485 */
486
487 ident *
488 get_enumeration_ident (type_enumeration *enumeration) {
489   assert(enumeration);
490   return enumeration->name;
491 }
492
493 /*
494 void   set_enumeration_name  (type_enumeration *enumeration, char *name);
495 void   set_enumeration_ident (type_enumeration *enumeration, ident* ident);
496 */
497 /*
498 void     set_enumeration_n_enums (type_enumeration *enumeration, int n);
499 int     *get_enumeration_n_enums (type_enumeration *enumeration);
500 void     set_enumeration_enum    (type_enumeration *enumeration, int pos,
501                                  ir_node const);
502 ir_node *get_enumeration_enum    (type_enumeration *enumeration, int pos);
503 */
504
505
506 /*******************************************************************/
507 /** TYPE_POINTER                                                  **/
508 /*******************************************************************/
509
510 /* create a new type pointer */
511 type_pointer *
512 new_type_pointer (ident *name, type *points_to)
513 {
514   type_pointer *res;
515
516   res = (type_pointer *) xmalloc (sizeof (type_pointer));
517   add_irp_type((type *) res);   /* Remember the new type global. */
518   res->kind = k_type_pointer;
519   res->name = name;
520   res->points_to = points_to;
521
522   res->visit = 0;
523
524   return res;
525 }
526
527 /* manipulate fields of type_pointer */
528 /*
529 char *
530 get_pointer_name  (type_pointer *pointer) {
531   assert(pointer);
532   return ID_TO_STR(pointer->name);
533 }
534 */
535
536 ident *
537 get_pointer_ident (type_pointer *pointer) {
538   assert(pointer);
539   return pointer->name;
540 }
541
542 /*
543 void   set_pointer_name  (type_pointer *pointer, char *name);
544 void   set_pointer_ident (type_pointer *pointer, ident* ident);
545 */
546
547 inline void
548 set_pointer_points_to_type (type_pointer *pointer, type* type) {
549   pointer->points_to = type;
550 }
551
552 inline type *
553 get_pointer_points_to_type (type_pointer *pointer) {
554   return pointer->points_to;
555 }
556
557
558 /*******************************************************************/
559 /** TYPE_PRIMITIVE                                                **/
560 /*******************************************************************/
561
562 /* create a new type_primitive */
563 inline type_primitive *
564 new_type_primitive (ident *name, ir_mode *mode)
565 {
566   type_primitive *res;
567
568   res = (type_primitive *) xmalloc (sizeof (type_primitive));
569   add_irp_type((type *) res);   /* Remember the new type global. */
570   res->kind = k_type_primitive;
571   res->name = name;
572   res->mode = mode;
573
574   res->visit = 0;
575
576   return res;
577 }
578
579 /* manipulate fields of type_primitive */
580 /*
581
582 char  *
583 get_primitive_name  (type_primitive *primitive) {
584   assert(primitive);
585   return ID_TO_STR(primitive->name);
586 }
587 */
588
589 ident *
590 get_primitive_ident (type_primitive *primitive) {
591   assert(primitive);
592   return primitive->name;
593 }
594 /*
595 void   set_primitive_name  (type_primitive *primitive, char *name);
596 void   set_primitive_ident (type_primitive *primitive, ident* ident);
597 */
598
599 inline ir_mode *
600 get_primitive_mode (type_primitive *primitive) {
601   return primitive->mode;
602 }
603
604 inline void
605 set_primitive_mode (type_primitive *primitive, ir_mode *mode) {
606   primitive->mode = mode;
607 }
608
609
610
611
612 /*******************************************************************/
613 /**  To manage all different types the same                       **/
614 /*******************************************************************/
615
616
617 int
618 is_type(void *thing) {
619   firm_kind kind;
620
621   kind = get_kind(thing);
622   if (   (kind == k_type_class)
623       || (kind == k_type_strct)
624       || (kind == k_type_method)
625       || (kind == k_type_union)
626       || (kind == k_type_array)
627       || (kind == k_type_enumeration)
628       || (kind == k_type_pointer)
629       || (kind == k_type_primitive))
630     return 1;
631   else
632     return 0;
633 }