2 * Stupid C parser, version 1e-6.
4 * Let's see how hard this is to do.
6 * Copyright (C) 2003 Transmeta Corp.
9 * Licensed under the Open Software License version 1.1
25 #include "expression.h"
28 static struct symbol_list
**function_symbol_list
;
29 struct symbol_list
*function_computed_target_list
;
30 struct statement_list
*function_computed_goto_list
;
32 // Add a symbol to the list of function-local symbols
33 #define fn_local_symbol(x) add_symbol(function_symbol_list, (x))
35 static struct token
*statement(struct token
*token
, struct statement
**tree
);
36 static struct token
*external_declaration(struct token
*token
, struct symbol_list
**list
);
38 static int match_idents(struct token
*token
, ...)
42 if (token_type(token
) != TOKEN_IDENT
)
45 va_start(args
, token
);
47 struct ident
* next
= va_arg(args
, struct ident
*);
50 if (token
->ident
== next
)
56 struct statement
*alloc_statement(struct position pos
, int type
)
58 struct statement
*stmt
= __alloc_statement(0);
64 static struct token
*struct_declaration_list(struct token
*token
, struct symbol_list
**list
);
66 static struct symbol
* indirect(struct position pos
, struct ctype
*ctype
, int type
)
68 struct symbol
*sym
= alloc_symbol(pos
, type
);
70 sym
->ctype
.base_type
= ctype
->base_type
;
71 sym
->ctype
.modifiers
= ctype
->modifiers
& ~MOD_STORAGE
;
73 ctype
->base_type
= sym
;
74 ctype
->modifiers
&= MOD_STORAGE
;
78 static struct symbol
*lookup_or_create_symbol(enum namespace ns
, enum type type
, struct token
*token
)
80 struct symbol
*sym
= lookup_symbol(token
->ident
, ns
);
82 sym
= alloc_symbol(token
->pos
, type
);
83 sym
->ident
= token
->ident
;
84 bind_symbol(sym
, token
->ident
, ns
);
85 if (type
== SYM_LABEL
)
92 * NOTE! NS_LABEL is not just a different namespace,
93 * it also ends up using function scope instead of the
94 * regular symbol scope.
96 struct symbol
*label_symbol(struct token
*token
)
98 return lookup_or_create_symbol(NS_LABEL
, SYM_LABEL
, token
);
101 struct token
*struct_union_enum_specifier(enum type type
,
102 struct token
*token
, struct ctype
*ctype
,
103 struct token
*(*parse
)(struct token
*, struct symbol
*))
107 ctype
->modifiers
= 0;
108 if (token_type(token
) == TOKEN_IDENT
) {
109 sym
= lookup_symbol(token
->ident
, NS_STRUCT
);
111 (sym
->scope
!= block_scope
&&
112 (match_op(token
->next
,';') || match_op(token
->next
,'{')))) {
113 // Either a new symbol, or else an out-of-scope
114 // symbol being redefined.
115 sym
= alloc_symbol(token
->pos
, type
);
116 sym
->ident
= token
->ident
;
117 bind_symbol(sym
, token
->ident
, NS_STRUCT
);
119 if (sym
->type
!= type
)
120 error(token
->pos
, "invalid tag applied to %s", show_typename (sym
));
122 ctype
->base_type
= sym
;
123 if (match_op(token
, '{')) {
124 // The following test is actually wrong for empty
125 // structs, but (1) they are not C99, (2) gcc does
126 // the same thing, and (3) it's easier.
127 if (sym
->symbol_list
)
128 error(token
->pos
, "redefinition of %s", show_typename (sym
));
129 token
= parse(token
->next
, sym
);
130 token
= expect(token
, '}', "at end of struct-union-enum-specifier");
135 // private struct/union/enum type
136 if (!match_op(token
, '{')) {
137 warn(token
->pos
, "expected declaration");
138 ctype
->base_type
= &bad_type
;
142 sym
= alloc_symbol(token
->pos
, type
);
143 token
= parse(token
->next
, sym
);
144 ctype
->base_type
= sym
;
145 return expect(token
, '}', "at end of specifier");
148 static struct token
*parse_struct_declaration(struct token
*token
, struct symbol
*sym
)
150 return struct_declaration_list(token
, &sym
->symbol_list
);
153 struct token
*struct_or_union_specifier(enum type type
, struct token
*token
, struct ctype
*ctype
)
155 return struct_union_enum_specifier(type
, token
, ctype
, parse_struct_declaration
);
158 static struct token
*parse_enum_declaration(struct token
*token
, struct symbol
*parent
)
161 while (token_type(token
) == TOKEN_IDENT
) {
162 struct token
*next
= token
->next
;
165 sym
= alloc_symbol(token
->pos
, SYM_ENUM
);
166 bind_symbol(sym
, token
->ident
, NS_SYMBOL
);
167 sym
->ctype
.base_type
= parent
;
168 parent
->ctype
.base_type
= &int_ctype
;
170 if (match_op(next
, '=')) {
171 struct expression
*expr
;
172 next
= constant_expression(next
->next
, &expr
);
173 nextval
= get_expression_value(expr
);
175 sym
->value
= nextval
;
178 if (!match_op(token
, ','))
181 nextval
= nextval
+ 1;
186 struct token
*enum_specifier(struct token
*token
, struct ctype
*ctype
)
188 return struct_union_enum_specifier(SYM_ENUM
, token
, ctype
, parse_enum_declaration
);
191 struct token
*typeof_specifier(struct token
*token
, struct ctype
*ctype
)
195 if (!match_op(token
, '(')) {
196 warn(token
->pos
, "expected '(' after typeof");
199 if (lookup_type(token
->next
)) {
200 token
= typename(token
->next
, &sym
);
203 struct symbol
*typeof_sym
= alloc_symbol(token
->pos
, SYM_TYPEOF
);
204 token
= parse_expression(token
->next
, &typeof_sym
->initializer
);
206 ctype
->modifiers
= 0;
207 ctype
->base_type
= typeof_sym
;
209 return expect(token
, ')', "after typeof");
212 static const char * handle_attribute(struct ctype
*ctype
, struct ident
*attribute
, struct expression
*expr
)
214 if (attribute
== &packed_ident
||
215 attribute
== &__packed___ident
) {
216 ctype
->alignment
= 1;
219 if (attribute
== &aligned_ident
||
220 attribute
== &__aligned___ident
) {
221 int alignment
= max_alignment
;
223 alignment
= get_expression_value(expr
);
224 ctype
->alignment
= alignment
;
227 if (attribute
== &nocast_ident
) {
228 ctype
->modifiers
|= MOD_NOCAST
;
231 if (attribute
== &noderef_ident
) {
232 ctype
->modifiers
|= MOD_NODEREF
;
235 if (attribute
== &safe_ident
) {
236 ctype
->modifiers
|= MOD_SAFE
;
239 if (attribute
== &force_ident
) {
240 ctype
->modifiers
|= MOD_FORCE
;
243 if (attribute
== &address_space_ident
) {
245 return "expected address space number";
246 ctype
->as
= get_expression_value(expr
);
249 if (attribute
== &context_ident
) {
250 if (expr
&& expr
->type
== EXPR_COMMA
) {
251 int mask
= get_expression_value(expr
->left
);
252 int value
= get_expression_value(expr
->right
);
254 return "nonsense attribute types";
255 ctype
->contextmask
|= mask
;
256 ctype
->context
|= value
;
259 return "expected context mask and value";
261 if (attribute
== &mode_ident
||
262 attribute
== &__mode___ident
) {
263 if (expr
&& expr
->type
== EXPR_SYMBOL
) {
264 struct ident
*ident
= expr
->symbol_name
;
267 * Match against __QI__/__HI__/__SI__/__DI__
269 * FIXME! This is broken - we don't actually get
270 * the type information updated properly at this
271 * stage for some reason.
273 if (ident
== &__QI___ident
||
274 ident
== &QI_ident
) {
275 ctype
->modifiers
|= MOD_CHAR
;
276 ctype
->base_type
= ctype_integer(ctype
->modifiers
);
279 if (ident
== &__HI___ident
||
280 ident
== &HI_ident
) {
281 ctype
->modifiers
|= MOD_SHORT
;
282 ctype
->base_type
= ctype_integer(ctype
->modifiers
);
285 if (ident
== &__SI___ident
||
286 ident
== &SI_ident
) {
290 if (ident
== &__DI___ident
||
291 ident
== &DI_ident
) {
292 ctype
->modifiers
|= MOD_LONGLONG
;
293 ctype
->base_type
= ctype_integer(ctype
->modifiers
);
296 if (ident
== &__word___ident
||
297 ident
== &word_ident
) {
298 ctype
->modifiers
|= MOD_LONG
;
299 ctype
->base_type
= ctype_integer(ctype
->modifiers
);
302 return "unknown mode attribute";
304 return "expected attribute mode symbol";
307 /* Throw away for now.. */
308 if (attribute
== &format_ident
||
309 attribute
== &__format___ident
)
311 if (attribute
== §ion_ident
||
312 attribute
== &__section___ident
)
314 if (attribute
== &unused_ident
||
315 attribute
== &__unused___ident
)
317 if (attribute
== &const_ident
||
318 attribute
== &__const_ident
||
319 attribute
== &__const___ident
)
321 if (attribute
== &noreturn_ident
||
322 attribute
== &__noreturn___ident
)
324 if (attribute
== ®parm_ident
)
326 if (attribute
== &weak_ident
)
328 if (attribute
== &alias_ident
)
330 if (attribute
== &pure_ident
)
332 if (attribute
== &always_inline_ident
)
334 if (attribute
== &syscall_linkage_ident
)
336 if (attribute
== &visibility_ident
)
339 return "unknown attribute";
342 struct token
*attribute_specifier(struct token
*token
, struct ctype
*ctype
)
344 ctype
->modifiers
= 0;
345 token
= expect(token
, '(', "after attribute");
346 token
= expect(token
, '(', "after attribute");
350 struct ident
*attribute_name
;
351 struct expression
*attribute_expr
;
353 if (eof_token(token
))
355 if (match_op(token
, ';'))
357 if (token_type(token
) != TOKEN_IDENT
)
359 attribute_name
= token
->ident
;
361 attribute_expr
= NULL
;
362 if (match_op(token
, '('))
363 token
= parens_expression(token
, &attribute_expr
, "in attribute");
364 error
= handle_attribute(ctype
, attribute_name
, attribute_expr
);
366 warn(token
->pos
, "attribute '%s': %s", show_ident(attribute_name
), error
);
367 if (!match_op(token
, ','))
372 token
= expect(token
, ')', "after attribute");
373 token
= expect(token
, ')', "after attribute");
377 #define MOD_SPECIALBITS (MOD_STRUCTOF | MOD_UNIONOF | MOD_ENUMOF | MOD_ATTRIBUTE | MOD_TYPEOF)
378 #define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | MOD_SIGNED | MOD_UNSIGNED)
380 struct symbol
* ctype_integer(unsigned long spec
)
382 static struct symbol
*const integer_ctypes
[][2] = {
383 { &llong_ctype
, &ullong_ctype
},
384 { &long_ctype
, &ulong_ctype
},
385 { &short_ctype
, &ushort_ctype
},
386 { &char_ctype
, &uchar_ctype
},
387 { &int_ctype
, &uint_ctype
},
389 struct symbol
*const (*ctype
)[2];
391 ctype
= integer_ctypes
;
392 if (!(spec
& MOD_LONGLONG
)) {
394 if (!(spec
& MOD_LONG
)) {
396 if (!(spec
& MOD_SHORT
)) {
398 if (!(spec
& MOD_CHAR
))
403 return ctype
[0][(spec
& MOD_UNSIGNED
) != 0];
406 struct symbol
* ctype_fp(unsigned long spec
)
408 if (spec
& MOD_LONGLONG
)
409 return &ldouble_ctype
;
411 return &double_ctype
;
415 static void apply_ctype(struct position pos
, struct ctype
*thistype
, struct ctype
*ctype
)
417 unsigned long mod
= thistype
->modifiers
;
420 unsigned long old
= ctype
->modifiers
;
421 unsigned long extra
= 0, dup
, conflict
;
423 if (mod
& old
& MOD_LONG
) {
424 extra
= MOD_LONGLONG
| MOD_LONG
;
428 dup
= (mod
& old
) | (extra
& old
) | (extra
& mod
);
430 warn(pos
, "Just how %sdo you want this type to be?",
431 modifier_string(dup
));
433 conflict
= !(~mod
& ~old
& (MOD_LONG
| MOD_SHORT
));
435 warn(pos
, "You cannot have both long and short modifiers.");
437 conflict
= !(~mod
& ~old
& (MOD_SIGNED
| MOD_UNSIGNED
));
439 warn(pos
, "You cannot have both signed and unsigned modifiers.");
441 // Only one storage modifier allowed, except that "inline" doesn't count.
442 conflict
= (mod
| old
) & (MOD_STORAGE
& ~MOD_INLINE
);
443 conflict
&= (conflict
- 1);
445 warn(pos
, "multiple storage classes");
447 ctype
->modifiers
= old
| mod
| extra
;
450 /* Context mask and value */
451 if ((ctype
->context
^ thistype
->context
) & (ctype
->contextmask
& thistype
->contextmask
)) {
452 warn(pos
, "inconsistent attribute types");
453 thistype
->context
= 0;
454 thistype
->contextmask
= 0;
456 ctype
->context
|= thistype
->context
;
457 ctype
->contextmask
|= thistype
->contextmask
;
460 if (thistype
->alignment
& (thistype
->alignment
-1)) {
461 warn(pos
, "I don't like non-power-of-2 alignments");
462 thistype
->alignment
= 0;
464 if (thistype
->alignment
> ctype
->alignment
)
465 ctype
->alignment
= thistype
->alignment
;
468 ctype
->as
= thistype
->as
;
471 static void check_modifiers(struct position
*pos
, struct symbol
*s
, unsigned long mod
)
473 unsigned long banned
, wrong
;
474 unsigned long this_mod
= s
->ctype
.modifiers
;
475 const unsigned long BANNED_SIZE
= MOD_LONG
| MOD_LONGLONG
| MOD_SHORT
;
476 const unsigned long BANNED_SIGN
= MOD_SIGNED
| MOD_UNSIGNED
;
478 if (this_mod
& (MOD_STRUCTOF
| MOD_UNIONOF
| MOD_ENUMOF
))
479 banned
= BANNED_SIZE
| BANNED_SIGN
;
480 else if (this_mod
& MOD_SPECIALBITS
)
482 else if (s
->ctype
.base_type
== &fp_type
)
483 banned
= BANNED_SIGN
;
484 else if (s
->ctype
.base_type
== &int_type
|| !s
->ctype
.base_type
|| is_int_type (s
))
490 // vector_type <-- whatever that is
491 banned
= BANNED_SIZE
| BANNED_SIGN
;
494 wrong
= mod
& banned
;
496 warn(*pos
, "modifier %sis invalid in this context",
497 modifier_string (wrong
));
501 static struct token
*declaration_specifiers(struct token
*next
, struct ctype
*ctype
, int qual
)
505 while ( (token
= next
) != NULL
) {
506 struct ctype thistype
;
508 struct symbol
*s
, *type
;
512 if (token_type(token
) != TOKEN_IDENT
)
514 ident
= token
->ident
;
516 s
= lookup_symbol(ident
, NS_TYPEDEF
);
520 mod
= thistype
.modifiers
;
521 if (qual
&& (mod
& ~(MOD_ATTRIBUTE
| MOD_CONST
| MOD_VOLATILE
)))
523 if (mod
& MOD_SPECIALBITS
) {
524 if (mod
& MOD_STRUCTOF
)
525 next
= struct_or_union_specifier(SYM_STRUCT
, next
, &thistype
);
526 else if (mod
& MOD_UNIONOF
)
527 next
= struct_or_union_specifier(SYM_UNION
, next
, &thistype
);
528 else if (mod
& MOD_ENUMOF
)
529 next
= enum_specifier(next
, &thistype
);
530 else if (mod
& MOD_ATTRIBUTE
)
531 next
= attribute_specifier(next
, &thistype
);
532 else if (mod
& MOD_TYPEOF
)
533 next
= typeof_specifier(next
, &thistype
);
534 mod
= thistype
.modifiers
;
536 type
= thistype
.base_type
;
540 if (ctype
->base_type
)
542 /* User types only mix with qualifiers */
543 if (mod
& MOD_USERTYPE
) {
544 if (ctype
->modifiers
& MOD_SPECIFIER
)
547 ctype
->base_type
= type
;
550 check_modifiers(&token
->pos
, s
, ctype
->modifiers
);
551 apply_ctype(token
->pos
, &thistype
, ctype
);
554 /* Turn the "virtual types" into real types with real sizes etc */
555 if (!ctype
->base_type
) {
556 struct symbol
*base
= &incomplete_ctype
;
559 * If we have modifiers, we'll default to an integer
560 * type, and "ctype_integer()" will turn this into
563 if (ctype
->modifiers
& MOD_SPECIFIER
)
565 ctype
->base_type
= base
;
568 if (ctype
->base_type
== &int_type
) {
569 ctype
->base_type
= ctype_integer(ctype
->modifiers
);
570 ctype
->modifiers
&= ~MOD_SPECIFIER
;
573 if (ctype
->base_type
== &fp_type
) {
574 ctype
->base_type
= ctype_fp(ctype
->modifiers
& MOD_SPECIFIER
);
575 ctype
->modifiers
&= ~MOD_SPECIFIER
;
581 static struct token
*abstract_array_declarator(struct token
*token
, struct symbol
*sym
)
583 struct expression
*expr
= NULL
;
585 token
= parse_expression(token
, &expr
);
586 sym
->array_size
= expr
;
590 static struct token
*parameter_type_list(struct token
*, struct symbol
*);
591 static struct token
*declarator(struct token
*token
, struct symbol
**tree
, struct ident
**p
);
593 static struct token
*direct_declarator(struct token
*token
, struct symbol
**tree
, struct ident
**p
)
595 struct ctype
*ctype
= &(*tree
)->ctype
;
597 if (p
&& token_type(token
) == TOKEN_IDENT
) {
603 if (match_idents(token
, &__attribute___ident
, &__attribute_ident
, NULL
)) {
604 struct ctype thistype
= { 0, };
605 token
= attribute_specifier(token
->next
, &thistype
);
606 apply_ctype(token
->pos
, &thistype
, ctype
);
609 if (token_type(token
) != TOKEN_SPECIAL
)
613 * This can be either a parameter list or a grouping.
614 * For the direct (non-abstract) case, we know if must be
615 * a parameter list if we already saw the identifier.
616 * For the abstract case, we know if must be a parameter
617 * list if it is empty or starts with a type.
619 if (token
->special
== '(') {
621 struct token
*next
= token
->next
;
622 int fn
= (p
&& *p
) || match_op(next
, ')') || lookup_type(next
);
625 struct symbol
*base_type
= ctype
->base_type
;
626 token
= declarator(next
, tree
, p
);
627 token
= expect(token
, ')', "in nested declarator");
628 while (ctype
->base_type
!= base_type
)
629 ctype
= &ctype
->base_type
->ctype
;
634 sym
= indirect(token
->pos
, ctype
, SYM_FN
);
635 token
= parameter_type_list(next
, sym
);
636 token
= expect(token
, ')', "in function declarator");
639 if (token
->special
== '[') {
640 struct symbol
*array
= indirect(token
->pos
, ctype
, SYM_ARRAY
);
641 token
= abstract_array_declarator(token
->next
, array
);
642 token
= expect(token
, ']', "in abstract_array_declarator");
643 ctype
= &array
->ctype
;
654 static struct token
*pointer(struct token
*token
, struct ctype
*ctype
)
656 unsigned long modifiers
;
657 struct symbol
*base_type
;
659 modifiers
= ctype
->modifiers
& ~(MOD_TYPEDEF
| MOD_ATTRIBUTE
);
660 base_type
= ctype
->base_type
;
661 ctype
->modifiers
= modifiers
;
663 while (match_op(token
,'*')) {
664 struct symbol
*ptr
= alloc_symbol(token
->pos
, SYM_PTR
);
665 ptr
->ctype
.modifiers
= modifiers
& ~MOD_STORAGE
;
666 ptr
->ctype
.as
= ctype
->as
;
667 ptr
->ctype
.context
= ctype
->context
;
668 ptr
->ctype
.contextmask
= ctype
->contextmask
;
669 ptr
->ctype
.base_type
= base_type
;
672 ctype
->modifiers
= modifiers
& MOD_STORAGE
;
673 ctype
->base_type
= base_type
;
676 ctype
->contextmask
= 0;
678 token
= declaration_specifiers(token
->next
, ctype
, 1);
679 modifiers
= ctype
->modifiers
;
684 static struct token
*declarator(struct token
*token
, struct symbol
**tree
, struct ident
**p
)
686 token
= pointer(token
, &(*tree
)->ctype
);
687 return direct_declarator(token
, tree
, p
);
690 static struct token
*struct_declaration_list(struct token
*token
, struct symbol_list
**list
)
692 while (!match_op(token
, '}')) {
693 struct ctype ctype
= {0, };
695 token
= declaration_specifiers(token
, &ctype
, 0);
697 struct ident
*ident
= NULL
;
698 struct symbol
*decl
= alloc_symbol(token
->pos
, SYM_NODE
);
700 token
= declarator(token
, &decl
, &ident
);
701 if (match_op(token
, ':')) {
702 struct ctype
*ctype
= &decl
->ctype
;
703 struct expression
*expr
;
704 struct symbol
*bitfield
;
707 if (is_int_type (ctype
->base_type
)) {
708 bitfield
= indirect(token
->pos
, ctype
, SYM_BITFIELD
);
709 token
= conditional_expression(token
->next
, &expr
);
710 width
= get_expression_value(expr
);
711 bitfield
->fieldwidth
= width
;
713 warn(token
->pos
, "invalid negative bitfield width, %lld.", width
);
714 bitfield
->fieldwidth
= 8;
715 } else if (decl
->ident
&& width
== 0) {
716 warn(token
->pos
, "invalid named zero-width bitfield `%s'",
717 show_ident (decl
->ident
));
718 bitfield
->fieldwidth
= 8;
719 } else if (width
!= bitfield
->fieldwidth
) {
721 unsigned int stupid_gcc
= -1;
722 bitfield
->fieldwidth
= stupid_gcc
;
723 warn(token
->pos
, "truncating large bitfield from %lld to %d bits", width
, bitfield
->fieldwidth
);
725 struct symbol
*base_type
= bitfield
->ctype
.base_type
;
726 int is_signed
= !(base_type
->ctype
.modifiers
& MOD_UNSIGNED
);
728 bitfield
->fieldwidth
== 1 &&
730 // Valid values are either {-1;0} or {0}, depending on integer
731 // representation. The latter makes for very efficient code...
732 warn(token
->pos
, "dubious one-bit signed bitfield");
734 if (Wdefault_bitfield_sign
&&
736 base_type
->type
!= SYM_ENUM
&&
737 !(base_type
->ctype
.modifiers
& MOD_EXPLICITLY_SIGNED
) &&
739 // The sign of bitfields is unspecified by default.
740 warn (token
->pos
, "dubious bitfield without explicit `signed' or `unsigned'");
744 warn(token
->pos
, "invalid bitfield specifier for type %s.", show_typename (ctype
->base_type
));
745 // Parse this to recover gracefully.
746 token
= conditional_expression(token
->next
, &expr
);
748 while (match_idents(token
, &__attribute___ident
, &__attribute_ident
, NULL
)) {
749 struct ctype thistype
= { 0, };
750 token
= attribute_specifier(token
->next
, &thistype
);
751 apply_ctype(token
->pos
, &thistype
, ctype
);
754 add_symbol(list
, decl
);
755 if (!match_op(token
, ','))
759 if (!match_op(token
, ';')) {
760 warn(token
->pos
, "expected ; at end of declaration");
768 static struct token
*parameter_declaration(struct token
*token
, struct symbol
**tree
)
770 struct ident
*ident
= NULL
;
772 struct ctype ctype
= { 0, };
774 token
= declaration_specifiers(token
, &ctype
, 0);
775 sym
= alloc_symbol(token
->pos
, SYM_NODE
);
778 token
= declarator(token
, tree
, &ident
);
782 struct token
*typename(struct token
*token
, struct symbol
**p
)
784 struct symbol
*sym
= alloc_symbol(token
->pos
, SYM_NODE
);
786 token
= declaration_specifiers(token
, &sym
->ctype
, 0);
787 return declarator(token
, &sym
, NULL
);
790 struct token
*expression_statement(struct token
*token
, struct expression
**tree
)
792 token
= parse_expression(token
, tree
);
793 return expect(token
, ';', "at end of statement");
796 static struct token
*parse_asm_operands(struct token
*token
, struct statement
*stmt
)
798 struct expression
*expr
;
800 /* Allow empty operands */
801 if (match_op(token
->next
, ':') || match_op(token
->next
, ')'))
804 if (match_op(token
->next
, '[') &&
805 token_type(token
->next
->next
) == TOKEN_IDENT
&&
806 match_op(token
->next
->next
->next
, ']'))
807 token
= token
->next
->next
->next
;
808 token
= primary_expression(token
->next
, &expr
);
809 token
= parens_expression(token
, &expr
, "in asm parameter");
810 } while (match_op(token
, ','));
814 static struct token
*parse_asm_clobbers(struct token
*token
, struct statement
*stmt
)
816 struct expression
*expr
;
819 token
= primary_expression(token
->next
, &expr
);
820 } while (match_op(token
, ','));
824 static struct token
*parse_asm(struct token
*token
, struct statement
*stmt
)
826 struct expression
*expr
;
828 stmt
->type
= STMT_ASM
;
829 if (match_idents(token
, &__volatile___ident
, &volatile_ident
, NULL
)) {
832 token
= expect(token
, '(', "after asm");
833 token
= parse_expression(token
->next
, &expr
);
834 if (match_op(token
, ':'))
835 token
= parse_asm_operands(token
, stmt
);
836 if (match_op(token
, ':'))
837 token
= parse_asm_operands(token
, stmt
);
838 if (match_op(token
, ':'))
839 token
= parse_asm_clobbers(token
, stmt
);
840 token
= expect(token
, ')', "after asm");
841 return expect(token
, ';', "at end of asm-statement");
844 /* Make a statement out of an expression */
845 static struct statement
*make_statement(struct expression
*expr
)
847 struct statement
*stmt
;
851 stmt
= alloc_statement(expr
->pos
, STMT_EXPRESSION
);
852 stmt
->expression
= expr
;
857 * All iterators have two symbols associated with them:
858 * the "continue" and "break" symbols, which are targets
859 * for continue and break statements respectively.
861 * They are in a special name-space, but they follow
862 * all the normal visibility rules, so nested iterators
863 * automatically work right.
865 static void start_iterator(struct statement
*stmt
)
867 struct symbol
*cont
, *brk
;
869 start_symbol_scope();
870 cont
= alloc_symbol(stmt
->pos
, SYM_NODE
);
871 cont
->ident
= &continue_ident
;
872 bind_symbol(cont
, &continue_ident
, NS_ITERATOR
);
873 brk
= alloc_symbol(stmt
->pos
, SYM_NODE
);
874 brk
->ident
= &break_ident
;
875 bind_symbol(brk
, &break_ident
, NS_ITERATOR
);
877 stmt
->type
= STMT_ITERATOR
;
878 stmt
->iterator_break
= brk
;
879 stmt
->iterator_continue
= cont
;
880 fn_local_symbol(brk
);
881 fn_local_symbol(cont
);
884 static void end_iterator(struct statement
*stmt
)
889 static struct statement
*start_function(struct symbol
*sym
)
892 struct statement
*stmt
= alloc_statement(sym
->pos
, STMT_COMPOUND
);
894 start_function_scope();
895 ret
= alloc_symbol(sym
->pos
, SYM_NODE
);
896 ret
->ident
= &return_ident
;
897 ret
->ctype
= sym
->ctype
.base_type
->ctype
;
898 ret
->ctype
.modifiers
&= ~(MOD_STORAGE
| MOD_CONST
| MOD_VOLATILE
| MOD_INLINE
| MOD_ADDRESSABLE
| MOD_NOCAST
| MOD_NODEREF
| MOD_ACCESSED
| MOD_TOPLEVEL
);
899 ret
->ctype
.modifiers
|= (MOD_AUTO
| MOD_REGISTER
);
900 bind_symbol(ret
, &return_ident
, NS_ITERATOR
);
902 fn_local_symbol(ret
);
904 // static const char __func__[] = "function-name";
906 struct symbol
*funcname
= alloc_symbol(sym
->pos
, SYM_NODE
);
907 struct symbol
*array
= alloc_symbol(sym
->pos
, SYM_ARRAY
);
908 struct expression
*expr
= alloc_expression(sym
->pos
, EXPR_STRING
);
909 int len
= sym
->ident
->len
;
910 struct string
*string
= __alloc_string(len
+1);
912 array
->ctype
.base_type
= &char_ctype
;
913 array
->ctype
.modifiers
= MOD_CONST
| MOD_STATIC
;
915 memcpy(string
->data
, sym
->ident
->name
, len
);
916 string
->data
[len
] = '\0';
917 string
->length
= len
+ 1;
919 expr
->string
= string
;
921 funcname
->initializer
= expr
;
922 funcname
->ctype
.modifiers
= array
->ctype
.modifiers
;
923 funcname
->ctype
.base_type
= array
;
924 funcname
->ident
= &__func___ident
;
925 bind_symbol(funcname
, &__func___ident
, NS_SYMBOL
);
927 add_symbol(&stmt
->syms
, funcname
);
928 fn_local_symbol(funcname
);
934 static void end_function(struct symbol
*sym
)
936 end_function_scope();
940 * A "switch()" statement, like an iterator, has a
941 * the "break" symbol associated with it. It works
942 * exactly like the iterator break - it's the target
943 * for any break-statements in scope, and means that
944 * "break" handling doesn't even need to know whether
945 * it's breaking out of an iterator or a switch.
947 * In addition, the "case" symbol is a marker for the
948 * case/default statements to find the switch statement
949 * that they are associated with.
951 static void start_switch(struct statement
*stmt
)
953 struct symbol
*brk
, *switch_case
;
955 start_symbol_scope();
956 brk
= alloc_symbol(stmt
->pos
, SYM_NODE
);
957 brk
->ident
= &break_ident
;
958 bind_symbol(brk
, &break_ident
, NS_ITERATOR
);
960 switch_case
= alloc_symbol(stmt
->pos
, SYM_NODE
);
961 switch_case
->ident
= &case_ident
;
962 bind_symbol(switch_case
, &case_ident
, NS_ITERATOR
);
963 switch_case
->stmt
= stmt
;
965 stmt
->type
= STMT_SWITCH
;
966 stmt
->switch_break
= brk
;
967 stmt
->switch_case
= switch_case
;
969 fn_local_symbol(brk
);
970 fn_local_symbol(switch_case
);
973 static void end_switch(struct statement
*stmt
)
975 if (!stmt
->switch_case
->symbol_list
)
976 warn(stmt
->pos
, "switch with no cases");
980 static void add_case_statement(struct statement
*stmt
)
982 struct symbol
*target
= lookup_symbol(&case_ident
, NS_ITERATOR
);
986 warn(stmt
->pos
, "not in switch scope");
989 sym
= alloc_symbol(stmt
->pos
, SYM_NODE
);
990 add_symbol(&target
->symbol_list
, sym
);
992 stmt
->case_label
= sym
;
993 fn_local_symbol(sym
);
996 static struct token
*parse_return_statement(struct token
*token
, struct statement
*stmt
)
998 struct symbol
*target
= lookup_symbol(&return_ident
, NS_ITERATOR
);
1001 error(token
->pos
, "internal error: return without a function target");
1002 stmt
->type
= STMT_RETURN
;
1003 stmt
->ret_target
= target
;
1004 return expression_statement(token
->next
, &stmt
->ret_value
);
1007 static struct token
*parse_for_statement(struct token
*token
, struct statement
*stmt
)
1009 struct symbol_list
*syms
;
1010 struct expression
*e1
, *e2
, *e3
;
1011 struct statement
*iterator
;
1013 start_iterator(stmt
);
1014 token
= expect(token
->next
, '(', "after 'for'");
1018 /* C99 variable declaration? */
1019 if (lookup_type(token
)) {
1020 token
= external_declaration(token
, &syms
);
1022 token
= parse_expression(token
, &e1
);
1023 token
= expect(token
, ';', "in 'for'");
1025 token
= parse_expression(token
, &e2
);
1026 token
= expect(token
, ';', "in 'for'");
1027 token
= parse_expression(token
, &e3
);
1028 token
= expect(token
, ')', "in 'for'");
1029 token
= statement(token
, &iterator
);
1031 stmt
->iterator_syms
= syms
;
1032 stmt
->iterator_pre_statement
= make_statement(e1
);
1033 stmt
->iterator_pre_condition
= e2
;
1034 stmt
->iterator_post_statement
= make_statement(e3
);
1035 stmt
->iterator_post_condition
= e2
;
1036 stmt
->iterator_statement
= iterator
;
1042 struct token
*parse_while_statement(struct token
*token
, struct statement
*stmt
)
1044 struct expression
*expr
;
1045 struct statement
*iterator
;
1047 start_iterator(stmt
);
1048 token
= parens_expression(token
->next
, &expr
, "after 'while'");
1049 token
= statement(token
, &iterator
);
1051 stmt
->iterator_pre_condition
= expr
;
1052 stmt
->iterator_post_condition
= expr
;
1053 stmt
->iterator_statement
= iterator
;
1059 struct token
*parse_do_statement(struct token
*token
, struct statement
*stmt
)
1061 struct expression
*expr
;
1062 struct statement
*iterator
;
1064 start_iterator(stmt
);
1065 token
= statement(token
->next
, &iterator
);
1066 if (token_type(token
) == TOKEN_IDENT
&& token
->ident
== &while_ident
)
1067 token
= token
->next
;
1069 warn(token
->pos
, "expected 'while' after 'do'");
1070 token
= parens_expression(token
, &expr
, "after 'do-while'");
1072 stmt
->iterator_post_condition
= expr
;
1073 stmt
->iterator_statement
= iterator
;
1076 return expect(token
, ';', "after statement");
1079 static struct token
*statement(struct token
*token
, struct statement
**tree
)
1081 struct statement
*stmt
= alloc_statement(token
->pos
, STMT_NONE
);
1084 if (token_type(token
) == TOKEN_IDENT
) {
1085 if (token
->ident
== &if_ident
) {
1086 stmt
->type
= STMT_IF
;
1087 token
= parens_expression(token
->next
, &stmt
->if_conditional
, "after if");
1088 token
= statement(token
, &stmt
->if_true
);
1089 if (token_type(token
) != TOKEN_IDENT
)
1091 if (token
->ident
!= &else_ident
)
1093 return statement(token
->next
, &stmt
->if_false
);
1096 if (token
->ident
== &return_ident
)
1097 return parse_return_statement(token
, stmt
);
1099 if (token
->ident
== &break_ident
|| token
->ident
== &continue_ident
) {
1100 struct symbol
*target
= lookup_symbol(token
->ident
, NS_ITERATOR
);
1101 stmt
->type
= STMT_GOTO
;
1102 stmt
->goto_label
= target
;
1104 warn(stmt
->pos
, "break/continue not in iterator scope");
1105 return expect(token
->next
, ';', "at end of statement");
1107 if (token
->ident
== &default_ident
) {
1108 token
= token
->next
;
1109 goto default_statement
;
1111 if (token
->ident
== &case_ident
) {
1112 token
= parse_expression(token
->next
, &stmt
->case_expression
);
1113 if (match_op(token
, SPECIAL_ELLIPSIS
))
1114 token
= parse_expression(token
->next
, &stmt
->case_to
);
1116 stmt
->type
= STMT_CASE
;
1117 token
= expect(token
, ':', "after default/case");
1118 add_case_statement(stmt
);
1119 return statement(token
, &stmt
->case_statement
);
1121 if (token
->ident
== &switch_ident
) {
1122 stmt
->type
= STMT_SWITCH
;
1124 token
= parens_expression(token
->next
, &stmt
->switch_expression
, "after 'switch'");
1125 token
= statement(token
, &stmt
->switch_statement
);
1129 if (token
->ident
== &for_ident
)
1130 return parse_for_statement(token
, stmt
);
1132 if (token
->ident
== &while_ident
)
1133 return parse_while_statement(token
, stmt
);
1135 if (token
->ident
== &do_ident
)
1136 return parse_do_statement(token
, stmt
);
1138 if (token
->ident
== &goto_ident
) {
1139 stmt
->type
= STMT_GOTO
;
1140 token
= token
->next
;
1141 if (match_op(token
, '*')) {
1142 token
= parse_expression(token
->next
, &stmt
->goto_expression
);
1143 add_statement(&function_computed_goto_list
, stmt
);
1144 } else if (token_type(token
) == TOKEN_IDENT
) {
1145 stmt
->goto_label
= label_symbol(token
);
1146 token
= token
->next
;
1148 warn(token
->pos
, "Expected identifier or goto expression");
1150 return expect(token
, ';', "at end of statement");
1152 if (match_idents(token
, &asm_ident
, &__asm___ident
, &__asm_ident
, NULL
)) {
1153 return parse_asm(token
->next
, stmt
);
1155 if (match_op(token
->next
, ':')) {
1156 stmt
->type
= STMT_LABEL
;
1157 stmt
->label_identifier
= label_symbol(token
);
1158 return statement(token
->next
->next
, &stmt
->label_statement
);
1162 if (match_op(token
, '{')) {
1163 stmt
->type
= STMT_COMPOUND
;
1164 start_symbol_scope();
1165 token
= compound_statement(token
->next
, stmt
);
1168 return expect(token
, '}', "at end of compound statement");
1171 stmt
->type
= STMT_EXPRESSION
;
1172 return expression_statement(token
, &stmt
->expression
);
1175 struct token
* statement_list(struct token
*token
, struct statement_list
**list
)
1178 struct statement
* stmt
;
1179 if (eof_token(token
))
1181 if (match_op(token
, '}'))
1183 token
= statement(token
, &stmt
);
1184 add_statement(list
, stmt
);
1189 static struct token
*parameter_type_list(struct token
*token
, struct symbol
*fn
)
1191 struct symbol_list
**list
= &fn
->arguments
;
1193 if (match_op(token
, ')'))
1196 struct symbol
*sym
= alloc_symbol(token
->pos
, SYM_NODE
);
1198 if (match_op(token
, SPECIAL_ELLIPSIS
)) {
1200 token
= token
->next
;
1203 token
= parameter_declaration(token
, &sym
);
1204 if (sym
->ctype
.base_type
== &void_ctype
) {
1205 /* Special case: (void) */
1206 if (!*list
&& !sym
->ident
)
1208 warn(token
->pos
, "void parameter");
1210 add_symbol(list
, sym
);
1211 if (!match_op(token
, ','))
1213 token
= token
->next
;
1219 struct token
*compound_statement(struct token
*token
, struct statement
*stmt
)
1221 while (!eof_token(token
)) {
1222 if (!lookup_type(token
))
1224 token
= external_declaration(token
, &stmt
->syms
);
1226 token
= statement_list(token
, &stmt
->stmts
);
1230 static struct expression
*identifier_expression(struct token
*token
)
1232 struct expression
*expr
= alloc_expression(token
->pos
, EXPR_IDENTIFIER
);
1233 expr
->expr_ident
= token
->ident
;
1237 static struct expression
*index_expression(struct expression
*from
, struct expression
*to
)
1239 int idx_from
, idx_to
;
1240 struct expression
*expr
= alloc_expression(from
->pos
, EXPR_INDEX
);
1242 idx_from
= get_expression_value(from
);
1245 idx_to
= get_expression_value(to
);
1246 if (idx_to
< idx_from
|| idx_from
< 0)
1247 warn(from
->pos
, "nonsense array initializer index range");
1249 expr
->idx_from
= idx_from
;
1250 expr
->idx_to
= idx_to
;
1254 static struct token
*initializer_list(struct expression_list
**list
, struct token
*token
)
1257 struct token
*next
= token
->next
;
1258 struct expression
*expr
;
1260 if (match_op(token
, '.') && (token_type(next
) == TOKEN_IDENT
) && match_op(next
->next
, '=')) {
1261 add_expression(list
, identifier_expression(next
));
1262 token
= next
->next
->next
;
1263 } else if ((token_type(token
) == TOKEN_IDENT
) && match_op(next
, ':')) {
1264 add_expression(list
, identifier_expression(token
));
1266 } else if (match_op(token
, '[')) {
1267 struct expression
*from
= NULL
, *to
= NULL
;
1268 token
= constant_expression(token
->next
, &from
);
1269 if (match_op(token
, SPECIAL_ELLIPSIS
))
1270 token
= constant_expression(token
->next
, &to
);
1271 add_expression(list
, index_expression(from
, to
));
1272 token
= expect(token
, ']', "at end of initializer index");
1273 token
= expect(token
, '=', "at end of initializer index");
1277 token
= initializer(&expr
, token
);
1280 add_expression(list
, expr
);
1281 if (!match_op(token
, ','))
1283 token
= token
->next
;
1288 struct token
*initializer(struct expression
**tree
, struct token
*token
)
1290 if (match_op(token
, '{')) {
1291 struct expression
*expr
= alloc_expression(token
->pos
, EXPR_INITIALIZER
);
1293 token
= initializer_list(&expr
->expr_list
, token
->next
);
1294 return expect(token
, '}', "at end of initializer");
1296 return assignment_expression(token
, tree
);
1299 static void declare_argument(struct symbol
*sym
, struct symbol
*fn
)
1302 warn(sym
->pos
, "no identifier for function argument");
1305 bind_symbol(sym
, sym
->ident
, NS_SYMBOL
);
1308 static struct token
*parse_function_body(struct token
*token
, struct symbol
*decl
,
1309 struct symbol_list
**list
)
1311 struct symbol
*base_type
= decl
->ctype
.base_type
;
1312 struct statement
*stmt
, **p
;
1315 if (decl
->ctype
.modifiers
& MOD_INLINE
) {
1316 function_symbol_list
= &decl
->inline_symbol_list
;
1317 p
= &base_type
->inline_stmt
;
1319 function_symbol_list
= &decl
->symbol_list
;
1320 p
= &base_type
->stmt
;
1322 function_computed_target_list
= NULL
;
1323 function_computed_goto_list
= NULL
;
1325 if (decl
->ctype
.modifiers
& MOD_EXTERN
) {
1326 if (!(decl
->ctype
.modifiers
& MOD_INLINE
))
1327 warn(decl
->pos
, "function with external linkage has definition");
1329 if (!(decl
->ctype
.modifiers
& MOD_STATIC
))
1330 decl
->ctype
.modifiers
|= MOD_EXTERN
;
1332 stmt
= start_function(decl
);
1335 FOR_EACH_PTR (base_type
->arguments
, arg
) {
1336 declare_argument(arg
, base_type
);
1339 token
= compound_statement(token
->next
, stmt
);
1342 if (!(decl
->ctype
.modifiers
& MOD_INLINE
))
1343 add_symbol(list
, decl
);
1344 check_declaration(decl
);
1345 function_symbol_list
= NULL
;
1346 if (function_computed_goto_list
) {
1347 if (!function_computed_target_list
)
1348 warn(decl
->pos
, "function has computed goto but no targets?");
1350 struct statement
*stmt
;
1351 FOR_EACH_PTR(function_computed_goto_list
, stmt
) {
1352 stmt
->target_list
= function_computed_target_list
;
1356 return expect(token
, '}', "at end of function");
1359 static void promote_k_r_types(struct symbol
*arg
)
1361 struct symbol
*base
= arg
->ctype
.base_type
;
1362 if (base
&& base
->ctype
.base_type
== &int_type
&& (base
->ctype
.modifiers
& (MOD_CHAR
| MOD_SHORT
))) {
1363 arg
->ctype
.base_type
= &int_ctype
;
1367 static void apply_k_r_types(struct symbol_list
*argtypes
, struct symbol
*fn
)
1369 struct symbol_list
*real_args
= fn
->ctype
.base_type
->arguments
;
1372 FOR_EACH_PTR(real_args
, arg
) {
1373 struct symbol
*type
;
1375 /* This is quadratic in the number of arguments. We _really_ don't care */
1376 FOR_EACH_PTR(argtypes
, type
) {
1377 if (type
->ident
== arg
->ident
)
1380 warn(arg
->pos
, "missing type declaration for parameter '%s'", show_ident(arg
->ident
));
1384 /* "char" and "short" promote to "int" */
1385 promote_k_r_types(type
);
1387 arg
->ctype
= type
->ctype
;
1390 FOR_EACH_PTR(argtypes
, arg
) {
1392 warn(arg
->pos
, "nonsensical parameter declaration '%s'", show_ident(arg
->ident
));
1397 static struct token
*parse_k_r_arguments(struct token
*token
, struct symbol
*decl
,
1398 struct symbol_list
**list
)
1400 struct symbol_list
*args
= NULL
;
1402 warn(token
->pos
, "non-ANSI function declaration");
1404 token
= external_declaration(token
, &args
);
1405 } while (lookup_type(token
));
1407 apply_k_r_types(args
, decl
);
1409 if (!match_op(token
, '{')) {
1410 warn(token
->pos
, "expected function body");
1413 return parse_function_body(token
, decl
, list
);
1417 static struct token
*external_declaration(struct token
*token
, struct symbol_list
**list
)
1419 struct ident
*ident
= NULL
;
1420 struct symbol
*decl
;
1421 struct ctype ctype
= { 0, };
1422 struct symbol
*base_type
;
1425 /* Top-level inline asm? */
1426 if (match_idents(token
, &asm_ident
, &__asm___ident
, &__asm_ident
, NULL
)) {
1427 struct symbol
*anon
= alloc_symbol(token
->pos
, SYM_NODE
);
1428 struct symbol
*fn
= alloc_symbol(token
->pos
, SYM_FN
);
1429 struct statement
*stmt
;
1431 anon
->ctype
.base_type
= fn
;
1432 function_symbol_list
= &anon
->symbol_list
;
1433 stmt
= start_function(anon
);
1434 token
= parse_asm(token
->next
, stmt
);
1436 function_symbol_list
= NULL
;
1437 add_symbol(list
, anon
);
1441 /* Parse declaration-specifiers, if any */
1442 token
= declaration_specifiers(token
, &ctype
, 0);
1443 decl
= alloc_symbol(token
->pos
, SYM_NODE
);
1444 decl
->ctype
= ctype
;
1445 token
= declarator(token
, &decl
, &ident
);
1447 /* Just a type declaration? */
1449 return expect(token
, ';', "end of type declaration");
1451 decl
->ident
= ident
;
1453 /* type define declaration? */
1454 is_typedef
= (ctype
.modifiers
& MOD_TYPEDEF
) != 0;
1456 /* Typedef's don't have meaningful storage */
1458 ctype
.modifiers
&= ~MOD_STORAGE
;
1459 decl
->ctype
.modifiers
&= ~MOD_STORAGE
;
1460 decl
->ctype
.modifiers
|= MOD_USERTYPE
;
1463 bind_symbol(decl
, ident
, is_typedef
? NS_TYPEDEF
: NS_SYMBOL
);
1465 base_type
= decl
->ctype
.base_type
;
1466 if (!is_typedef
&& base_type
&& base_type
->type
== SYM_FN
) {
1467 /* K&R argument declaration? */
1468 if (lookup_type(token
))
1469 return parse_k_r_arguments(token
, decl
, list
);
1470 if (match_op(token
, '{'))
1471 return parse_function_body(token
, decl
, list
);
1473 if (!(decl
->ctype
.modifiers
& MOD_STATIC
))
1474 decl
->ctype
.modifiers
|= MOD_EXTERN
;
1475 } else if (!is_typedef
&& base_type
== &void_ctype
&& !(decl
->ctype
.modifiers
& MOD_EXTERN
)) {
1476 warn(token
->pos
, "void declaration");
1480 if (token_type(token
) == TOKEN_IDENT
) {
1481 if (token
->ident
== &asm_ident
|| token
->ident
== &__asm_ident
|| token
->ident
== &__asm___ident
) {
1482 struct expression
*expr
;
1484 token
= expect(token
->next
, '(', "after asm");
1485 token
= parse_expression(token
->next
, &expr
);
1486 token
= expect(token
, ')', "after asm");
1489 if (!is_typedef
&& match_op(token
, '=')) {
1490 if (decl
->ctype
.modifiers
& MOD_EXTERN
) {
1491 warn(decl
->pos
, "symbol with external linkage has initializer");
1492 decl
->ctype
.modifiers
&= ~MOD_EXTERN
;
1494 token
= initializer(&decl
->initializer
, token
->next
);
1497 if (!(decl
->ctype
.modifiers
& (MOD_EXTERN
| MOD_INLINE
))) {
1498 add_symbol(list
, decl
);
1499 if (function_symbol_list
)
1500 fn_local_symbol(decl
);
1503 check_declaration(decl
);
1505 if (!match_op(token
, ','))
1508 token
= token
->next
;
1510 decl
= alloc_symbol(token
->pos
, SYM_NODE
);
1511 decl
->ctype
= ctype
;
1512 token
= declaration_specifiers(token
, &decl
->ctype
, 1);
1513 token
= declarator(token
, &decl
, &ident
);
1515 warn(token
->pos
, "expected identifier name in type definition");
1519 bind_symbol(decl
, ident
, is_typedef
? NS_TYPEDEF
: NS_SYMBOL
);
1521 /* Function declarations are automatically extern unless specifically static */
1522 base_type
= decl
->ctype
.base_type
;
1523 if (!is_typedef
&& base_type
&& base_type
->type
== SYM_FN
) {
1524 if (!(decl
->ctype
.modifiers
& MOD_STATIC
))
1525 decl
->ctype
.modifiers
|= MOD_EXTERN
;
1528 return expect(token
, ';', "at end of declaration");
1531 void translation_unit(struct token
*token
, struct symbol_list
**list
)
1533 while (!eof_token(token
))
1534 token
= external_declaration(token
, list
);
1535 // They aren't needed any more
1536 clear_token_alloc();