add some assert where typedef/typeof types should not be used, add missing skip_typer...
[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(unsigned 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_INVALID:
262                 fputs("invalid", out);
263                 return;
264         case TYPE_ENUM:
265                 print_type_enum((enum_type_t*) type);
266                 return;
267         case TYPE_ATOMIC:
268                 print_atomic_type((atomic_type_t*) type);
269                 return;
270         case TYPE_COMPOUND_STRUCT:
271         case TYPE_COMPOUND_UNION:
272                 print_compound_type((compound_type_t*) type);
273                 return;
274         case TYPE_BUILTIN:
275                 fputs(((builtin_type_t*) type)->symbol->string, out);
276                 return;
277         case TYPE_FUNCTION:
278                 print_function_type_pre((function_type_t*) type);
279                 return;
280         case TYPE_POINTER:
281                 print_pointer_type_pre((pointer_type_t*) type);
282                 return;
283         case TYPE_ARRAY:
284                 print_array_type_pre((array_type_t*) type);
285                 return;
286         case TYPE_TYPEDEF:
287                 print_typedef_type_pre((typedef_type_t*) type);
288                 return;
289         case TYPE_TYPEOF:
290                 print_typeof_type_pre((typeof_type_t*) type);
291                 return;
292         }
293         fputs("unknown", out);
294 }
295
296 static void intern_print_type_post(type_t *type)
297 {
298         switch(type->type) {
299         case TYPE_FUNCTION:
300                 print_function_type_post((const function_type_t*) type, NULL);
301                 return;
302         case TYPE_POINTER:
303                 print_pointer_type_post((const pointer_type_t*) type);
304                 return;
305         case TYPE_ARRAY:
306                 print_array_type_post((const array_type_t*) type);
307                 return;
308         case TYPE_INVALID:
309         case TYPE_ATOMIC:
310         case TYPE_ENUM:
311         case TYPE_COMPOUND_STRUCT:
312         case TYPE_COMPOUND_UNION:
313         case TYPE_BUILTIN:
314         case TYPE_TYPEOF:
315         case TYPE_TYPEDEF:
316                 break;
317         }
318 }
319
320 void print_type(type_t *type)
321 {
322         print_type_ext(type, NULL, NULL);
323 }
324
325 void print_type_ext(type_t *type, const symbol_t *symbol,
326                     const context_t *context)
327 {
328         if(type == NULL) {
329                 fputs("nil type", out);
330                 return;
331         }
332
333         intern_print_type_pre(type);
334         if(symbol != NULL) {
335                 fputc(' ', out);
336                 fputs(symbol->string, out);
337         }
338         if(type->type == TYPE_FUNCTION) {
339                 print_function_type_post((const function_type_t*) type, context);
340         } else {
341                 intern_print_type_post(type);
342         }
343 }
344
345 bool type_valid(const type_t *type)
346 {
347         return type->type != TYPE_INVALID;
348 }
349
350 bool is_type_integer(const type_t *type)
351 {
352         assert(!is_typeref(type));
353
354         if(type->type == TYPE_ENUM)
355                 return true;
356
357         if(type->type != TYPE_ATOMIC)
358                 return false;
359
360         atomic_type_t *atomic_type = (atomic_type_t*) type;
361         switch(atomic_type->atype) {
362         case ATOMIC_TYPE_BOOL:
363         case ATOMIC_TYPE_CHAR:
364         case ATOMIC_TYPE_SCHAR:
365         case ATOMIC_TYPE_UCHAR:
366         case ATOMIC_TYPE_SHORT:
367         case ATOMIC_TYPE_USHORT:
368         case ATOMIC_TYPE_INT:
369         case ATOMIC_TYPE_UINT:
370         case ATOMIC_TYPE_LONG:
371         case ATOMIC_TYPE_ULONG:
372         case ATOMIC_TYPE_LONGLONG:
373         case ATOMIC_TYPE_ULONGLONG:
374                 return true;
375         default:
376                 return false;
377         }
378 }
379
380 bool is_type_floating(const type_t *type)
381 {
382         assert(!is_typeref(type));
383
384         if(type->type != TYPE_ATOMIC)
385                 return false;
386
387         atomic_type_t *atomic_type = (atomic_type_t*) type;
388         switch(atomic_type->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         atomic_type_t *atomic_type = (atomic_type_t*) type;
418         switch(atomic_type->atype) {
419         case ATOMIC_TYPE_CHAR:
420         case ATOMIC_TYPE_SCHAR:
421         case ATOMIC_TYPE_SHORT:
422         case ATOMIC_TYPE_INT:
423         case ATOMIC_TYPE_LONG:
424         case ATOMIC_TYPE_LONGLONG:
425         case ATOMIC_TYPE_FLOAT:
426         case ATOMIC_TYPE_DOUBLE:
427         case ATOMIC_TYPE_LONG_DOUBLE:
428 #ifdef PROVIDE_COMPLEX
429         case ATOMIC_TYPE_FLOAT_COMPLEX:
430         case ATOMIC_TYPE_DOUBLE_COMPLEX:
431         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
432         case ATOMIC_TYPE_FLOAT_IMAGINARY:
433         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
434         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
435 #endif
436                 return true;
437
438         case ATOMIC_TYPE_BOOL:
439         case ATOMIC_TYPE_UCHAR:
440         case ATOMIC_TYPE_USHORT:
441         case ATOMIC_TYPE_UINT:
442         case ATOMIC_TYPE_ULONG:
443         case ATOMIC_TYPE_ULONGLONG:
444                 return false;
445
446         case ATOMIC_TYPE_INVALID:
447         case ATOMIC_TYPE_VOID:
448                 return false;
449         }
450
451         panic("invalid atomic type found");
452         return false;
453 }
454
455 bool is_type_arithmetic(const type_t *type)
456 {
457         assert(!is_typeref(type));
458
459         if(is_type_integer(type) || is_type_floating(type))
460                 return 1;
461
462         return 0;
463 }
464
465 bool is_type_scalar(const type_t *type)
466 {
467         assert(!is_typeref(type));
468
469         if(type->type == TYPE_POINTER)
470                 return 1;
471
472         return is_type_arithmetic(type);
473 }
474
475 bool is_type_incomplete(const type_t *type)
476 {
477         assert(!is_typeref(type));
478
479         switch(type->type) {
480         case TYPE_COMPOUND_STRUCT:
481         case TYPE_COMPOUND_UNION: {
482                 const compound_type_t *compound_type
483                         = (const compound_type_t*) type;
484                 declaration_t *declaration = compound_type->declaration;
485                 return !declaration->init.is_defined;
486         }
487         case TYPE_FUNCTION:
488                 return true;
489
490         case TYPE_ARRAY: {
491                 const array_type_t *array_type = (const array_type_t*) type;
492
493                 return array_type->size == NULL;
494         }
495
496         case TYPE_ATOMIC:
497         case TYPE_POINTER:
498         case TYPE_ENUM:
499                 return false;
500
501         case TYPE_TYPEDEF:
502         case TYPE_TYPEOF:
503         case TYPE_BUILTIN:
504                 panic("is_type_incomplete called without typerefs skipped");
505         case TYPE_INVALID:
506                 break;
507         }
508
509         panic("invalid type found");
510 }
511
512 bool types_compatible(const type_t *type1, const type_t *type2)
513 {
514         assert(!is_typeref(type1));
515         assert(!is_typeref(type2));
516
517         /* TODO: really incomplete */
518         if(type1 == type2)
519                 return true;
520
521         if(type1->type == TYPE_ATOMIC && type2->type == TYPE_ATOMIC) {
522                 const atomic_type_t *atomic1 = (const atomic_type_t*) type1;
523                 const atomic_type_t *atomic2 = (const atomic_type_t*) type2;
524
525                 return atomic1->atype == atomic2->atype;
526         }
527
528         return false;
529 }
530
531 bool pointers_compatible(const type_t *type1, const type_t *type2)
532 {
533         assert(!is_typeref(type1));
534         assert(!is_typeref(type2));
535
536         assert(type1->type == TYPE_POINTER);
537         assert(type2->type == TYPE_POINTER);
538 #if 0
539         pointer_type_t *pointer_type1 = (pointer_type_t*) type1;
540         pointer_type_t *pointer_type2 = (pointer_type_t*) type2;
541         return types_compatible(pointer_type1->points_to,
542                                 pointer_type2->points_to);
543 #endif
544         return true;
545 }
546
547 static size_t get_type_size(type_t *type)
548 {
549         switch(type->type) {
550         case TYPE_ATOMIC:          return sizeof(atomic_type_t); break;
551         case TYPE_COMPOUND_STRUCT:
552         case TYPE_COMPOUND_UNION:  return sizeof(compound_type_t); break;
553         case TYPE_ENUM:            return sizeof(enum_type_t); break;
554         case TYPE_FUNCTION:        return sizeof(function_type_t); break;
555         case TYPE_POINTER:         return sizeof(pointer_type_t); break;
556         case TYPE_ARRAY:           return sizeof(array_type_t); break;
557         case TYPE_BUILTIN:         return sizeof(builtin_type_t); break;
558         case TYPE_TYPEDEF:         return sizeof(typedef_type_t); break;
559         case TYPE_TYPEOF:          return sizeof(typeof_type_t); break;
560         case TYPE_INVALID:         panic("invalid type found"); break;
561         }
562         panic("unknown type found");
563 }
564
565 /**
566  * duplicates a type
567  * note that this does not produce a deep copy!
568  */
569 static type_t *duplicate_type(type_t *type)
570 {
571         size_t size = get_type_size(type);
572
573         type_t *copy = obstack_alloc(type_obst, size);
574         memcpy(copy, type, size);
575
576         (void) duplicate_type;
577
578         return type;
579 }
580
581 type_t *skip_typeref(type_t *type)
582 {
583         unsigned qualifiers = type->qualifiers;
584
585         while(1) {
586                 switch(type->type) {
587                 case TYPE_TYPEDEF: {
588                         qualifiers |= type->qualifiers;
589                         const typedef_type_t *typedef_type = (const typedef_type_t*) type;
590                         if(typedef_type->resolved_type != NULL) {
591                                 type = typedef_type->resolved_type;
592                                 break;
593                         }
594                         type = typedef_type->declaration->type;
595                         continue;
596                 }
597                 case TYPE_TYPEOF: {
598                         const typeof_type_t *typeof_type = (const typeof_type_t *) type;
599                         if(typeof_type->typeof_type != NULL) {
600                                 type = typeof_type->typeof_type;
601                         } else {
602                                 type = typeof_type->expression->datatype;
603                         }
604                         continue;
605                 }
606                 case TYPE_BUILTIN: {
607                         const builtin_type_t *builtin_type = (const builtin_type_t*) type;
608                         type = builtin_type->real_type;
609                         continue;
610                 }
611                 default:
612                         break;
613                 }
614                 break;
615         }
616
617         return type;
618 }
619
620
621
622 static type_t *identify_new_type(type_t *type)
623 {
624         type_t *result = typehash_insert(type);
625         if(result != type) {
626                 obstack_free(type_obst, type);
627         }
628         return result;
629 }
630
631 type_t *make_atomic_type(atomic_type_type_t type, type_qualifiers_t qualifiers)
632 {
633         atomic_type_t *atomic_type
634                 = obstack_alloc(type_obst, sizeof(atomic_type[0]));
635         memset(atomic_type, 0, sizeof(atomic_type[0]));
636         atomic_type->type.type       = TYPE_ATOMIC;
637         atomic_type->type.qualifiers = qualifiers;
638         atomic_type->atype           = type;
639
640         return identify_new_type((type_t*) atomic_type);
641 }
642
643 type_t *make_pointer_type(type_t *points_to, type_qualifiers_t qualifiers)
644 {
645         pointer_type_t *pointer_type
646                 = obstack_alloc(type_obst, sizeof(pointer_type[0]));
647         memset(pointer_type, 0, sizeof(pointer_type[0]));
648         pointer_type->type.type       = TYPE_POINTER;
649         pointer_type->type.qualifiers = qualifiers;
650         pointer_type->points_to       = points_to;
651
652         return identify_new_type((type_t*) pointer_type);
653 }
654
655 static __attribute__((unused))
656 void dbg_type(type_t *type)
657 {
658         FILE *old_out = out;
659         out = stderr;
660         print_type(type);
661         puts("\n");
662         fflush(stderr);
663         out = old_out;
664 }