avoid more casts of type structs
[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 void print_type_qualifiers(type_qualifiers_t qualifiers)
44 {
45         if(qualifiers & TYPE_QUALIFIER_CONST)    fputs("const ",    out);
46         if(qualifiers & TYPE_QUALIFIER_VOLATILE) fputs("volatile ", out);
47         if(qualifiers & TYPE_QUALIFIER_RESTRICT) fputs("restrict ", out);
48 }
49
50 static
51 void print_atomic_type(const atomic_type_t *type)
52 {
53         print_type_qualifiers(type->type.qualifiers);
54
55         const char *s;
56         switch(type->atype) {
57         case ATOMIC_TYPE_INVALID:     s = "INVALIDATOMIC";      break;
58         case ATOMIC_TYPE_VOID:        s = "void";               break;
59         case ATOMIC_TYPE_BOOL:        s = "_Bool";              break;
60         case ATOMIC_TYPE_CHAR:        s = "char";               break;
61         case ATOMIC_TYPE_SCHAR:       s = "signed char";        break;
62         case ATOMIC_TYPE_UCHAR:       s = "unsigned char";      break;
63         case ATOMIC_TYPE_INT:         s = "int";                break;
64         case ATOMIC_TYPE_UINT:        s = "unsigned int";       break;
65         case ATOMIC_TYPE_SHORT:       s = "short";              break;
66         case ATOMIC_TYPE_USHORT:      s = "unsigned short";     break;
67         case ATOMIC_TYPE_LONG:        s = "long";               break;
68         case ATOMIC_TYPE_ULONG:       s = "unsigned long";      break;
69         case ATOMIC_TYPE_LONGLONG:    s = "long long";          break;
70         case ATOMIC_TYPE_ULONGLONG:   s = "unsigned long long"; break;
71         case ATOMIC_TYPE_LONG_DOUBLE: s = "long double";        break;
72         case ATOMIC_TYPE_FLOAT:       s = "float";              break;
73         case ATOMIC_TYPE_DOUBLE:      s = "double";             break;
74         default:                      s = "UNKNOWNATOMIC";      break;
75         }
76         fputs(s, out);
77 }
78
79 static void print_function_type_pre(const function_type_t *type)
80 {
81         print_type_qualifiers(type->type.qualifiers);
82
83         intern_print_type_pre(type->result_type);
84
85         /* TODO: don't emit braces if we're the toplevel type... */
86         fputc('(', out);
87 }
88
89 static void print_function_type_post(const function_type_t *type,
90                                      const context_t *context)
91 {
92         /* TODO: don't emit braces if we're the toplevel type... */
93         intern_print_type_post(type->result_type);
94         fputc(')', out);
95
96         fputc('(', out);
97
98         int                 first     = 1;
99         if(context == NULL) {
100                 function_parameter_t *parameter = type->parameters;
101                 for( ; parameter != NULL; parameter = parameter->next) {
102                         if(first) {
103                                 first = 0;
104                         } else {
105                                 fputs(", ", out);
106                         }
107                         print_type(parameter->type);
108                 }
109         } else {
110                 declaration_t *parameter = context->declarations;
111                 for( ; parameter != NULL; parameter = parameter->next) {
112                         if(first) {
113                                 first = 0;
114                         } else {
115                                 fputs(", ", out);
116                         }
117                         print_type_ext(parameter->type, parameter->symbol,
118                                        &parameter->context);
119                 }
120         }
121         if(type->variadic) {
122                 if(first) {
123                         first = 0;
124                 } else {
125                         fputs(", ", out);
126                 }
127                 fputs("...", out);
128         }
129         if(first && !type->unspecified_parameters) {
130                 fputs("void", out);
131         }
132         fputc(')', out);
133 }
134
135 static void print_pointer_type_pre(const pointer_type_t *type)
136 {
137         intern_print_type_pre(type->points_to);
138         fputs("*", out);
139         print_type_qualifiers(type->type.qualifiers);
140 }
141
142 static void print_pointer_type_post(const pointer_type_t *type)
143 {
144         intern_print_type_post(type->points_to);
145 }
146
147 static void print_array_type_pre(const array_type_t *type)
148 {
149         intern_print_type_pre(type->element_type);
150 }
151
152 static void print_array_type_post(const array_type_t *type)
153 {
154         fputc('[', out);
155         if(type->is_static) {
156                 fputs("static ", out);
157         }
158         print_type_qualifiers(type->type.qualifiers);
159         if(type->size != NULL) {
160                 print_expression(type->size);
161         }
162         fputc(']', out);
163         intern_print_type_post(type->element_type);
164 }
165
166 void print_enum_definition(const declaration_t *declaration)
167 {
168         fputs("{\n", out);
169
170         change_indent(1);
171
172         declaration_t *entry = declaration->next;
173         for( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
174                entry = entry->next) {
175
176                 print_indent();
177                 fprintf(out, "%s", entry->symbol->string);
178                 if(entry->init.initializer != NULL) {
179                         fprintf(out, " = ");
180                         print_expression(entry->init.enum_value);
181                 }
182                 fprintf(out, ",\n");
183         }
184
185         change_indent(-1);
186         print_indent();
187         fputs("}", out);
188 }
189
190 static void print_type_enum(const enum_type_t *type)
191 {
192         print_type_qualifiers(type->type.qualifiers);
193         fputs("enum ", out);
194
195         declaration_t *declaration = type->declaration;
196         symbol_t      *symbol      = declaration->symbol;
197         if(symbol != NULL) {
198                 fputs(symbol->string, out);
199         } else {
200                 print_enum_definition(declaration);
201         }
202 }
203
204 void print_compound_definition(const declaration_t *declaration)
205 {
206         fputs("{\n", out);
207         change_indent(1);
208
209         declaration_t *iter = declaration->context.declarations;
210         for( ; iter != NULL; iter = iter->next) {
211                 print_indent();
212                 print_declaration(iter);
213                 fputc('\n', out);
214         }
215
216         change_indent(-1);
217         print_indent();
218         fputs("}", out);
219 }
220
221 static void print_compound_type(const compound_type_t *type)
222 {
223         print_type_qualifiers(type->type.qualifiers);
224
225         if(type->type.type == TYPE_COMPOUND_STRUCT) {
226                 fputs("struct ", out);
227         } else {
228                 assert(type->type.type == TYPE_COMPOUND_UNION);
229                 fputs("union ", out);
230         }
231
232         declaration_t *declaration = type->declaration;
233         symbol_t      *symbol      = declaration->symbol;
234         if(symbol != NULL) {
235                 fputs(symbol->string, out);
236         } else {
237                 print_compound_definition(declaration);
238         }
239 }
240
241 static void print_typedef_type_pre(typedef_type_t *type)
242 {
243         fputs(type->declaration->symbol->string, out);
244 }
245
246 static void print_typeof_type_pre(typeof_type_t *type)
247 {
248         fputs("typeof(", out);
249         if(type->expression != NULL) {
250                 assert(type->typeof_type == NULL);
251                 print_expression(type->expression);
252         } else {
253                 print_type(type->typeof_type);
254         }
255         fputc(')', out);
256 }
257
258 static void intern_print_type_pre(type_t *type)
259 {
260         switch(type->type) {
261         case TYPE_COUNT:
262         case TYPE_INVALID:
263                 fputs("invalid", out);
264                 return;
265         case TYPE_ENUM:
266                 print_type_enum(&type->enumt);
267                 return;
268         case TYPE_ATOMIC:
269                 print_atomic_type(&type->atomic);
270                 return;
271         case TYPE_COMPOUND_STRUCT:
272         case TYPE_COMPOUND_UNION:
273                 print_compound_type(&type->compound);
274                 return;
275         case TYPE_BUILTIN:
276                 fputs(type->builtin.symbol->string, out);
277                 return;
278         case TYPE_FUNCTION:
279                 print_function_type_pre(&type->function);
280                 return;
281         case TYPE_POINTER:
282                 print_pointer_type_pre(&type->pointer);
283                 return;
284         case TYPE_ARRAY:
285                 print_array_type_pre(&type->array);
286                 return;
287         case TYPE_TYPEDEF:
288                 print_typedef_type_pre(&type->typedeft);
289                 return;
290         case TYPE_TYPEOF:
291                 print_typeof_type_pre(&type->typeoft);
292                 return;
293         }
294         fputs("unknown", out);
295 }
296
297 static void intern_print_type_post(type_t *type)
298 {
299         switch(type->type) {
300         case TYPE_FUNCTION:
301                 print_function_type_post(&type->function, NULL);
302                 return;
303         case TYPE_POINTER:
304                 print_pointer_type_post(&type->pointer);
305                 return;
306         case TYPE_ARRAY:
307                 print_array_type_post(&type->array);
308                 return;
309         case TYPE_INVALID:
310         case TYPE_COUNT:
311         case TYPE_ATOMIC:
312         case TYPE_ENUM:
313         case TYPE_COMPOUND_STRUCT:
314         case TYPE_COMPOUND_UNION:
315         case TYPE_BUILTIN:
316         case TYPE_TYPEOF:
317         case TYPE_TYPEDEF:
318                 break;
319         }
320 }
321
322 void print_type(type_t *type)
323 {
324         print_type_ext(type, NULL, NULL);
325 }
326
327 void print_type_ext(type_t *type, const symbol_t *symbol,
328                     const context_t *context)
329 {
330         if(type == NULL) {
331                 fputs("nil type", out);
332                 return;
333         }
334
335         intern_print_type_pre(type);
336         if(symbol != NULL) {
337                 fputc(' ', out);
338                 fputs(symbol->string, out);
339         }
340         if(type->type == TYPE_FUNCTION) {
341                 print_function_type_post((const function_type_t*) type, context);
342         } else {
343                 intern_print_type_post(type);
344         }
345 }
346
347 bool type_valid(const type_t *type)
348 {
349         return type->type != TYPE_INVALID;
350 }
351
352 bool is_type_integer(const type_t *type)
353 {
354         assert(!is_typeref(type));
355
356         if(type->type == TYPE_ENUM)
357                 return true;
358
359         if(type->type != TYPE_ATOMIC)
360                 return false;
361
362         switch(type->atomic.atype) {
363         case ATOMIC_TYPE_BOOL:
364         case ATOMIC_TYPE_CHAR:
365         case ATOMIC_TYPE_SCHAR:
366         case ATOMIC_TYPE_UCHAR:
367         case ATOMIC_TYPE_SHORT:
368         case ATOMIC_TYPE_USHORT:
369         case ATOMIC_TYPE_INT:
370         case ATOMIC_TYPE_UINT:
371         case ATOMIC_TYPE_LONG:
372         case ATOMIC_TYPE_ULONG:
373         case ATOMIC_TYPE_LONGLONG:
374         case ATOMIC_TYPE_ULONGLONG:
375                 return true;
376         default:
377                 return false;
378         }
379 }
380
381 bool is_type_floating(const type_t *type)
382 {
383         assert(!is_typeref(type));
384
385         if(type->type != TYPE_ATOMIC)
386                 return false;
387
388         switch(type->atomic.atype) {
389         case ATOMIC_TYPE_FLOAT:
390         case ATOMIC_TYPE_DOUBLE:
391         case ATOMIC_TYPE_LONG_DOUBLE:
392 #ifdef PROVIDE_COMPLEX
393         case ATOMIC_TYPE_FLOAT_COMPLEX:
394         case ATOMIC_TYPE_DOUBLE_COMPLEX:
395         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
396         case ATOMIC_TYPE_FLOAT_IMAGINARY:
397         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
398         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
399 #endif
400                 return true;
401         default:
402                 return false;
403         }
404 }
405
406 bool is_type_signed(const type_t *type)
407 {
408         assert(!is_typeref(type));
409
410         /* enum types are int for now */
411         if(type->type == TYPE_ENUM)
412                 return true;
413
414         if(type->type != TYPE_ATOMIC)
415                 return false;
416
417         switch(type->atomic.atype) {
418         case ATOMIC_TYPE_CHAR:
419         case ATOMIC_TYPE_SCHAR:
420         case ATOMIC_TYPE_SHORT:
421         case ATOMIC_TYPE_INT:
422         case ATOMIC_TYPE_LONG:
423         case ATOMIC_TYPE_LONGLONG:
424         case ATOMIC_TYPE_FLOAT:
425         case ATOMIC_TYPE_DOUBLE:
426         case ATOMIC_TYPE_LONG_DOUBLE:
427 #ifdef PROVIDE_COMPLEX
428         case ATOMIC_TYPE_FLOAT_COMPLEX:
429         case ATOMIC_TYPE_DOUBLE_COMPLEX:
430         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
431         case ATOMIC_TYPE_FLOAT_IMAGINARY:
432         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
433         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
434 #endif
435                 return true;
436
437         case ATOMIC_TYPE_BOOL:
438         case ATOMIC_TYPE_UCHAR:
439         case ATOMIC_TYPE_USHORT:
440         case ATOMIC_TYPE_UINT:
441         case ATOMIC_TYPE_ULONG:
442         case ATOMIC_TYPE_ULONGLONG:
443                 return false;
444
445         case ATOMIC_TYPE_INVALID:
446         case ATOMIC_TYPE_VOID:
447                 return false;
448         }
449
450         panic("invalid atomic type found");
451         return false;
452 }
453
454 bool is_type_arithmetic(const type_t *type)
455 {
456         assert(!is_typeref(type));
457
458         if(is_type_integer(type) || is_type_floating(type))
459                 return 1;
460
461         return 0;
462 }
463
464 bool is_type_scalar(const type_t *type)
465 {
466         assert(!is_typeref(type));
467
468         if(type->type == TYPE_POINTER)
469                 return 1;
470
471         return is_type_arithmetic(type);
472 }
473
474 bool is_type_incomplete(const type_t *type)
475 {
476         assert(!is_typeref(type));
477
478         switch(type->type) {
479         case TYPE_COMPOUND_STRUCT:
480         case TYPE_COMPOUND_UNION: {
481                 const compound_type_t *compound_type = &type->compound;
482                 declaration_t         *declaration   = compound_type->declaration;
483                 return !declaration->init.is_defined;
484         }
485         case TYPE_FUNCTION:
486                 return true;
487
488         case TYPE_ARRAY:
489                 return type->array.size == NULL;
490
491         case TYPE_ATOMIC:
492         case TYPE_POINTER:
493         case TYPE_ENUM:
494                 return false;
495
496         case TYPE_TYPEDEF:
497         case TYPE_TYPEOF:
498         case TYPE_BUILTIN:
499                 panic("is_type_incomplete called without typerefs skipped");
500         case TYPE_COUNT:
501         case TYPE_INVALID:
502                 break;
503         }
504
505         panic("invalid type found");
506 }
507
508 bool types_compatible(const type_t *type1, const type_t *type2)
509 {
510         assert(!is_typeref(type1));
511         assert(!is_typeref(type2));
512
513         /* TODO: really incomplete */
514         if(type1 == type2)
515                 return true;
516
517         if(type1->type == TYPE_ATOMIC && type2->type == TYPE_ATOMIC) {
518                 return type1->atomic.atype == type2->atomic.atype;
519         }
520
521         return false;
522 }
523
524 bool pointers_compatible(const type_t *type1, const type_t *type2)
525 {
526         assert(!is_typeref(type1));
527         assert(!is_typeref(type2));
528
529         assert(type1->type == TYPE_POINTER);
530         assert(type2->type == TYPE_POINTER);
531         /* TODO */
532         return true;
533 }
534
535 static size_t get_type_size(type_t *type)
536 {
537         switch(type->type) {
538         case TYPE_ATOMIC:          return sizeof(atomic_type_t); break;
539         case TYPE_COMPOUND_STRUCT:
540         case TYPE_COMPOUND_UNION:  return sizeof(compound_type_t); break;
541         case TYPE_ENUM:            return sizeof(enum_type_t); break;
542         case TYPE_FUNCTION:        return sizeof(function_type_t); break;
543         case TYPE_POINTER:         return sizeof(pointer_type_t); break;
544         case TYPE_ARRAY:           return sizeof(array_type_t); break;
545         case TYPE_BUILTIN:         return sizeof(builtin_type_t); break;
546         case TYPE_TYPEDEF:         return sizeof(typedef_type_t); break;
547         case TYPE_TYPEOF:          return sizeof(typeof_type_t); break;
548         case TYPE_COUNT:
549         case TYPE_INVALID:         panic("invalid type found"); break;
550         }
551         panic("unknown type found");
552 }
553
554 /**
555  * duplicates a type
556  * note that this does not produce a deep copy!
557  */
558 static type_t *duplicate_type(type_t *type)
559 {
560         size_t size = get_type_size(type);
561
562         type_t *copy = obstack_alloc(type_obst, size);
563         memcpy(copy, type, size);
564
565         (void) duplicate_type;
566
567         return type;
568 }
569
570 type_t *skip_typeref(type_t *type)
571 {
572         unsigned qualifiers = type->base.qualifiers;
573
574         while(1) {
575                 switch(type->type) {
576                 case TYPE_TYPEDEF: {
577                         qualifiers |= type->base.qualifiers;
578                         const typedef_type_t *typedef_type = &type->typedeft;
579                         if(typedef_type->resolved_type != NULL) {
580                                 type = typedef_type->resolved_type;
581                                 break;
582                         }
583                         type = typedef_type->declaration->type;
584                         continue;
585                 }
586                 case TYPE_TYPEOF: {
587                         const typeof_type_t *typeof_type = &type->typeoft;
588                         if(typeof_type->typeof_type != NULL) {
589                                 type = typeof_type->typeof_type;
590                         } else {
591                                 type = typeof_type->expression->datatype;
592                         }
593                         continue;
594                 }
595                 case TYPE_BUILTIN: {
596                         const builtin_type_t *builtin_type = &type->builtin;
597                         type = builtin_type->real_type;
598                         continue;
599                 }
600                 default:
601                         break;
602                 }
603                 break;
604         }
605
606         return type;
607 }
608
609
610
611 static type_t *identify_new_type(type_t *type)
612 {
613         type_t *result = typehash_insert(type);
614         if(result != type) {
615                 obstack_free(type_obst, type);
616         }
617         return result;
618 }
619
620 type_t *make_atomic_type(atomic_type_type_t atype, type_qualifiers_t qualifiers)
621 {
622         type_t *type = obstack_alloc(type_obst, sizeof(atomic_type_t));
623         memset(type, 0, sizeof(atomic_type_t));
624
625         type->type            = TYPE_ATOMIC;
626         type->base.qualifiers = qualifiers;
627         type->atomic.atype    = atype;
628
629         return identify_new_type(type);
630 }
631
632 type_t *make_pointer_type(type_t *points_to, type_qualifiers_t qualifiers)
633 {
634         type_t *type = obstack_alloc(type_obst, sizeof(pointer_type_t));
635         memset(type, 0, sizeof(pointer_type_t));
636
637         type->type              = TYPE_POINTER;
638         type->base.qualifiers   = qualifiers;
639         type->pointer.points_to = points_to;
640
641         return identify_new_type(type);
642 }
643
644 static __attribute__((unused))
645 void dbg_type(type_t *type)
646 {
647         FILE *old_out = out;
648         out = stderr;
649         print_type(type);
650         puts("\n");
651         fflush(stderr);
652         out = old_out;
653 }