Commit | Line | Data |
---|---|---|
3cd4b0f8 MW |
1 | #include "cparse.h" |
2 | #include <assert.h> | |
3 | ||
4 | /* combine two declaration_specifires structs that are bits of the same list of | |
5 | * declaration specifiers, checking relevant constraints on the way */ | |
6 | struct declaration_specifiers *merge_declaration_specifiers | |
7 | (struct declaration_specifiers *a, | |
8 | struct declaration_specifiers *b) { | |
9 | unsigned long basic, ci, length, sign, definition; | |
10 | ||
11 | /* constraints comes from C99 6.7.2 */ | |
12 | ||
13 | /* can only have one basic type specifier */ | |
14 | if((basic = a->type_specifiers & TS__BASIC)) { | |
15 | if(b->type_specifiers & TS__BASIC) | |
16 | inputerror(0, "invalid combination of type specifiers"); | |
17 | } else | |
18 | basic = b->type_specifiers & TS__BASIC; | |
19 | ||
20 | /* can only have one _Complex or _Imaginary */ | |
21 | if((ci = a->type_specifiers & TS__CI)) { | |
22 | if(b->type_specifiers & TS__CI) | |
23 | inputerror(0, "invalid combination of complex type specifiers"); | |
24 | } else | |
25 | ci = b->type_specifiers & TS__CI; | |
26 | ||
27 | /* _Complex and _Imaginary can't be used with basic type specifiers other | |
28 | * than float or double */ | |
29 | if(ci) | |
30 | switch(basic) { | |
31 | case 0: | |
32 | case TS_FLOAT: | |
33 | case TS_DOUBLE: | |
34 | break; | |
35 | default: | |
36 | inputerror(0, "invalid use of complex type specifier"); | |
37 | ci = 0; /* don't repeat errors */ | |
38 | break; | |
39 | } | |
40 | ||
41 | /* can only have one length specifer except that 'long long' is permitted */ | |
42 | if((length = a->type_specifiers & TS__LENGTH)) { | |
43 | switch(b->type_specifiers & TS__LENGTH) { | |
44 | case 0: | |
45 | break; | |
46 | case TS_LONG: | |
47 | if(length == TS_LONG) | |
48 | length = TS_LONGLONG; | |
49 | else { | |
50 | default: | |
51 | inputerror(0, "invalid use of type length specifiers"); | |
52 | length = 0; /* don't repeat errors */ | |
53 | } | |
54 | break; | |
55 | } | |
56 | } else | |
57 | length = b->type_specifiers & TS__LENGTH; | |
58 | ||
59 | /* length specifiers can only be used with int, or long with double */ | |
60 | if(length) { | |
61 | switch(basic) { | |
62 | case 0: | |
63 | case TS_INT: | |
64 | break; | |
65 | case TS_DOUBLE: | |
66 | if(length != TS_LONG) { | |
67 | inputerror(0, "invalid floating type length specifier"); | |
68 | length = 0; /* don't repeat errors */ | |
69 | } | |
70 | break; | |
71 | } | |
72 | } | |
73 | ||
74 | /* can only have one sign specifier */ | |
75 | if((sign = a->type_specifiers & TS__SIGN)) { | |
76 | if(b->type_specifiers & TS__SIGN) | |
77 | inputerror(0, "invalid combination of type signedness specifier"); | |
78 | } else | |
79 | sign = b->type_specifiers & TS__SIGN; | |
80 | ||
81 | /* only int and char can be signed or unsigned */ | |
82 | if(sign) { | |
83 | switch(basic) { | |
84 | case 0: | |
85 | case TS_INT: | |
86 | case TS_CHAR: | |
87 | break; | |
88 | default: | |
89 | inputerror(0, "invalid use of type signedness specifier"); | |
90 | sign = 0; /* don't repeat errors */ | |
91 | break; | |
92 | } | |
93 | } | |
94 | ||
95 | /* C99 6.7.1 only one storage class specifier per declaration */ | |
96 | if(a->storage_class_specifiers && b->storage_class_specifiers) | |
97 | inputerror(0, "at most one storage class specifier is allowed in a declaration"); | |
98 | ||
99 | /* C99 6.7.3, 6.7.4 duplicate type qualifiers and function speciciers are | |
100 | * both allowed */ | |
101 | ||
102 | /* if basic didn't come from a it must have come from b, in which case we | |
103 | * copy the relevant extra fields and zap the irrelevant ones */ | |
104 | if(basic != (a->type_specifiers & TS__BASIC)) { | |
105 | a->name = b->name; | |
106 | a->structure = b->structure; | |
107 | a->enumerators = b->enumerators; | |
108 | a->type = b->type; | |
109 | definition = b->type_specifiers & TS_DEFINITION; | |
110 | } else | |
111 | definition = a->type_specifiers & TS_DEFINITION; | |
112 | ||
113 | /* put it all together */ | |
114 | a->type_specifiers = basic | ci | length | sign | definition; | |
115 | a->storage_class_specifiers |= b->storage_class_specifiers; | |
116 | a->type_qualifiers |= b->type_qualifiers; | |
117 | a->function_specifiers |= b->function_specifiers; | |
118 | ||
119 | return a; | |
120 | } | |
121 | ||
122 | /* return true if D has integral type. typedefs should have been resolved. */ | |
123 | int is_integral_type(const struct declarator *d) { | |
124 | /* pointers, functions, arrays aren't integral */ | |
125 | if(d->declarator_type) | |
126 | return 0; | |
127 | /* check the basic type */ | |
128 | switch(d->declaration_specifiers->type_specifiers & TS__BASIC) { | |
129 | case 0: | |
130 | case TS_BOOL: | |
131 | case TS_INT: | |
132 | case TS_CHAR: | |
133 | case TS_ENUM: | |
134 | return 1; | |
135 | default: | |
136 | return 0; | |
137 | } | |
138 | } | |
139 | ||
140 | /* return true if D has arithmetic type. typedefs should have been | |
141 | * resolved. */ | |
142 | int is_arithmetic_type(const struct declarator *d) { | |
143 | /* pointers, functions, arrays aren't integral */ | |
144 | if(d->declarator_type) | |
145 | return 0; | |
146 | /* check the basic type */ | |
147 | switch(d->declaration_specifiers->type_specifiers & TS__BASIC) { | |
148 | case 0: | |
149 | case TS_BOOL: | |
150 | case TS_INT: | |
151 | case TS_CHAR: | |
152 | case TS_ENUM: | |
153 | case TS_FLOAT: | |
154 | case TS_DOUBLE: | |
155 | return 1; | |
156 | default: | |
157 | return 0; | |
158 | } | |
159 | } | |
160 | ||
161 | /* return true if D has scalar type. typedefs should have been resolved. */ | |
162 | int is_scalar_type(const struct declarator *d) { | |
163 | /* functions, arrays aren't integral */ | |
164 | if(d->declarator_type) | |
165 | return d->declarator_type->type == dt_pointer; | |
166 | /* check the basic type */ | |
167 | switch(d->declaration_specifiers->type_specifiers & TS__BASIC) { | |
168 | case 0: | |
169 | case TS_BOOL: | |
170 | case TS_INT: | |
171 | case TS_CHAR: | |
172 | case TS_ENUM: | |
173 | case TS_FLOAT: | |
174 | case TS_DOUBLE: | |
175 | return 1; | |
176 | default: | |
177 | return 0; | |
178 | } | |
179 | } | |
180 | ||
181 | /* return true if D has pointer type. typedefs should have been resolved. */ | |
182 | int is_pointer_type(const struct declarator *d) { | |
183 | return d->declarator_type && d->declarator_type->type == dt_pointer; | |
184 | } | |
185 | ||
186 | /* resolve typedefs in value types */ | |
187 | struct declarator *resolve_typedefs(struct declarator *d) { | |
188 | struct declarator_type *dt, *dt_head, **dt_end, *du; | |
189 | struct declaration_specifiers *ds = d->declaration_specifiers, *nds; | |
190 | struct declarator *nd; | |
191 | unsigned tq; | |
192 | ||
193 | /* cache answers */ | |
194 | if(d->resolved) | |
195 | return d->resolved; | |
196 | ||
197 | if(ds->type) { | |
198 | /* We must duplicate our declarator_type chain, hang the typedef's | |
199 | * declarator_type chain off the end, and use the typedef's declarator | |
200 | * instead of ours, and do this as many times as necessary (hence the | |
201 | * while). | |
202 | * | |
203 | * Naturally we don't want to duplicate ever lengthening versions of our | |
204 | * declarator chain if there are multiple typdefs to resolve so we should | |
205 | * go through the whole thing in a single go building up the new | |
206 | * declarator_type chain as we go. | |
207 | */ | |
208 | ||
209 | /* first we duplicate our own declarator_type chain. These values mean | |
210 | * {decorations} of <base type> where <base type> is the typedef name. */ | |
211 | dt_end = &dt_head; | |
212 | du = d->declarator_type; | |
213 | while(du) { | |
214 | NEW(dt); | |
215 | *dt = *du; | |
216 | *dt_end = dt; | |
217 | dt_end = &dt->next; | |
218 | du = du->next; | |
219 | } | |
220 | ||
221 | /* now for each typedef name we encounter we append its declarator_type | |
222 | * chain */ | |
223 | ||
224 | /* this is the set of qualifiers to add to typedef's type */ | |
225 | tq = ds->type_qualifiers; | |
226 | ||
227 | while(ds->type) { | |
228 | /* The set of type qualifiers that are being added to the typedef should | |
229 | * be applied to the head of the typedef's bit of the declarator_type | |
230 | * chain: we are asking for (e.g.) a 'const foo'; if foo is an 'int *' | |
231 | * then it is the * that is const, not the int | |
232 | * | |
233 | * If it doesn't have one then we'll trickle them down to the next type. | |
234 | */ | |
235 | du = ds->type->declarator_type; | |
236 | while(du) { | |
237 | NEW(dt); | |
238 | *dt = *du; | |
239 | dt->type_qualifiers |= tq; | |
240 | tq = 0; /* no more type qualifiers */ | |
241 | *dt_end = dt; | |
242 | dt_end = &dt->next; | |
243 | du = du->next; | |
244 | } | |
245 | ds = ds->type->declaration_specifiers; | |
246 | tq |= ds->type_qualifiers; | |
247 | } | |
248 | /* we end when we hit a built-in type or some kind of weird anomalous | |
249 | * typedef without a definition */ | |
250 | ||
251 | assert(dt_end == &dt_head || *dt_end == 0); | |
252 | *dt_end = 0; | |
253 | ||
254 | /* if there are any left over type qualifiers we might need a new | |
255 | * declaration_specifiers */ | |
256 | if((ds->type_qualifiers | tq) != ds->type_qualifiers) { | |
257 | NEW(nds); | |
258 | *nds = *ds; | |
259 | nds->type_qualifiers |= tq; | |
260 | } | |
261 | ||
262 | /* make up a new declarator with the right declarator_type chain and | |
263 | * declaration_specifiers */ | |
264 | NEW(nd); | |
265 | *nd = *d; | |
266 | nd->declarator_type = dt_head; | |
267 | nd->declaration_specifiers = ds; | |
268 | d->resolved = nd; | |
269 | d = nd; | |
270 | } else | |
271 | d->resolved = d; | |
272 | return d; | |
273 | } | |
274 | ||
275 | /* return (as a declarator) the target type of an array or whatever. Usually | |
276 | * only makes sense after typedefs have been resolved. */ | |
277 | struct declarator *target_type(struct declarator *d) { | |
278 | struct declarator *nd; | |
279 | ||
280 | NEW(nd); | |
281 | *nd = *d; | |
282 | nd->declarator_type = d->declarator_type->next; | |
283 | return nd; | |
284 | } | |
285 | ||
286 | size_t width(unsigned long ts) { | |
287 | switch(ts & ~TS__SIGN) { | |
288 | case TS_CHAR: return 1; | |
289 | case TS_BOOL: return P_BOOL_SIZE; | |
290 | case TS_INT|TS_SHORT: case TS_SHORT: return P_SHORT_SIZE; | |
291 | case TS_INT: case 0: return P_INT_SIZE; | |
292 | case TS_INT|TS_LONG: case TS_LONG: return P_LONG_SIZE; | |
293 | case TS_INT|TS_LONGLONG: case TS_LONGLONG: return P_LLONG_SIZE; | |
294 | default: return 0; | |
295 | } | |
296 | } | |
297 | ||
298 | /* | |
299 | Local Variables: | |
300 | c-basic-offset:2 | |
301 | comment-column:40 | |
302 | fill-column:79 | |
303 | End: | |
304 | */ |