Commit | Line | Data |
---|---|---|
3cd4b0f8 MW |
1 | #include "cparse.h" |
2 | #include <assert.h> | |
3 | ||
4 | /* C99 6.4.3 */ | |
5 | void ucn_constraints(unsigned long u) { | |
6 | switch(u) { | |
7 | case 0x24: | |
8 | case 0x40: | |
9 | case 0x60: | |
10 | break; | |
11 | default: | |
12 | if(u < 0x00A0) | |
13 | yyerror("UCN values below \\u00A0 are not allowed"); | |
14 | else if(u >= 0xD800 && u <= 0xDFFF) | |
15 | yyerror("UCN values in [\\uD800, \\uDFFF] are not allowed"); | |
16 | break; | |
17 | } | |
18 | } | |
19 | ||
20 | enum type_category get_type_category(const struct declaration_specifiers *ds, | |
21 | const struct declarator_type *dt) { | |
22 | if(dt) { | |
23 | switch(dt->type) { | |
24 | case dt_function: | |
25 | case dt_old_function: | |
26 | return tc_function; | |
27 | case dt_pointer: | |
28 | return tc_complete; | |
29 | case dt_array: | |
30 | if(get_type_category(ds, dt->next) == tc_complete | |
31 | && (dt->u.array.size || (dt->u.array.flags & AF_STAR))) | |
32 | return tc_complete; | |
33 | return tc_incomplete; | |
34 | } | |
35 | abort(); | |
36 | } else { | |
37 | if((ds->type_specifiers & TS__BASIC) == TS_VOID) | |
38 | return tc_incomplete; | |
39 | /* XXX detect incomplete struct/union types */ | |
40 | return tc_complete; | |
41 | } | |
42 | } | |
43 | ||
44 | /* C99 6.7.5.3 function declarators */ | |
45 | static void check_function_return_type(const struct declarator_type *dt) { | |
46 | if(dt) switch(dt->type) { | |
47 | case dt_array: | |
48 | inputerror(&dt->where, "function returns an array"); | |
49 | break; | |
50 | case dt_function: | |
51 | case dt_old_function: | |
52 | inputerror(&dt->where, "function returns a function"); | |
53 | break; | |
54 | case dt_pointer: | |
55 | break; | |
56 | } | |
57 | } | |
58 | ||
59 | int is_void_args(const struct declarator_type *dt) { | |
60 | const struct declaration *args; | |
61 | const struct declarator *d; | |
62 | const struct declaration_specifiers *ds; | |
63 | ||
64 | if(dt->u.function.variadic) return 0; | |
65 | args = dt->u.function.args; | |
66 | if(!args || args->next) return 0; | |
67 | d = args->declarator_list; | |
68 | if(d->name || d->declarator_type) return 0; | |
69 | ds = d->declaration_specifiers; | |
70 | if(ds->storage_class_specifiers | |
71 | || ds->type_qualifiers | |
72 | || ds->type_specifiers != TS_VOID) | |
73 | return 0; | |
74 | return 1; | |
75 | } | |
76 | ||
77 | static int valid_bitfield_type(const struct declaration_specifiers *ds, | |
78 | const struct declarator_type *dt) { | |
79 | if(dt) return 0; | |
80 | switch(ds->type_specifiers) { | |
81 | case TS_INT: | |
82 | case TS_SIGNED|TS_INT: | |
83 | case TS_UNSIGNED|TS_INT: | |
84 | case TS_SIGNED: | |
85 | case TS_UNSIGNED: | |
86 | case TS_BOOL: | |
87 | return 1; | |
88 | default: | |
89 | return 0; | |
90 | } | |
91 | } | |
92 | ||
93 | void declaration_constraints(const struct declaration *decl, | |
94 | enum declarator_context context) { | |
95 | const struct declarator *d; | |
96 | ||
97 | /* C99 6.7.2 need at least one type specifier */ | |
98 | if(!decl->declaration_specifiers->type_specifiers) | |
99 | inputerror(&decl->where, "no type specifiers in declaration"); | |
100 | ||
101 | for(d = decl->declarator_list; d; d = d->next) | |
102 | declarator_constraints(d->declaration_specifiers, | |
103 | d, context, 0); | |
104 | } | |
105 | ||
106 | void declarator_constraints(const struct declaration_specifiers *ds, | |
107 | const struct declarator *d, | |
108 | enum declarator_context context, | |
109 | int argno) { | |
110 | const struct declarator_type *dt = d->declarator_type; | |
111 | const struct location *declloc = dt ? &dt->where : &d->where; | |
112 | ||
113 | switch(context) { | |
114 | case dc_function_definition: | |
115 | if(ds->storage_class_specifiers & ~(SCS_EXTERN|SCS_STATIC)) | |
116 | inputerror(&d->where, "invalid storage class specifiers for a function"); | |
117 | if(!dt || (dt->type != dt_function | |
118 | && dt->type != dt_old_function)) { | |
119 | if(d->name) | |
120 | inputerror(&d->where, | |
121 | "function definition of '%s' requires a function declarator", | |
122 | d->name); | |
123 | else | |
124 | inputerror(&d->where, | |
125 | "function definition requires a function declarator"); | |
126 | } | |
127 | break; | |
128 | ||
129 | case dc_function_definition_parameter: | |
130 | if(!d->name) | |
131 | inputerror(declloc, "parameter %d has no name", argno); | |
132 | case dc_function_parameter: | |
133 | if(ds->storage_class_specifiers & (~SCS_REGISTER)) { | |
134 | if(d->name) | |
135 | inputerror(&d->where, "parameter '%s' has invalid storage class", | |
136 | d->name); | |
137 | else | |
138 | inputerror(&d->where, "parameter %d has invalid storage class", | |
139 | argno); | |
140 | } | |
141 | switch(get_type_category(ds, dt)) { | |
142 | case tc_incomplete: | |
143 | if(context == dc_function_definition_parameter) { | |
144 | /* arrays of completely-typed objects are allowed */ | |
145 | if(!(dt | |
146 | && dt->type == dt_array | |
147 | && get_type_category(ds, dt->next) == tc_complete)) { | |
148 | if(d->name) | |
149 | inputerror(declloc, "parameter '%s' has incomplete type", | |
150 | d->name); | |
151 | /* if no name, will already have reported an error */ | |
152 | } | |
153 | } | |
154 | break; | |
155 | case tc_function: | |
156 | if(d->name) | |
157 | inputerror(declloc, "parameter '%s' has function type", d->name); | |
158 | else | |
159 | inputerror(declloc, "parameter %d has function type", argno); | |
160 | break; | |
161 | case tc_complete: | |
162 | break; | |
163 | } | |
164 | break; | |
165 | ||
166 | case dc_struct_member: | |
167 | if(d->bits) { | |
168 | if(!valid_bitfield_type(ds, dt)) { | |
169 | if(d->name) | |
170 | inputerror(&d->where, "member '%s' has invalid type for a bit field"); | |
171 | else | |
172 | inputerror(&d->where, "member has invalid type for a bit field"); | |
173 | } | |
174 | /* XXX field size must be integral */ | |
175 | } else { | |
176 | switch(get_type_category(ds, dt)) { | |
177 | case tc_function: | |
178 | inputerror(declloc, "member '%s' has function type", d->name); | |
179 | break; | |
180 | case tc_incomplete: | |
181 | if(dt | |
182 | && dt->type == dt_array | |
183 | && !dt->u.array.size | |
184 | && !dt->u.array.flags) | |
185 | inputwarning(declloc, warn_compat, | |
186 | "member '%s' is a GNU C flexible array", d->name); | |
187 | else | |
188 | inputerror(declloc, "member '%s' has incomplete type", d->name); | |
189 | break; | |
190 | case tc_complete: | |
191 | break; | |
192 | } | |
193 | } | |
194 | break; | |
195 | ||
196 | case dc_cast: | |
197 | switch(get_type_category(ds, dt)) { | |
198 | case tc_function: | |
199 | inputerror(declloc, "cannot convert to function type"); | |
200 | break; | |
201 | case tc_incomplete: | |
202 | if(ds->type_specifiers != TS_VOID) | |
203 | inputerror(declloc, "cannot convert to incomplete type"); | |
204 | break; | |
205 | case tc_complete: | |
206 | switch(ds->type_specifiers & TS__BASIC) { | |
207 | case TS_STRUCT: | |
208 | case TS_UNION: | |
209 | if(dt == 0) { | |
210 | /* XXX and some typedefs */ | |
211 | inputerror(declloc, "cannot convert to aggregate type"); | |
212 | } else switch(dt->type) { | |
213 | case dt_array: | |
214 | inputerror(declloc, "cannot convert to array type"); | |
215 | break; | |
216 | case dt_function: | |
217 | case dt_old_function: | |
218 | inputerror(declloc, "cannot convert to function type"); | |
219 | break; | |
220 | case dt_pointer: | |
221 | /* pointers are OK */ | |
222 | break; | |
223 | } | |
224 | break; | |
225 | } | |
226 | break; | |
227 | } | |
228 | break; | |
229 | ||
230 | case dc_compound_literal: | |
231 | switch(get_type_category(ds, dt)) { | |
232 | case tc_function: | |
233 | inputerror(declloc, "compound literals cannot have incomplete type"); | |
234 | break; | |
235 | case tc_incomplete: | |
236 | inputerror(declloc, "compound literals cannot have incomplete type"); | |
237 | break; | |
238 | case tc_complete: | |
239 | break; | |
240 | } | |
241 | break; | |
242 | ||
243 | case dc_sizeof: | |
244 | switch(get_type_category(ds, dt)) { | |
245 | case tc_function: | |
246 | inputerror(declloc, "cannot take size of function type"); | |
247 | break; | |
248 | case tc_incomplete: | |
249 | inputerror(declloc, "cannot take size of incomplete type"); | |
250 | break; | |
251 | case tc_complete: | |
252 | break; | |
253 | } | |
254 | break; | |
255 | ||
256 | case dc_file_scope: | |
257 | case dc_block_scope: | |
258 | break; | |
259 | } | |
260 | for(dt = d->declarator_type; dt; dt = dt->next) { | |
261 | switch(dt->type) { | |
262 | case dt_pointer: | |
263 | break; | |
264 | ||
265 | /* C99 6.7.5.2 array declarators */ | |
266 | ||
267 | case dt_array: | |
268 | if((dt->storage_class_specifiers | |
269 | || dt->type_qualifiers) | |
270 | && !(dt == d->declarator_type | |
271 | && (context == dc_function_parameter | |
272 | || context == dc_function_definition_parameter))) | |
273 | inputerror(&dt->where, "invalid array declarator"); | |
274 | switch(get_type_category(ds, dt->next)) { | |
275 | case tc_complete: | |
276 | break; | |
277 | case tc_function: | |
278 | inputerror(&dt->where, "array element type has function type"); | |
279 | break; | |
280 | case tc_incomplete: | |
281 | inputerror(&dt->where, "array element type has incomplete type"); | |
282 | break; | |
283 | } | |
284 | /* XXX size must have integral type */ | |
285 | break; | |
286 | ||
287 | /* C99 6.7.5.3 function declarators */ | |
288 | ||
289 | case dt_old_function: | |
290 | check_function_return_type(dt->next); | |
291 | if(dt->u.old_function.args) { | |
292 | if(!(dt == d->declarator_type && context == dc_function_definition)) | |
293 | inputerror(&dt->where, | |
294 | "non-empty identifier-list in function declarator"); | |
295 | else { | |
296 | /* check for duplicates */ | |
297 | struct dict *dict = dict_new(); | |
298 | struct identifier_list *i; | |
299 | ||
300 | for(i = dt->u.old_function.args; i; i = i->next) { | |
301 | if(dict_get(dict, i->id)) { | |
302 | inputerror(&dt->where, "duplicate '%s' in function parameters", | |
303 | i->id); | |
304 | break; | |
305 | } | |
306 | dict_add(dict, i->id, i->id); | |
307 | } | |
308 | } | |
309 | } | |
310 | break; | |
311 | ||
312 | case dt_function: | |
313 | check_function_return_type(dt->next); | |
314 | if(!is_void_args(dt)) { | |
315 | /* recursively check arguments */ | |
316 | int n = 1; | |
317 | const struct declaration *a; | |
318 | ||
319 | for(a = dt->u.function.args; a; a = a->next) | |
320 | declarator_constraints(a->declaration_specifiers, | |
321 | a->declarator_list, | |
322 | context == dc_function_definition | |
323 | ? dc_function_definition_parameter | |
324 | : dc_function_parameter, | |
325 | n++); | |
326 | } | |
327 | break; | |
328 | } | |
329 | } | |
330 | } | |
331 | ||
332 | /* | |
333 | Local Variables: | |
334 | c-basic-offset:2 | |
335 | comment-column:40 | |
336 | End: | |
337 | */ |