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