implement atomic entity initialisation
[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 static
44 void print_type_qualifiers(unsigned qualifiers)
45 {
46         if(qualifiers & TYPE_QUALIFIER_CONST)    fputs("const ",    out);
47         if(qualifiers & TYPE_QUALIFIER_VOLATILE) fputs("volatile ", out);
48         if(qualifiers & TYPE_QUALIFIER_RESTRICT) fputs("restrict ", out);
49         if(qualifiers & TYPE_QUALIFIER_INLINE)   fputs("inline ",   out);
50 }
51
52 static
53 void print_atomic_type(const atomic_type_t *type)
54 {
55         print_type_qualifiers(type->type.qualifiers);
56
57         const char *s;
58         switch(type->atype) {
59         case ATOMIC_TYPE_INVALID:     s = "INVALIDATOMIC";      break;
60         case ATOMIC_TYPE_VOID:        s = "void";               break;
61         case ATOMIC_TYPE_BOOL:        s = "_Bool";              break;
62         case ATOMIC_TYPE_CHAR:        s = "char";               break;
63         case ATOMIC_TYPE_SCHAR:       s = "signed char";        break;
64         case ATOMIC_TYPE_UCHAR:       s = "unsigned char";      break;
65         case ATOMIC_TYPE_INT:         s = "int";                break;
66         case ATOMIC_TYPE_UINT:        s = "unsigned int";       break;
67         case ATOMIC_TYPE_SHORT:       s = "short";              break;
68         case ATOMIC_TYPE_USHORT:      s = "unsigned short";     break;
69         case ATOMIC_TYPE_LONG:        s = "long";               break;
70         case ATOMIC_TYPE_ULONG:       s = "unsigned long";      break;
71         case ATOMIC_TYPE_LONGLONG:    s = "long long";          break;
72         case ATOMIC_TYPE_ULONGLONG:   s = "unsigned long long"; break;
73         case ATOMIC_TYPE_LONG_DOUBLE: s = "long double";        break;
74         case ATOMIC_TYPE_FLOAT:       s = "float";              break;
75         case ATOMIC_TYPE_DOUBLE:      s = "double";             break;
76         default:                      s = "UNKNOWNATOMIC";      break;
77         }
78         fputs(s, out);
79 }
80
81 static void print_function_type_pre(const function_type_t *type)
82 {
83         print_type_qualifiers(type->type.qualifiers);
84
85         intern_print_type_pre(type->result_type);
86
87         /* TODO: don't emit braces if we're the toplevel type... */
88         fputc('(', out);
89 }
90
91 static void print_function_type_post(const function_type_t *type,
92                                      const context_t *context)
93 {
94         /* TODO: don't emit braces if we're the toplevel type... */
95         intern_print_type_post(type->result_type);
96         fputc(')', out);
97
98         fputc('(', out);
99
100         int                 first     = 1;
101         if(context == NULL) {
102                 function_parameter_t *parameter = type->parameters;
103                 for( ; parameter != NULL; parameter = parameter->next) {
104                         if(first) {
105                                 first = 0;
106                         } else {
107                                 fputs(", ", out);
108                         }
109                         print_type(parameter->type);
110                 }
111         } else {
112                 declaration_t *parameter = context->declarations;
113                 for( ; parameter != NULL; parameter = parameter->next) {
114                         if(first) {
115                                 first = 0;
116                         } else {
117                                 fputs(", ", out);
118                         }
119                         print_type_ext(parameter->type, parameter->symbol,
120                                        &parameter->context);
121                 }
122         }
123         if(type->variadic) {
124                 if(first) {
125                         first = 0;
126                 } else {
127                         fputs(", ", out);
128                 }
129                 fputs("...", out);
130         }
131         if(first && !type->unspecified_parameters) {
132                 fputs("void", out);
133         }
134         fputc(')', out);
135 }
136
137 static
138 void print_pointer_type_pre(const pointer_type_t *type)
139 {
140         intern_print_type_pre(type->points_to);
141         fputs("*", out);
142         print_type_qualifiers(type->type.qualifiers);
143 }
144
145 static void print_pointer_type_post(const pointer_type_t *type)
146 {
147         intern_print_type_post(type->points_to);
148 }
149
150 static void print_array_type_post(const array_type_t *type)
151 {
152         fputc('[', out);
153         if(type->is_static) {
154                 fputs("static ", out);
155         }
156         print_type_qualifiers(type->type.qualifiers);
157         if(type->size != NULL) {
158                 print_expression(type->size);
159         }
160         fputc(']', out);
161 }
162
163 void print_enum_definition(const declaration_t *declaration)
164 {
165         fputs("{\n", out);
166
167         change_indent(1);
168
169         declaration_t *entry = declaration->next;
170         for( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
171                entry = entry->next) {
172
173                 print_indent();
174                 fprintf(out, "%s", entry->symbol->string);
175                 if(entry->init.initializer != NULL) {
176                         fprintf(out, " = ");
177                         print_initializer(entry->init.initializer);
178                 }
179                 fprintf(out, ",\n");
180         }
181
182         change_indent(-1);
183         print_indent();
184         fputs("}", out);
185 }
186
187 static void print_type_enum(const enum_type_t *type)
188 {
189         print_type_qualifiers(type->type.qualifiers);
190         fputs("enum ", out);
191
192         declaration_t *declaration = type->declaration;
193         symbol_t      *symbol      = declaration->symbol;
194         if(symbol != NULL) {
195                 fputs(symbol->string, out);
196         } else {
197                 print_enum_definition(declaration);
198         }
199 }
200
201 void print_compound_definition(const declaration_t *declaration)
202 {
203         fputs("{\n", out);
204         change_indent(1);
205
206         declaration_t *iter = declaration->context.declarations;
207         for( ; iter != NULL; iter = iter->next) {
208                 print_indent();
209                 print_declaration(iter);
210                 fputc('\n', out);
211         }
212
213         change_indent(-1);
214         print_indent();
215         fputs("}", out);
216 }
217
218 static void print_compound_type(const compound_type_t *type)
219 {
220         print_type_qualifiers(type->type.qualifiers);
221
222         if(type->type.type == TYPE_COMPOUND_STRUCT) {
223                 fputs("struct ", out);
224         } else {
225                 assert(type->type.type == TYPE_COMPOUND_UNION);
226                 fputs("union ", out);
227         }
228
229         declaration_t *declaration = type->declaration;
230         symbol_t      *symbol      = declaration->symbol;
231         if(symbol != NULL) {
232                 fputs(symbol->string, out);
233         } else {
234                 print_compound_definition(declaration);
235         }
236 }
237
238 static void print_typedef_type_pre(typedef_type_t *type)
239 {
240         fputs(type->declaration->symbol->string, out);
241 }
242
243 static void print_typeof_type_pre(typeof_type_t *type)
244 {
245         fputs("typeof(", out);
246         if(type->expression != NULL) {
247                 assert(type->typeof_type == NULL);
248                 print_expression(type->expression);
249         } else {
250                 print_type(type->typeof_type);
251         }
252         fputc(')', out);
253 }
254
255 static void intern_print_type_pre(type_t *type)
256 {
257         switch(type->type) {
258         case TYPE_INVALID:
259                 fputs("invalid", out);
260                 return;
261         case TYPE_ENUM:
262                 print_type_enum((enum_type_t*) type);
263                 return;
264         case TYPE_ATOMIC:
265                 print_atomic_type((atomic_type_t*) type);
266                 return;
267         case TYPE_COMPOUND_STRUCT:
268         case TYPE_COMPOUND_UNION:
269                 print_compound_type((compound_type_t*) type);
270                 return;
271         case TYPE_BUILTIN:
272                 fputs(((builtin_type_t*) type)->symbol->string, out);
273                 return;
274         case TYPE_FUNCTION:
275                 print_function_type_pre((function_type_t*) type);
276                 return;
277         case TYPE_POINTER:
278                 print_pointer_type_pre((pointer_type_t*) type);
279                 return;
280         case TYPE_ARRAY:
281                 return;
282         case TYPE_TYPEDEF:
283                 print_typedef_type_pre((typedef_type_t*) type);
284                 return;
285         case TYPE_TYPEOF:
286                 print_typeof_type_pre((typeof_type_t*) type);
287                 return;
288         }
289         fputs("unknown", out);
290 }
291
292 static void intern_print_type_post(type_t *type)
293 {
294         switch(type->type) {
295         case TYPE_FUNCTION:
296                 print_function_type_post((const function_type_t*) type, NULL);
297                 return;
298         case TYPE_POINTER:
299                 print_pointer_type_post((const pointer_type_t*) type);
300                 return;
301         case TYPE_ARRAY:
302                 print_array_type_post((const array_type_t*) type);
303                 return;
304         case TYPE_INVALID:
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         if(type->type == TYPE_ENUM)
349                 return true;
350
351         if(type->type != TYPE_ATOMIC)
352                 return false;
353
354         atomic_type_t *atomic_type = (atomic_type_t*) type;
355         switch(atomic_type->atype) {
356         case ATOMIC_TYPE_BOOL:
357         case ATOMIC_TYPE_CHAR:
358         case ATOMIC_TYPE_SCHAR:
359         case ATOMIC_TYPE_UCHAR:
360         case ATOMIC_TYPE_SHORT:
361         case ATOMIC_TYPE_USHORT:
362         case ATOMIC_TYPE_INT:
363         case ATOMIC_TYPE_UINT:
364         case ATOMIC_TYPE_LONG:
365         case ATOMIC_TYPE_ULONG:
366         case ATOMIC_TYPE_LONGLONG:
367         case ATOMIC_TYPE_ULONGLONG:
368                 return true;
369         default:
370                 return false;
371         }
372 }
373
374 bool is_type_floating(const type_t *type)
375 {
376         if(type->type != TYPE_ATOMIC)
377                 return false;
378
379         atomic_type_t *atomic_type = (atomic_type_t*) type;
380         switch(atomic_type->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 #endif
389 #ifdef PROVIDE_IMAGINARY
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         atomic_type_t *atomic_type = (atomic_type_t*) type;
410         switch(atomic_type->atype) {
411         case ATOMIC_TYPE_CHAR:
412         case ATOMIC_TYPE_SCHAR:
413         case ATOMIC_TYPE_SHORT:
414         case ATOMIC_TYPE_INT:
415         case ATOMIC_TYPE_LONG:
416         case ATOMIC_TYPE_LONGLONG:
417         case ATOMIC_TYPE_FLOAT:
418         case ATOMIC_TYPE_DOUBLE:
419         case ATOMIC_TYPE_LONG_DOUBLE:
420 #ifdef PROVIDE_COMPLEX
421         case ATOMIC_TYPE_FLOAT_COMPLEX:
422         case ATOMIC_TYPE_DOUBLE_COMPLEX:
423         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
424 #endif
425 #ifdef PROVIDE_IMAGINARY
426         case ATOMIC_TYPE_FLOAT_IMAGINARY:
427         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
428         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
429 #endif
430                 return true;
431
432         case ATOMIC_TYPE_BOOL:
433         case ATOMIC_TYPE_UCHAR:
434         case ATOMIC_TYPE_USHORT:
435         case ATOMIC_TYPE_UINT:
436         case ATOMIC_TYPE_ULONG:
437         case ATOMIC_TYPE_ULONGLONG:
438                 return false;
439
440         case ATOMIC_TYPE_INVALID:
441         case ATOMIC_TYPE_VOID:
442                 return false;
443         }
444
445         panic("invalid atomic type found");
446         return false;
447 }
448
449 bool is_type_arithmetic(const type_t *type)
450 {
451         if(is_type_integer(type) || is_type_floating(type))
452                 return 1;
453
454         return 0;
455 }
456
457 bool is_type_scalar(const type_t *type)
458 {
459         if(type->type == TYPE_POINTER)
460                 return 1;
461
462         return is_type_arithmetic(type);
463 }
464
465 bool pointers_compatible(const type_t *type1, const type_t *type2)
466 {
467         assert(type1->type == TYPE_POINTER);
468         assert(type2->type == TYPE_POINTER);
469         return true;
470 }
471
472 type_t *skip_typeref(type_t *type)
473 {
474         while(1) {
475                 switch(type->type) {
476                 case TYPE_TYPEDEF: {
477                         const typedef_type_t *typedef_type = (const typedef_type_t*) type;
478                         type = typedef_type->declaration->type;
479                         continue;
480                 }
481                 case TYPE_TYPEOF: {
482                         const typeof_type_t *typeof_type = (const typeof_type_t *) type;
483                         if(typeof_type->typeof_type != NULL) {
484                                 type = typeof_type->typeof_type;
485                         } else {
486                                 type = typeof_type->expression->datatype;
487                         }
488                         continue;
489                 }
490                 case TYPE_BUILTIN: {
491                         const builtin_type_t *builtin_type = (const builtin_type_t*) type;
492                         type = builtin_type->real_type;
493                         continue;
494                 }
495                 default:
496                         break;
497                 }
498                 break;
499         }
500
501         return type;
502 }
503
504
505
506 static type_t *identify_new_type(type_t *type)
507 {
508         type_t *result = typehash_insert(type);
509         if(result != type) {
510                 obstack_free(type_obst, type);
511         }
512         return result;
513 }
514
515 type_t *make_atomic_type(atomic_type_type_t type, type_qualifier_t qualifiers)
516 {
517         atomic_type_t *atomic_type
518                 = obstack_alloc(type_obst, sizeof(atomic_type[0]));
519         memset(atomic_type, 0, sizeof(atomic_type[0]));
520         atomic_type->type.type       = TYPE_ATOMIC;
521         atomic_type->type.qualifiers = qualifiers;
522         atomic_type->atype           = type;
523
524         return identify_new_type((type_t*) atomic_type);
525 }
526
527 type_t *make_pointer_type(type_t *points_to, type_qualifier_t qualifiers)
528 {
529         pointer_type_t *pointer_type
530                 = obstack_alloc(type_obst, sizeof(pointer_type[0]));
531         memset(pointer_type, 0, sizeof(pointer_type[0]));
532         pointer_type->type.type       = TYPE_POINTER;
533         pointer_type->type.qualifiers = qualifiers;
534         pointer_type->points_to       = points_to;
535
536         return identify_new_type((type_t*) pointer_type);
537 }
538
539 static __attribute__((unused))
540 void dbg_type(type_t *type)
541 {
542         FILE *old_out = out;
543         out = stderr;
544         print_type(type);
545         puts("\n");
546         fflush(stderr);
547         out = old_out;
548 }