introduce some builtin 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
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_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 bool type_valid(const type_t *type)
340 {
341         return type->type != TYPE_INVALID;
342 }
343
344 bool is_type_integer(const type_t *type)
345 {
346         assert(!is_typeref(type));
347
348         if(type->type == TYPE_ENUM)
349                 return true;
350
351         if(type->type != TYPE_ATOMIC)
352                 return false;
353
354         switch(type->atomic.atype) {
355         case ATOMIC_TYPE_BOOL:
356         case ATOMIC_TYPE_CHAR:
357         case ATOMIC_TYPE_SCHAR:
358         case ATOMIC_TYPE_UCHAR:
359         case ATOMIC_TYPE_SHORT:
360         case ATOMIC_TYPE_USHORT:
361         case ATOMIC_TYPE_INT:
362         case ATOMIC_TYPE_UINT:
363         case ATOMIC_TYPE_LONG:
364         case ATOMIC_TYPE_ULONG:
365         case ATOMIC_TYPE_LONGLONG:
366         case ATOMIC_TYPE_ULONGLONG:
367                 return true;
368         default:
369                 return false;
370         }
371 }
372
373 bool is_type_floating(const type_t *type)
374 {
375         assert(!is_typeref(type));
376
377         if(type->type != TYPE_ATOMIC)
378                 return false;
379
380         switch(type->atomic.atype) {
381         case ATOMIC_TYPE_FLOAT:
382         case ATOMIC_TYPE_DOUBLE:
383         case ATOMIC_TYPE_LONG_DOUBLE:
384 #ifdef PROVIDE_COMPLEX
385         case ATOMIC_TYPE_FLOAT_COMPLEX:
386         case ATOMIC_TYPE_DOUBLE_COMPLEX:
387         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
388         case ATOMIC_TYPE_FLOAT_IMAGINARY:
389         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
390         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
391 #endif
392                 return true;
393         default:
394                 return false;
395         }
396 }
397
398 bool is_type_signed(const type_t *type)
399 {
400         assert(!is_typeref(type));
401
402         /* enum types are int for now */
403         if(type->type == TYPE_ENUM)
404                 return true;
405
406         if(type->type != TYPE_ATOMIC)
407                 return false;
408
409         switch(type->atomic.atype) {
410         case ATOMIC_TYPE_CHAR:
411         case ATOMIC_TYPE_SCHAR:
412         case ATOMIC_TYPE_SHORT:
413         case ATOMIC_TYPE_INT:
414         case ATOMIC_TYPE_LONG:
415         case ATOMIC_TYPE_LONGLONG:
416         case ATOMIC_TYPE_FLOAT:
417         case ATOMIC_TYPE_DOUBLE:
418         case ATOMIC_TYPE_LONG_DOUBLE:
419 #ifdef PROVIDE_COMPLEX
420         case ATOMIC_TYPE_FLOAT_COMPLEX:
421         case ATOMIC_TYPE_DOUBLE_COMPLEX:
422         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
423         case ATOMIC_TYPE_FLOAT_IMAGINARY:
424         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
425         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
426 #endif
427                 return true;
428
429         case ATOMIC_TYPE_BOOL:
430         case ATOMIC_TYPE_UCHAR:
431         case ATOMIC_TYPE_USHORT:
432         case ATOMIC_TYPE_UINT:
433         case ATOMIC_TYPE_ULONG:
434         case ATOMIC_TYPE_ULONGLONG:
435                 return false;
436
437         case ATOMIC_TYPE_INVALID:
438         case ATOMIC_TYPE_VOID:
439                 return false;
440         }
441
442         panic("invalid atomic type found");
443         return false;
444 }
445
446 bool is_type_arithmetic(const type_t *type)
447 {
448         assert(!is_typeref(type));
449
450         if(is_type_integer(type) || is_type_floating(type))
451                 return 1;
452
453         return 0;
454 }
455
456 bool is_type_scalar(const type_t *type)
457 {
458         assert(!is_typeref(type));
459
460         if(type->type == TYPE_POINTER)
461                 return 1;
462
463         return is_type_arithmetic(type);
464 }
465
466 bool is_type_incomplete(const type_t *type)
467 {
468         assert(!is_typeref(type));
469
470         switch(type->type) {
471         case TYPE_COMPOUND_STRUCT:
472         case TYPE_COMPOUND_UNION: {
473                 const compound_type_t *compound_type = &type->compound;
474                 declaration_t         *declaration   = compound_type->declaration;
475                 return !declaration->init.is_defined;
476         }
477         case TYPE_FUNCTION:
478                 return true;
479
480         case TYPE_ARRAY:
481                 return type->array.size == NULL;
482
483         case TYPE_ATOMIC:
484         case TYPE_POINTER:
485         case TYPE_ENUM:
486                 return false;
487
488         case TYPE_TYPEDEF:
489         case TYPE_TYPEOF:
490         case TYPE_BUILTIN:
491                 panic("is_type_incomplete called without typerefs skipped");
492         case TYPE_INVALID:
493                 break;
494         }
495
496         panic("invalid type found");
497 }
498
499 bool types_compatible(const type_t *type1, const type_t *type2)
500 {
501         assert(!is_typeref(type1));
502         assert(!is_typeref(type2));
503
504         /* TODO: really incomplete */
505         if(type1 == type2)
506                 return true;
507
508         if(type1->type == TYPE_ATOMIC && type2->type == TYPE_ATOMIC) {
509                 return type1->atomic.atype == type2->atomic.atype;
510         }
511
512         return false;
513 }
514
515 bool pointers_compatible(const type_t *type1, const type_t *type2)
516 {
517         assert(!is_typeref(type1));
518         assert(!is_typeref(type2));
519
520         assert(type1->type == TYPE_POINTER);
521         assert(type2->type == TYPE_POINTER);
522         /* TODO */
523         return true;
524 }
525
526 static size_t get_type_size(type_t *type)
527 {
528         switch(type->type) {
529         case TYPE_ATOMIC:          return sizeof(atomic_type_t);
530         case TYPE_COMPOUND_STRUCT:
531         case TYPE_COMPOUND_UNION:  return sizeof(compound_type_t);
532         case TYPE_ENUM:            return sizeof(enum_type_t);
533         case TYPE_FUNCTION:        return sizeof(function_type_t);
534         case TYPE_POINTER:         return sizeof(pointer_type_t);
535         case TYPE_ARRAY:           return sizeof(array_type_t);
536         case TYPE_BUILTIN:         return sizeof(builtin_type_t);
537         case TYPE_TYPEDEF:         return sizeof(typedef_type_t);
538         case TYPE_TYPEOF:          return sizeof(typeof_type_t);
539         case TYPE_INVALID:         panic("invalid type found");
540         }
541         panic("unknown type found");
542 }
543
544 /**
545  * duplicates a type
546  * note that this does not produce a deep copy!
547  */
548 type_t *duplicate_type(type_t *type)
549 {
550         size_t size = get_type_size(type);
551
552         type_t *copy = obstack_alloc(type_obst, size);
553         memcpy(copy, type, size);
554
555         return copy;
556 }
557
558 type_t *skip_typeref(type_t *type)
559 {
560         unsigned qualifiers = type->base.qualifiers;
561
562         while(1) {
563                 switch(type->type) {
564                 case TYPE_TYPEDEF: {
565                         qualifiers |= type->base.qualifiers;
566                         const typedef_type_t *typedef_type = &type->typedeft;
567                         if(typedef_type->resolved_type != NULL) {
568                                 type = typedef_type->resolved_type;
569                                 break;
570                         }
571                         type = typedef_type->declaration->type;
572                         continue;
573                 }
574                 case TYPE_TYPEOF: {
575                         const typeof_type_t *typeof_type = &type->typeoft;
576                         if(typeof_type->typeof_type != NULL) {
577                                 type = typeof_type->typeof_type;
578                         } else {
579                                 type = typeof_type->expression->base.datatype;
580                         }
581                         continue;
582                 }
583                 case TYPE_BUILTIN: {
584                         const builtin_type_t *builtin_type = &type->builtin;
585                         type = builtin_type->real_type;
586                         continue;
587                 }
588                 default:
589                         break;
590                 }
591                 break;
592         }
593
594         return type;
595 }
596
597
598
599 static type_t *identify_new_type(type_t *type)
600 {
601         type_t *result = typehash_insert(type);
602         if(result != type) {
603                 obstack_free(type_obst, type);
604         }
605         return result;
606 }
607
608 type_t *make_atomic_type(atomic_type_type_t atype, type_qualifiers_t qualifiers)
609 {
610         type_t *type = obstack_alloc(type_obst, sizeof(atomic_type_t));
611         memset(type, 0, sizeof(atomic_type_t));
612
613         type->type            = TYPE_ATOMIC;
614         type->base.qualifiers = qualifiers;
615         type->atomic.atype    = atype;
616
617         return identify_new_type(type);
618 }
619
620 type_t *make_pointer_type(type_t *points_to, type_qualifiers_t qualifiers)
621 {
622         type_t *type = obstack_alloc(type_obst, sizeof(pointer_type_t));
623         memset(type, 0, sizeof(pointer_type_t));
624
625         type->type              = TYPE_POINTER;
626         type->base.qualifiers   = qualifiers;
627         type->pointer.points_to = points_to;
628
629         return identify_new_type(type);
630 }
631
632 static __attribute__((unused))
633 void dbg_type(type_t *type)
634 {
635         FILE *old_out = out;
636         out = stderr;
637         print_type(type);
638         puts("\n");
639         fflush(stderr);
640         out = old_out;
641 }