more work on parser, stdio.h is fully parsed now
[cparser] / type.c
1 #include <config.h>
2
3 #include "type_t.h"
4 #include "adt/error.h"
5
6 static struct obstack  _type_obst;
7 struct obstack        *type_obst = &_type_obst;
8
9 void init_types()
10 {
11         obstack_init(type_obst);
12 }
13
14 void exit_types()
15 {
16         obstack_free(type_obst, NULL);
17 }
18
19 static
20 void print_type_qualifiers(FILE *out, const type_t *type)
21 {
22         unsigned qualifiers = type->qualifiers;
23         if(qualifiers & TYPE_QUALIFIER_CONST) {
24                 fputs("const ", out);
25         }
26         if(qualifiers & TYPE_QUALIFIER_VOLATILE) {
27                 fputs("volatile ", out);
28         }
29         if(qualifiers & TYPE_QUALIFIER_RESTRICT) {
30                 fputs("restrict ", out);
31         }
32         if(qualifiers & TYPE_QUALIFIER_INLINE) {
33                 fputs("inline ", out);
34         }
35 }
36
37 static
38 void print_atomic_type(FILE *out, const atomic_type_t *type)
39 {
40         print_type_qualifiers(out, & type->type);
41
42         switch(type->atype) {
43         case ATOMIC_TYPE_INVALID:     fputs("INVALIDATOMIC", out); return;
44         case ATOMIC_TYPE_VOID:        fputs("void", out); return;
45         case ATOMIC_TYPE_BOOL:        fputs("bool", out); return;
46         case ATOMIC_TYPE_CHAR:        fputs("char", out); return;
47         case ATOMIC_TYPE_SCHAR:       fputs("signed char", out); return;
48         case ATOMIC_TYPE_UCHAR:       fputs("unsigned char", out); return;
49         case ATOMIC_TYPE_INT:         fputs("int", out); return;
50         case ATOMIC_TYPE_UINT:        fputs("unsigned int", out); return;
51         case ATOMIC_TYPE_SHORT:       fputs("short", out); return;
52         case ATOMIC_TYPE_USHORT:      fputs("unsigned short", out); return;
53         case ATOMIC_TYPE_LONG:        fputs("long", out); return;
54         case ATOMIC_TYPE_ULONG:       fputs("unsigned long", out); return;
55         case ATOMIC_TYPE_LONGLONG:    fputs("long long", out); return;
56         case ATOMIC_TYPE_ULONGLONG:   fputs("unsigned long long", out); return;
57         case ATOMIC_TYPE_LONG_DOUBLE: fputs("long double", out); return;
58         case ATOMIC_TYPE_FLOAT:       fputs("float", out); return;
59         case ATOMIC_TYPE_DOUBLE:      fputs("double", out); return;
60         }
61         fputs("UNKNOWNATOMIC", out);
62 }
63
64 static
65 void print_method_type(FILE *out, const method_type_t *type)
66 {
67         print_type_qualifiers(out, & type->type);
68
69         fputs("<", out);
70         print_type(out, type->result_type);
71         fputs(" ", out);
72
73         if(type->abi_style != NULL) {
74                 fprintf(out, "\"%s\" ", type->abi_style);
75         }
76         fputs("method(", out);
77         method_parameter_type_t *param_type = type->parameter_types;
78         int first = 1;
79         while(param_type != NULL) {
80                 if(first) {
81                         first = 0;
82                 } else {
83                         fputs(", ", out);
84                 }
85                 print_type(out, param_type->type);
86                 param_type = param_type->next;
87         }
88         fputs(")>", out);
89 }
90
91 static
92 void print_pointer_type(FILE *out, const pointer_type_t *type)
93 {
94         print_type(out, type->points_to);
95         fputs("*", out);
96         print_type_qualifiers(out, &type->type);
97 }
98
99 void print_type(FILE *out, const type_t *type)
100 {
101         if(type == NULL) {
102                 fputs("nil type", out);
103                 return;
104         }
105
106         switch(type->type) {
107         case TYPE_INVALID:
108                 fputs("invalid", out);
109                 return;
110         case TYPE_ENUM:
111                 print_type_qualifiers(out, type);
112                 fputs("enum (TODO)", out);
113                 return;
114         case TYPE_ATOMIC:
115                 print_atomic_type(out, (const atomic_type_t*) type);
116                 return;
117         case TYPE_COMPOUND_STRUCT:
118         case TYPE_COMPOUND_UNION:
119                 print_type_qualifiers(out, type);
120                 if(((const compound_type_t*) type)->symbol != NULL) {
121                         fprintf(out, "%s", ((const compound_type_t*) type)->symbol->string);
122                 }
123                 return;
124         case TYPE_BUILTIN:
125                 fputs(((builtin_type_t*) type)->symbol->string, out);
126                 return;
127         case TYPE_METHOD:
128                 print_method_type(out, (const method_type_t*) type);
129                 return;
130         case TYPE_POINTER:
131                 print_pointer_type(out, (const pointer_type_t*) type);
132                 return;
133         }
134         fputs("unknown", out);
135 }
136
137 int type_valid(const type_t *type)
138 {
139         return type->type != TYPE_INVALID;
140 }
141
142 int is_type_int(const type_t *type)
143 {
144         if(type->type != TYPE_ATOMIC)
145                 return 0;
146
147         atomic_type_t *atomic_type = (atomic_type_t*) type;
148         switch(atomic_type->atype) {
149         case ATOMIC_TYPE_CHAR:
150         case ATOMIC_TYPE_SCHAR:
151         case ATOMIC_TYPE_UCHAR:
152         case ATOMIC_TYPE_SHORT:
153         case ATOMIC_TYPE_USHORT:
154         case ATOMIC_TYPE_INT:
155         case ATOMIC_TYPE_UINT:
156         case ATOMIC_TYPE_LONG:
157         case ATOMIC_TYPE_ULONG:
158         case ATOMIC_TYPE_LONGLONG:
159         case ATOMIC_TYPE_ULONGLONG:
160                 return 1;
161         default:
162                 return 0;
163         }
164 }
165
166 static __attribute__((unused))
167 void dbg_type(const type_t *type)
168 {
169         print_type(stdout,type);
170         puts("\n");
171         fflush(stdout);
172 }