convert ast types to firm types
[cparser] / ast2firm.c
1 #include <config.h>
2
3 #define _GNU_SOURCE
4
5 #include <assert.h>
6 #include <libfirm/firm.h>
7 #include <libfirm/adt/obst.h>
8
9 #include "adt/error.h"
10 #include "token_t.h"
11 #include "type_t.h"
12 #include "ast_t.h"
13
14 static ir_type *ir_type_const_char;
15 static ir_type *ir_type_void;
16 static ir_type *ir_type_int;
17 static ir_type *ir_type_void_ptr;
18
19 static type_t *type_const_char;
20 static type_t *type_void;
21 static type_t *type_int;
22
23 typedef struct type2firm_env_t type2firm_env_t;
24 struct type2firm_env_t {
25         int can_cache;       /* nonzero if type can safely be cached because
26                                 no typevariables are in the hierarchy */
27 };
28
29 static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type);
30 static ir_type *get_ir_type(type_t *type);
31
32 ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
33 {
34         (void) pos;
35 #if 0
36         const declaration_t *declaration = & value_numbers[pos]->declaration;
37
38         print_warning_prefix(declaration->source_position);
39         fprintf(stderr, "variable '%s' might be used uninitialized\n",
40                         declaration->symbol->string);
41 #endif
42         fprintf(stderr, "Some variable might be used uninitialized\n");
43         return new_r_Unknown(irg, mode);
44 }
45
46 unsigned dbg_snprint(char *buf, unsigned len, const dbg_info *dbg)
47 {
48         const source_position_t *pos = (const source_position_t*) dbg;
49         if(pos == NULL)
50                 return 0;
51         return (unsigned) snprintf(buf, len, "%s:%u", pos->input_name,
52                                    pos->linenr);
53 }
54
55 const char *retrieve_dbg(const dbg_info *dbg, unsigned *line)
56 {
57         const source_position_t *pos = (const source_position_t*) dbg;
58         if(pos == NULL)
59                 return NULL;
60         if(line != NULL)
61                 *line = pos->linenr;
62         return pos->input_name;
63 }
64
65 void init_ast2firm(void)
66 {
67         type_const_char = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_CONST);
68         type_void       = make_atomic_type(ATOMIC_TYPE_VOID, 0);
69         type_int        = make_atomic_type(ATOMIC_TYPE_INT, 0);
70
71         ir_type_const_char = get_ir_type(type_const_char);
72         ir_type_void       = get_ir_type(type_void);
73         ir_type_void_ptr   = new_type_pointer(new_id_from_str("void_ptr"),
74                                               ir_type_void, mode_P_data);
75         ir_type_int        = get_ir_type(type_int);
76 }
77
78 void exit_ast2firm(void)
79 {
80 }
81
82 static unsigned unique_id = 0;
83
84 static ident *unique_ident(const char *tag)
85 {
86         char buf[256];
87
88         snprintf(buf, sizeof(buf), "%s.%d", tag, unique_id);
89         unique_id++;
90         return new_id_from_str(buf);
91 }
92
93 #if 0
94 static symbol_t *unique_symbol(const char *tag)
95 {
96         obstack_printf(&symbol_obstack, "%s.%d", tag, unique_id);
97         unique_id++;
98
99         const char *string = obstack_finish(&symbol_obstack);
100         symbol_t   *symbol = symbol_table_insert(string);
101
102         assert(symbol->string == string);
103
104         return symbol;
105 }
106 #endif
107
108 static type_t *skip_typeref(type_t *type)
109 {
110         while(1) {
111                 switch(type->type) {
112                 case TYPE_TYPEDEF: {
113                         const typedef_type_t *typedef_type = (const typedef_type_t*) type;
114                         type = typedef_type->declaration->type;
115                         continue;
116                 }
117                 case TYPE_TYPEOF: {
118                         const typeof_type_t *typeof_type = (const typeof_type_t *) type;
119                         if(typeof_type->typeof_type != NULL) {
120                                 type = typeof_type->typeof_type;
121                         } else {
122                                 type = typeof_type->expression->datatype;
123                         }
124                         continue;
125                 }
126                 default:
127                         break;
128                 }
129                 break;
130         }
131
132         return type;
133 }
134
135 static ir_mode *get_atomic_mode(const atomic_type_t* atomic_type)
136 {
137         switch(atomic_type->atype) {
138         case ATOMIC_TYPE_SCHAR:
139         case ATOMIC_TYPE_CHAR:
140                 return mode_Bs;
141         case ATOMIC_TYPE_UCHAR:
142                 return mode_Bu;
143         case ATOMIC_TYPE_SHORT:
144                 return mode_Hs;
145         case ATOMIC_TYPE_USHORT:
146                 return mode_Hu;
147         case ATOMIC_TYPE_LONG:
148         case ATOMIC_TYPE_INT:
149                 return mode_Is;
150         case ATOMIC_TYPE_ULONG:
151         case ATOMIC_TYPE_UINT:
152                 return mode_Iu;
153         case ATOMIC_TYPE_LONGLONG:
154                 return mode_Ls;
155         case ATOMIC_TYPE_ULONGLONG:
156                 return mode_Lu;
157         case ATOMIC_TYPE_FLOAT:
158                 return mode_F;
159         case ATOMIC_TYPE_DOUBLE:
160                 return mode_D;
161         case ATOMIC_TYPE_LONG_DOUBLE:
162                 return mode_E;
163         case ATOMIC_TYPE_BOOL:
164                 return mode_b;
165 #ifdef PROVIDE_COMPLEX
166         case ATOMIC_TYPE_FLOAT_COMPLEX:
167         case ATOMIC_TYPE_DOUBLE_COMPLEX:
168         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
169                 panic("complex lowering not implemented yet");
170                 break;
171         case ATOMIC_TYPE_FLOAT_IMAGINARY:
172         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
173         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
174                 panic("imaginary lowering not implemented yet");
175                 break;
176 #endif
177         case ATOMIC_TYPE_VOID:
178                 panic("tried to get mode from void type");
179                 break;
180         case ATOMIC_TYPE_INVALID:
181                 break;
182         }
183         panic("Encountered unknown atomic type");
184 }
185
186
187 static unsigned get_type_size(type_t *type);
188
189 static unsigned get_atomic_type_size(const atomic_type_t *type)
190 {
191         switch(type->atype) {
192         case ATOMIC_TYPE_CHAR:
193         case ATOMIC_TYPE_SCHAR:
194         case ATOMIC_TYPE_UCHAR:
195                 return 1;
196
197         case ATOMIC_TYPE_SHORT:
198         case ATOMIC_TYPE_USHORT:
199                 return 2;
200
201         case ATOMIC_TYPE_BOOL:
202         case ATOMIC_TYPE_INT:
203         case ATOMIC_TYPE_UINT:
204         case ATOMIC_TYPE_LONG:
205         case ATOMIC_TYPE_ULONG:
206         case ATOMIC_TYPE_FLOAT:
207                 return 4;
208
209         case ATOMIC_TYPE_LONGLONG:
210         case ATOMIC_TYPE_ULONGLONG:
211         case ATOMIC_TYPE_DOUBLE:
212                 return 8;
213
214         case ATOMIC_TYPE_LONG_DOUBLE:
215                 return 12;
216
217         case ATOMIC_TYPE_VOID:
218                 return 1;
219
220         case ATOMIC_TYPE_INVALID:
221                 break;
222         }
223         panic("Trying to determine size of invalid atomic type");
224 }
225
226 static unsigned get_compound_type_size(compound_type_t *type)
227 {
228         ir_type *irtype = get_ir_type(&type->type);
229         return get_type_size_bytes(irtype);
230 }
231
232 static unsigned get_array_type_size(array_type_t *type)
233 {
234         ir_type *irtype = get_ir_type(&type->type);
235         return get_type_size_bytes(irtype);
236 }
237
238 static unsigned get_type_size(type_t *type)
239 {
240         type = skip_typeref(type);
241
242         switch(type->type) {
243         case TYPE_ATOMIC:
244                 return get_atomic_type_size((const atomic_type_t*) type);
245         case TYPE_ENUM:
246                 return get_mode_size_bytes(mode_Is);
247         case TYPE_COMPOUND_UNION:
248         case TYPE_COMPOUND_STRUCT:
249                 return get_compound_type_size((compound_type_t*) type);
250         case TYPE_METHOD:
251                 /* just a pointer to the method */
252                 return get_mode_size_bytes(mode_P_code);
253         case TYPE_POINTER:
254                 return get_mode_size_bytes(mode_P_data);
255         case TYPE_ARRAY:
256                 return get_array_type_size((array_type_t*) type);
257         case TYPE_BUILTIN:
258         case TYPE_TYPEDEF:
259         case TYPE_TYPEOF:
260         case TYPE_INVALID:
261                 break;
262         }
263         panic("Trying to determine size of invalid type");
264 }
265
266 static unsigned count_parameters(const method_type_t *method_type)
267 {
268         unsigned count = 0;
269
270         method_parameter_t *parameter = method_type->parameters;
271         for ( ; parameter != NULL; parameter = parameter->next) {
272                 ++count;
273         }
274
275         return count;
276 }
277
278
279
280
281 static ir_type *get_atomic_type(type2firm_env_t *env, const atomic_type_t *type)
282 {
283         (void) env;
284         ir_mode *mode   = get_atomic_mode(type);
285         ident   *id     = get_mode_ident(mode);
286         ir_type *irtype = new_type_primitive(id, mode);
287
288         return irtype;
289 }
290
291 static ir_type *get_method_type(type2firm_env_t *env,
292                                 const method_type_t *method_type)
293 {
294         type_t  *result_type  = method_type->result_type;
295
296         ident   *id           = unique_ident("methodtype");
297         int      n_parameters = count_parameters(method_type);
298         int      n_results    = result_type == type_void ? 0 : 1;
299         ir_type *irtype       = new_type_method(id, n_parameters, n_results);
300
301         if(result_type != type_void) {
302                 ir_type *restype = _get_ir_type(env, result_type);
303                 set_method_res_type(irtype, 0, restype);
304         }
305
306         method_parameter_t *parameter = method_type->parameters;
307         int                 n         = 0;
308         for( ; parameter != NULL; parameter = parameter->next) {
309                 ir_type *p_irtype = _get_ir_type(env, parameter->type);
310                 set_method_param_type(irtype, n, p_irtype);
311                 ++n;
312         }
313
314         if(method_type->variadic) {
315                 set_method_variadicity(irtype, variadicity_variadic);
316         }
317
318         return irtype;
319 }
320
321 static ir_type *get_pointer_type(type2firm_env_t *env, pointer_type_t *type)
322 {
323         type_t  *points_to = type->points_to;
324         ir_type *ir_points_to;
325         /* Avoid endless recursion if the points_to type contains this poiner type
326          * again (might be a struct). We therefore first create a void* pointer
327          * and then set the real points_to type
328          */
329         ir_type *ir_type_void = get_ir_type(type_void);
330         ir_type *ir_type      = new_type_pointer(unique_ident("pointer"),
331                                              ir_type_void, mode_P_data);
332         type->type.firm_type  = ir_type;
333
334         ir_points_to = _get_ir_type(env, points_to);
335         set_pointer_points_to_type(ir_type, ir_points_to);
336
337         return ir_type;
338 }
339
340 static ir_type *get_array_type(type2firm_env_t *env, array_type_t *type)
341 {
342         type_t  *element_type    = type->element_type;
343         ir_type *ir_element_type = _get_ir_type(env, element_type);
344
345         /* TODO... */
346         int n_elements = 0;
347         panic("TODO arraytpye size not implemented yet");
348
349         ir_type *ir_type = new_type_array(unique_ident("array"), 1, ir_element_type);
350         set_array_bounds_int(ir_type, 0, 0, n_elements);
351
352         size_t elemsize = get_type_size_bytes(ir_element_type);
353         int align = get_type_alignment_bytes(ir_element_type);
354         if(elemsize % align > 0) {
355                 elemsize += align - (elemsize % align);
356         }
357         set_type_size_bytes(ir_type, n_elements * elemsize);
358         set_type_alignment_bytes(ir_type, align);
359         set_type_state(ir_type, layout_fixed);
360
361         return ir_type;
362 }
363
364 #define INVALID_TYPE ((ir_type_ptr)-1)
365
366 static ir_type *get_struct_type(type2firm_env_t *env, compound_type_t *type)
367 {
368         symbol_t *symbol = type->declaration->symbol;
369         ident    *id;
370         if(symbol != NULL) {
371                 id = unique_ident(symbol->string);
372         } else {
373                 id = unique_ident("__anonymous_struct");
374         }
375         ir_type *ir_type = new_type_struct(id);
376
377         type->type.firm_type = ir_type;
378
379         int align_all = 1;
380         int offset    = 0;
381         declaration_t *entry = type->declaration->context.declarations;
382         for( ; entry != NULL; entry = entry->next) {
383                 ident       *ident         = new_id_from_str(entry->symbol->string);
384                 ir_type_ptr  entry_ir_type = _get_ir_type(env, entry->type);
385
386                 int entry_size      = get_type_size_bytes(entry_ir_type);
387                 int entry_alignment = get_type_alignment_bytes(entry_ir_type);
388                 int misalign = offset % entry_alignment;
389                 offset += misalign;
390
391                 ir_entity *entity = new_entity(ir_type, ident, entry_ir_type);
392                 set_entity_offset(entity, offset);
393                 add_struct_member(ir_type, entity);
394                 entry->entity = entity;
395
396                 offset += entry_size;
397                 if(entry_alignment > align_all) {
398                         if(entry_alignment % align_all != 0) {
399                                 panic("Uneven alignments not supported yet");
400                         }
401                         align_all = entry_alignment;
402                 }
403         }
404
405         int misalign = offset % align_all;
406         offset += misalign;
407         set_type_alignment_bytes(ir_type, align_all);
408         set_type_size_bytes(ir_type, offset);
409         set_type_state(ir_type, layout_fixed);
410
411         return ir_type;
412 }
413
414 static ir_type *get_union_type(type2firm_env_t *env, compound_type_t *type)
415 {
416         declaration_t *declaration = type->declaration;
417         symbol_t      *symbol      = declaration->symbol;
418         ident         *id;
419         if(symbol != NULL) {
420                 id = unique_ident(symbol->string);
421         } else {
422                 id = unique_ident("__anonymous_union");
423         }
424         ir_type  *ir_type = new_type_union(id);
425
426         type->type.firm_type = ir_type;
427
428         int align_all = 1;
429         int size      = 0;
430         declaration_t *entry = declaration->context.declarations;
431         for( ; entry != NULL; entry = entry->next) {
432                 ident       *ident         = new_id_from_str(entry->symbol->string);
433                 ir_type_ptr  entry_ir_type = _get_ir_type(env, entry->type);
434
435                 int entry_size      = get_type_size_bytes(entry_ir_type);
436                 int entry_alignment = get_type_alignment_bytes(entry_ir_type);
437
438                 ir_entity *entity = new_entity(ir_type, ident, entry_ir_type);
439                 add_union_member(ir_type, entity);
440                 set_entity_offset(entity, 0);
441                 entry->entity = entity;
442
443                 if(entry_size > size) {
444                         size = entry_size;
445                 }
446                 if(entry_alignment > align_all) {
447                         if(entry_alignment % align_all != 0) {
448                                 panic("Uneven alignments not supported yet");
449                         }
450                         align_all = entry_alignment;
451                 }
452         }
453
454         set_type_alignment_bytes(ir_type, align_all);
455         set_type_size_bytes(ir_type, size);
456         set_type_state(ir_type, layout_fixed);
457
458         return ir_type;
459 }
460
461 static ir_type *_get_ir_type(type2firm_env_t *env, type_t *type)
462 {
463         assert(type != NULL);
464
465         type = skip_typeref(type);
466
467         if(type->firm_type != NULL) {
468                 assert(type->firm_type != INVALID_TYPE);
469                 return type->firm_type;
470         }
471
472         ir_type *firm_type = NULL;
473         switch(type->type) {
474         case TYPE_ATOMIC:
475                 firm_type = get_atomic_type(env, (atomic_type_t*) type);
476                 break;
477         case TYPE_METHOD:
478                 firm_type = get_method_type(env, (method_type_t*) type);
479                 break;
480         case TYPE_POINTER:
481                 firm_type = get_pointer_type(env, (pointer_type_t*) type);
482                 break;
483         case TYPE_ARRAY:
484                 firm_type = get_array_type(env, (array_type_t*) type);
485                 break;
486         case TYPE_COMPOUND_STRUCT:
487                 firm_type = get_struct_type(env, (compound_type_t*) type);
488                 break;
489         case TYPE_COMPOUND_UNION:
490                 firm_type = get_union_type(env, (compound_type_t*) type);
491                 break;
492         case TYPE_ENUM:
493                 firm_type = ir_type_int;
494                 break;
495         case TYPE_BUILTIN:
496         case TYPE_TYPEOF:
497         case TYPE_TYPEDEF:
498         case TYPE_INVALID:
499                 break;
500         }
501         if(firm_type == NULL)
502                 panic("unknown type found");
503
504         if(env->can_cache) {
505                 type->firm_type = firm_type;
506         }
507         return firm_type;
508
509 }
510
511 static ir_type *get_ir_type(type_t *type)
512 {
513         type2firm_env_t env;
514         env.can_cache = 1;
515
516         return _get_ir_type(&env, type);
517 }
518
519 static inline ir_mode *get_ir_mode(type_t *type)
520 {
521         ir_type *irtype = get_ir_type(type);
522         ir_mode *mode   = get_type_mode(irtype);
523         assert(mode != NULL);
524         return mode;
525 }
526
527 int dummy(void)
528 {
529         return get_type_size(type_int);
530 }