*** empty log message ***
[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 inline int
262 get_method_arity (type_method *method) {
263   return method->arity;
264 }
265
266 /*
267 inline void
268 set_method_arity (type_method *method, int arity) {
269   method->arity = arity;
270   / change array size, somehow copy.  *
271 }
272 */
273
274 inline type *
275 get_method_param_type(type_method *method, int pos) {
276   return method->param_type[pos];
277 }
278
279 inline void
280 set_method_param_type(type_method *method, int pos, type* type) {
281   method->param_type[pos] = type;
282 }
283
284
285 inline int
286 get_method_n_res (type_method *method) {
287   return method->n_res;
288 }
289
290 /*
291 inline void
292 set_method_n_res (type_method *method, int n_res) {
293   method->n_res = n_res;
294 }
295 */
296
297 inline type *
298 get_method_res_type(type_method *method, int pos) {
299   return method->res_type[pos];
300 }
301
302 inline void
303 set_method_res_type(type_method *method, int pos, type* type) {
304   method->res_type[pos] = type;
305 }
306
307
308 /*******************************************************************/
309 /** TYPE_UNION                                                    **/
310 /*******************************************************************/
311
312 /* create a new type_union -- set unioned types by hand. */
313 type_union *
314 new_type_union (ident *name, int n_types)
315 {
316   type_union *res;
317
318   res = (type_union *) xmalloc (sizeof (type_union));
319   add_irp_type((type *) res);   /* Remember the new type global. */
320   res->kind = k_type_union;
321   res->name = name;   // do I need a name?
322   res->n_types = n_types;
323   /*
324   res->unioned_type = (int *) xmalloc (sizeof (int) * n_types);
325   */
326
327   res->visit = 0;
328
329   return res;
330 }
331
332 /* manipulate fields of type_union */
333 /*
334 char *
335 get_union_name  (type_union *uni) {
336   assert(uni);
337   return ID_TO_STR(uni->name);
338 }
339 */
340
341 ident *
342 get_union_ident (type_union *uni) {
343   assert(uni);
344   return uni->name;
345 }
346
347 /*
348 void   set_union_name  (type_union *union, char *name);
349 void   set_union_ident (type_union *union, ident* ident);
350 */
351 /*
352 int    get_union_n_types (type_union *union);
353 void   set_union_n_types (type_union *union, int n);
354 type  *get_union_unioned_type (type_union *union, int pos);
355 void   set_union_unioned_type (type_union *union, int pos, type *type);
356 */
357
358 /*******************************************************************/
359 /** TYPE_ARRAY                                                    **/
360 /*******************************************************************/
361
362 /* create a new type_array */
363 inline type_array *
364 new_type_array (ident *name, int n_dimensions)
365 {
366   type_array *res;
367
368   res = (type_array *) xmalloc (sizeof (type_array));
369   add_irp_type((type *) res);   /* Remember the new type global. */
370   res->kind = k_type_array;
371   res->name = name;
372   res->n_dimensions = n_dimensions;
373   res->lower_bound = (int *) xmalloc (sizeof (int) * n_dimensions);
374   res->upper_bound = (int *) xmalloc (sizeof (int) * n_dimensions);
375
376   res->visit = 0;
377
378   return res;
379 }
380
381 /* manipulate fields of type_array */
382 /*
383 char *
384 get_array_name  (type_array *array) {
385   assert(array);
386   return ID_TO_STR(array->name);
387 }
388 */
389
390 ident *
391 get_array_ident (type_array *array) {
392   assert(array);
393   return array->name;
394 }
395
396 /*
397 void   set_array_name  (type_array *array, char *name);
398 void   set_array_ident (type_array *array, ident* ident);
399 */
400
401 inline void
402 set_array_dimensions (type_array* array, int n) {
403   array->n_dimensions = n;
404 }
405
406 inline int
407 get_array_dimensions (type_array* array) {
408   return array->n_dimensions;
409 }
410
411 inline void
412 set_array_bounds (type_array* array, int dimension, int lower_bound,
413                   int upper_bound) {
414   array->lower_bound[dimension-1] = lower_bound;
415   array->upper_bound[dimension-1] = upper_bound;
416 }
417
418 inline void
419 set_array_lower_bound (type_array* array, int dimension, int lower_bound) {
420   array->lower_bound[dimension-1] = lower_bound;
421 }
422
423 inline void
424 set_array_upper_bound (type_array* array, int dimension, int upper_bound) {
425   array->upper_bound[dimension-1] = upper_bound;
426 }
427
428 inline int
429 get_array_lower_bound (type_array* array, int dimension) {
430   return array->lower_bound[dimension-1];
431 }
432
433 inline int
434 get_array_upper_bound (type_array* array, int dimension) {
435   return array->upper_bound[dimension-1];
436 }
437
438 inline void set_array_element_type (type_array *array, type *type) {
439   array->element_type = type;
440 }
441
442 inline type *
443 get_array_element_type (type_array *array) {
444   return array->element_type;
445 }
446
447
448 /*******************************************************************/
449 /** TYPE_ENUMERATION                                              **/
450 /*******************************************************************/
451
452 /* create a new type enumeration -- set the enumerators independently */
453 type_enumeration *
454 new_type_enumeration (ident *name /* , int n_enums */)
455 {
456   type_enumeration *res;
457
458   res = (type_enumeration *) xmalloc (sizeof (type_enumeration));
459   add_irp_type((type *) res);   /* Remember the new type global. */
460   res->kind = k_type_enumeration;
461   res->name = name;
462   /*
463   res->n_enums = n_enums;
464   res->enum = (int *) xmalloc (sizeof (int) * n_enums);
465   */
466
467   res->visit = 0;
468
469   return res;
470 }
471
472 /* manipulate fields of type_enumeration */
473 /*
474 char *
475 get_enumeration_name  (type_enumeration *enumeration) {
476   assert(enumeration);
477   return ID_TO_STR(enumeration->name);
478 }
479 */
480
481 ident *
482 get_enumeration_ident (type_enumeration *enumeration) {
483   assert(enumeration);
484   return enumeration->name;
485 }
486
487 /*
488 void   set_enumeration_name  (type_enumeration *enumeration, char *name);
489 void   set_enumeration_ident (type_enumeration *enumeration, ident* ident);
490 */
491 /*
492 void     set_enumeration_n_enums (type_enumeration *enumeration, int n);
493 int     *get_enumeration_n_enums (type_enumeration *enumeration);
494 void     set_enumeration_enum    (type_enumeration *enumeration, int pos,
495                                  ir_node const);
496 ir_node *get_enumeration_enum    (type_enumeration *enumeration, int pos);
497 */
498
499
500 /*******************************************************************/
501 /** TYPE_POINTER                                                  **/
502 /*******************************************************************/
503
504 /* create a new type pointer */
505 type_pointer *
506 new_type_pointer (ident *name, type *points_to)
507 {
508   type_pointer *res;
509
510   res = (type_pointer *) xmalloc (sizeof (type_pointer));
511   add_irp_type((type *) res);   /* Remember the new type global. */
512   res->kind = k_type_pointer;
513   res->name = name;
514   res->points_to = points_to;
515
516   res->visit = 0;
517
518   return res;
519 }
520
521 /* manipulate fields of type_pointer */
522 /*
523 char *
524 get_pointer_name  (type_pointer *pointer) {
525   assert(pointer);
526   return ID_TO_STR(pointer->name);
527 }
528 */
529
530 ident *
531 get_pointer_ident (type_pointer *pointer) {
532   assert(pointer);
533   return pointer->name;
534 }
535
536 /*
537 void   set_pointer_name  (type_pointer *pointer, char *name);
538 void   set_pointer_ident (type_pointer *pointer, ident* ident);
539 */
540
541 inline void
542 set_pointer_points_to_type (type_pointer *pointer, type* type) {
543   pointer->points_to = type;
544 }
545
546 inline type *
547 get_pointer_points_to_type (type_pointer *pointer) {
548   return pointer->points_to;
549 }
550
551
552 /*******************************************************************/
553 /** TYPE_PRIMITIVE                                                **/
554 /*******************************************************************/
555
556 /* create a new type_primitive */
557 inline type_primitive *
558 new_type_primitive (ident *name, ir_mode *mode)
559 {
560   type_primitive *res;
561
562   res = (type_primitive *) xmalloc (sizeof (type_primitive));
563   add_irp_type((type *) res);   /* Remember the new type global. */
564   res->kind = k_type_primitive;
565   res->name = name;
566   res->mode = mode;
567
568   res->visit = 0;
569
570   return res;
571 }
572
573 /* manipulate fields of type_primitive */
574 /*
575
576 char  *
577 get_primitive_name  (type_primitive *primitive) {
578   assert(primitive);
579   return ID_TO_STR(primitive->name);
580 }
581 */
582
583 ident *
584 get_primitive_ident (type_primitive *primitive) {
585   assert(primitive);
586   return primitive->name;
587 }
588 /*
589 void   set_primitive_name  (type_primitive *primitive, char *name);
590 void   set_primitive_ident (type_primitive *primitive, ident* ident);
591 */
592
593 inline ir_mode *
594 get_primitive_mode (type_primitive *primitive) {
595   return primitive->mode;
596 }
597
598 inline void
599 set_primitive_mode (type_primitive *primitive, ir_mode *mode) {
600   primitive->mode = mode;
601 }
602
603
604
605
606 /*******************************************************************/
607 /**  To manage all different types the same                       **/
608 /*******************************************************************/
609
610
611 int
612 is_type(void *thing) {
613   firm_kind kind;
614
615   kind = get_kind(thing);
616   if (   (kind == k_type_class)
617       || (kind == k_type_strct)
618       || (kind == k_type_method)
619       || (kind == k_type_union)
620       || (kind == k_type_array)
621       || (kind == k_type_enumeration)
622       || (kind == k_type_pointer)
623       || (kind == k_type_primitive))
624     return 1;
625   else
626     return 0;
627 }