convert ast types to firm types
[cparser] / type.c
1 #include <config.h>
2
3 #include <stdio.h>
4 #include <assert.h>
5 #include "type_t.h"
6 #include "type_hash.h"
7 #include "adt/error.h"
8
9 static struct obstack   _type_obst;
10 struct obstack         *type_obst = &_type_obst;
11 static FILE            *out;
12 static int              type_visited = 0;
13 static bool             print_compound_entries;
14
15 static void intern_print_type_pre(type_t *type);
16 static void intern_print_type_post(type_t *type);
17
18 void init_types(void)
19 {
20         obstack_init(type_obst);
21 }
22
23 void exit_types(void)
24 {
25         obstack_free(type_obst, NULL);
26 }
27
28 void type_set_output(FILE *stream)
29 {
30         out = stream;
31 }
32
33 void set_print_compound_entries(bool enabled)
34 {
35         print_compound_entries = enabled;
36 }
37
38 void inc_type_visited(void)
39 {
40         type_visited++;
41 }
42
43 static
44 void print_type_qualifiers(unsigned qualifiers)
45 {
46         if(qualifiers & TYPE_QUALIFIER_CONST)    fputs("const ",    out);
47         if(qualifiers & TYPE_QUALIFIER_VOLATILE) fputs("volatile ", out);
48         if(qualifiers & TYPE_QUALIFIER_RESTRICT) fputs("restrict ", out);
49         if(qualifiers & TYPE_QUALIFIER_INLINE)   fputs("inline ",   out);
50 }
51
52 static
53 void print_atomic_type(const atomic_type_t *type)
54 {
55         print_type_qualifiers(type->type.qualifiers);
56
57         const char *s;
58         switch(type->atype) {
59         case ATOMIC_TYPE_INVALID:     s = "INVALIDATOMIC";      break;
60         case ATOMIC_TYPE_VOID:        s = "void";               break;
61         case ATOMIC_TYPE_BOOL:        s = "_Bool";              break;
62         case ATOMIC_TYPE_CHAR:        s = "char";               break;
63         case ATOMIC_TYPE_SCHAR:       s = "signed char";        break;
64         case ATOMIC_TYPE_UCHAR:       s = "unsigned char";      break;
65         case ATOMIC_TYPE_INT:         s = "int";                break;
66         case ATOMIC_TYPE_UINT:        s = "unsigned int";       break;
67         case ATOMIC_TYPE_SHORT:       s = "short";              break;
68         case ATOMIC_TYPE_USHORT:      s = "unsigned short";     break;
69         case ATOMIC_TYPE_LONG:        s = "long";               break;
70         case ATOMIC_TYPE_ULONG:       s = "unsigned long";      break;
71         case ATOMIC_TYPE_LONGLONG:    s = "long long";          break;
72         case ATOMIC_TYPE_ULONGLONG:   s = "unsigned long long"; break;
73         case ATOMIC_TYPE_LONG_DOUBLE: s = "long double";        break;
74         case ATOMIC_TYPE_FLOAT:       s = "float";              break;
75         case ATOMIC_TYPE_DOUBLE:      s = "double";             break;
76         default:                      s = "UNKNOWNATOMIC";      break;
77         }
78         fputs(s, out);
79 }
80
81 static
82 void print_method_type_pre(const method_type_t *type)
83 {
84         print_type_qualifiers(type->type.qualifiers);
85
86         intern_print_type_pre(type->result_type);
87
88         /* TODO: don't emit braces if we're the toplevel type... */
89         fputc('(', out);
90 }
91
92 static
93 void print_method_type_post(const method_type_t *type, const context_t *context)
94 {
95         /* TODO: don't emit braces if we're the toplevel type... */
96         intern_print_type_post(type->result_type);
97         fputc(')', out);
98
99         fputc('(', out);
100
101         int                 first     = 1;
102         if(context == NULL) {
103                 method_parameter_t *parameter = type->parameters;
104                 for( ; parameter != NULL; parameter = parameter->next) {
105                         if(first) {
106                                 first = 0;
107                         } else {
108                                 fputs(", ", out);
109                         }
110                         print_type(parameter->type);
111                 }
112         } else {
113                 declaration_t *parameter = context->declarations;
114                 for( ; parameter != NULL; parameter = parameter->context_next) {
115                         if(first) {
116                                 first = 0;
117                         } else {
118                                 fputs(", ", out);
119                         }
120                         print_type_ext(parameter->type, parameter->symbol,
121                                        &parameter->context);
122                 }
123         }
124         if(type->variadic) {
125                 if(first) {
126                         first = 0;
127                 } else {
128                         fputs(", ", out);
129                 }
130                 fputs("...", out);
131         }
132         if(first && !type->unspecified_parameters) {
133                 fputs("void", out);
134         }
135         fputc(')', out);
136 }
137
138 static
139 void print_pointer_type_pre(const pointer_type_t *type)
140 {
141         intern_print_type_pre(type->points_to);
142         fputs("*", out);
143         print_type_qualifiers(type->type.qualifiers);
144 }
145
146 static void print_pointer_type_post(const pointer_type_t *type)
147 {
148         intern_print_type_post(type->points_to);
149 }
150
151 static void print_array_type_post(const array_type_t *type)
152 {
153         fputc('[', out);
154         if(type->is_static) {
155                 fputs("static ", out);
156         }
157         print_type_qualifiers(type->type.qualifiers);
158         if(type->size != NULL) {
159                 print_expression(type->size);
160         }
161         fputc(']', out);
162 }
163
164 void print_enum_definition(const declaration_t *declaration)
165 {
166         fputs("{\n", out);
167
168         change_indent(1);
169
170         declaration_t *entry = declaration->context_next;
171         for( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
172                entry = entry->context_next) {
173
174                 print_indent();
175                 fprintf(out, "%s", entry->symbol->string);
176                 if(entry->init.initializer != NULL) {
177                         fprintf(out, " = ");
178                         print_initializer(entry->init.initializer);
179                 }
180                 fprintf(out, ",\n");
181         }
182
183         change_indent(-1);
184         print_indent();
185         fputs("}", out);
186 }
187
188 static void print_type_enum(const enum_type_t *type)
189 {
190         print_type_qualifiers(type->type.qualifiers);
191         fputs("enum ", out);
192
193         declaration_t *declaration = type->declaration;
194         symbol_t      *symbol      = declaration->symbol;
195         if(symbol != NULL) {
196                 fputs(symbol->string, out);
197         } else {
198                 print_enum_definition(declaration);
199         }
200 }
201
202 void print_compound_definition(const declaration_t *declaration)
203 {
204         fputs("{\n", out);
205         change_indent(1);
206
207         declaration_t *iter = declaration->context.declarations;
208         for( ; iter != NULL; iter = iter->context_next) {
209                 print_indent();
210                 print_declaration(iter);
211                 fputc('\n', out);
212         }
213
214         change_indent(-1);
215         print_indent();
216         fputs("}", out);
217 }
218
219 static void print_compound_type(const compound_type_t *type)
220 {
221         print_type_qualifiers(type->type.qualifiers);
222
223         if(type->type.type == TYPE_COMPOUND_STRUCT) {
224                 fputs("struct ", out);
225         } else {
226                 assert(type->type.type == TYPE_COMPOUND_UNION);
227                 fputs("union ", out);
228         }
229
230         declaration_t *declaration = type->declaration;
231         symbol_t      *symbol      = declaration->symbol;
232         if(symbol != NULL) {
233                 fputs(symbol->string, out);
234         } else {
235                 print_compound_definition(declaration);
236         }
237 }
238
239 static void print_typedef_type_pre(typedef_type_t *type)
240 {
241         fputs(type->declaration->symbol->string, out);
242 }
243
244 static void print_typeof_type_pre(typeof_type_t *type)
245 {
246         fputs("typeof(", out);
247         if(type->expression != NULL) {
248                 assert(type->typeof_type == NULL);
249                 print_expression(type->expression);
250         } else {
251                 print_type(type->typeof_type);
252         }
253         fputc(')', out);
254 }
255
256 static void intern_print_type_pre(type_t *type)
257 {
258         switch(type->type) {
259         case TYPE_INVALID:
260                 fputs("invalid", out);
261                 return;
262         case TYPE_ENUM:
263                 print_type_enum((enum_type_t*) type);
264                 return;
265         case TYPE_ATOMIC:
266                 print_atomic_type((atomic_type_t*) type);
267                 return;
268         case TYPE_COMPOUND_STRUCT:
269         case TYPE_COMPOUND_UNION:
270                 print_compound_type((compound_type_t*) type);
271                 return;
272         case TYPE_BUILTIN:
273                 fputs(((builtin_type_t*) type)->symbol->string, out);
274                 return;
275         case TYPE_METHOD:
276                 print_method_type_pre((method_type_t*) type);
277                 return;
278         case TYPE_POINTER:
279                 print_pointer_type_pre((pointer_type_t*) type);
280                 return;
281         case TYPE_ARRAY:
282                 return;
283         case TYPE_TYPEDEF:
284                 print_typedef_type_pre((typedef_type_t*) type);
285                 return;
286         case TYPE_TYPEOF:
287                 print_typeof_type_pre((typeof_type_t*) type);
288                 return;
289         }
290         fputs("unknown", out);
291 }
292
293 static
294 void intern_print_type_post(type_t *type)
295 {
296         switch(type->type) {
297         case TYPE_METHOD:
298                 print_method_type_post((const method_type_t*) type, NULL);
299                 return;
300         case TYPE_POINTER:
301                 print_pointer_type_post((const pointer_type_t*) type);
302                 return;
303         case TYPE_ARRAY:
304                 print_array_type_post((const array_type_t*) type);
305                 return;
306         case TYPE_INVALID:
307         case TYPE_ATOMIC:
308         case TYPE_ENUM:
309         case TYPE_COMPOUND_STRUCT:
310         case TYPE_COMPOUND_UNION:
311         case TYPE_BUILTIN:
312         case TYPE_TYPEOF:
313         case TYPE_TYPEDEF:
314                 break;
315         }
316 }
317
318 void print_type(type_t *type)
319 {
320         print_type_ext(type, NULL, NULL);
321 }
322
323 void print_type_ext(type_t *type, const symbol_t *symbol,
324                     const context_t *context)
325 {
326         if(type == NULL) {
327                 fputs("nil type", out);
328                 return;
329         }
330
331         intern_print_type_pre(type);
332         if(symbol != NULL) {
333                 fputc(' ', out);
334                 fputs(symbol->string, out);
335         }
336         if(type->type == TYPE_METHOD) {
337                 print_method_type_post((const method_type_t*) type, context);
338         } else {
339                 intern_print_type_post(type);
340         }
341 }
342
343 bool type_valid(const type_t *type)
344 {
345         return type->type != TYPE_INVALID;
346 }
347
348 bool is_type_integer(const type_t *type)
349 {
350         if(type->type == TYPE_ENUM)
351                 return 1;
352
353         if(type->type != TYPE_ATOMIC)
354                 return 0;
355
356         atomic_type_t *atomic_type = (atomic_type_t*) type;
357         switch(atomic_type->atype) {
358         case ATOMIC_TYPE_BOOL:
359         case ATOMIC_TYPE_CHAR:
360         case ATOMIC_TYPE_SCHAR:
361         case ATOMIC_TYPE_UCHAR:
362         case ATOMIC_TYPE_SHORT:
363         case ATOMIC_TYPE_USHORT:
364         case ATOMIC_TYPE_INT:
365         case ATOMIC_TYPE_UINT:
366         case ATOMIC_TYPE_LONG:
367         case ATOMIC_TYPE_ULONG:
368         case ATOMIC_TYPE_LONGLONG:
369         case ATOMIC_TYPE_ULONGLONG:
370                 return 1;
371         default:
372                 return 0;
373         }
374 }
375
376 bool is_type_floating(const type_t *type)
377 {
378         if(type->type != TYPE_ATOMIC)
379                 return 0;
380
381         atomic_type_t *atomic_type = (atomic_type_t*) type;
382         switch(atomic_type->atype) {
383         case ATOMIC_TYPE_FLOAT:
384         case ATOMIC_TYPE_DOUBLE:
385         case ATOMIC_TYPE_LONG_DOUBLE:
386 #ifdef PROVIDE_COMPLEX
387         case ATOMIC_TYPE_FLOAT_COMPLEX:
388         case ATOMIC_TYPE_DOUBLE_COMPLEX:
389         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
390 #endif
391 #ifdef PROVIDE_IMAGINARY
392         case ATOMIC_TYPE_FLOAT_IMAGINARY:
393         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
394         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
395 #endif
396                 return 1;
397         default:
398                 return 0;
399         }
400 }
401
402 bool is_type_arithmetic(const type_t *type)
403 {
404         if(is_type_integer(type) || is_type_floating(type))
405                 return 1;
406
407         return 0;
408 }
409
410 bool is_type_scalar(const type_t *type)
411 {
412         if(type->type == TYPE_POINTER)
413                 return 1;
414
415         return is_type_arithmetic(type);
416 }
417
418 static type_t *identify_new_type(type_t *type)
419 {
420         type_t *result = typehash_insert(type);
421         if(result != type) {
422                 obstack_free(type_obst, type);
423         }
424         return result;
425 }
426
427 type_t *make_atomic_type(atomic_type_type_t type, type_qualifier_t qualifiers)
428 {
429         atomic_type_t *atomic_type
430                 = obstack_alloc(type_obst, sizeof(atomic_type[0]));
431         memset(atomic_type, 0, sizeof(atomic_type[0]));
432         atomic_type->type.type       = TYPE_ATOMIC;
433         atomic_type->type.qualifiers = qualifiers;
434         atomic_type->atype           = type;
435
436         return identify_new_type((type_t*) atomic_type);
437 }
438
439 type_t *make_pointer_type(type_t *points_to, type_qualifier_t qualifiers)
440 {
441         pointer_type_t *pointer_type
442                 = obstack_alloc(type_obst, sizeof(pointer_type[0]));
443         memset(pointer_type, 0, sizeof(pointer_type[0]));
444         pointer_type->type.type       = TYPE_POINTER;
445         pointer_type->type.qualifiers = qualifiers;
446         pointer_type->points_to       = points_to;
447
448         return identify_new_type((type_t*) pointer_type);
449 }
450
451 static __attribute__((unused))
452 void dbg_type(type_t *type)
453 {
454         FILE *old_out = out;
455         out = stderr;
456         print_type(type);
457         puts("\n");
458         fflush(stderr);
459         out = old_out;
460 }