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