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.
22 #include "expression.h"
24 struct statement
*alloc_statement(struct position pos
, int type
)
26 struct statement
*stmt
= __alloc_statement(0);
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
;
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
);
50 sym
= alloc_symbol(token
->pos
, type
);
51 sym
->ident
= token
->ident
;
52 bind_symbol(sym
, token
->ident
, ns
);
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
*))
74 if (token_type(token
) == TOKEN_IDENT
) {
75 sym
= lookup_or_create_symbol(ns
, type
, token
);
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");
85 // private struct/union/enum type
86 if (!match_op(token
, '{')) {
87 warn(token
->pos
, "expected declaration");
88 ctype
->base_type
= &bad_type
;
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
)
111 while (token_type(token
) == TOKEN_IDENT
) {
112 struct token
*next
= token
->next
;
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
;
127 if (!match_op(token
, ','))
130 nextval
= nextval
+ 1;
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
)
144 if (!match_op(token
, '(')) {
145 warn(token
->pos
, "expected '(' after typeof");
148 if (lookup_type(token
->next
)) {
149 token
= typename(token
->next
, &sym
);
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;
167 if (match_string_ident(attribute
, "aligned")) {
168 ctype
->alignment
= get_expression_value(expr
);
171 if (match_string_ident(attribute
, "nocast")) {
172 ctype
->modifiers
|= MOD_NOCAST
;
175 if (match_string_ident(attribute
, "noderef")) {
176 ctype
->modifiers
|= MOD_NODEREF
;
179 if (match_string_ident(attribute
, "address_space")) {
180 ctype
->as
= get_expression_value(expr
);
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
);
188 warn(expr
->pos
, "nonsense attribute types");
191 ctype
->contextmask
|= mask
;
192 ctype
->context
|= value
;
199 struct token
*attribute_specifier(struct token
*token
, struct ctype
*ctype
)
201 token
= expect(token
, '(', "after attribute");
202 token
= expect(token
, '(', "after attribute");
205 struct ident
*attribute_name
;
206 struct expression
*attribute_expr
;
208 if (eof_token(token
))
210 if (match_op(token
, ';'))
212 if (token_type(token
) != TOKEN_IDENT
)
214 attribute_name
= token
->ident
;
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
, ','))
225 token
= expect(token
, ')', "after attribute");
226 token
= expect(token
, ')', "after attribute");
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
)) {
247 if (!(spec
& MOD_LONG
)) {
249 if (!(spec
& MOD_SHORT
)) {
251 if (!(spec
& MOD_CHAR
))
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
;
264 return &double_ctype
;
268 static void apply_ctype(struct position pos
, struct ctype
*thistype
, struct ctype
*ctype
)
270 unsigned long mod
= thistype
->modifiers
;
273 unsigned long old
= ctype
->modifiers
;
274 unsigned long extra
= 0, dup
;
276 if (mod
& old
& MOD_LONG
) {
277 extra
= MOD_LONGLONG
| MOD_LONG
;
281 dup
= (mod
& old
) | (extra
& old
) | (extra
& mod
);
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
;
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
;
306 ctype
->as
= thistype
->as
;
310 static struct token
*declaration_specifiers(struct token
*next
, struct ctype
*ctype
, int qual
)
314 while ( (token
= next
) != NULL
) {
315 struct ctype thistype
;
317 struct symbol
*s
, *type
;
321 if (token_type(token
) != TOKEN_IDENT
)
323 ident
= token
->ident
;
325 s
= lookup_symbol(ident
, NS_TYPEDEF
);
329 mod
= thistype
.modifiers
;
330 if (qual
&& (mod
& ~(MOD_ATTRIBUTE
| MOD_CONST
| MOD_VOLATILE
)))
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
;
349 if (type
!= ctype
->base_type
) {
350 if (ctype
->base_type
) {
351 warn(token
->pos
, "Strange mix of types");
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
;
370 if (ctype
->base_type
== &fp_type
) {
371 ctype
->base_type
= ctype_fp(ctype
->modifiers
& MOD_SPECIFIER
);
372 ctype
->modifiers
&= ~MOD_SPECIFIER
;
378 static struct token
*abstract_array_declarator(struct token
*token
, struct symbol
*sym
)
380 struct expression
*expr
= NULL
;
382 token
= parse_expression(token
, &expr
);
384 sym
->array_size
= get_expression_value(expr
);
386 sym
->array_size
= -1;
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
) {
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
);
409 if (token_type(token
) != TOKEN_SPECIAL
)
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
== '(') {
421 struct token
*next
= token
->next
;
422 int fn
= (p
&& *p
) || match_op(next
, ')') || lookup_type(next
);
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
;
434 sym
= indirect(token
->pos
, ctype
, SYM_FN
);
435 token
= parameter_type_list(next
, sym
);
436 token
= expect(token
, ')', "in function declarator");
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");
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
);
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
;
476 ctype
->modifiers
= modifiers
& MOD_STORAGE
;
477 ctype
->base_type
= base_type
;
479 token
= declaration_specifiers(token
->next
, ctype
, 1);
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);
497 struct ident
*ident
= NULL
;
498 struct symbol
*decl
= alloc_symbol(token
->pos
, SYM_NODE
);
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
, ','))
511 if (!match_op(token
, ';'))
518 static struct token
*parameter_declaration(struct token
*token
, struct symbol
**tree
)
520 struct ident
*ident
= NULL
;
522 struct ctype ctype
= { 0, };
524 token
= declaration_specifiers(token
, &ctype
, 0);
525 sym
= alloc_symbol(token
->pos
, SYM_NODE
);
528 token
= pointer(token
, &sym
->ctype
);
529 token
= direct_declarator(token
, tree
, &ident
);
533 struct token
*typename(struct token
*token
, struct symbol
**p
)
535 struct symbol
*sym
= alloc_symbol(token
->pos
, SYM_NODE
);
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
, ')'))
555 token
= primary_expression(token
->next
, &expr
);
556 token
= parens_expression(token
, &expr
, "in asm parameter");
557 } while (match_op(token
, ','));
561 static struct token
*parse_asm_clobbers(struct token
*token
, struct statement
*stmt
)
563 struct expression
*expr
;
566 token
= primary_expression(token
->next
, &expr
);
567 } while (match_op(token
, ','));
571 /* Make a statement out of an expression */
572 static struct statement
*make_statement(struct expression
*expr
)
574 struct statement
*stmt
;
578 stmt
= alloc_statement(expr
->pos
, STMT_EXPRESSION
);
579 stmt
->expression
= expr
;
583 struct token
*statement(struct token
*token
, struct statement
**tree
)
585 struct statement
*stmt
= alloc_statement(token
->pos
, STMT_NONE
);
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
)
595 if (token
->ident
!= &else_ident
)
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
) {
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
);
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
;
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
;
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
)
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
;
685 if (token_type(token
) == TOKEN_IDENT
) {
686 stmt
->goto_label
= label_symbol(token
);
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
;
696 if (token_type(token
) == TOKEN_IDENT
) {
697 if (token
->ident
== &__volatile___ident
|| token
->ident
== &volatile_ident
)
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
);
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
)
734 struct statement
* stmt
;
735 if (eof_token(token
))
737 if (match_op(token
, '}'))
739 token
= statement(token
, &stmt
);
740 add_statement(list
, stmt
);
745 static struct token
*parameter_type_list(struct token
*token
, struct symbol
*fn
)
747 struct symbol_list
**list
= &fn
->arguments
;
749 struct symbol
*sym
= alloc_symbol(token
->pos
, SYM_NODE
);
751 if (match_op(token
, SPECIAL_ELLIPSIS
)) {
757 token
= parameter_declaration(token
, &sym
);
758 /* Special case: (void) */
759 if (!*list
&& !sym
->ident
&& sym
->ctype
.base_type
== &void_ctype
)
761 add_symbol(list
, sym
);
762 if (!match_op(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
))
777 token
= external_declaration(token
, &stmt
->syms
);
779 token
= statement_list(token
, &stmt
->stmts
);
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
;
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
);
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
;
807 static struct token
*initializer_list(struct expression_list
**list
, struct token
*token
)
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
));
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");
829 token
= initializer(&expr
, token
);
832 add_expression(list
, expr
);
833 if (!match_op(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
);
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
;
856 warn(decl
->pos
, "no identifier for function argument");
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
;
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
);
873 token
= pointer(token
, &decl
->ctype
);
874 token
= declarator(token
, &decl
, &ident
);
876 /* Just a type declaration? */
878 return expect(token
, ';', "end of type declaration");
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
;
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
, ','))
921 decl
= alloc_symbol(token
->pos
, SYM_NODE
);
923 token
= pointer(token
, &decl
->ctype
);
924 token
= declarator(token
->next
, &decl
, &ident
);
926 warn(token
->pos
, "expected identifier name in type definition");
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