Warn about undefined preprocessor symbols at expansion time, not parse time
[smatch.git] / parse.c
bloba1fedac1e3ec13d569445f39e3e57ec14e26a603
1 /*
2 * Stupid C parser, version 1e-6.
4 * Let's see how hard this is to do.
6 * Copyright (C) 2003 Transmeta Corp.
7 * 2003-2004 Linus Torvalds
9 * Licensed under the Open Software License version 1.1
12 #include <stdarg.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <limits.h>
21 #include "lib.h"
22 #include "allocate.h"
23 #include "token.h"
24 #include "parse.h"
25 #include "symbol.h"
26 #include "scope.h"
27 #include "expression.h"
28 #include "target.h"
30 #define warn_on_mixed (1)
32 static struct symbol_list **function_symbol_list;
33 struct symbol_list *function_computed_target_list;
34 struct statement_list *function_computed_goto_list;
36 static struct token *statement(struct token *token, struct statement **tree);
38 // Add a symbol to the list of function-local symbols
39 static void fn_local_symbol(struct symbol *sym)
41 if (function_symbol_list)
42 add_symbol(function_symbol_list, sym);
45 static int match_idents(struct token *token, ...)
47 va_list args;
49 if (token_type(token) != TOKEN_IDENT)
50 return 0;
52 va_start(args, token);
53 for (;;) {
54 struct ident * next = va_arg(args, struct ident *);
55 if (!next)
56 return 0;
57 if (token->ident == next)
58 return 1;
63 struct statement *alloc_statement(struct position pos, int type)
65 struct statement *stmt = __alloc_statement(0);
66 stmt->type = type;
67 stmt->pos = pos;
68 return stmt;
71 static struct token *struct_declaration_list(struct token *token, struct symbol_list **list);
73 static struct symbol * indirect(struct position pos, struct ctype *ctype, int type)
75 struct symbol *sym = alloc_symbol(pos, type);
77 sym->ctype.base_type = ctype->base_type;
78 sym->ctype.modifiers = ctype->modifiers & ~MOD_STORAGE;
80 ctype->base_type = sym;
81 ctype->modifiers &= MOD_STORAGE;
82 return sym;
85 static struct symbol *lookup_or_create_symbol(enum namespace ns, enum type type, struct token *token)
87 struct symbol *sym = lookup_symbol(token->ident, ns);
88 if (!sym) {
89 sym = alloc_symbol(token->pos, type);
90 bind_symbol(sym, token->ident, ns);
91 if (type == SYM_LABEL)
92 fn_local_symbol(sym);
94 return sym;
98 * NOTE! NS_LABEL is not just a different namespace,
99 * it also ends up using function scope instead of the
100 * regular symbol scope.
102 struct symbol *label_symbol(struct token *token)
104 return lookup_or_create_symbol(NS_LABEL, SYM_LABEL, token);
107 static struct token *struct_union_enum_specifier(enum type type,
108 struct token *token, struct ctype *ctype,
109 struct token *(*parse)(struct token *, struct symbol *))
111 struct symbol *sym;
113 ctype->modifiers = 0;
114 if (token_type(token) == TOKEN_IDENT) {
115 sym = lookup_symbol(token->ident, NS_STRUCT);
116 if (!sym ||
117 (sym->scope != block_scope &&
118 (match_op(token->next,';') || match_op(token->next,'{')))) {
119 // Either a new symbol, or else an out-of-scope
120 // symbol being redefined.
121 sym = alloc_symbol(token->pos, type);
122 bind_symbol(sym, token->ident, NS_STRUCT);
124 if (sym->type != type)
125 error_die(token->pos, "invalid tag applied to %s", show_typename (sym));
126 token = token->next;
127 ctype->base_type = sym;
128 if (match_op(token, '{')) {
129 // The following test is actually wrong for empty
130 // structs, but (1) they are not C99, (2) gcc does
131 // the same thing, and (3) it's easier.
132 if (sym->symbol_list)
133 error_die(token->pos, "redefinition of %s", show_typename (sym));
134 token = parse(token->next, sym);
135 token = expect(token, '}', "at end of struct-union-enum-specifier");
137 // Mark the structure as needing re-examination
138 sym->examined = 0;
140 return token;
143 // private struct/union/enum type
144 if (!match_op(token, '{')) {
145 warning(token->pos, "expected declaration");
146 ctype->base_type = &bad_ctype;
147 return token;
150 sym = alloc_symbol(token->pos, type);
151 token = parse(token->next, sym);
152 ctype->base_type = sym;
153 return expect(token, '}', "at end of specifier");
156 static struct token *parse_struct_declaration(struct token *token, struct symbol *sym)
158 return struct_declaration_list(token, &sym->symbol_list);
161 static struct token *struct_or_union_specifier(enum type type, struct token *token, struct ctype *ctype)
163 return struct_union_enum_specifier(type, token, ctype, parse_struct_declaration);
166 typedef struct {
167 int x;
168 unsigned long long y;
169 } Num;
171 static void upper_boundary(Num *n, Num *v)
173 if (n->x > v->x)
174 return;
175 if (n->x < v->x) {
176 *n = *v;
177 return;
179 if (n->y < v->y)
180 n->y = v->y;
183 static void lower_boundary(Num *n, Num *v)
185 if (n->x < v->x)
186 return;
187 if (n->x > v->x) {
188 *n = *v;
189 return;
191 if (n->y > v->y)
192 n->y = v->y;
195 static int type_is_ok(struct symbol *type, Num *upper, Num *lower)
197 int shift = type->bit_size;
198 int is_unsigned = type->ctype.modifiers & MOD_UNSIGNED;
200 if (!is_unsigned)
201 shift--;
202 if (upper->x == 0 && upper->y >> shift)
203 return 0;
204 if (lower->x == 0 || (!is_unsigned && (~lower->y >> shift) == 0))
205 return 1;
206 return 0;
209 static struct token *parse_enum_declaration(struct token *token, struct symbol *parent)
211 unsigned long long lastval = 0;
212 struct symbol *ctype = NULL, *base_type = NULL;
213 Num upper = {-1, 0}, lower = {1, 0};
215 parent->examined = 1;
216 parent->ctype.base_type = &int_ctype;
217 while (token_type(token) == TOKEN_IDENT) {
218 struct expression *expr = NULL;
219 struct token *next = token->next;
220 struct symbol *sym;
222 sym = alloc_symbol(token->pos, SYM_NODE);
223 bind_symbol(sym, token->ident, NS_SYMBOL);
224 sym->ctype.modifiers &= ~MOD_ADDRESSABLE;
226 if (match_op(next, '=')) {
227 next = constant_expression(next->next, &expr);
228 lastval = get_expression_value(expr);
229 ctype = &void_ctype;
230 if (expr && expr->ctype)
231 ctype = expr->ctype;
232 } else if (!ctype) {
233 ctype = &int_ctype;
234 } else if (is_int_type(ctype)) {
235 lastval++;
236 } else {
237 error_die(token->pos, "can't increment the last enum member");
240 if (!expr) {
241 expr = alloc_expression(token->pos, EXPR_VALUE);
242 expr->value = lastval;
245 sym->initializer = expr;
246 sym->ctype.base_type = parent;
248 if (base_type != &bad_ctype) {
249 if (ctype->type == SYM_NODE)
250 ctype = ctype->ctype.base_type;
251 if (ctype->type == SYM_ENUM) {
252 if (ctype == parent)
253 ctype = base_type;
254 else
255 ctype = ctype->ctype.base_type;
258 * base_type rules:
259 * - if all enum's are of the same type, then
260 * the base_type is that type (two first
261 * cases)
262 * - if enums are of different types, they
263 * all have to be integer types, and the
264 * base type is "int_ctype".
265 * - otherwise the base_type is "bad_ctype".
267 if (!base_type) {
268 base_type = ctype;
269 } else if (ctype == base_type) {
270 /* nothing */
271 } else if (is_int_type(base_type) && is_int_type(ctype)) {
272 base_type = &int_ctype;
273 } else
274 base_type = &bad_ctype;
276 if (is_int_type(base_type)) {
277 Num v = {.y = lastval};
278 if (ctype->ctype.modifiers & MOD_UNSIGNED)
279 v.x = 0;
280 else if ((long long)lastval >= 0)
281 v.x = 0;
282 else
283 v.x = -1;
284 upper_boundary(&upper, &v);
285 lower_boundary(&lower, &v);
287 token = next;
288 if (!match_op(token, ','))
289 break;
290 token = token->next;
292 if (!base_type) {
293 warning(token->pos, "bad enum definition");
294 base_type = &bad_ctype;
296 else if (!is_int_type(base_type))
297 base_type = base_type;
298 else if (type_is_ok(base_type, &upper, &lower))
299 base_type = base_type;
300 else if (type_is_ok(&int_ctype, &upper, &lower))
301 base_type = &int_ctype;
302 else if (type_is_ok(&uint_ctype, &upper, &lower))
303 base_type = &uint_ctype;
304 else if (type_is_ok(&long_ctype, &upper, &lower))
305 base_type = &long_ctype;
306 else if (type_is_ok(&ulong_ctype, &upper, &lower))
307 base_type = &ulong_ctype;
308 else if (type_is_ok(&llong_ctype, &upper, &lower))
309 base_type = &llong_ctype;
310 else if (type_is_ok(&ullong_ctype, &upper, &lower))
311 base_type = &ullong_ctype;
312 else
313 base_type = &bad_ctype;
314 parent->ctype.base_type = base_type;
315 parent->ctype.modifiers |= (base_type->ctype.modifiers & MOD_UNSIGNED);
316 parent->examined = 0;
317 return token;
320 static struct token *enum_specifier(struct token *token, struct ctype *ctype)
322 struct token *ret = struct_union_enum_specifier(SYM_ENUM, token, ctype, parse_enum_declaration);
324 ctype = &ctype->base_type->ctype;
325 if (!ctype->base_type)
326 ctype->base_type = &incomplete_ctype;
328 return ret;
331 static struct token *typeof_specifier(struct token *token, struct ctype *ctype)
333 struct symbol *sym;
335 if (!match_op(token, '(')) {
336 warning(token->pos, "expected '(' after typeof");
337 return token;
339 if (lookup_type(token->next)) {
340 token = typename(token->next, &sym);
341 *ctype = sym->ctype;
342 } else {
343 struct symbol *typeof_sym = alloc_symbol(token->pos, SYM_TYPEOF);
344 token = parse_expression(token->next, &typeof_sym->initializer);
346 ctype->modifiers = 0;
347 ctype->base_type = typeof_sym;
349 return expect(token, ')', "after typeof");
352 static const char * handle_attribute(struct ctype *ctype, struct ident *attribute, struct expression *expr)
354 if (attribute == &packed_ident ||
355 attribute == &__packed___ident) {
356 ctype->alignment = 1;
357 return NULL;
359 if (attribute == &aligned_ident ||
360 attribute == &__aligned___ident) {
361 int alignment = max_alignment;
362 if (expr)
363 alignment = get_expression_value(expr);
364 ctype->alignment = alignment;
365 return NULL;
367 if (attribute == &nocast_ident) {
368 ctype->modifiers |= MOD_NOCAST;
369 return NULL;
371 if (attribute == &noderef_ident) {
372 ctype->modifiers |= MOD_NODEREF;
373 return NULL;
375 if (attribute == &safe_ident) {
376 ctype->modifiers |= MOD_SAFE;
377 return NULL;
379 if (attribute == &force_ident) {
380 ctype->modifiers |= MOD_FORCE;
381 return NULL;
383 if (attribute == &bitwise_ident ||
384 attribute == &__bitwise___ident) {
385 if (Wbitwise)
386 ctype->modifiers |= MOD_BITWISE;
387 return NULL;
389 if (attribute == &address_space_ident) {
390 if (!expr)
391 return "expected address space number";
392 ctype->as = get_expression_value(expr);
393 return NULL;
395 if (attribute == &context_ident) {
396 if (expr && expr->type == EXPR_COMMA) {
397 int input = get_expression_value(expr->left);
398 int output = get_expression_value(expr->right);
399 ctype->in_context = input;
400 ctype->out_context = output;
401 return NULL;
403 return "expected context input/output values";
405 if (attribute == &mode_ident ||
406 attribute == &__mode___ident) {
407 if (expr && expr->type == EXPR_SYMBOL) {
408 struct ident *ident = expr->symbol_name;
411 * Match against __QI__/__HI__/__SI__/__DI__
413 * FIXME! This is broken - we don't actually get
414 * the type information updated properly at this
415 * stage for some reason.
417 if (ident == &__QI___ident ||
418 ident == &QI_ident) {
419 ctype->modifiers |= MOD_CHAR;
420 return NULL;
422 if (ident == &__HI___ident ||
423 ident == &HI_ident) {
424 ctype->modifiers |= MOD_SHORT;
425 return NULL;
427 if (ident == &__SI___ident ||
428 ident == &SI_ident) {
429 /* Nothing? */
430 return NULL;
432 if (ident == &__DI___ident ||
433 ident == &DI_ident) {
434 ctype->modifiers |= MOD_LONGLONG;
435 return NULL;
437 if (ident == &__word___ident ||
438 ident == &word_ident) {
439 ctype->modifiers |= MOD_LONG;
440 return NULL;
442 return "unknown mode attribute";
444 return "expected attribute mode symbol";
447 /* Throw away for now.. */
448 if (attribute == &__transparent_union___ident) {
449 if (Wtransparent_union)
450 return "ignoring attribute __transparent_union__";
451 return NULL;
453 if (attribute == &nothrow_ident ||
454 attribute == &__nothrow_ident ||
455 attribute == &__nothrow___ident)
456 return NULL;
457 if (attribute == &__malloc___ident)
458 return NULL;
459 if (attribute == &nonnull_ident ||
460 attribute == &__nonnull_ident ||
461 attribute == &__nonnull___ident)
462 return NULL;
463 if (attribute == &format_ident ||
464 attribute == &__format___ident ||
465 attribute == &__format_arg___ident)
466 return NULL;
467 if (attribute == &section_ident ||
468 attribute == &__section___ident)
469 return NULL;
470 if (attribute == &unused_ident ||
471 attribute == &__unused___ident)
472 return NULL;
473 if (attribute == &const_ident ||
474 attribute == &__const_ident ||
475 attribute == &__const___ident)
476 return NULL;
477 if (attribute == &noreturn_ident ||
478 attribute == &__noreturn___ident)
479 return NULL;
480 if (attribute == &regparm_ident)
481 return NULL;
482 if (attribute == &weak_ident ||
483 attribute == &__weak___ident)
484 return NULL;
485 if (attribute == &alias_ident)
486 return NULL;
487 if (attribute == &pure_ident ||
488 attribute == &__pure___ident)
489 return NULL;
490 if (attribute == &always_inline_ident)
491 return NULL;
492 if (attribute == &syscall_linkage_ident)
493 return NULL;
494 if (attribute == &visibility_ident)
495 return NULL;
496 if (attribute == &deprecated_ident ||
497 attribute == &__deprecated___ident)
498 return NULL;
499 if (attribute == &noinline_ident)
500 return NULL;
501 if (attribute == &__used___ident)
502 return NULL;
503 if (attribute == &warn_unused_result_ident ||
504 attribute == &__warn_unused_result___ident)
505 return NULL;
506 if (attribute == &model_ident ||
507 attribute == &__model___ident)
508 return NULL;
510 return "unknown attribute";
513 static struct token *attribute_specifier(struct token *token, struct ctype *ctype)
515 ctype->modifiers = 0;
516 token = expect(token, '(', "after attribute");
517 token = expect(token, '(', "after attribute");
519 for (;;) {
520 const char *error;
521 struct ident *attribute_name;
522 struct expression *attribute_expr;
524 if (eof_token(token))
525 break;
526 if (match_op(token, ';'))
527 break;
528 if (token_type(token) != TOKEN_IDENT)
529 break;
530 attribute_name = token->ident;
531 token = token->next;
532 attribute_expr = NULL;
533 if (match_op(token, '('))
534 token = parens_expression(token, &attribute_expr, "in attribute");
535 error = handle_attribute(ctype, attribute_name, attribute_expr);
536 if (error)
537 warning(token->pos, "attribute '%s': %s", show_ident(attribute_name), error);
538 if (!match_op(token, ','))
539 break;
540 token = token->next;
543 token = expect(token, ')', "after attribute");
544 token = expect(token, ')', "after attribute");
545 return token;
548 struct symbol * ctype_integer(unsigned long spec)
550 static struct symbol *const integer_ctypes[][3] = {
551 { &llong_ctype, &sllong_ctype, &ullong_ctype },
552 { &long_ctype, &slong_ctype, &ulong_ctype },
553 { &short_ctype, &sshort_ctype, &ushort_ctype },
554 { &char_ctype, &schar_ctype, &uchar_ctype },
555 { &int_ctype, &sint_ctype, &uint_ctype },
557 struct symbol *const (*ctype)[3];
558 int sub;
560 ctype = integer_ctypes;
561 if (!(spec & MOD_LONGLONG)) {
562 ctype++;
563 if (!(spec & MOD_LONG)) {
564 ctype++;
565 if (!(spec & MOD_SHORT)) {
566 ctype++;
567 if (!(spec & MOD_CHAR))
568 ctype++;
573 sub = ((spec & MOD_UNSIGNED)
575 : ((spec & MOD_EXPLICITLY_SIGNED)
577 : 0));
579 return ctype[0][sub];
582 struct symbol * ctype_fp(unsigned long spec)
584 if (spec & MOD_LONGLONG)
585 return &ldouble_ctype;
586 if (spec & MOD_LONG)
587 return &double_ctype;
588 return &float_ctype;
591 static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype)
593 unsigned long mod = thistype->modifiers;
595 if (mod) {
596 unsigned long old = ctype->modifiers;
597 unsigned long extra = 0, dup, conflict;
599 if (mod & old & MOD_LONG) {
600 extra = MOD_LONGLONG | MOD_LONG;
601 mod &= ~MOD_LONG;
602 old &= ~MOD_LONG;
604 dup = (mod & old) | (extra & old) | (extra & mod);
605 if (dup)
606 warning(pos, "Just how %sdo you want this type to be?",
607 modifier_string(dup));
609 conflict = !(~mod & ~old & (MOD_LONG | MOD_SHORT));
610 if (conflict)
611 warning(pos, "You cannot have both long and short modifiers.");
613 conflict = !(~mod & ~old & (MOD_SIGNED | MOD_UNSIGNED));
614 if (conflict)
615 warning(pos, "You cannot have both signed and unsigned modifiers.");
617 // Only one storage modifier allowed, except that "inline" doesn't count.
618 conflict = (mod | old) & (MOD_STORAGE & ~MOD_INLINE);
619 conflict &= (conflict - 1);
620 if (conflict)
621 warning(pos, "multiple storage classes");
623 ctype->modifiers = old | mod | extra;
626 /* Context mask and value */
627 ctype->in_context += thistype->in_context;
628 ctype->out_context += thistype->out_context;
630 /* Alignment */
631 if (thistype->alignment & (thistype->alignment-1)) {
632 warning(pos, "I don't like non-power-of-2 alignments");
633 thistype->alignment = 0;
635 if (thistype->alignment > ctype->alignment)
636 ctype->alignment = thistype->alignment;
638 /* Address space */
639 if (thistype->as)
640 ctype->as = thistype->as;
643 static void check_modifiers(struct position *pos, struct symbol *s, unsigned long mod)
645 unsigned long banned, wrong;
646 unsigned long this_mod = s->ctype.modifiers;
647 const unsigned long BANNED_SIZE = MOD_LONG | MOD_LONGLONG | MOD_SHORT;
648 const unsigned long BANNED_SIGN = MOD_SIGNED | MOD_UNSIGNED;
650 if (this_mod & (MOD_STRUCTOF | MOD_UNIONOF | MOD_ENUMOF))
651 banned = BANNED_SIZE | BANNED_SIGN;
652 else if (this_mod & MOD_SPECIALBITS)
653 banned = 0;
654 else if (s->ctype.base_type == &fp_type)
655 banned = BANNED_SIGN;
656 else if (s->ctype.base_type == &int_type || !s->ctype.base_type || is_int_type (s))
657 banned = 0;
658 else {
659 // label_type
660 // void_type
661 // bad_type
662 // vector_type <-- whatever that is
663 banned = BANNED_SIZE | BANNED_SIGN;
666 wrong = mod & banned;
667 if (wrong)
668 warning(*pos, "modifier %sis invalid in this context",
669 modifier_string (wrong));
673 static struct token *declaration_specifiers(struct token *next, struct ctype *ctype, int qual)
675 struct token *token;
677 while ( (token = next) != NULL ) {
678 struct ctype thistype;
679 struct ident *ident;
680 struct symbol *s, *type;
681 unsigned long mod;
683 next = token->next;
684 if (token_type(token) != TOKEN_IDENT)
685 break;
686 ident = token->ident;
688 s = lookup_symbol(ident, NS_TYPEDEF);
689 if (!s)
690 break;
691 thistype = s->ctype;
692 mod = thistype.modifiers;
693 if (qual && (mod & ~(MOD_ATTRIBUTE | MOD_CONST | MOD_VOLATILE)))
694 break;
695 if (mod & MOD_SPECIALBITS) {
696 if (mod & MOD_STRUCTOF)
697 next = struct_or_union_specifier(SYM_STRUCT, next, &thistype);
698 else if (mod & MOD_UNIONOF)
699 next = struct_or_union_specifier(SYM_UNION, next, &thistype);
700 else if (mod & MOD_ENUMOF)
701 next = enum_specifier(next, &thistype);
702 else if (mod & MOD_ATTRIBUTE)
703 next = attribute_specifier(next, &thistype);
704 else if (mod & MOD_TYPEOF)
705 next = typeof_specifier(next, &thistype);
706 mod = thistype.modifiers;
708 type = thistype.base_type;
709 if (type) {
710 if (qual)
711 break;
712 if (ctype->base_type)
713 break;
714 /* User types only mix with qualifiers */
715 if (mod & MOD_USERTYPE) {
716 if (ctype->modifiers & MOD_SPECIFIER)
717 break;
719 ctype->base_type = type;
722 check_modifiers(&token->pos, s, ctype->modifiers);
723 apply_ctype(token->pos, &thistype, ctype);
726 /* Turn the "virtual types" into real types with real sizes etc */
727 if (!ctype->base_type) {
728 struct symbol *base = &incomplete_ctype;
731 * If we have modifiers, we'll default to an integer
732 * type, and "ctype_integer()" will turn this into
733 * a specific one.
735 if (ctype->modifiers & MOD_SPECIFIER)
736 base = &int_type;
737 ctype->base_type = base;
739 if (ctype->base_type == &int_type) {
740 ctype->base_type = ctype_integer(ctype->modifiers);
741 ctype->modifiers &= ~MOD_SPECIFIER;
742 } else if (ctype->base_type == &fp_type) {
743 ctype->base_type = ctype_fp(ctype->modifiers);
744 ctype->modifiers &= ~MOD_SPECIFIER;
746 if (ctype->modifiers & MOD_BITWISE) {
747 struct symbol *type;
748 ctype->modifiers &= ~(MOD_BITWISE | MOD_SPECIFIER);
749 if (!is_int_type(ctype->base_type)) {
750 warning(token->pos, "invalid modifier");
751 return token;
753 type = alloc_symbol(token->pos, SYM_BASETYPE);
754 *type = *ctype->base_type;
755 type->ctype.base_type = ctype->base_type;
756 type->type = SYM_RESTRICT;
757 type->ctype.modifiers &= ~MOD_SPECIFIER;
758 ctype->base_type = type;
760 return token;
763 static struct token *abstract_array_declarator(struct token *token, struct symbol *sym)
765 struct expression *expr = NULL;
767 token = parse_expression(token, &expr);
768 sym->array_size = expr;
769 return token;
772 static struct token *parameter_type_list(struct token *, struct symbol *, struct ident **p);
773 static struct token *declarator(struct token *token, struct symbol *sym, struct ident **p);
775 static struct token *handle_attributes(struct token *token, struct ctype *ctype)
777 for (;;) {
778 if (token_type(token) != TOKEN_IDENT)
779 break;
780 if (match_idents(token, &__attribute___ident, &__attribute_ident, NULL)) {
781 struct ctype thistype = { 0, };
782 token = attribute_specifier(token->next, &thistype);
783 apply_ctype(token->pos, &thistype, ctype);
784 continue;
786 if (match_idents(token, &asm_ident, &__asm_ident, &__asm___ident)) {
787 struct expression *expr;
788 token = expect(token->next, '(', "after asm");
789 token = parse_expression(token->next, &expr);
790 token = expect(token, ')', "after asm");
791 continue;
793 break;
795 return token;
798 static struct token *direct_declarator(struct token *token, struct symbol *decl, struct ident **p)
800 struct ctype *ctype = &decl->ctype;
802 if (p && token_type(token) == TOKEN_IDENT) {
803 *p = token->ident;
804 token = token->next;
807 for (;;) {
808 token = handle_attributes(token, ctype);
810 if (token_type(token) != TOKEN_SPECIAL)
811 return token;
814 * This can be either a parameter list or a grouping.
815 * For the direct (non-abstract) case, we know if must be
816 * a parameter list if we already saw the identifier.
817 * For the abstract case, we know if must be a parameter
818 * list if it is empty or starts with a type.
820 if (token->special == '(') {
821 struct symbol *sym;
822 struct token *next = token->next;
823 int fn = (p && *p) || match_op(next, ')') || lookup_type(next);
825 if (!fn) {
826 struct symbol *base_type = ctype->base_type;
827 token = declarator(next, decl, p);
828 token = expect(token, ')', "in nested declarator");
829 while (ctype->base_type != base_type)
830 ctype = &ctype->base_type->ctype;
831 p = NULL;
832 continue;
835 sym = indirect(token->pos, ctype, SYM_FN);
836 token = parameter_type_list(next, sym, p);
837 token = expect(token, ')', "in function declarator");
838 continue;
840 if (token->special == '[') {
841 struct symbol *array = indirect(token->pos, ctype, SYM_ARRAY);
842 token = abstract_array_declarator(token->next, array);
843 token = expect(token, ']', "in abstract_array_declarator");
844 ctype = &array->ctype;
845 continue;
847 break;
849 return token;
852 static struct token *pointer(struct token *token, struct ctype *ctype)
854 unsigned long modifiers;
855 struct symbol *base_type;
857 modifiers = ctype->modifiers & ~(MOD_TYPEDEF | MOD_ATTRIBUTE);
858 base_type = ctype->base_type;
859 ctype->modifiers = modifiers;
861 while (match_op(token,'*')) {
862 struct symbol *ptr = alloc_symbol(token->pos, SYM_PTR);
863 ptr->ctype.modifiers = modifiers & ~MOD_STORAGE;
864 ptr->ctype.as = ctype->as;
865 ptr->ctype.in_context += ctype->in_context;
866 ptr->ctype.out_context += ctype->out_context;
867 ptr->ctype.base_type = base_type;
869 base_type = ptr;
870 ctype->modifiers = modifiers & MOD_STORAGE;
871 ctype->base_type = base_type;
872 ctype->as = 0;
873 ctype->in_context = 0;
874 ctype->out_context = 0;
876 token = declaration_specifiers(token->next, ctype, 1);
877 modifiers = ctype->modifiers;
879 return token;
882 static struct token *declarator(struct token *token, struct symbol *sym, struct ident **p)
884 token = pointer(token, &sym->ctype);
885 return direct_declarator(token, sym, p);
888 static struct token *handle_bitfield(struct token *token, struct symbol *decl)
890 struct ctype *ctype = &decl->ctype;
891 struct expression *expr;
892 struct symbol *bitfield;
893 long long width;
895 if (!is_int_type(ctype->base_type)) {
896 warning(token->pos, "invalid bitfield specifier for type %s.",
897 show_typename(ctype->base_type));
898 // Parse this to recover gracefully.
899 return conditional_expression(token->next, &expr);
902 bitfield = indirect(token->pos, ctype, SYM_BITFIELD);
903 token = conditional_expression(token->next, &expr);
904 width = get_expression_value(expr);
905 bitfield->bit_size = width;
907 if (width < 0 || width > INT_MAX) {
908 warning(token->pos, "invalid bitfield width, %lld.", width);
909 width = -1;
910 } else if (decl->ident && width == 0) {
911 warning(token->pos, "invalid named zero-width bitfield `%s'",
912 show_ident(decl->ident));
913 width = -1;
914 } else if (decl->ident) {
915 struct symbol *base_type = bitfield->ctype.base_type;
916 int is_signed = !(base_type->ctype.modifiers & MOD_UNSIGNED);
917 if (width == 1 && is_signed) {
918 // Valid values are either {-1;0} or {0}, depending on integer
919 // representation. The latter makes for very efficient code...
920 warning(token->pos, "dubious one-bit signed bitfield");
922 if (Wdefault_bitfield_sign &&
923 base_type->type != SYM_ENUM &&
924 !(base_type->ctype.modifiers & MOD_EXPLICITLY_SIGNED) &&
925 is_signed) {
926 // The sign of bitfields is unspecified by default.
927 warning (token->pos, "dubious bitfield without explicit `signed' or `unsigned'");
930 bitfield->bit_size = width;
931 return token;
934 static struct token *struct_declaration_list(struct token *token, struct symbol_list **list)
936 while (!match_op(token, '}')) {
937 struct ctype ctype = {0, };
939 token = declaration_specifiers(token, &ctype, 0);
940 for (;;) {
941 struct ident *ident = NULL;
942 struct symbol *decl = alloc_symbol(token->pos, SYM_NODE);
943 decl->ctype = ctype;
944 token = declarator(token, decl, &ident);
945 decl->ident = ident;
946 if (match_op(token, ':')) {
947 token = handle_bitfield(token, decl);
948 token = handle_attributes(token, &decl->ctype);
950 add_symbol(list, decl);
951 if (!match_op(token, ','))
952 break;
953 token = token->next;
955 if (!match_op(token, ';')) {
956 warning(token->pos, "expected ; at end of declaration");
957 break;
959 token = token->next;
961 return token;
964 static struct token *parameter_declaration(struct token *token, struct symbol **tree)
966 struct ident *ident = NULL;
967 struct symbol *sym;
968 struct ctype ctype = { 0, };
970 token = declaration_specifiers(token, &ctype, 0);
971 sym = alloc_symbol(token->pos, SYM_NODE);
972 sym->ctype = ctype;
973 *tree = sym;
974 token = declarator(token, sym, &ident);
975 sym->ident = ident;
976 return token;
979 struct token *typename(struct token *token, struct symbol **p)
981 struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
982 *p = sym;
983 token = declaration_specifiers(token, &sym->ctype, 0);
984 return declarator(token, sym, NULL);
987 static struct token *expression_statement(struct token *token, struct expression **tree)
989 token = parse_expression(token, tree);
990 return expect(token, ';', "at end of statement");
993 static struct token *parse_asm_operands(struct token *token, struct statement *stmt,
994 struct expression_list **inout)
996 struct expression *expr;
998 /* Allow empty operands */
999 if (match_op(token->next, ':') || match_op(token->next, ')'))
1000 return token->next;
1001 do {
1002 struct ident *ident = NULL;
1003 if (match_op(token->next, '[') &&
1004 token_type(token->next->next) == TOKEN_IDENT &&
1005 match_op(token->next->next->next, ']')) {
1006 ident = token->next->next->ident;
1007 token = token->next->next->next;
1009 add_expression(inout, (struct expression *)ident); /* UGGLEE!!! */
1010 token = primary_expression(token->next, &expr);
1011 add_expression(inout, expr);
1012 token = parens_expression(token, &expr, "in asm parameter");
1013 add_expression(inout, expr);
1014 } while (match_op(token, ','));
1015 return token;
1018 static struct token *parse_asm_clobbers(struct token *token, struct statement *stmt,
1019 struct expression_list **clobbers)
1021 struct expression *expr;
1023 do {
1024 token = primary_expression(token->next, &expr);
1025 add_expression(clobbers, expr);
1026 } while (match_op(token, ','));
1027 return token;
1030 static struct token *parse_asm(struct token *token, struct statement *stmt)
1032 stmt->type = STMT_ASM;
1033 if (match_idents(token, &__volatile___ident, &__volatile_ident, &volatile_ident, NULL)) {
1034 token = token->next;
1036 token = expect(token, '(', "after asm");
1037 token = parse_expression(token, &stmt->asm_string);
1038 if (match_op(token, ':'))
1039 token = parse_asm_operands(token, stmt, &stmt->asm_outputs);
1040 if (match_op(token, ':'))
1041 token = parse_asm_operands(token, stmt, &stmt->asm_inputs);
1042 if (match_op(token, ':'))
1043 token = parse_asm_clobbers(token, stmt, &stmt->asm_clobbers);
1044 token = expect(token, ')', "after asm");
1045 return expect(token, ';', "at end of asm-statement");
1048 /* Make a statement out of an expression */
1049 static struct statement *make_statement(struct expression *expr)
1051 struct statement *stmt;
1053 if (!expr)
1054 return NULL;
1055 stmt = alloc_statement(expr->pos, STMT_EXPRESSION);
1056 stmt->expression = expr;
1057 return stmt;
1061 * All iterators have two symbols associated with them:
1062 * the "continue" and "break" symbols, which are targets
1063 * for continue and break statements respectively.
1065 * They are in a special name-space, but they follow
1066 * all the normal visibility rules, so nested iterators
1067 * automatically work right.
1069 static void start_iterator(struct statement *stmt)
1071 struct symbol *cont, *brk;
1073 start_symbol_scope();
1074 cont = alloc_symbol(stmt->pos, SYM_NODE);
1075 bind_symbol(cont, &continue_ident, NS_ITERATOR);
1076 brk = alloc_symbol(stmt->pos, SYM_NODE);
1077 bind_symbol(brk, &break_ident, NS_ITERATOR);
1079 stmt->type = STMT_ITERATOR;
1080 stmt->iterator_break = brk;
1081 stmt->iterator_continue = cont;
1082 fn_local_symbol(brk);
1083 fn_local_symbol(cont);
1086 static void end_iterator(struct statement *stmt)
1088 end_symbol_scope();
1091 static struct statement *start_function(struct symbol *sym)
1093 struct symbol *ret;
1094 struct statement *stmt = alloc_statement(sym->pos, STMT_COMPOUND);
1096 start_function_scope();
1097 ret = alloc_symbol(sym->pos, SYM_NODE);
1098 ret->ctype = sym->ctype.base_type->ctype;
1099 ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_CONST | MOD_VOLATILE | MOD_INLINE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF | MOD_ACCESSED | MOD_TOPLEVEL);
1100 ret->ctype.modifiers |= (MOD_AUTO | MOD_REGISTER);
1101 bind_symbol(ret, &return_ident, NS_ITERATOR);
1102 stmt->ret = ret;
1103 fn_local_symbol(ret);
1105 // Currently parsed symbol for __func__/__FUNCTION__/__PRETTY_FUNCTION__
1106 current_fn = sym;
1108 return stmt;
1111 static void end_function(struct symbol *sym)
1113 current_fn = NULL;
1114 end_function_scope();
1118 * A "switch()" statement, like an iterator, has a
1119 * the "break" symbol associated with it. It works
1120 * exactly like the iterator break - it's the target
1121 * for any break-statements in scope, and means that
1122 * "break" handling doesn't even need to know whether
1123 * it's breaking out of an iterator or a switch.
1125 * In addition, the "case" symbol is a marker for the
1126 * case/default statements to find the switch statement
1127 * that they are associated with.
1129 static void start_switch(struct statement *stmt)
1131 struct symbol *brk, *switch_case;
1133 start_symbol_scope();
1134 brk = alloc_symbol(stmt->pos, SYM_NODE);
1135 bind_symbol(brk, &break_ident, NS_ITERATOR);
1137 switch_case = alloc_symbol(stmt->pos, SYM_NODE);
1138 bind_symbol(switch_case, &case_ident, NS_ITERATOR);
1139 switch_case->stmt = stmt;
1141 stmt->type = STMT_SWITCH;
1142 stmt->switch_break = brk;
1143 stmt->switch_case = switch_case;
1145 fn_local_symbol(brk);
1146 fn_local_symbol(switch_case);
1149 static void end_switch(struct statement *stmt)
1151 if (!stmt->switch_case->symbol_list)
1152 warning(stmt->pos, "switch with no cases");
1153 end_symbol_scope();
1156 static void add_case_statement(struct statement *stmt)
1158 struct symbol *target = lookup_symbol(&case_ident, NS_ITERATOR);
1159 struct symbol *sym;
1161 if (!target) {
1162 warning(stmt->pos, "not in switch scope");
1163 stmt->type = STMT_NONE;
1164 return;
1166 sym = alloc_symbol(stmt->pos, SYM_NODE);
1167 add_symbol(&target->symbol_list, sym);
1168 sym->stmt = stmt;
1169 stmt->case_label = sym;
1170 fn_local_symbol(sym);
1173 static struct token *parse_return_statement(struct token *token, struct statement *stmt)
1175 struct symbol *target = lookup_symbol(&return_ident, NS_ITERATOR);
1177 if (!target)
1178 error_die(token->pos, "internal error: return without a function target");
1179 stmt->type = STMT_RETURN;
1180 stmt->ret_target = target;
1181 return expression_statement(token->next, &stmt->ret_value);
1184 static struct token *parse_for_statement(struct token *token, struct statement *stmt)
1186 struct symbol_list *syms;
1187 struct expression *e1, *e2, *e3;
1188 struct statement *iterator;
1190 start_iterator(stmt);
1191 token = expect(token->next, '(', "after 'for'");
1193 syms = NULL;
1194 e1 = NULL;
1195 /* C99 variable declaration? */
1196 if (lookup_type(token)) {
1197 token = external_declaration(token, &syms);
1198 } else {
1199 token = parse_expression(token, &e1);
1200 token = expect(token, ';', "in 'for'");
1202 token = parse_expression(token, &e2);
1203 token = expect(token, ';', "in 'for'");
1204 token = parse_expression(token, &e3);
1205 token = expect(token, ')', "in 'for'");
1206 token = statement(token, &iterator);
1208 stmt->iterator_syms = syms;
1209 stmt->iterator_pre_statement = make_statement(e1);
1210 stmt->iterator_pre_condition = e2;
1211 stmt->iterator_post_statement = make_statement(e3);
1212 stmt->iterator_post_condition = NULL;
1213 stmt->iterator_statement = iterator;
1214 end_iterator(stmt);
1216 return token;
1219 static struct token *parse_while_statement(struct token *token, struct statement *stmt)
1221 struct expression *expr;
1222 struct statement *iterator;
1224 start_iterator(stmt);
1225 token = parens_expression(token->next, &expr, "after 'while'");
1226 token = statement(token, &iterator);
1228 stmt->iterator_pre_condition = expr;
1229 stmt->iterator_post_condition = NULL;
1230 stmt->iterator_statement = iterator;
1231 end_iterator(stmt);
1233 return token;
1236 static struct token *parse_do_statement(struct token *token, struct statement *stmt)
1238 struct expression *expr;
1239 struct statement *iterator;
1241 start_iterator(stmt);
1242 token = statement(token->next, &iterator);
1243 if (token_type(token) == TOKEN_IDENT && token->ident == &while_ident)
1244 token = token->next;
1245 else
1246 warning(token->pos, "expected 'while' after 'do'");
1247 token = parens_expression(token, &expr, "after 'do-while'");
1249 stmt->iterator_post_condition = expr;
1250 stmt->iterator_statement = iterator;
1251 end_iterator(stmt);
1253 return expect(token, ';', "after statement");
1256 static struct token *statement(struct token *token, struct statement **tree)
1258 struct statement *stmt = alloc_statement(token->pos, STMT_NONE);
1260 *tree = stmt;
1261 if (token_type(token) == TOKEN_IDENT) {
1262 if (token->ident == &if_ident) {
1263 stmt->type = STMT_IF;
1264 token = parens_expression(token->next, &stmt->if_conditional, "after if");
1265 token = statement(token, &stmt->if_true);
1266 if (token_type(token) != TOKEN_IDENT)
1267 return token;
1268 if (token->ident != &else_ident)
1269 return token;
1270 return statement(token->next, &stmt->if_false);
1273 if (token->ident == &return_ident)
1274 return parse_return_statement(token, stmt);
1276 if (token->ident == &break_ident || token->ident == &continue_ident) {
1277 struct symbol *target = lookup_symbol(token->ident, NS_ITERATOR);
1278 stmt->type = STMT_GOTO;
1279 stmt->goto_label = target;
1280 if (!target)
1281 warning(stmt->pos, "break/continue not in iterator scope");
1282 return expect(token->next, ';', "at end of statement");
1284 if (token->ident == &default_ident) {
1285 token = token->next;
1286 goto default_statement;
1288 if (token->ident == &case_ident) {
1289 token = parse_expression(token->next, &stmt->case_expression);
1290 if (match_op(token, SPECIAL_ELLIPSIS))
1291 token = parse_expression(token->next, &stmt->case_to);
1292 default_statement:
1293 stmt->type = STMT_CASE;
1294 token = expect(token, ':', "after default/case");
1295 add_case_statement(stmt);
1296 return statement(token, &stmt->case_statement);
1298 if (token->ident == &switch_ident) {
1299 stmt->type = STMT_SWITCH;
1300 start_switch(stmt);
1301 token = parens_expression(token->next, &stmt->switch_expression, "after 'switch'");
1302 token = statement(token, &stmt->switch_statement);
1303 end_switch(stmt);
1304 return token;
1306 if (token->ident == &for_ident)
1307 return parse_for_statement(token, stmt);
1309 if (token->ident == &while_ident)
1310 return parse_while_statement(token, stmt);
1312 if (token->ident == &do_ident)
1313 return parse_do_statement(token, stmt);
1315 if (token->ident == &goto_ident) {
1316 stmt->type = STMT_GOTO;
1317 token = token->next;
1318 if (match_op(token, '*')) {
1319 token = parse_expression(token->next, &stmt->goto_expression);
1320 add_statement(&function_computed_goto_list, stmt);
1321 } else if (token_type(token) == TOKEN_IDENT) {
1322 stmt->goto_label = label_symbol(token);
1323 token = token->next;
1324 } else {
1325 warning(token->pos, "Expected identifier or goto expression");
1327 return expect(token, ';', "at end of statement");
1329 if (match_idents(token, &asm_ident, &__asm___ident, &__asm_ident, NULL)) {
1330 return parse_asm(token->next, stmt);
1332 if (token->ident == &__context___ident) {
1333 stmt->type = STMT_CONTEXT;
1334 token = parse_expression(token->next, &stmt->expression);
1335 return expect(token, ';', "at end of statement");
1337 if (token->ident == &__range___ident) {
1338 stmt->type = STMT_RANGE;
1339 token = assignment_expression(token->next, &stmt->range_expression);
1340 token = expect(token, ',', "after range expression");
1341 token = assignment_expression(token, &stmt->range_low);
1342 token = expect(token, ',', "after low range");
1343 token = assignment_expression(token, &stmt->range_high);
1344 return expect(token, ';', "after range statement");
1346 if (match_op(token->next, ':')) {
1347 stmt->type = STMT_LABEL;
1348 stmt->label_identifier = label_symbol(token);
1349 return statement(token->next->next, &stmt->label_statement);
1353 if (match_op(token, '{')) {
1354 stmt->type = STMT_COMPOUND;
1355 start_symbol_scope();
1356 token = compound_statement(token->next, stmt);
1357 end_symbol_scope();
1359 return expect(token, '}', "at end of compound statement");
1362 stmt->type = STMT_EXPRESSION;
1363 return expression_statement(token, &stmt->expression);
1366 static struct token * statement_list(struct token *token, struct statement_list **list, struct symbol_list **syms)
1368 for (;;) {
1369 struct statement * stmt;
1370 if (eof_token(token))
1371 break;
1372 if (match_op(token, '}'))
1373 break;
1374 if (lookup_type(token)) {
1375 if (warn_on_mixed && *list)
1376 warning(token->pos, "mixing declarations and code");
1377 token = external_declaration(token, syms);
1378 continue;
1380 token = statement(token, &stmt);
1381 add_statement(list, stmt);
1383 return token;
1386 static struct token *parameter_type_list(struct token *token, struct symbol *fn, struct ident **p)
1388 struct symbol_list **list = &fn->arguments;
1390 if (match_op(token, ')')) {
1391 // No warning for "void oink ();"
1392 // Bug or feature: warns for "void oink () __attribute__ ((noreturn));"
1393 if (p && !match_op(token->next, ';'))
1394 warning(token->pos, "non-ANSI function declaration of function '%s'", show_ident(*p));
1395 return token;
1398 for (;;) {
1399 struct symbol *sym;
1401 if (match_op(token, SPECIAL_ELLIPSIS)) {
1402 if (!*list)
1403 warning(token->pos, "variadic functions must have one named argument");
1404 fn->variadic = 1;
1405 token = token->next;
1406 break;
1409 sym = alloc_symbol(token->pos, SYM_NODE);
1410 token = parameter_declaration(token, &sym);
1411 if (sym->ctype.base_type == &void_ctype) {
1412 /* Special case: (void) */
1413 if (!*list && !sym->ident)
1414 break;
1415 warning(token->pos, "void parameter");
1417 add_symbol(list, sym);
1418 if (!match_op(token, ','))
1419 break;
1420 token = token->next;
1423 return token;
1426 struct token *compound_statement(struct token *token, struct statement *stmt)
1428 token = statement_list(token, &stmt->stmts, &stmt->syms);
1429 return token;
1432 static struct expression *identifier_expression(struct token *token)
1434 struct expression *expr = alloc_expression(token->pos, EXPR_IDENTIFIER);
1435 expr->expr_ident = token->ident;
1436 return expr;
1439 static struct expression *index_expression(struct expression *from, struct expression *to)
1441 int idx_from, idx_to;
1442 struct expression *expr = alloc_expression(from->pos, EXPR_INDEX);
1444 idx_from = get_expression_value(from);
1445 idx_to = idx_from;
1446 if (to) {
1447 idx_to = get_expression_value(to);
1448 if (idx_to < idx_from || idx_from < 0)
1449 warning(from->pos, "nonsense array initializer index range");
1451 expr->idx_from = idx_from;
1452 expr->idx_to = idx_to;
1453 return expr;
1456 static struct token *single_initializer(struct expression **ep, struct token *token)
1458 int expect_equal = 0;
1459 struct token *next = token->next;
1460 struct expression **tail = ep;
1461 int nested;
1463 *ep = NULL;
1465 if ((token_type(token) == TOKEN_IDENT) && match_op(next, ':')) {
1466 struct expression *expr = identifier_expression(token);
1467 warning(token->pos, "obsolete struct initializer, use C99 syntax");
1468 token = initializer(&expr->ident_expression, next->next);
1469 if (expr->ident_expression)
1470 *ep = expr;
1471 return token;
1474 for (tail = ep, nested = 0; ; nested++, next = token->next) {
1475 if (match_op(token, '.') && (token_type(next) == TOKEN_IDENT)) {
1476 struct expression *expr = identifier_expression(next);
1477 *tail = expr;
1478 tail = &expr->ident_expression;
1479 expect_equal = 1;
1480 token = next->next;
1481 } else if (match_op(token, '[')) {
1482 struct expression *from = NULL, *to = NULL, *expr;
1483 token = constant_expression(token->next, &from);
1484 if (!from) {
1485 warning(token->pos, "Expected constant expression");
1486 break;
1488 if (match_op(token, SPECIAL_ELLIPSIS))
1489 token = constant_expression(token->next, &to);
1490 expr = index_expression(from, to);
1491 *tail = expr;
1492 tail = &expr->idx_expression;
1493 token = expect(token, ']', "at end of initializer index");
1494 if (nested)
1495 expect_equal = 1;
1496 } else {
1497 break;
1500 if (nested && !expect_equal) {
1501 if (!match_op(token, '='))
1502 warning(token->pos, "obsolete array initializer, use C99 syntax");
1503 else
1504 expect_equal = 1;
1506 if (expect_equal)
1507 token = expect(token, '=', "at end of initializer index");
1509 token = initializer(tail, token);
1510 if (!*tail)
1511 *ep = NULL;
1512 return token;
1515 static struct token *initializer_list(struct expression_list **list, struct token *token)
1517 struct expression *expr;
1519 for (;;) {
1520 token = single_initializer(&expr, token);
1521 if (!expr)
1522 break;
1523 add_expression(list, expr);
1524 if (!match_op(token, ','))
1525 break;
1526 token = token->next;
1528 return token;
1531 struct token *initializer(struct expression **tree, struct token *token)
1533 if (match_op(token, '{')) {
1534 struct expression *expr = alloc_expression(token->pos, EXPR_INITIALIZER);
1535 *tree = expr;
1536 token = initializer_list(&expr->expr_list, token->next);
1537 return expect(token, '}', "at end of initializer");
1539 return assignment_expression(token, tree);
1542 static void declare_argument(struct symbol *sym, struct symbol *fn)
1544 if (!sym->ident) {
1545 warning(sym->pos, "no identifier for function argument");
1546 return;
1548 bind_symbol(sym, sym->ident, NS_SYMBOL);
1551 static struct token *parse_function_body(struct token *token, struct symbol *decl,
1552 struct symbol_list **list)
1554 struct symbol_list **old_symbol_list;
1555 struct symbol *base_type = decl->ctype.base_type;
1556 struct statement *stmt, **p;
1557 struct symbol *arg;
1559 old_symbol_list = function_symbol_list;
1560 if (decl->ctype.modifiers & MOD_INLINE) {
1561 function_symbol_list = &decl->inline_symbol_list;
1562 p = &base_type->inline_stmt;
1563 } else {
1564 function_symbol_list = &decl->symbol_list;
1565 p = &base_type->stmt;
1567 function_computed_target_list = NULL;
1568 function_computed_goto_list = NULL;
1570 if (decl->ctype.modifiers & MOD_EXTERN) {
1571 if (!(decl->ctype.modifiers & MOD_INLINE))
1572 warning(decl->pos, "function '%s' with external linkage has definition", show_ident(decl->ident));
1574 if (!(decl->ctype.modifiers & MOD_STATIC))
1575 decl->ctype.modifiers |= MOD_EXTERN;
1577 stmt = start_function(decl);
1579 *p = stmt;
1580 FOR_EACH_PTR (base_type->arguments, arg) {
1581 declare_argument(arg, base_type);
1582 } END_FOR_EACH_PTR(arg);
1584 token = compound_statement(token->next, stmt);
1586 end_function(decl);
1587 if (!(decl->ctype.modifiers & MOD_INLINE))
1588 add_symbol(list, decl);
1589 check_declaration(decl);
1590 function_symbol_list = old_symbol_list;
1591 if (function_computed_goto_list) {
1592 if (!function_computed_target_list)
1593 warning(decl->pos, "function '%s' has computed goto but no targets?", show_ident(decl->ident));
1594 else {
1595 struct statement *stmt;
1596 FOR_EACH_PTR(function_computed_goto_list, stmt) {
1597 stmt->target_list = function_computed_target_list;
1598 } END_FOR_EACH_PTR(stmt);
1601 return expect(token, '}', "at end of function");
1604 static void promote_k_r_types(struct symbol *arg)
1606 struct symbol *base = arg->ctype.base_type;
1607 if (base && base->ctype.base_type == &int_type && (base->ctype.modifiers & (MOD_CHAR | MOD_SHORT))) {
1608 arg->ctype.base_type = &int_ctype;
1612 static void apply_k_r_types(struct symbol_list *argtypes, struct symbol *fn)
1614 struct symbol_list *real_args = fn->ctype.base_type->arguments;
1615 struct symbol *arg;
1617 FOR_EACH_PTR(real_args, arg) {
1618 struct symbol *type;
1620 /* This is quadratic in the number of arguments. We _really_ don't care */
1621 FOR_EACH_PTR(argtypes, type) {
1622 if (type->ident == arg->ident)
1623 goto match;
1624 } END_FOR_EACH_PTR(type);
1625 warning(arg->pos, "missing type declaration for parameter '%s'", show_ident(arg->ident));
1626 continue;
1627 match:
1628 type->used = 1;
1629 /* "char" and "short" promote to "int" */
1630 promote_k_r_types(type);
1632 arg->ctype = type->ctype;
1633 } END_FOR_EACH_PTR(arg);
1635 FOR_EACH_PTR(argtypes, arg) {
1636 if (!arg->used)
1637 warning(arg->pos, "nonsensical parameter declaration '%s'", show_ident(arg->ident));
1638 } END_FOR_EACH_PTR(arg);
1642 static struct token *parse_k_r_arguments(struct token *token, struct symbol *decl,
1643 struct symbol_list **list)
1645 struct symbol_list *args = NULL;
1647 warning(token->pos, "non-ANSI function declaration of function '%s'", show_ident(decl->ident));
1648 do {
1649 token = external_declaration(token, &args);
1650 } while (lookup_type(token));
1652 apply_k_r_types(args, decl);
1654 if (!match_op(token, '{')) {
1655 warning(token->pos, "expected function body");
1656 return token;
1658 return parse_function_body(token, decl, list);
1662 struct token *external_declaration(struct token *token, struct symbol_list **list)
1664 struct ident *ident = NULL;
1665 struct symbol *decl;
1666 struct ctype ctype = { 0, };
1667 struct symbol *base_type;
1668 int is_typedef;
1670 /* Top-level inline asm? */
1671 if (match_idents(token, &asm_ident, &__asm___ident, &__asm_ident, NULL)) {
1672 struct symbol *anon = alloc_symbol(token->pos, SYM_NODE);
1673 struct symbol *fn = alloc_symbol(token->pos, SYM_FN);
1674 struct statement *stmt;
1676 anon->ctype.base_type = fn;
1677 stmt = alloc_statement(token->pos, STMT_NONE);
1678 fn->stmt = stmt;
1680 token = parse_asm(token->next, stmt);
1682 add_symbol(list, anon);
1683 return token;
1686 /* Parse declaration-specifiers, if any */
1687 token = declaration_specifiers(token, &ctype, 0);
1688 decl = alloc_symbol(token->pos, SYM_NODE);
1689 decl->ctype = ctype;
1690 token = declarator(token, decl, &ident);
1692 /* Just a type declaration? */
1693 if (!ident)
1694 return expect(token, ';', "end of type declaration");
1696 /* type define declaration? */
1697 is_typedef = (ctype.modifiers & MOD_TYPEDEF) != 0;
1699 /* Typedef's don't have meaningful storage */
1700 if (is_typedef) {
1701 ctype.modifiers &= ~MOD_STORAGE;
1702 decl->ctype.modifiers &= ~MOD_STORAGE;
1703 decl->ctype.modifiers |= MOD_USERTYPE;
1706 bind_symbol(decl, ident, is_typedef ? NS_TYPEDEF: NS_SYMBOL);
1708 base_type = decl->ctype.base_type;
1710 if (is_typedef) {
1711 if (base_type && !base_type->ident)
1712 base_type->ident = ident;
1713 } else if (base_type && base_type->type == SYM_FN) {
1714 /* K&R argument declaration? */
1715 if (lookup_type(token))
1716 return parse_k_r_arguments(token, decl, list);
1717 if (match_op(token, '{'))
1718 return parse_function_body(token, decl, list);
1720 if (!(decl->ctype.modifiers & MOD_STATIC))
1721 decl->ctype.modifiers |= MOD_EXTERN;
1722 } else if (base_type == &void_ctype && !(decl->ctype.modifiers & MOD_EXTERN)) {
1723 warning(token->pos, "void declaration");
1726 for (;;) {
1727 if (!is_typedef && match_op(token, '=')) {
1728 if (decl->ctype.modifiers & MOD_EXTERN) {
1729 warning(decl->pos, "symbol with external linkage has initializer");
1730 decl->ctype.modifiers &= ~MOD_EXTERN;
1732 token = initializer(&decl->initializer, token->next);
1734 if (!is_typedef) {
1735 if (!(decl->ctype.modifiers & (MOD_EXTERN | MOD_INLINE))) {
1736 add_symbol(list, decl);
1737 fn_local_symbol(decl);
1740 check_declaration(decl);
1742 if (!match_op(token, ','))
1743 break;
1745 token = token->next;
1746 ident = NULL;
1747 decl = alloc_symbol(token->pos, SYM_NODE);
1748 decl->ctype = ctype;
1749 token = declaration_specifiers(token, &decl->ctype, 1);
1750 token = declarator(token, decl, &ident);
1751 if (!ident) {
1752 warning(token->pos, "expected identifier name in type definition");
1753 return token;
1756 bind_symbol(decl, ident, is_typedef ? NS_TYPEDEF: NS_SYMBOL);
1758 /* Function declarations are automatically extern unless specifically static */
1759 base_type = decl->ctype.base_type;
1760 if (!is_typedef && base_type && base_type->type == SYM_FN) {
1761 if (!(decl->ctype.modifiers & MOD_STATIC))
1762 decl->ctype.modifiers |= MOD_EXTERN;
1765 return expect(token, ';', "at end of declaration");