rename method to function
[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->context_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->context_next;
170         for( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY;
171                entry = entry->context_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->context_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
293 void intern_print_type_post(type_t *type)
294 {
295         switch(type->type) {
296         case TYPE_FUNCTION:
297                 print_function_type_post((const function_type_t*) type, NULL);
298                 return;
299         case TYPE_POINTER:
300                 print_pointer_type_post((const pointer_type_t*) type);
301                 return;
302         case TYPE_ARRAY:
303                 print_array_type_post((const array_type_t*) type);
304                 return;
305         case TYPE_INVALID:
306         case TYPE_ATOMIC:
307         case TYPE_ENUM:
308         case TYPE_COMPOUND_STRUCT:
309         case TYPE_COMPOUND_UNION:
310         case TYPE_BUILTIN:
311         case TYPE_TYPEOF:
312         case TYPE_TYPEDEF:
313                 break;
314         }
315 }
316
317 void print_type(type_t *type)
318 {
319         print_type_ext(type, NULL, NULL);
320 }
321
322 void print_type_ext(type_t *type, const symbol_t *symbol,
323                     const context_t *context)
324 {
325         if(type == NULL) {
326                 fputs("nil type", out);
327                 return;
328         }
329
330         intern_print_type_pre(type);
331         if(symbol != NULL) {
332                 fputc(' ', out);
333                 fputs(symbol->string, out);
334         }
335         if(type->type == TYPE_FUNCTION) {
336                 print_function_type_post((const function_type_t*) type, context);
337         } else {
338                 intern_print_type_post(type);
339         }
340 }
341
342 bool type_valid(const type_t *type)
343 {
344         return type->type != TYPE_INVALID;
345 }
346
347 bool is_type_integer(const type_t *type)
348 {
349         if(type->type == TYPE_ENUM)
350                 return 1;
351
352         if(type->type != TYPE_ATOMIC)
353                 return 0;
354
355         atomic_type_t *atomic_type = (atomic_type_t*) type;
356         switch(atomic_type->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 1;
370         default:
371                 return 0;
372         }
373 }
374
375 bool is_type_floating(const type_t *type)
376 {
377         if(type->type != TYPE_ATOMIC)
378                 return 0;
379
380         atomic_type_t *atomic_type = (atomic_type_t*) type;
381         switch(atomic_type->atype) {
382         case ATOMIC_TYPE_FLOAT:
383         case ATOMIC_TYPE_DOUBLE:
384         case ATOMIC_TYPE_LONG_DOUBLE:
385 #ifdef PROVIDE_COMPLEX
386         case ATOMIC_TYPE_FLOAT_COMPLEX:
387         case ATOMIC_TYPE_DOUBLE_COMPLEX:
388         case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
389 #endif
390 #ifdef PROVIDE_IMAGINARY
391         case ATOMIC_TYPE_FLOAT_IMAGINARY:
392         case ATOMIC_TYPE_DOUBLE_IMAGINARY:
393         case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
394 #endif
395                 return 1;
396         default:
397                 return 0;
398         }
399 }
400
401 bool is_type_arithmetic(const type_t *type)
402 {
403         if(is_type_integer(type) || is_type_floating(type))
404                 return 1;
405
406         return 0;
407 }
408
409 bool is_type_scalar(const type_t *type)
410 {
411         if(type->type == TYPE_POINTER)
412                 return 1;
413
414         return is_type_arithmetic(type);
415 }
416
417 static type_t *identify_new_type(type_t *type)
418 {
419         type_t *result = typehash_insert(type);
420         if(result != type) {
421                 obstack_free(type_obst, type);
422         }
423         return result;
424 }
425
426 type_t *make_atomic_type(atomic_type_type_t type, type_qualifier_t qualifiers)
427 {
428         atomic_type_t *atomic_type
429                 = obstack_alloc(type_obst, sizeof(atomic_type[0]));
430         memset(atomic_type, 0, sizeof(atomic_type[0]));
431         atomic_type->type.type       = TYPE_ATOMIC;
432         atomic_type->type.qualifiers = qualifiers;
433         atomic_type->atype           = type;
434
435         return identify_new_type((type_t*) atomic_type);
436 }
437
438 type_t *make_pointer_type(type_t *points_to, type_qualifier_t qualifiers)
439 {
440         pointer_type_t *pointer_type
441                 = obstack_alloc(type_obst, sizeof(pointer_type[0]));
442         memset(pointer_type, 0, sizeof(pointer_type[0]));
443         pointer_type->type.type       = TYPE_POINTER;
444         pointer_type->type.qualifiers = qualifiers;
445         pointer_type->points_to       = points_to;
446
447         return identify_new_type((type_t*) pointer_type);
448 }
449
450 static __attribute__((unused))
451 void dbg_type(type_t *type)
452 {
453         FILE *old_out = out;
454         out = stderr;
455         print_type(type);
456         puts("\n");
457         fflush(stderr);
458         out = old_out;
459 }