Make the "obfuscate" backend actually generate a few
[smatch.git] / parse.c
blob5e957c6831cb6c4b9038f770a94b7bafe28383ce
1 /*
2 * Stupid C parser, version 1e-6.
4 * Let's see how hard this is to do.
6 * Copyright (C) 2003 Transmeta Corp, all rights reserved.
7 */
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <unistd.h>
15 #include <fcntl.h>
17 #include "lib.h"
18 #include "token.h"
19 #include "parse.h"
20 #include "symbol.h"
21 #include "scope.h"
22 #include "expression.h"
24 struct statement *alloc_statement(struct position pos, int type)
26 struct statement *stmt = __alloc_statement(0);
27 stmt->type = type;
28 stmt->pos = pos;
29 return stmt;
32 static struct token *struct_declaration_list(struct token *token, struct symbol_list **list);
34 static struct symbol * indirect(struct position pos, struct ctype *ctype, int type)
36 struct symbol *sym = alloc_symbol(pos, type);
38 sym->ctype.base_type = ctype->base_type;
39 sym->ctype.modifiers = ctype->modifiers & ~MOD_STORAGE;
41 ctype->base_type = sym;
42 ctype->modifiers &= MOD_STORAGE;
43 return sym;
46 static struct symbol *lookup_or_create_symbol(enum namespace ns, enum type type, struct token *token)
48 struct symbol *sym = lookup_symbol(token->ident, ns);
49 if (!sym) {
50 sym = alloc_symbol(token->pos, type);
51 sym->ident = token->ident;
52 bind_symbol(sym, token->ident, ns);
54 return sym;
58 * NOTE! NS_LABEL is not just a different namespace,
59 * it also ends up using function scope instead of the
60 * regular symbol scope.
62 static struct symbol *label_symbol(struct token *token)
64 return lookup_or_create_symbol(NS_LABEL, SYM_LABEL, token);
67 struct token *struct_union_enum_specifier(enum namespace ns, enum type type,
68 struct token *token, struct ctype *ctype,
69 struct token *(*parse)(struct token *, struct symbol *))
71 struct symbol *sym;
73 ctype->modifiers = 0;
74 if (token_type(token) == TOKEN_IDENT) {
75 sym = lookup_or_create_symbol(ns, type, token);
76 token = token->next;
77 ctype->base_type = sym;
78 if (match_op(token, '{')) {
79 token = parse(token->next, sym);
80 token = expect(token, '}', "at end of struct-union-enum-specifier");
82 return token;
85 // private struct/union/enum type
86 if (!match_op(token, '{')) {
87 warn(token->pos, "expected declaration");
88 ctype->base_type = &bad_type;
89 return token;
92 sym = alloc_symbol(token->pos, type);
93 token = parse(token->next, sym);
94 ctype->base_type = sym;
95 return expect(token, '}', "at end of specifier");
98 static struct token *parse_struct_declaration(struct token *token, struct symbol *sym)
100 return struct_declaration_list(token, &sym->symbol_list);
103 struct token *struct_or_union_specifier(enum type type, struct token *token, struct ctype *ctype)
105 return struct_union_enum_specifier(NS_STRUCT, type, token, ctype, parse_struct_declaration);
108 static struct token *parse_enum_declaration(struct token *token, struct symbol *parent)
110 int nextval = 0;
111 while (token_type(token) == TOKEN_IDENT) {
112 struct token *next = token->next;
113 struct symbol *sym;
115 sym = alloc_symbol(token->pos, SYM_NODE);
116 bind_symbol(sym, token->ident, NS_SYMBOL);
117 sym->ctype.base_type = parent;
119 if (match_op(next, '=')) {
120 struct expression *expr;
121 next = constant_expression(next->next, &expr);
122 nextval = get_expression_value(expr);
124 sym->value = nextval;
126 token = next;
127 if (!match_op(token, ','))
128 break;
129 token = token->next;
130 nextval = nextval + 1;
132 return token;
135 struct token *enum_specifier(struct token *token, struct ctype *ctype)
137 return struct_union_enum_specifier(NS_ENUM, SYM_ENUM, token, ctype, parse_enum_declaration);
140 struct token *typeof_specifier(struct token *token, struct ctype *ctype)
142 struct symbol *sym;
144 if (!match_op(token, '(')) {
145 warn(token->pos, "expected '(' after typeof");
146 return token;
148 if (lookup_type(token->next)) {
149 token = typename(token->next, &sym);
150 *ctype = sym->ctype;
151 } else {
152 struct symbol *typeof_sym = alloc_symbol(token->pos, SYM_TYPEOF);
153 token = parse_expression(token->next, &typeof_sym->initializer);
155 ctype->modifiers = 0;
156 ctype->base_type = typeof_sym;
158 return expect(token, ')', "after typeof");
161 static void handle_attribute(struct ctype *ctype, struct ident *attribute, struct expression *expr)
163 if (match_string_ident(attribute, "packed")) {
164 ctype->alignment = 1;
165 return;
167 if (match_string_ident(attribute, "aligned")) {
168 ctype->alignment = get_expression_value(expr);
169 return;
171 if (match_string_ident(attribute, "nocast")) {
172 ctype->modifiers |= MOD_NOCAST;
173 return;
175 if (match_string_ident(attribute, "noderef")) {
176 ctype->modifiers |= MOD_NODEREF;
177 return;
179 if (match_string_ident(attribute, "address_space")) {
180 ctype->as = get_expression_value(expr);
181 return;
183 if (match_string_ident(attribute, "context")) {
184 if (expr->type == EXPR_COMMA) {
185 int mask = get_expression_value(expr->left);
186 int value = get_expression_value(expr->right);
187 if (value & ~mask) {
188 warn(expr->pos, "nonsense attribute types");
189 return;
191 ctype->contextmask |= mask;
192 ctype->context |= value;
193 return;
199 struct token *attribute_specifier(struct token *token, struct ctype *ctype)
201 token = expect(token, '(', "after attribute");
202 token = expect(token, '(', "after attribute");
204 for (;;) {
205 struct ident *attribute_name;
206 struct expression *attribute_expr;
208 if (eof_token(token))
209 break;
210 if (match_op(token, ';'))
211 break;
212 if (token_type(token) != TOKEN_IDENT)
213 break;
214 attribute_name = token->ident;
215 token = token->next;
216 attribute_expr = NULL;
217 if (match_op(token, '('))
218 token = parens_expression(token, &attribute_expr, "in attribute");
219 handle_attribute(ctype, attribute_name, attribute_expr);
220 if (!match_op(token, ','))
221 break;
222 token = token->next;
225 token = expect(token, ')', "after attribute");
226 token = expect(token, ')', "after attribute");
227 return token;
230 #define MOD_SPECIALBITS (MOD_STRUCTOF | MOD_UNIONOF | MOD_ENUMOF | MOD_ATTRIBUTE | MOD_TYPEOF)
231 #define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | MOD_SIGNED | MOD_UNSIGNED)
233 struct symbol * ctype_integer(unsigned int spec)
235 static struct symbol *const integer_ctypes[][2] = {
236 { &llong_ctype, &ullong_ctype },
237 { &long_ctype, &ulong_ctype },
238 { &short_ctype, &ushort_ctype },
239 { &char_ctype, &uchar_ctype },
240 { &int_ctype, &uint_ctype },
242 struct symbol *const (*ctype)[2];
244 ctype = integer_ctypes;
245 if (!(spec & MOD_LONGLONG)) {
246 ctype++;
247 if (!(spec & MOD_LONG)) {
248 ctype++;
249 if (!(spec & MOD_SHORT)) {
250 ctype++;
251 if (!(spec & MOD_CHAR))
252 ctype++;
256 return ctype[0][(spec & MOD_UNSIGNED) != 0];
259 struct symbol * ctype_fp(unsigned int spec)
261 if (spec & MOD_LONGLONG)
262 return &ldouble_ctype;
263 if (spec & MOD_LONG)
264 return &double_ctype;
265 return &float_ctype;
268 static void apply_ctype(struct position pos, struct ctype *thistype, struct ctype *ctype)
270 unsigned long mod = thistype->modifiers;
272 if (mod) {
273 unsigned long old = ctype->modifiers;
274 unsigned long extra = 0, dup;
276 if (mod & old & MOD_LONG) {
277 extra = MOD_LONGLONG | MOD_LONG;
278 mod &= ~MOD_LONG;
279 old &= ~MOD_LONG;
281 dup = (mod & old) | (extra & old) | (extra & mod);
282 if (dup)
283 warn(pos, "Just how %sdo you want this type to be?",
284 modifier_string(dup));
285 ctype->modifiers = old | mod | extra;
288 /* Context mask and value */
289 if ((ctype->context ^ thistype->context) & (ctype->contextmask & thistype->contextmask)) {
290 warn(pos, "inconsistend attribute types");
291 thistype->context = 0;
292 thistype->contextmask = 0;
294 ctype->context |= thistype->context;
295 ctype->contextmask |= thistype->contextmask;
297 /* Alignment */
298 if (thistype->alignment & (thistype->alignment-1)) {
299 warn(pos, "I don't like non-power-of-2 alignments");
300 thistype->alignment = 0;
302 if (thistype->alignment > ctype->alignment)
303 ctype->alignment = thistype->alignment;
305 /* Address space */
306 ctype->as = thistype->as;
310 static struct token *declaration_specifiers(struct token *next, struct ctype *ctype, int qual)
312 struct token *token;
314 while ( (token = next) != NULL ) {
315 struct ctype thistype;
316 struct ident *ident;
317 struct symbol *s, *type;
318 unsigned long mod;
320 next = token->next;
321 if (token_type(token) != TOKEN_IDENT)
322 break;
323 ident = token->ident;
325 s = lookup_symbol(ident, NS_TYPEDEF);
326 if (!s)
327 break;
328 thistype = s->ctype;
329 mod = thistype.modifiers;
330 if (qual && (mod & ~(MOD_ATTRIBUTE | MOD_CONST | MOD_VOLATILE)))
331 break;
332 if (mod & MOD_SPECIALBITS) {
333 if (mod & MOD_STRUCTOF)
334 next = struct_or_union_specifier(SYM_STRUCT, next, &thistype);
335 else if (mod & MOD_UNIONOF)
336 next = struct_or_union_specifier(SYM_UNION, next, &thistype);
337 else if (mod & MOD_ENUMOF)
338 next = enum_specifier(next, &thistype);
339 else if (mod & MOD_ATTRIBUTE)
340 next = attribute_specifier(next, &thistype);
341 else if (mod & MOD_TYPEOF)
342 next = typeof_specifier(next, &thistype);
343 mod = thistype.modifiers;
345 type = thistype.base_type;
346 if (type) {
347 if (qual)
348 break;
349 if (type != ctype->base_type) {
350 if (ctype->base_type) {
351 warn(token->pos, "Strange mix of types");
352 continue;
354 ctype->base_type = type;
358 apply_ctype(token->pos, &thistype, ctype);
361 /* Turn the "virtual types" into real types with real sizes etc */
362 if (!ctype->base_type && (ctype->modifiers & MOD_SPECIFIER))
363 ctype->base_type = &int_type;
365 if (ctype->base_type == &int_type) {
366 ctype->base_type = ctype_integer(ctype->modifiers & MOD_SPECIFIER);
367 ctype->modifiers &= ~MOD_SPECIFIER;
368 return token;
370 if (ctype->base_type == &fp_type) {
371 ctype->base_type = ctype_fp(ctype->modifiers & MOD_SPECIFIER);
372 ctype->modifiers &= ~MOD_SPECIFIER;
373 return token;
375 return token;
378 static struct token *abstract_array_declarator(struct token *token, struct symbol *sym)
380 struct expression *expr = NULL;
382 token = parse_expression(token, &expr);
383 if (expr)
384 sym->array_size = get_expression_value(expr);
385 else
386 sym->array_size = -1;
387 return token;
390 static struct token *parameter_type_list(struct token *, struct symbol *);
391 static struct token *declarator(struct token *token, struct symbol **tree, struct ident **p);
393 static struct token *direct_declarator(struct token *token, struct symbol **tree, struct ident **p)
395 struct ctype *ctype = &(*tree)->ctype;
397 if (p && token_type(token) == TOKEN_IDENT) {
398 *p = token->ident;
399 token = token->next;
402 for (;;) {
403 if (match_ident(token, &__attribute___ident) || match_ident(token, &__attribute_ident)) {
404 struct ctype thistype = { 0, };
405 token = attribute_specifier(token->next, &thistype);
406 apply_ctype(token->pos, &thistype, ctype);
407 continue;
409 if (token_type(token) != TOKEN_SPECIAL)
410 return token;
413 * This can be either a parameter list or a grouping.
414 * For the direct (non-abstract) case, we know if must be
415 * a paramter list if we already saw the identifier.
416 * For the abstract case, we know if must be a parameter
417 * list if it is empty or starts with a type.
419 if (token->special == '(') {
420 struct symbol *sym;
421 struct token *next = token->next;
422 int fn = (p && *p) || match_op(next, ')') || lookup_type(next);
424 if (!fn) {
425 struct symbol *base_type = ctype->base_type;
426 token = declarator(next, tree, p);
427 token = expect(token, ')', "in nested declarator");
428 while (ctype->base_type != base_type)
429 ctype = &ctype->base_type->ctype;
430 p = NULL;
431 continue;
434 sym = indirect(token->pos, ctype, SYM_FN);
435 token = parameter_type_list(next, sym);
436 token = expect(token, ')', "in function declarator");
437 continue;
439 if (token->special == '[') {
440 struct symbol *array = indirect(token->pos, ctype, SYM_ARRAY);
441 token = abstract_array_declarator(token->next, array);
442 token = expect(token, ']', "in abstract_array_declarator");
443 continue;
445 if (token->special == ':') {
446 struct symbol *bitfield;
447 struct expression *expr;
448 bitfield = indirect(token->pos, ctype, SYM_BITFIELD);
449 token = conditional_expression(token->next, &expr);
450 bitfield->fieldwidth = get_expression_value(expr);
451 continue;
453 break;
455 if (p) {
456 (*tree)->ident = *p;
458 return token;
461 static struct token *pointer(struct token *token, struct ctype *ctype)
463 unsigned long modifiers;
464 struct symbol *base_type;
466 modifiers = ctype->modifiers & ~(MOD_TYPEDEF | MOD_ATTRIBUTE);
467 base_type = ctype->base_type;
468 ctype->modifiers = modifiers;
470 while (match_op(token,'*')) {
471 struct symbol *ptr = alloc_symbol(token->pos, SYM_PTR);
472 ptr->ctype.modifiers = modifiers & ~MOD_STORAGE;
473 ptr->ctype.base_type = base_type;
475 base_type = ptr;
476 ctype->modifiers = modifiers & MOD_STORAGE;
477 ctype->base_type = base_type;
479 token = declaration_specifiers(token->next, ctype, 1);
481 return token;
484 static struct token *declarator(struct token *token, struct symbol **tree, struct ident **p)
486 token = pointer(token, &(*tree)->ctype);
487 return direct_declarator(token, tree, p);
490 static struct token *struct_declaration_list(struct token *token, struct symbol_list **list)
492 while (!match_op(token, '}')) {
493 struct ctype ctype = {0, };
495 token = declaration_specifiers(token, &ctype, 0);
496 for (;;) {
497 struct ident *ident = NULL;
498 struct symbol *decl = alloc_symbol(token->pos, SYM_NODE);
499 decl->ctype = ctype;
500 token = pointer(token, &decl->ctype);
501 token = direct_declarator(token, &decl, &ident);
502 if (match_op(token, ':')) {
503 struct expression *expr;
504 token = parse_expression(token->next, &expr);
506 add_symbol(list, decl);
507 if (!match_op(token, ','))
508 break;
509 token = token->next;
511 if (!match_op(token, ';'))
512 break;
513 token = token->next;
515 return token;
518 static struct token *parameter_declaration(struct token *token, struct symbol **tree)
520 struct ident *ident = NULL;
521 struct symbol *sym;
522 struct ctype ctype = { 0, };
524 token = declaration_specifiers(token, &ctype, 0);
525 sym = alloc_symbol(token->pos, SYM_NODE);
526 sym->ctype = ctype;
527 *tree = sym;
528 token = pointer(token, &sym->ctype);
529 token = direct_declarator(token, tree, &ident);
530 return token;
533 struct token *typename(struct token *token, struct symbol **p)
535 struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
536 *p = sym;
537 token = declaration_specifiers(token, &sym->ctype, 0);
538 return declarator(token, &sym, NULL);
541 struct token *expression_statement(struct token *token, struct expression **tree)
543 token = parse_expression(token, tree);
544 return expect(token, ';', "at end of statement");
547 static struct token *parse_asm_operands(struct token *token, struct statement *stmt)
549 struct expression *expr;
551 /* Allow empty operands */
552 if (match_op(token->next, ':') || match_op(token->next, ')'))
553 return token->next;
554 do {
555 token = primary_expression(token->next, &expr);
556 token = parens_expression(token, &expr, "in asm parameter");
557 } while (match_op(token, ','));
558 return token;
561 static struct token *parse_asm_clobbers(struct token *token, struct statement *stmt)
563 struct expression *expr;
565 do {
566 token = primary_expression(token->next, &expr);
567 } while (match_op(token, ','));
568 return token;
571 /* Make a statement out of an expression */
572 static struct statement *make_statement(struct expression *expr)
574 struct statement *stmt;
576 if (!expr)
577 return NULL;
578 stmt = alloc_statement(expr->pos, STMT_EXPRESSION);
579 stmt->expression = expr;
580 return stmt;
583 struct token *statement(struct token *token, struct statement **tree)
585 struct statement *stmt = alloc_statement(token->pos, STMT_NONE);
587 *tree = stmt;
588 if (token_type(token) == TOKEN_IDENT) {
589 if (token->ident == &if_ident) {
590 stmt->type = STMT_IF;
591 token = parens_expression(token->next, &stmt->if_conditional, "after if");
592 token = statement(token, &stmt->if_true);
593 if (token_type(token) != TOKEN_IDENT)
594 return token;
595 if (token->ident != &else_ident)
596 return token;
597 return statement(token->next, &stmt->if_false);
599 if (token->ident == &return_ident) {
600 stmt->type = STMT_RETURN;
601 return expression_statement(token->next, &stmt->expression);
603 if (token->ident == &break_ident) {
604 stmt->type = STMT_BREAK;
605 return expect(token->next, ';', "at end of statement");
607 if (token->ident == &continue_ident) {
608 stmt->type = STMT_CONTINUE;
609 return expect(token->next, ';', "at end of statement");
611 if (token->ident == &default_ident) {
612 token = token->next;
613 goto default_statement;
615 if (token->ident == &case_ident) {
616 token = parse_expression(token->next, &stmt->case_expression);
617 if (match_op(token, SPECIAL_ELLIPSIS))
618 token = parse_expression(token->next, &stmt->case_to);
619 default_statement:
620 stmt->type = STMT_CASE;
621 token = expect(token, ':', "after default/case");
622 return statement(token, &stmt->case_statement);
624 if (token->ident == &switch_ident) {
625 stmt->type = STMT_SWITCH;
626 token = parens_expression(token->next, &stmt->switch_expression, "after 'switch'");
627 return statement(token, &stmt->switch_statement);
629 if (token->ident == &for_ident) {
630 struct expression *e1, *e2, *e3;
631 struct statement *iterator;
633 token = expect(token->next, '(', "after 'for'");
634 token = parse_expression(token, &e1);
635 token = expect(token, ';', "in 'for'");
636 token = parse_expression(token, &e2);
637 token = expect(token, ';', "in 'for'");
638 token = parse_expression(token, &e3);
639 token = expect(token, ')', "in 'for'");
640 token = statement(token, &iterator);
642 stmt->type = STMT_ITERATOR;
643 stmt->iterator_pre_statement = make_statement(e1);
644 stmt->iterator_pre_condition = e2;
645 stmt->iterator_post_statement = make_statement(e3);
646 stmt->iterator_post_condition = e2;
647 stmt->iterator_statement = iterator;
649 return token;
651 if (token->ident == &while_ident) {
652 struct expression *expr;
653 struct statement *iterator;
655 token = parens_expression(token->next, &expr, "after 'while'");
656 token = statement(token, &iterator);
658 stmt->type = STMT_ITERATOR;
659 stmt->iterator_pre_condition = expr;
660 stmt->iterator_post_condition = expr;
661 stmt->iterator_statement = iterator;
663 return token;
665 if (token->ident == &do_ident) {
666 struct expression *expr;
667 struct statement *iterator;
669 token = statement(token->next, &iterator);
670 if (token_type(token) == TOKEN_IDENT && token->ident == &while_ident)
671 token = token->next;
672 else
673 warn(token->pos, "expected 'while' after 'do'");
674 token = parens_expression(token, &expr, "after 'do-while'");
676 stmt->type = STMT_ITERATOR;
677 stmt->iterator_post_condition = expr;
678 stmt->iterator_statement = iterator;
680 return expect(token, ';', "after statement");
682 if (token->ident == &goto_ident) {
683 stmt->type = STMT_GOTO;
684 token = token->next;
685 if (token_type(token) == TOKEN_IDENT) {
686 stmt->goto_label = label_symbol(token);
687 token = token->next;
688 } else
689 warn(token->pos, "invalid label");
690 return expect(token, ';', "at end of statement");
692 if (token->ident == &asm_ident || token->ident == &__asm___ident || token->ident == &__asm_ident) {
693 struct expression *expr;
694 stmt->type = STMT_ASM;
695 token = token->next;
696 if (token_type(token) == TOKEN_IDENT) {
697 if (token->ident == &__volatile___ident || token->ident == &volatile_ident)
698 token = token->next;
700 token = expect(token, '(', "after asm");
701 token = parse_expression(token->next, &expr);
702 if (match_op(token, ':'))
703 token = parse_asm_operands(token, stmt);
704 if (match_op(token, ':'))
705 token = parse_asm_operands(token, stmt);
706 if (match_op(token, ':'))
707 token = parse_asm_clobbers(token, stmt);
708 token = expect(token, ')', "after asm");
709 return expect(token, ';', "at end of asm-statement");
711 if (match_op(token->next, ':')) {
712 stmt->type = STMT_LABEL;
713 stmt->label_identifier = label_symbol(token);
714 return statement(token->next->next, &stmt->label_statement);
718 if (match_op(token, '{')) {
719 stmt->type = STMT_COMPOUND;
720 start_symbol_scope();
721 token = compound_statement(token->next, stmt);
722 end_symbol_scope();
724 return expect(token, '}', "at end of compound statement");
727 stmt->type = STMT_EXPRESSION;
728 return expression_statement(token, &stmt->expression);
731 struct token * statement_list(struct token *token, struct statement_list **list)
733 for (;;) {
734 struct statement * stmt;
735 if (eof_token(token))
736 break;
737 if (match_op(token, '}'))
738 break;
739 token = statement(token, &stmt);
740 add_statement(list, stmt);
742 return token;
745 static struct token *parameter_type_list(struct token *token, struct symbol *fn)
747 struct symbol_list **list = &fn->arguments;
748 for (;;) {
749 struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
751 if (match_op(token, SPECIAL_ELLIPSIS)) {
752 fn->variadic = 1;
753 token = token->next;
754 break;
757 token = parameter_declaration(token, &sym);
758 /* Special case: (void) */
759 if (!*list && !sym->ident && sym->ctype.base_type == &void_ctype)
760 break;
761 add_symbol(list, sym);
762 if (!match_op(token, ','))
763 break;
764 token = token->next;
767 return token;
770 static struct token *external_declaration(struct token *token, struct symbol_list **list);
772 struct token *compound_statement(struct token *token, struct statement *stmt)
774 while (!eof_token(token)) {
775 if (!lookup_type(token))
776 break;
777 token = external_declaration(token, &stmt->syms);
779 token = statement_list(token, &stmt->stmts);
780 return token;
783 static struct expression *identifier_expression(struct token *token)
785 struct expression *expr = alloc_expression(token->pos, EXPR_IDENTIFIER);
786 expr->expr_ident = token->ident;
787 return expr;
790 static struct expression *index_expression(struct expression *from, struct expression *to)
792 int idx_from, idx_to;
793 struct expression *expr = alloc_expression(from->pos, EXPR_INDEX);
795 idx_from = get_expression_value(from);
796 idx_to = idx_from;
797 if (to) {
798 idx_to = get_expression_value(to);
799 if (idx_to < idx_from)
800 warn(from->pos, "nonsense array initializer index range");
802 expr->idx_from = idx_from;
803 expr->idx_to = idx_to;
804 return expr;
807 static struct token *initializer_list(struct expression_list **list, struct token *token)
809 for (;;) {
810 struct token *next = token->next;
811 struct expression *expr;
813 if (match_op(token, '.') && (token_type(next) == TOKEN_IDENT) && match_op(next->next, '=')) {
814 add_expression(list, identifier_expression(next));
815 token = next->next->next;
816 } else if ((token_type(token) == TOKEN_IDENT) && match_op(next, ':')) {
817 add_expression(list, identifier_expression(token));
818 token = next->next;
819 } else if (match_op(token, '[')) {
820 struct expression *from = NULL, *to = NULL;
821 token = constant_expression(token->next, &from);
822 if (match_op(token, SPECIAL_ELLIPSIS))
823 token = constant_expression(token->next, &to);
824 add_expression(list, index_expression(from, to));
825 token = expect(token, ']', "at end of initializer index");
828 expr = NULL;
829 token = initializer(&expr, token);
830 if (!expr)
831 break;
832 add_expression(list, expr);
833 if (!match_op(token, ','))
834 break;
835 token = token->next;
837 return token;
840 struct token *initializer(struct expression **tree, struct token *token)
842 if (match_op(token, '{')) {
843 struct expression *expr = alloc_expression(token->pos, EXPR_INITIALIZER);
844 *tree = expr;
845 token = initializer_list(&expr->expr_list, token->next);
846 return expect(token, '}', "at end of initializer");
848 return assignment_expression(token, tree);
851 static void declare_argument(struct symbol *sym, void *data, int flags)
853 struct symbol *decl = data;
855 if (!sym->ident) {
856 warn(decl->pos, "no identifier for function argument");
857 return;
859 bind_symbol(sym, sym->ident, NS_SYMBOL);
862 static struct token *external_declaration(struct token *token, struct symbol_list **list)
864 struct ident *ident = NULL;
865 struct symbol *decl;
866 struct ctype ctype = { 0, };
867 struct symbol *base_type;
869 /* Parse declaration-specifiers, if any */
870 token = declaration_specifiers(token, &ctype, 0);
871 decl = alloc_symbol(token->pos, SYM_NODE);
872 decl->ctype = ctype;
873 token = pointer(token, &decl->ctype);
874 token = declarator(token, &decl, &ident);
876 /* Just a type declaration? */
877 if (!ident)
878 return expect(token, ';', "end of type declaration");
880 decl->ident = ident;
882 /* type define declaration? */
883 bind_symbol(decl, ident, (ctype.modifiers & MOD_TYPEDEF) ? NS_TYPEDEF: NS_SYMBOL);
885 base_type = decl->ctype.base_type;
886 if (base_type && base_type->type == SYM_FN) {
887 if (match_op(token, '{')) {
888 if (decl->ctype.modifiers & MOD_EXTERN) {
889 if (!(decl->ctype.modifiers & MOD_INLINE))
890 warn(decl->pos, "function with external linkage has definition");
891 decl->ctype.modifiers &= ~MOD_EXTERN;
893 base_type->stmt = alloc_statement(token->pos, STMT_COMPOUND);
894 start_function_scope();
895 symbol_iterate(base_type->arguments, declare_argument, decl);
896 token = compound_statement(token->next, base_type->stmt);
897 end_function_scope();
898 add_symbol(list, decl);
899 return expect(token, '}', "at end of function");
901 decl->ctype.modifiers |= MOD_EXTERN;
904 for (;;) {
905 if (match_op(token, '=')) {
906 if (decl->ctype.modifiers & MOD_EXTERN) {
907 warn(decl->pos, "symbol with external linkage has initializer");
908 decl->ctype.modifiers &= ~MOD_EXTERN;
910 token = initializer(&decl->initializer, token->next);
912 if (!(decl->ctype.modifiers & MOD_EXTERN)) {
913 if (!(ctype.modifiers & MOD_TYPEDEF))
914 add_symbol(list, decl);
917 if (!match_op(token, ','))
918 break;
920 ident = NULL;
921 decl = alloc_symbol(token->pos, SYM_NODE);
922 decl->ctype = ctype;
923 token = pointer(token, &decl->ctype);
924 token = declarator(token->next, &decl, &ident);
925 if (!ident) {
926 warn(token->pos, "expected identifier name in type definition");
927 return token;
930 bind_symbol(decl, ident, (ctype.modifiers & MOD_TYPEDEF) ? NS_TYPEDEF: NS_SYMBOL);
932 return expect(token, ';', "at end of declaration");
935 void translation_unit(struct token *token, struct symbol_list **list)
937 while (!eof_token(token))
938 token = external_declaration(token, list);
939 // They aren't needed any more
940 clear_token_alloc();