c6c0801e5a1c42cd3db29a98033bb814bac960e5
[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 type_t *type)
52 {
53         print_type_qualifiers(type->qualifiers);
54
55         const char *s;
56         switch(type->v.atomic_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 type_t *type)
80 {
81         print_type_qualifiers(type->qualifiers);
82
83         intern_print_type_pre(type->v.function_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 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->v.function_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->v.function_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->v.function_type.variadic) {
122                 if(first) {
123                         first = 0;
124                 } else {
125                         fputs(", ", out);
126                 }
127                 fputs("...", out);
128         }
129         if(first && !type->v.function_type.unspecified_parameters) {
130                 fputs("void", out);
131         }
132         fputc(')', out);
133 }
134
135 static void print_pointer_type_pre(const type_t *type)
136 {
137         intern_print_type_pre(type->v.pointer_type.points_to);
138         fputs("*", out);
139         print_type_qualifiers(type->qualifiers);
140 }
141
142 static void print_pointer_type_post(const type_t *type)
143 {
144         intern_print_type_post(type->v.pointer_type.points_to);
145 }
146
147 static void print_array_type_pre(const type_t *type)
148 {
149         intern_print_type_pre(type->v.array_type.element_type);
150 }
151
152 static void print_array_type_post(const type_t *type)
153 {
154         fputc('[', out);
155         if(type->v.array_type.is_static) {
156                 fputs("static ", out);
157         }
158         print_type_qualifiers(type->qualifiers);
159         if(type->v.array_type.size != NULL) {
160                 print_expression(type->v.array_type.size);
161         }
162         fputc(']', out);
163         intern_print_type_post(type->v.array_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 type_t *type)
191 {
192         print_type_qualifiers(type->qualifiers);
193         fputs("enum ", out);
194
195         declaration_t *declaration = type->v.enum_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 type_t *type)
222 {
223         print_type_qualifiers(type->qualifiers);
224
225         if(type->type == TYPE_COMPOUND_STRUCT) {
226                 fputs("struct ", out);
227         } else {
228                 assert(type->type == TYPE_COMPOUND_UNION);
229                 fputs("union ", out);
230         }
231
232         declaration_t *declaration = type->v.compound_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(type_t *type)
242 {
243         fputs(type->v.typedef_type.declaration->symbol->string, out);
244 }
245
246 static void print_typeof_type_pre(type_t *type)
247 {
248         fputs("typeof(", out);
249         if(type->v.typeof_type.expression != NULL) {
250                 assert(type->v.typeof_type.typeof_type == NULL);
251                 print_expression(type->v.typeof_type.expression);
252         } else {
253                 print_type(type->v.typeof_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(type);
266                 return;
267         case TYPE_ATOMIC:
268                 print_atomic_type(type);
269                 return;
270         case TYPE_COMPOUND_STRUCT:
271         case TYPE_COMPOUND_UNION:
272                 print_compound_type(type);
273                 return;
274         case TYPE_BUILTIN:
275                 fputs(type->v.builtin_type.symbol->string, out);
276                 return;
277         case TYPE_FUNCTION:
278                 print_function_type_pre(type);
279                 return;
280         case TYPE_POINTER:
281                 print_pointer_type_pre(type);
282                 return;
283         case TYPE_ARRAY:
284                 print_array_type_pre(type);
285                 return;
286         case TYPE_TYPEDEF:
287                 print_typedef_type_pre(type);
288                 return;
289         case TYPE_TYPEOF:
290                 print_typeof_type_pre(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(type, NULL);
301                 return;
302         case TYPE_POINTER:
303                 print_pointer_type_post(type);
304                 return;
305         case TYPE_ARRAY:
306                 print_array_type_post(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(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         if(type->type == TYPE_ENUM)
353                 return true;
354
355         if(type->type != TYPE_ATOMIC)
356                 return false;
357
358         switch(type->v.atomic_type.atype) {
359         case ATOMIC_TYPE_BOOL:
360         case ATOMIC_TYPE_CHAR:
361         case ATOMIC_TYPE_SCHAR:
362         case ATOMIC_TYPE_UCHAR:
363         case ATOMIC_TYPE_SHORT:
364         case ATOMIC_TYPE_USHORT:
365         case ATOMIC_TYPE_INT:
366         case ATOMIC_TYPE_UINT:
367         case ATOMIC_TYPE_LONG:
368         case ATOMIC_TYPE_ULONG:
369         case ATOMIC_TYPE_LONGLONG:
370         case ATOMIC_TYPE_ULONGLONG:
371                 return true;
372         default:
373                 return false;
374         }
375 }
376
377 bool is_type_floating(const type_t *type)
378 {
379         if(type->type != TYPE_ATOMIC)
380                 return false;
381
382         switch(type->v.atomic_type.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         /* 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->v.atomic_type.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         if(is_type_integer(type) || is_type_floating(type))
449                 return 1;
450
451         return 0;
452 }
453
454 bool is_type_scalar(const type_t *type)
455 {
456         if(type->type == TYPE_POINTER)
457                 return 1;
458
459         return is_type_arithmetic(type);
460 }
461
462 bool is_type_incomplete(const type_t *type)
463 {
464         switch(type->type) {
465         case TYPE_COMPOUND_STRUCT:
466         case TYPE_COMPOUND_UNION: {
467                 declaration_t *declaration = type->v.compound_type.declaration;
468                 return !declaration->init.is_defined;
469         }
470         case TYPE_FUNCTION:
471                 return true;
472
473         case TYPE_ARRAY:
474                 return type->v.array_type.size == NULL;
475
476         case TYPE_ATOMIC:
477         case TYPE_POINTER:
478         case TYPE_ENUM:
479                 return false;
480
481         case TYPE_TYPEDEF:
482         case TYPE_TYPEOF:
483         case TYPE_BUILTIN:
484                 panic("is_type_incomplete called without typerefs skipped");
485         case TYPE_INVALID:
486                 break;
487         }
488
489         panic("invalid type found");
490 }
491
492 bool types_compatible(const type_t *type1, const type_t *type2)
493 {
494         /* TODO: really incomplete */
495         if(type1 == type2)
496                 return true;
497
498         if(type1->type == TYPE_ATOMIC && type2->type == TYPE_ATOMIC)
499                 return type1->v.atomic_type.atype == type2->v.atomic_type.atype;
500
501         return false;
502 }
503
504 bool pointers_compatible(const type_t *type1, const type_t *type2)
505 {
506         assert(type1->type == TYPE_POINTER);
507         assert(type2->type == TYPE_POINTER);
508 #if 0
509         return types_compatible(type1->v.pointer_type.points_to,
510                                 type2->v.pointer_type.points_to);
511 #endif
512         return true;
513 }
514
515 /**
516  * duplicates a type
517  * note that this does not produce a deep copy!
518  */
519 static type_t *duplicate_type(type_t *type)
520 {
521         type_t *copy = obstack_alloc(type_obst, sizeof(*copy));
522         memcpy(copy, type, sizeof(*copy));
523
524         (void) duplicate_type;
525
526         return type;
527 }
528
529 type_t *skip_typeref(type_t *type)
530 {
531         unsigned qualifiers = type->qualifiers;
532
533         while(1) {
534                 switch(type->type) {
535                 case TYPE_TYPEDEF:
536                         qualifiers |= type->qualifiers;
537                         if(type->v.typedef_type.resolved_type != NULL) {
538                                 type = type->v.typedef_type.resolved_type;
539                                 break;
540                         }
541                         type = type->v.typedef_type.declaration->type;
542                         continue;
543                 case TYPE_TYPEOF:
544                         if(type->v.typeof_type.typeof_type != NULL) {
545                                 type = type->v.typeof_type.typeof_type;
546                         } else {
547                                 type = type->v.typeof_type.expression->datatype;
548                         }
549                         continue;
550                 case TYPE_BUILTIN:
551                         type = type->v.builtin_type.real_type;
552                         continue;
553                 default:
554                         break;
555                 }
556                 break;
557         }
558
559         return type;
560 }
561
562
563
564 static type_t *identify_new_type(type_t *type)
565 {
566         type_t *result = typehash_insert(type);
567         if(result != type) {
568                 obstack_free(type_obst, type);
569         }
570         return result;
571 }
572
573 type_t *make_atomic_type(atomic_type_type_t type, type_qualifiers_t qualifiers)
574 {
575         type_t *atomic_type = obstack_alloc(type_obst, sizeof(atomic_type[0]));
576         memset(atomic_type, 0, sizeof(atomic_type[0]));
577         atomic_type->type                = TYPE_ATOMIC;
578         atomic_type->qualifiers          = qualifiers;
579         atomic_type->v.atomic_type.atype = type;
580
581         return identify_new_type(atomic_type);
582 }
583
584 type_t *make_pointer_type(type_t *points_to, type_qualifiers_t qualifiers)
585 {
586         type_t *pointer_type = obstack_alloc(type_obst, sizeof(pointer_type[0]));
587         memset(pointer_type, 0, sizeof(pointer_type[0]));
588         pointer_type->type                     = TYPE_POINTER;
589         pointer_type->qualifiers               = qualifiers;
590         pointer_type->v.pointer_type.points_to = points_to;
591
592         return identify_new_type(pointer_type);
593 }
594
595 static __attribute__((unused))
596 void dbg_type(type_t *type)
597 {
598         FILE *old_out = out;
599         out = stderr;
600         print_type(type);
601         puts("\n");
602         fflush(stderr);
603         out = old_out;
604 }