struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / src / SDCC.y
blob4da57a75f5825095dfa28a043f98dd3ce44c11d1
1 /*-----------------------------------------------------------------------
3 SDCC.y - parser definition file for sdcc
5 Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 Revised by : Philipp Klaus Krause krauspeh@informatik.uni-freiburg.de (2022)
7 Using inspiration from the grammar by Jutta Degener as extended by Jens Gustedt (under Expat license)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include "SDCCglobl.h"
32 #include "SDCCattr.h"
33 #include "SDCCsymt.h"
34 #include "SDCChasht.h"
35 #include "SDCCval.h"
36 #include "SDCCmem.h"
37 #include "SDCCast.h"
38 #include "port.h"
39 #include "newalloc.h"
40 #include "SDCCerr.h"
41 #include "SDCCutil.h"
42 #include "SDCCbtree.h"
43 #include "SDCCopt.h"
44 #include "dbuf_string.h"
46 extern int yyerror (char *);
47 extern FILE *yyin;
48 long NestLevel = 0; /* current NestLevel */
49 int stackPtr = 1; /* stack pointer */
50 int xstackPtr = 0; /* xstack pointer */
51 int reentrant = 0;
52 int blockNo = 0; /* sequential block number */
53 int currBlockno=0;
54 int inCriticalFunction = 0;
55 int inCriticalBlock = 0;
56 int seqPointNo= 1; /* sequence point number */
57 int ignoreTypedefType=0;
58 extern int yylex();
59 int yyparse(void);
60 extern int noLineno;
61 char lbuff[1024]; /* local buffer */
62 char function_name[256] = {0};
64 /* break & continue stacks */
65 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
66 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
67 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
68 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
69 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
71 value *cenum = NULL; /* current enumeration type chain*/
72 bool uselessDecl = true;
74 #define YYDEBUG 1
77 %expect 3
79 %union {
80 attribute *attr; /* attribute */
81 symbol *sym; /* symbol table pointer */
82 structdef *sdef; /* structure definition */
83 char yychar[SDCC_NAME_MAX+1];
84 sym_link *lnk; /* declarator or specifier */
85 int yyint; /* integer value returned */
86 value *val; /* for integer constant */
87 initList *ilist; /* initial list */
88 designation*dsgn; /* designator */
89 const char *yystr; /* pointer to dynamicaly allocated string */
90 ast *asts; /* expression tree */
93 %token <yychar> IDENTIFIER TYPE_NAME ADDRSPACE_NAME
94 %token <val> CONSTANT
95 %token SIZEOF OFFSETOF
96 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
97 %token AND_OP OR_OP
98 %token ATTR_START TOK_SEP
99 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
100 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
101 %token <yyint> XOR_ASSIGN OR_ASSIGN
102 %token TYPEDEF EXTERN STATIC AUTO REGISTER CONSTEXPR CODE EEPROM INTERRUPT SFR SFR16 SFR32 ADDRESSMOD
103 %token AT SBIT REENTRANT USING XDATA DATA IDATA PDATA ELLIPSIS CRITICAL
104 %token NONBANKED BANKED SHADOWREGS SD_WPARAM
105 %token SD_BOOL SD_CHAR SD_SHORT SD_INT SD_LONG SIGNED UNSIGNED SD_FLOAT DOUBLE FIXED16X16 SD_CONST VOLATILE SD_VOID BIT
106 %token COMPLEX IMAGINARY
107 %token STRUCT UNION ENUM RANGE SD_FAR
108 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
109 %token NAKED JAVANATIVE OVERLAY TRAP
110 %token <yystr> STRING_LITERAL INLINEASM FUNC
111 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SET_VALUE_AT_ADDRESS SPIL UNSPIL GETABIT GETBYTE GETWORD
112 %token BITWISEAND UNARYMINUS IPUSH IPUSH_VALUE_AT_ADDRESS IPOP PCALL ENDFUNCTION JUMPTABLE
113 %token ROT
114 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
115 %token DUMMY_READ_VOLATILE ENDCRITICAL INLINE RESTRICT SMALLC RAISONANCE IAR COSMIC SDCCCALL PRESERVES_REGS Z88DK_FASTCALL Z88DK_CALLEE Z88DK_SHORTCALL Z88DK_PARAMS_OFFSET
117 /* C11 */
118 %token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL
120 /* C23 problem: too many legacy FALSE and TRUE still in SDCC, workaround: prefix by TOKEN_*/
121 %token TOKEN_FALSE TOKEN_TRUE NULLPTR TYPEOF TYPEOF_UNQUAL SD_BITINT
122 %token DECIMAL32 DECIMAL64 DECIMAL128
124 /* SDCC extensions */
125 %token ASM
127 /* For internal use (in further stages of SDCC) */
128 %token GENERIC_ASSOC_LIST GENERIC_ASSOCIATION
130 /* If an enum type specifier is another enum (invalid but syntactically possible), make sure that the next '{' is part of the inner enum.
131 * If an enum specifier is in a struct, the next ':' belongs to its enum type specifier.
132 * Reason from C23: "If an enum type specifier is present, then the longest possible sequence of tokens that can be
133 * interpreted as a specifier qualifier list is interpreted as part of the enum type specifier." */
134 %right ENUM '{' ':'
136 %type <yyint> Interrupt_storage
137 %type <attr> attribute_specifier_sequence attribute_specifier_sequence_opt attribute_specifier attribute_list attribute attribute_opt
138 %type <sym> identifier attribute_token declarator declarator2 direct_declarator array_declarator enumerator_list enumerator
139 %type <sym> member_declarator function_declarator
140 %type <sym> member_declarator_list member_declaration member_declaration_list
141 %type <sym> declaration init_declarator_list init_declarator
142 %type <sym> declaration_list identifier_list
143 %type <sym> kr_declaration kr_declaration_list
144 %type <sym> declaration_after_statement
145 %type <sym> declarator2_function_attributes while do for critical
146 %type <sym> addressmod
147 %type <lnk> pointer specifier_qualifier_list type_specifier_list_ type_specifier_qualifier type_specifier typeof_specifier type_qualifier_list type_qualifier_list_opt type_qualifier type_name
148 %type <lnk> type_specifier_list_without_struct_or_union type_specifier_qualifier_without_struct_or_union type_specifier_without_struct_or_union
149 %type <lnk> storage_class_specifier struct_or_union_specifier function_specifier alignment_specifier
150 %type <lnk> declaration_specifiers declaration_specifiers_ sfr_reg_bit sfr_attributes
151 %type <lnk> function_attribute function_attributes enum_specifier enum_comma_opt enum_type_specifier simple_typed_enum_decl
152 %type <lnk> abstract_declarator direct_abstract_declarator direct_abstract_declarator_opt array_abstract_declarator function_abstract_declarator
153 %type <lnk> unqualified_pointer
154 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
155 %type <sdef> stag opt_stag
156 %type <asts> primary_expression
157 %type <asts> postfix_expression unary_expression offsetof_member_designator cast_expression multiplicative_expression
158 %type <asts> additive_expression shift_expression relational_expression equality_expression
159 %type <asts> and_expression exclusive_or_expression inclusive_or_expression logical_or_expr
160 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr constant_range_expr
161 %type <asts> expression argument_expr_list function_definition expression_opt predefined_constant
162 %type <asts> statement_list statement labeled_statement unlabeled_statement compound_statement
163 %type <asts> primary_block secondary_block
164 %type <asts> expression_statement selection_statement iteration_statement
165 %type <asts> jump_statement else_statement function_body string_literal_val
166 %type <asts> critical_statement asm_statement label
167 %type <asts> generic_selection generic_assoc_list generic_association generic_controlling_operand
168 %type <asts> implicit_block statements_and_implicit block_item_list
169 %type <dsgn> designator designator_list designation designation_opt
170 %type <ilist> initializer initializer_list
171 %type <yyint> unary_operator assignment_operator struct_or_union
172 %type <yystr> asm_string_literal
174 %start file
178 /* C23 A.2.1 Expressions */
180 primary_expression
181 : identifier { $$ = newAst_VALUE (symbolVal ($1)); }
182 | CONSTANT { $$ = newAst_VALUE ($1); }
183 | string_literal_val
184 | '(' expression ')' { $$ = $2; }
185 | generic_selection
186 | predefined_constant
189 predefined_constant
190 : TOKEN_FALSE { $$ = newAst_VALUE (constBoolVal (false, true)); }
191 | TOKEN_TRUE { $$ = newAst_VALUE (constBoolVal (true, true)); }
192 | NULLPTR { $$ = newAst_VALUE (constNullptrVal ()); }
195 generic_selection
196 : GENERIC '(' generic_controlling_operand ',' generic_assoc_list ')' { $$ = newNode (GENERIC, $3, $5); }
199 generic_controlling_operand
200 : assignment_expr
201 | type_name { $$ = newAst_LINK ($1); }
204 generic_assoc_list
205 : generic_association { $$ = newNode (GENERIC_ASSOC_LIST, NULL, $1); }
206 | generic_assoc_list ',' generic_association { $$ = newNode (GENERIC_ASSOC_LIST, $1, $3); }
209 generic_association
210 : type_name ':' assignment_expr { $$ = newNode (GENERIC_ASSOCIATION, newAst_LINK($1), $3); }
211 | DEFAULT ':' assignment_expr { $$ = newNode (GENERIC_ASSOCIATION,NULL,$3); }
214 postfix_expression
215 : primary_expression
216 | postfix_expression '[' expression ']' { $$ = newNode ('[', $1, $3); }
217 | postfix_expression '(' ')' { $$ = newNode (CALL,$1,NULL);
218 $$->left->funcName = 1;}
219 | postfix_expression '(' argument_expr_list ')'
221 $$ = newNode (CALL,$1,$3); $$->left->funcName = 1;
223 | postfix_expression '.' { ignoreTypedefType = 1; } identifier
225 ignoreTypedefType = 0;
226 $4 = newSymbol($4->name,NestLevel);
227 $4->implicit = 1;
228 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
230 | postfix_expression PTR_OP { ignoreTypedefType = 1; } identifier
232 ignoreTypedefType = 0;
233 $4 = newSymbol($4->name,NestLevel);
234 $4->implicit = 1;
235 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
237 | postfix_expression INC_OP
238 { $$ = newNode(INC_OP,$1,NULL);}
239 | postfix_expression DEC_OP
240 { $$ = newNode(DEC_OP,$1,NULL); }
241 | '(' type_name ')' '{' initializer_list '}'
243 /* if (!options.std_c99) */
244 werror(E_COMPOUND_LITERALS_C99);
246 /* TODO: implement compound literals (C99) */
247 $$ = newAst_VALUE (valueFromLit (0));
249 | '(' type_name ')' '{' initializer_list ',' '}'
251 // if (!options.std_c99)
252 werror(E_COMPOUND_LITERALS_C99);
254 // TODO: implement compound literals (C99)
255 $$ = newAst_VALUE (valueFromLit (0));
257 | '(' type_name ')' '{' '}'
259 if (!options.std_c23)
260 werror(W_EMPTY_INIT_C23);
261 // if (!options.std_c99)
262 werror(E_COMPOUND_LITERALS_C99);
264 // TODO: implement compound literals (C99)
265 $$ = newAst_VALUE (valueFromLit (0));
269 argument_expr_list
270 : assignment_expr
271 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
274 unary_expression
275 : postfix_expression
276 | INC_OP unary_expression { $$ = newNode (INC_OP, NULL, $2); }
277 | DEC_OP unary_expression { $$ = newNode (DEC_OP, NULL, $2); }
278 | unary_operator cast_expression
280 if ($1 == '&' && IS_AST_OP ($2) && $2->opval.op == '*' && $2->right == NULL)
281 $$ = $2->left;
282 else if ($1 == '*' && IS_AST_OP ($2) && $2->opval.op == '&' && $2->right == NULL)
283 $$ = $2->left;
284 else
285 $$ = newNode ($1, $2, NULL);
287 | SIZEOF unary_expression { $$ = newNode (SIZEOF, NULL, $2); }
288 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE (sizeofOp ($3)); }
289 | ALIGNOF '(' type_name ')' { $$ = newAst_VALUE (alignofOp ($3)); }
290 | OFFSETOF '(' type_name ',' offsetof_member_designator ')' { $$ = offsetofOp($3, $5); }
291 | ROT '(' unary_expression ',' unary_expression ')' { $$ = newNode (ROT, $3, $5); }
294 unary_operator
295 : '&' { $$ = '&';}
296 | '*' { $$ = '*';}
297 | '+' { $$ = '+';}
298 | '-' { $$ = '-';}
299 | '~' { $$ = '~';}
300 | '!' { $$ = '!';}
303 cast_expression
304 : unary_expression
305 | '(' type_name ')' cast_expression { $$ = newNode(CAST,newAst_LINK($2),$4); }
308 multiplicative_expression
309 : cast_expression
310 | multiplicative_expression '*' cast_expression { $$ = newNode('*',$1,$3);}
311 | multiplicative_expression '/' cast_expression { $$ = newNode('/',$1,$3);}
312 | multiplicative_expression '%' cast_expression { $$ = newNode('%',$1,$3);}
315 additive_expression
316 : multiplicative_expression
317 | additive_expression '+' multiplicative_expression { $$=newNode('+',$1,$3);}
318 | additive_expression '-' multiplicative_expression { $$=newNode('-',$1,$3);}
321 shift_expression
322 : additive_expression
323 | shift_expression LEFT_OP additive_expression { $$ = newNode(LEFT_OP,$1,$3); }
324 | shift_expression RIGHT_OP additive_expression { $$ = newNode(RIGHT_OP,$1,$3); }
327 relational_expression
328 : shift_expression
329 | relational_expression '<' shift_expression { $$ = newNode('<', $1,$3);}
330 | relational_expression '>' shift_expression { $$ = newNode('>', $1,$3);}
331 | relational_expression LE_OP shift_expression { $$ = newNode(LE_OP,$1,$3);}
332 | relational_expression GE_OP shift_expression { $$ = newNode(GE_OP,$1,$3);}
335 equality_expression
336 : relational_expression
337 | equality_expression EQ_OP relational_expression { $$ = newNode(EQ_OP,$1,$3);}
338 | equality_expression NE_OP relational_expression { $$ = newNode(NE_OP,$1,$3);}
341 and_expression
342 : equality_expression
343 | and_expression '&' equality_expression { $$ = newNode('&',$1,$3);}
346 exclusive_or_expression
347 : and_expression
348 | exclusive_or_expression '^' and_expression { $$ = newNode('^',$1,$3);}
351 inclusive_or_expression
352 : exclusive_or_expression
353 | inclusive_or_expression '|' exclusive_or_expression { $$ = newNode('|',$1,$3);}
356 logical_and_expr
357 : inclusive_or_expression
358 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expression
359 { $$ = newNode(AND_OP,$1,$4);}
362 logical_or_expr
363 : logical_and_expr
364 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
365 { $$ = newNode(OR_OP,$1,$4); }
368 conditional_expr
369 : logical_or_expr
370 | logical_or_expr '?' { seqPointNo++;} expression ':' conditional_expr
372 $$ = newNode(':',$4,$6);
373 $$ = newNode('?',$1,$$);
377 assignment_expr
378 : conditional_expr
379 | unary_expression assignment_operator assignment_expr
382 switch ($2) {
383 case '=':
384 $$ = newNode($2,$1,$3);
385 break;
386 case MUL_ASSIGN:
387 $$ = createRMW($1, '*', $3);
388 break;
389 case DIV_ASSIGN:
390 $$ = createRMW($1, '/', $3);
391 break;
392 case MOD_ASSIGN:
393 $$ = createRMW($1, '%', $3);
394 break;
395 case ADD_ASSIGN:
396 $$ = createRMW($1, '+', $3);
397 break;
398 case SUB_ASSIGN:
399 $$ = createRMW($1, '-', $3);
400 break;
401 case LEFT_ASSIGN:
402 $$ = createRMW($1, LEFT_OP, $3);
403 break;
404 case RIGHT_ASSIGN:
405 $$ = createRMW($1, RIGHT_OP, $3);
406 break;
407 case AND_ASSIGN:
408 $$ = createRMW($1, '&', $3);
409 break;
410 case XOR_ASSIGN:
411 $$ = createRMW($1, '^', $3);
412 break;
413 case OR_ASSIGN:
414 $$ = createRMW($1, '|', $3);
415 break;
416 default :
417 $$ = NULL;
423 assignment_operator
424 : '=' { $$ = '=';}
425 | MUL_ASSIGN
426 | DIV_ASSIGN
427 | MOD_ASSIGN
428 | ADD_ASSIGN
429 | SUB_ASSIGN
430 | LEFT_ASSIGN
431 | RIGHT_ASSIGN
432 | AND_ASSIGN
433 | XOR_ASSIGN
434 | OR_ASSIGN
437 expression
438 : assignment_expr
439 | expression ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
442 expression_opt
443 : { $$ = NULL; seqPointNo++; }
444 | expression { $$ = $1; seqPointNo++; }
447 constant_expr
448 : conditional_expr
451 constant_range_expr
452 : constant_expr ELLIPSIS constant_expr { $$ = newNode(ELLIPSIS,$1,$3); }
455 /* C23 A.2.2 Declarations */
457 declaration
458 : simple_typed_enum_decl
460 uselessDecl = true;
461 $$ = NULL;
463 | declaration_specifiers ';'
465 /* Special case: if incomplete struct/union declared without name, */
466 /* make sure an incomplete type for it exists in the current scope */
467 if (IS_STRUCT($1))
469 structdef *sdef = SPEC_STRUCT($1);
470 structdef *osdef;
471 osdef = findSymWithBlock (StructTab, sdef->tagsym, currBlockno, NestLevel);
472 if (osdef && osdef->block != currBlockno)
474 sdef = newStruct(osdef->tagsym->name);
475 sdef->level = NestLevel;
476 sdef->block = currBlockno;
477 sdef->tagsym = newSymbol (osdef->tagsym->name, NestLevel);
478 addSym (StructTab, sdef, sdef->tag, sdef->level, currBlockno, 0);
479 uselessDecl = false;
482 if (uselessDecl)
483 werror(W_USELESS_DECL);
484 uselessDecl = true;
485 $$ = NULL;
487 | declaration_specifiers init_declarator_list ';'
489 /* add the specifier list to the id */
490 symbol *sym , *sym1;
492 bool autocandidate = options.std_c23 && IS_SPEC ($1) && SPEC_SCLS($1) == S_AUTO;
494 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
495 sym_link *lnk = copyLinkChain($1);
496 sym_link *l0 = NULL, *l1 = NULL, *l2 = NULL;
497 /* check illegal declaration */
498 for (l0 = sym->type; l0 != NULL; l0 = l0->next)
499 if (IS_PTR (l0))
500 break;
501 /* check if creating instances of structs with flexible arrays */
502 for (l1 = lnk; l1 != NULL; l1 = l1->next)
503 if (IS_STRUCT (l1) && SPEC_STRUCT (l1)->b_flexArrayMember)
504 break;
505 if (!options.std_c99 && l0 == NULL && l1 != NULL && SPEC_EXTR($1) != 1)
506 werror (W_FLEXARRAY_INSTRUCT, sym->name);
507 /* check if creating instances of function type */
508 for (l1 = lnk; l1 != NULL; l1 = l1->next)
509 if (IS_FUNC (l1))
510 break;
511 for (l2 = lnk; l2 != NULL; l2 = l2->next)
512 if (IS_PTR (l2))
513 break;
514 if (l0 == NULL && l2 == NULL && l1 != NULL)
515 werrorfl(sym->fileDef, sym->lineDef, E_TYPE_IS_FUNCTION, sym->name);
516 if (autocandidate && !sym->type && sym->ival && sym->ival->type == INIT_NODE) // C23 auto type inference
518 sym->type = sym->etype = typeofOp (sym->ival->init.node);
519 SPEC_SCLS (lnk) = 0;
521 /* do the pointer stuff */
522 pointerTypes(sym->type,lnk);
523 addDecl (sym,0,lnk);
526 uselessDecl = true;
527 $$ = sym1;
529 | static_assert_declaration
531 $$ = NULL;
533 | attribute_declaration
535 $$ = NULL;
539 declaration_specifiers : declaration_specifiers_ { $$ = finalizeSpec($1); };
541 declaration_specifiers_
542 : storage_class_specifier { $$ = $1; }
543 | storage_class_specifier declaration_specifiers_ {
544 /* if the decl $2 is not a specifier */
545 /* find the spec and replace it */
546 $$ = mergeDeclSpec($1, $2, "storage_class_specifier declaration_specifiers - skipped");
548 | type_specifier_qualifier { $$ = $1; }
549 | type_specifier_qualifier declaration_specifiers_ {
550 /* if the decl $2 is not a specifier */
551 /* find the spec and replace it */
552 $$ = mergeDeclSpec($1, $2, "type_specifier_qualifier declaration_specifiers - skipped");
554 | function_specifier { $$ = $1; }
555 | function_specifier declaration_specifiers_ {
556 /* if the decl $2 is not a specifier */
557 /* find the spec and replace it */
558 $$ = mergeDeclSpec($1, $2, "function_specifier declaration_specifiers - skipped");
562 init_declarator_list
563 : init_declarator
564 | init_declarator_list ',' init_declarator { $3->next = $1; $$ = $3;}
567 init_declarator
568 : declarator { $1->ival = NULL; }
569 | declarator '=' initializer { $1->ival = $3; seqPointNo++; }
572 attribute_declaration
573 : attribute_specifier_sequence ';'
576 storage_class_specifier
577 : TYPEDEF {
578 $$ = newLink (SPECIFIER);
579 SPEC_TYPEDEF($$) = 1;
581 | EXTERN {
582 $$ = newLink(SPECIFIER);
583 SPEC_EXTR($$) = 1;
585 | STATIC {
586 $$ = newLink (SPECIFIER);
587 SPEC_STAT($$) = 1;
589 | THREAD_LOCAL
591 $$ = 0;
592 werror(E_THREAD_LOCAL);
594 | AUTO {
595 $$ = newLink (SPECIFIER);
596 SPEC_SCLS($$) = S_AUTO;
598 | REGISTER {
599 $$ = newLink (SPECIFIER);
600 SPEC_SCLS($$) = S_REGISTER;
602 | CONSTEXPR {
603 $$ = newLink (SPECIFIER);
604 werror (E_CONSTEXPR);
608 /* NOTE:
609 * Structs and unions have been factored out to avoid parsing conflicts with
610 * enum-type-specifier, which semantically cannot be a struct or union, anyway.
613 type_specifier
614 : type_specifier_without_struct_or_union { $$ = $1; }
615 | struct_or_union_specifier {
616 uselessDecl = false;
617 $$ = $1;
618 ignoreTypedefType = 1;
622 type_specifier_without_struct_or_union
623 : SD_VOID {
624 $$=newLink(SPECIFIER);
625 SPEC_NOUN($$) = V_VOID;
626 ignoreTypedefType = 1;
628 | SD_CHAR {
629 $$=newLink(SPECIFIER);
630 SPEC_NOUN($$) = V_CHAR;
631 ignoreTypedefType = 1;
633 | SD_SHORT {
634 $$=newLink(SPECIFIER);
635 SPEC_SHORT($$) = 1;
636 ignoreTypedefType = 1;
638 | SD_INT {
639 $$=newLink(SPECIFIER);
640 SPEC_NOUN($$) = V_INT;
641 ignoreTypedefType = 1;
643 | SD_LONG {
644 $$=newLink(SPECIFIER);
645 SPEC_LONG($$) = 1;
646 ignoreTypedefType = 1;
648 | SD_FLOAT {
649 $$=newLink(SPECIFIER);
650 SPEC_NOUN($$) = V_FLOAT;
651 ignoreTypedefType = 1;
653 | DOUBLE {
654 $$=newLink(SPECIFIER);
655 SPEC_NOUN($$) = V_DOUBLE;
656 ignoreTypedefType = 1;
658 | SIGNED {
659 $$=newLink(SPECIFIER);
660 $$->select.s.b_signed = 1;
661 ignoreTypedefType = 1;
663 | UNSIGNED {
664 $$=newLink(SPECIFIER);
665 SPEC_USIGN($$) = 1;
666 ignoreTypedefType = 1;
668 | SD_BITINT '(' constant_expr ')' {
669 $$=newLink(SPECIFIER);
670 SPEC_NOUN($$) = V_BITINT;
671 SPEC_BITINTWIDTH($$) = (unsigned int) ulFromVal(constExprValue($3, true));
672 ignoreTypedefType = 1;
674 | SD_BOOL {
675 $$=newLink(SPECIFIER);
676 SPEC_NOUN($$) = V_BOOL;
677 ignoreTypedefType = 1;
679 | COMPLEX {
680 $$=newLink(SPECIFIER);
681 werror (E_COMPLEX_UNSUPPORTED);
683 | IMAGINARY {
684 $$=newLink(SPECIFIER);
685 werror (E_COMPLEX_UNSUPPORTED);
687 | DECIMAL32 {
688 $$=newLink(SPECIFIER);
689 werror (E_DECIMAL_FLOAT_UNSUPPORTED);
691 | DECIMAL64 {
692 $$=newLink(SPECIFIER);
693 werror (E_DECIMAL_FLOAT_UNSUPPORTED);
695 | DECIMAL128 {
696 $$=newLink(SPECIFIER);
697 werror (E_DECIMAL_FLOAT_UNSUPPORTED);
699 | enum_specifier {
700 cenum = NULL;
701 uselessDecl = false;
702 ignoreTypedefType = 1;
703 $$ = $1;
705 | TYPE_NAME
707 symbol *sym;
708 sym_link *p;
709 sym = findSym(TypedefTab,NULL,$1);
710 $$ = p = copyLinkChain(sym ? sym->type : NULL);
711 SPEC_TYPEDEF(getSpec(p)) = 0;
712 ignoreTypedefType = 1;
714 | typeof_specifier
716 $$ = $1;
718 | FIXED16X16 {
719 $$=newLink(SPECIFIER);
720 SPEC_NOUN($$) = V_FIXED16X16;
721 ignoreTypedefType = 1;
723 | BIT {
724 $$=newLink(SPECIFIER);
725 SPEC_NOUN($$) = V_BIT;
726 SPEC_SCLS($$) = S_BIT;
727 SPEC_BLEN($$) = 1;
728 SPEC_BSTR($$) = 0;
729 ignoreTypedefType = 1;
731 | AT CONSTANT {
732 $$=newLink(SPECIFIER);
733 /* add this to the storage class specifier */
734 SPEC_ABSA($$) = 1; /* set the absolute addr flag */
735 /* now get the abs addr from value */
736 SPEC_ADDR($$) = (unsigned int) ulFromVal(constExprValue(newAst_VALUE ($2), true));
738 | AT '(' constant_expr ')' {
739 $$=newLink(SPECIFIER);
740 /* add this to the storage class specifier */
741 SPEC_ABSA($$) = 1; /* set the absolute addr flag */
742 /* now get the abs addr from value */
743 SPEC_ADDR($$) = (unsigned int) ulFromVal(constExprValue($3, true));
747 | sfr_reg_bit;
749 typeof_specifier
750 : TYPEOF '(' expression ')'
752 $$ = typeofOp ($3);
753 wassert ($$);
755 | TYPEOF '(' type_name ')'
757 checkTypeSanity ($3, "(typeof)");
758 $$ = $3;
760 | TYPEOF_UNQUAL '(' expression ')'
762 $$ = typeofOp ($3);
763 wassert ($$);
764 wassert (IS_SPEC ($$));
765 SPEC_CONST ($$) = 0;
766 SPEC_RESTRICT ($$) = 0;
767 SPEC_VOLATILE ($$) = 0;
768 SPEC_ATOMIC ($$) = 0;
769 SPEC_ADDRSPACE ($$) = 0;
771 | TYPEOF_UNQUAL '(' type_name ')'
773 checkTypeSanity ($3, "(typeof_unqual)");
774 $$ = $3;
775 wassert (IS_SPEC ($$));
776 SPEC_CONST ($$) = 0;
777 SPEC_RESTRICT ($$) = 0;
778 SPEC_VOLATILE ($$) = 0;
779 SPEC_ATOMIC ($$) = 0;
780 SPEC_ADDRSPACE ($$) = 0;
783 struct_or_union_specifier
784 : struct_or_union attribute_specifier_sequence_opt opt_stag
786 structdef *sdef;
788 if (!$3->tagsym)
790 /* no tag given, so new struct def for current scope */
791 addSym (StructTab, $3, $3->tag, $3->level, currBlockno, 0);
793 else
795 sdef = findSymWithBlock (StructTab, $3->tagsym, currBlockno, NestLevel);
796 if (sdef)
798 /* Error if a complete type already defined in this scope */
799 if (sdef->block == currBlockno)
801 if (sdef->fields)
802 $3->redefinition = true;
803 else // We are completing an incomplete type
804 $3 = sdef;
806 else
808 /* There is an existing struct def in an outer scope. */
809 /* Create new struct def for current scope */
810 addSym (StructTab, $3, $3->tag, $3->level, currBlockno, 0);
813 else
815 /* There is no existing struct def at all. */
816 /* Create new struct def for current scope */
817 addSym (StructTab, $3, $3->tag, $3->level, currBlockno, 0);
821 if (!$3->type)
823 $3->type = $1;
825 else
827 if ($3->type != $1)
828 werror(E_BAD_TAG, $3->tag, $1==STRUCT ? "struct" : "union");
831 '{' member_declaration_list '}'
833 structdef *sdef;
834 symbol *sym, *dsym;
836 // check for errors in structure members
837 for (sym=$6; sym; sym=sym->next)
839 if (IS_ABSOLUTE(sym->etype))
841 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
842 SPEC_ABSA(sym->etype) = 0;
844 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype))
846 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
847 printTypeChainRaw (sym->type, NULL);
848 SPEC_SCLS(sym->etype) = 0;
850 for (dsym=sym->next; dsym; dsym=dsym->next)
852 if (*dsym->name && strcmp(sym->name, dsym->name)==0)
854 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
855 $1==STRUCT ? "struct" : "union", sym->name);
856 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
861 /* Create a structdef */
862 $3->fields = reverseSyms($6); /* link the fields */
863 $3->size = compStructSize($1, $3); /* update size of */
864 promoteAnonStructs ($1, $3);
866 if ($3->redefinition) // Since C23, multiple definitions for struct / union are allowed, if they are compatible and have the same tags. The current standard draft N3047 allows redeclarations of unions to have a different order of the members. We don't. The rule in N3047 is now considered a mistake by many, and will hopefully be changed to the SDCC behaviour via a national body comment for the final version of the standard.
868 sdef = findSymWithBlock (StructTab, $3->tagsym, currBlockno, NestLevel);
869 bool compatible = options.std_c23 && sdef->tagsym && $3->tagsym && !strcmp (sdef->tagsym->name, $3->tagsym->name);
870 for (symbol *fieldsym1 = sdef->fields, *fieldsym2 = $3->fields; compatible; fieldsym1 = fieldsym1->next, fieldsym2 = fieldsym2->next)
872 if (!fieldsym1 && !fieldsym2)
873 break;
874 if (!fieldsym1 || !fieldsym2)
875 compatible = false;
876 else if (strcmp (fieldsym1->name, fieldsym2->name))
877 compatible = false;
878 else if (compareType (fieldsym1->type, fieldsym2->type, true) <= 0)
879 compatible = false;
881 if (!compatible)
883 werror(E_STRUCT_REDEF_INCOMPATIBLE, $3->tag);
884 werrorfl(sdef->tagsym->fileDef, sdef->tagsym->lineDef, E_PREVIOUS_DEF);
887 else
888 sdef = $3;
890 /* Create the specifier */
891 $$ = newLink (SPECIFIER);
892 SPEC_NOUN($$) = V_STRUCT;
893 SPEC_STRUCT($$)= sdef;
895 | struct_or_union attribute_specifier_sequence_opt stag
897 structdef *sdef;
899 sdef = findSymWithBlock (StructTab, $3->tagsym, currBlockno, NestLevel);
901 if (sdef)
902 $3 = sdef;
903 else
905 /* new struct def for current scope */
906 addSym (StructTab, $3, $3->tag, $3->level, currBlockno, 0);
908 $$ = newLink(SPECIFIER);
909 SPEC_NOUN($$) = V_STRUCT;
910 SPEC_STRUCT($$) = $3;
912 if (!$3->type)
914 $3->type = $1;
916 else
918 if ($3->type != $1)
919 werror(E_BAD_TAG, $3->tag, $1==STRUCT ? "struct" : "union");
924 struct_or_union
925 : STRUCT { $$ = STRUCT; ignoreTypedefType = 1; }
926 | UNION { $$ = UNION; ignoreTypedefType = 1; }
929 member_declaration_list
930 : member_declaration
931 | member_declaration_list member_declaration
933 symbol *sym = $2;
935 /* go to the end of the chain */
936 while (sym->next) sym = sym->next;
937 sym->next = $1;
939 $$ = $2;
943 member_declaration
944 : attribute_specifier_sequence_opt specifier_qualifier_list member_declarator_list ';'
946 /* add this type to all the symbols */
947 symbol *sym;
948 for ( sym = $3; sym != NULL; sym = sym->next )
950 sym_link *btype = copyLinkChain($2);
952 pointerTypes(sym->type, btype);
953 if (!sym->type)
955 sym->type = btype;
956 sym->etype = getSpec(sym->type);
958 else
959 addDecl (sym, 0, btype);
960 /* make sure the type is complete and sane */
961 checkTypeSanity(sym->etype, sym->name);
963 ignoreTypedefType = 0;
964 $$ = $3;
968 type_specifier_qualifier
969 : type_specifier { $$ = $1; }
970 | type_qualifier { $$ = $1; }
971 | alignment_specifier { $$ = $1; }
974 type_specifier_qualifier_without_struct_or_union
975 : type_specifier_without_struct_or_union { $$ = $1; }
976 | struct_or_union { fatal (1, E_ENUM_UNDERLYING_TYPE); }
977 | type_qualifier { $$ = $1; }
978 | alignment_specifier { $$ = $1; }
981 member_declarator_list
982 : member_declarator
983 | member_declarator_list ',' member_declarator
985 $3->next = $1;
986 $$ = $3;
990 member_declarator
991 : declarator
992 | ':' constant_expr
994 unsigned int bitsize;
995 $$ = newSymbol (genSymName(NestLevel), NestLevel);
996 bitsize = (unsigned int) ulFromVal(constExprValue($2, true));
997 if (!bitsize)
998 bitsize = BITVAR_PAD;
999 $$->bitVar = bitsize;
1000 $$->bitUnnamed = 1;
1002 | declarator ':' constant_expr
1004 unsigned int bitsize;
1005 bitsize = (unsigned int) ulFromVal(constExprValue($3, true));
1007 if (!bitsize)
1009 $$ = newSymbol (genSymName(NestLevel), NestLevel);
1010 $$->bitVar = BITVAR_PAD;
1011 werror(W_BITFLD_NAMED);
1013 else
1014 $1->bitVar = bitsize;
1016 | { $$ = newSymbol ("", NestLevel); }
1019 enum_specifier
1020 : ENUM '{' enumerator_list enum_comma_opt '}'
1022 $$ = newEnumType ($3, NULL);
1023 SPEC_SCLS(getSpec($$)) = 0;
1025 | ENUM enum_type_specifier '{' enumerator_list enum_comma_opt '}'
1027 $$ = newEnumType ($4, $2);
1028 SPEC_SCLS(getSpec($$)) = 0;
1030 | ENUM identifier '{' enumerator_list enum_comma_opt '}'
1032 symbol *csym;
1033 sym_link *enumtype;
1035 enumtype = newEnumType ($4, NULL);
1036 SPEC_SCLS(getSpec(enumtype)) = 0;
1037 $2->type = enumtype;
1039 csym = findSymWithLevel(enumTab, $2);
1040 if ((csym && csym->level == $2->level))
1042 if (!options.std_c23 || compareType (csym->type, $2->type, true) <= 0)
1044 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF, csym->name);
1045 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1049 /* add this to the enumerator table */
1050 if (!csym)
1051 addSym (enumTab, $2, $2->name, $2->level, $2->block, 0);
1052 $$ = copyLinkChain(enumtype);
1054 | ENUM identifier enum_type_specifier '{' enumerator_list enum_comma_opt '}'
1056 symbol *csym;
1057 sym_link *enumtype;
1059 enumtype = newEnumType ($5, $3);
1060 SPEC_SCLS(getSpec(enumtype)) = 0;
1061 $2->type = enumtype;
1063 csym = findSymWithLevel(enumTab, $2);
1064 if ((csym && csym->level == $2->level))
1066 if (!options.std_c23 || compareType (csym->type, $2->type, true) <= 0)
1068 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF, csym->name);
1069 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
1073 /* add this to the enumerator table */
1074 if (!csym)
1075 addSym (enumTab, $2, $2->name, $2->level, $2->block, 0);
1076 $$ = copyLinkChain(enumtype);
1078 | ENUM identifier
1080 symbol *csym;
1082 /* check the enumerator table */
1083 if ((csym = findSymWithLevel(enumTab, $2)))
1084 $$ = copyLinkChain(csym->type);
1085 else
1087 $$ = newLink(SPECIFIER);
1088 SPEC_NOUN($$) = V_INT;
1093 /* C23:
1094 * An enum specifier of the form "enum identifier enum-type-specifier"
1095 * may not appear except in a declaration of the form "enum identifier enum-type-specifier ;"
1097 simple_typed_enum_decl
1098 : ENUM identifier enum_type_specifier ';'
1100 symbol *csym;
1102 /* let newEnumType check the enum-type-specifier and discard the returned type */
1103 newEnumType (NULL, $3);
1105 /* check the enumerator table */
1106 if ((csym = findSymWithLevel(enumTab, $2)))
1107 $$ = copyLinkChain(csym->type);
1108 else
1110 $$ = newLink(SPECIFIER);
1111 SPEC_NOUN($$) = V_INT;
1116 enum_comma_opt
1119 $$ = NULL;
1121 | ','
1123 if (!options.std_c99)
1124 werror (E_ENUM_COMMA_C99);
1125 $$ = NULL;
1128 enumerator_list
1129 : enumerator
1130 | enumerator_list ',' enumerator
1132 $3->next = $1;
1133 $$ = $3;
1137 enumerator
1138 : identifier attribute_specifier_sequence_opt opt_assign_expr
1140 symbol *sym;
1142 $1->type = copyLinkChain ($3->type);
1143 $1->etype = getSpec ($1->type);
1144 SPEC_ENUM ($1->etype) = 1;
1145 $$ = $1;
1147 // check if the symbol at the same level already exists
1148 if ((sym = findSymWithLevel (SymbolTab, $1)) && sym->level == $1->level)
1150 // C23 allows redefinitions of enumeration constants with the same value as part of a redeclaration of the same enumerated type.
1151 if (!options.std_c23 || ullFromVal (valFromType (sym->type)) != ullFromVal (valFromType ($1->type)))
1153 werrorfl ($1->fileDef, $1->lineDef, E_DUPLICATE_MEMBER, "enum", $1->name);
1154 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF);
1157 else
1159 // do this now, so we can use it for the next enums in the list
1160 addSymChain (&$1);
1165 enum_type_specifier
1166 : ':' type_specifier_list_without_struct_or_union
1168 if (!options.std_c23)
1169 werror (E_ENUM_TYPE_SPECIFIER_C23);
1170 $$ = finalizeSpec ($2);
1174 type_qualifier
1175 : SD_CONST {
1176 $$=newLink(SPECIFIER);
1177 SPEC_CONST($$) = 1;
1179 | RESTRICT {
1180 $$=newLink(SPECIFIER);
1181 SPEC_RESTRICT($$) = 1;
1183 | VOLATILE {
1184 $$=newLink(SPECIFIER);
1185 SPEC_VOLATILE($$) = 1;
1187 | ATOMIC {
1188 $$=newLink(SPECIFIER);
1189 werror (E_ATOMIC_UNSUPPORTED);
1191 | ADDRSPACE_NAME {
1192 $$=newLink(SPECIFIER);
1193 SPEC_ADDRSPACE($$) = findSym (AddrspaceTab, 0, $1);
1195 | XDATA {
1196 $$ = newLink (SPECIFIER);
1197 SPEC_SCLS($$) = S_XDATA;
1199 | CODE {
1200 $$ = newLink (SPECIFIER);
1201 SPEC_SCLS($$) = S_CODE;
1203 | EEPROM {
1204 $$ = newLink (SPECIFIER);
1205 SPEC_SCLS($$) = S_EEPROM;
1207 | DATA {
1208 $$ = newLink (SPECIFIER);
1209 SPEC_SCLS($$) = S_DATA;
1211 | IDATA {
1212 $$ = newLink (SPECIFIER);
1213 SPEC_SCLS($$) = S_IDATA;
1215 | PDATA {
1216 $$ = newLink (SPECIFIER);
1217 SPEC_SCLS($$) = S_PDATA;
1221 function_specifier
1222 : INLINE {
1223 $$ = newLink (SPECIFIER);
1224 SPEC_INLINE($$) = 1;
1226 | NORETURN {
1227 $$ = newLink (SPECIFIER);
1228 SPEC_NORETURN($$) = 1;
1232 alignment_specifier
1233 : ALIGNAS '(' type_name ')'
1235 checkTypeSanity ($3, "(_Alignas)");
1236 $$ = newLink (SPECIFIER);
1237 SPEC_ALIGNAS($$) = 1;
1239 | ALIGNAS '(' constant_expr ')'
1241 value *val = constExprValue ($3, true);
1242 $$ = newLink (SPECIFIER);
1243 SPEC_ALIGNAS($$) = 0;
1244 if (!val)
1245 werror (E_CONST_EXPECTED);
1246 else if (ulFromVal (val) == 0 || isPowerOf2 (ulFromVal (val)) && ulFromVal (val) <= port->mem.maxextalign)
1247 SPEC_ALIGNAS($$) = ulFromVal(val);
1248 else
1249 werror (E_ALIGNAS, ulFromVal(val));
1253 declarator
1254 : direct_declarator { $$ = $1; }
1255 | pointer direct_declarator
1257 addDecl ($2,0,reverseLink($1));
1258 $$ = $2;
1262 direct_declarator
1263 : identifier attribute_specifier_sequence_opt
1264 | '(' declarator ')' { $$ = $2; }
1265 | array_declarator attribute_specifier_sequence_opt
1266 | declarator2_function_attributes attribute_specifier_sequence_opt
1269 declarator2
1270 : identifier
1271 | '(' declarator ')' { $$ = $2; }
1272 | array_declarator
1275 array_declarator
1276 : direct_declarator '[' type_qualifier_list_opt ']'
1278 sym_link *p, *n;
1280 p = newLink (DECLARATOR);
1281 DCL_TYPE(p) = ARRAY;
1282 DCL_ELEM(p) = 0;
1284 if ($3)
1286 if (!options.std_c99)
1287 werror (E_QUALIFIED_ARRAY_PARAM_C99);
1289 DCL_PTR_CONST(p) = SPEC_CONST ($3);
1290 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($3);
1291 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($3);
1292 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($3);
1293 addDecl($1,0,p);
1294 n = newLink (SPECIFIER);
1295 SPEC_NEEDSPAR(n) = 1;
1296 addDecl($1,0,n);
1298 else
1299 addDecl($1,0,p);
1301 | direct_declarator '[' type_qualifier_list_opt assignment_expr ']'
1303 sym_link *p, *n;
1305 p = newLink (DECLARATOR);
1306 DCL_TYPE(p) = ARRAY;
1307 DCL_ELEM_AST (p) = $4;
1309 if ($3)
1311 if (!options.std_c99)
1312 werror (E_QUALIFIED_ARRAY_PARAM_C99);
1313 DCL_PTR_CONST(p) = SPEC_CONST ($3);
1314 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($3);
1315 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($3);
1316 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($3);
1317 addDecl($1, 0, p);
1318 n = newLink (SPECIFIER);
1319 SPEC_NEEDSPAR(n) = 1;
1320 addDecl($1,0,n);
1322 else
1323 addDecl($1, 0, p);
1325 | direct_declarator '[' STATIC type_qualifier_list_opt assignment_expr ']'
1327 sym_link *p, *n;
1329 if (!options.std_c99)
1330 werror (E_STATIC_ARRAY_PARAM_C99);
1332 p = newLink (DECLARATOR);
1333 DCL_TYPE(p) = ARRAY;
1334 DCL_ELEM_AST (p) = $5;
1336 if ($4)
1338 if (!options.std_c99)
1339 werror (E_QUALIFIED_ARRAY_PARAM_C99);
1340 DCL_PTR_CONST(p) = SPEC_CONST ($4);
1341 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($4);
1342 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($4);
1343 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($4);
1345 addDecl($1, 0, p);
1346 n = newLink (SPECIFIER);
1347 SPEC_NEEDSPAR(n) = 1;
1348 addDecl($1,0,n);
1350 | direct_declarator '[' type_qualifier_list STATIC assignment_expr ']'
1352 sym_link *p, *n;
1354 if (!options.std_c99)
1356 werror (E_QUALIFIED_ARRAY_PARAM_C99);
1357 werror (E_STATIC_ARRAY_PARAM_C99);
1360 p = newLink (DECLARATOR);
1361 DCL_TYPE(p) = ARRAY;
1362 DCL_ELEM_AST (p) = $5;
1364 DCL_PTR_CONST(p) = SPEC_CONST ($3);
1365 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($3);
1366 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($3);
1367 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($3);
1368 addDecl($1, 0, p);
1369 n = newLink (SPECIFIER);
1370 SPEC_NEEDSPAR(n) = 1;
1371 addDecl($1,0,n);
1375 declarator2_function_attributes
1376 : function_declarator { $$ = $1; }
1377 | function_declarator function_attributes {
1378 // copy the functionAttributes (not the args and hasVargs !!)
1379 sym_link *funcType=$1->type;
1381 while (funcType && !IS_FUNC(funcType))
1382 funcType = funcType->next;
1384 if (!funcType)
1385 werror (E_FUNC_ATTR);
1386 else
1388 struct value *args = FUNC_ARGS(funcType);
1389 unsigned hasVargs = FUNC_HASVARARGS(funcType);
1390 bool noprototype = FUNC_NOPROTOTYPE(funcType);
1392 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1393 sizeof($2->funcAttrs));
1395 FUNC_ARGS(funcType)=args;
1396 FUNC_HASVARARGS(funcType)=hasVargs;
1397 FUNC_NOPROTOTYPE(funcType)=noprototype;
1399 // just to be sure
1400 memset (&$2->funcAttrs, 0,
1401 sizeof($2->funcAttrs));
1403 addDecl ($1,0,$2);
1408 function_declarator
1409 : declarator2 '(' ')'
1411 addDecl ($1, FUNCTION, NULL);
1413 // Up to C17, this was a function declarator without a prototype.
1414 if (!options.std_c23)
1416 FUNC_NOPROTOTYPE($1->type) = true;
1417 if (!options.lessPedantic)
1418 werror (W_FUNCDECL_WITH_NO_PROTOTYPE);
1421 | declarator2 '('
1423 NestLevel += LEVEL_UNIT;
1424 STACK_PUSH(blockNum, currBlockno);
1425 btree_add_child(currBlockno, ++blockNo);
1426 currBlockno = blockNo;
1427 seqPointNo++; /* not a true sequence point, but helps resolve scope */
1429 parameter_type_list ')'
1431 sym_link *funcType;
1433 bool is_fptr = IS_FUNC($1->type); // Already a function, must be a function pointer.
1435 addDecl ($1, FUNCTION, NULL);
1436 funcType = $1->type;
1438 // For a function pointer, the parameter list here is for the returned type.
1439 if (is_fptr)
1440 funcType = funcType->next;
1442 while (funcType && !IS_FUNC(funcType))
1443 funcType = funcType->next;
1445 wassert (funcType);
1447 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1448 FUNC_ARGS(funcType) = reverseVal($4);
1450 FUNC_SDCCCALL(funcType) = -1;
1452 /* nest level was incremented to take care of the parms */
1453 leaveBlockScope (currBlockno);
1454 NestLevel -= LEVEL_UNIT;
1455 currBlockno = STACK_POP(blockNum);
1456 seqPointNo++; /* not a true sequence point, but helps resolve scope */
1458 // if this was a pointer (to a function)
1459 if (!IS_FUNC($1->type))
1460 cleanUpLevel(SymbolTab, NestLevel + LEVEL_UNIT);
1462 $$ = $1;
1464 | declarator2 '('
1466 NestLevel += LEVEL_UNIT;
1467 STACK_PUSH(blockNum, currBlockno);
1468 btree_add_child(currBlockno, ++blockNo);
1469 currBlockno = blockNo;
1470 seqPointNo++; /* not a true sequence point, but helps resolve scope */
1472 identifier_list ')'
1474 if (options.std_c23)
1475 werror(E_OLD_STYLE,$1->name);
1477 sym_link *funcType;
1479 bool is_fptr = IS_FUNC($1->type); // Already a function, must be a function pointer.
1481 addDecl ($1, FUNCTION, NULL);
1482 funcType = $1->type;
1484 // For a function pointer, the parameter list here is for the returned type.
1485 if (is_fptr)
1486 funcType = funcType->next;
1488 while (funcType && !IS_FUNC(funcType))
1489 funcType = funcType->next;
1491 wassert (funcType);
1493 // TODO: A K&R function does not create a prototype.
1494 // => use FUNC_NOPROTOTYPE, once prototype-less functions are
1495 // fully supported and K&R functions can be treated as such
1496 funcType->funcAttrs.oldStyle = 1;
1498 // initially give all parameters in the identifier_list the implicit type int
1499 for (symbol *loop = $4; loop ; loop = loop->next) {
1500 value *newVal;
1501 loop->type = loop->etype = newIntLink();
1502 loop->_isparm = 1;
1503 newVal = symbolVal(loop);
1504 newVal->next = FUNC_ARGS(funcType);
1505 FUNC_ARGS(funcType) = newVal;
1508 FUNC_SDCCCALL(funcType) = -1;
1510 /* nest level was incremented to take care of the parms */
1511 leaveBlockScope (currBlockno);
1512 NestLevel -= LEVEL_UNIT;
1513 currBlockno = STACK_POP(blockNum);
1514 seqPointNo++; /* not a true sequence point, but helps resolve scope */
1516 // if this was a pointer (to a function)
1517 if (!IS_FUNC($1->type))
1518 cleanUpLevel(SymbolTab, NestLevel + LEVEL_UNIT);
1520 $$ = $1;
1524 pointer
1525 : unqualified_pointer { $$ = $1;}
1526 | unqualified_pointer AT '(' constant_expr ')' /* Special case to allow __at at the end */
1528 sym_link *n = newLink(SPECIFIER);
1529 /* add this to the storage class specifier */
1530 SPEC_ABSA(n) = 1; /* set the absolute addr flag */
1531 /* now get the abs addr from value */
1532 SPEC_ADDR(n) = (unsigned int) ulFromVal(constExprValue($4,true));
1533 n->next = $1;
1534 $$ = n;
1536 | unqualified_pointer type_qualifier_list
1538 $$ = $1;
1539 if (IS_SPEC($2)) {
1540 DCL_TSPEC($1) = $2;
1541 DCL_PTR_CONST($1) = SPEC_CONST($2);
1542 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1543 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1544 DCL_PTR_ADDRSPACE($1) = SPEC_ADDRSPACE($2);
1546 else
1547 werror (W_PTR_TYPE_INVALID);
1549 | unqualified_pointer type_qualifier_list AT '(' constant_expr ')' /* Special case to allow __at at the end */
1551 if (IS_SPEC($2)) {
1552 DCL_TSPEC($1) = $2;
1553 DCL_PTR_CONST($1) = SPEC_CONST($2);
1554 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1555 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1556 DCL_PTR_ADDRSPACE($1) = SPEC_ADDRSPACE($2);
1558 else
1559 werror (W_PTR_TYPE_INVALID);
1561 sym_link *n = newLink(SPECIFIER);
1562 /* add this to the storage class specifier */
1563 SPEC_ABSA(n) = 1; /* set the absolute addr flag */
1564 /* now get the abs addr from value */
1565 SPEC_ADDR(n) = (unsigned int) ulFromVal(constExprValue($5,true));
1566 n->next = $1;
1567 $$ = n;
1569 | unqualified_pointer pointer
1571 $$ = $1;
1572 $$->next = $2;
1573 DCL_TYPE($2)=port->unqualified_pointer;
1575 | unqualified_pointer type_qualifier_list pointer
1577 $$ = $1;
1578 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1579 DCL_PTR_CONST($1) = SPEC_CONST($2);
1580 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1581 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1582 DCL_PTR_ADDRSPACE($1) = SPEC_ADDRSPACE($2);
1583 switch (SPEC_SCLS($2)) {
1584 case S_XDATA:
1585 DCL_TYPE($3) = FPOINTER;
1586 break;
1587 case S_IDATA:
1588 DCL_TYPE($3) = IPOINTER;
1589 break;
1590 case S_PDATA:
1591 DCL_TYPE($3) = PPOINTER;
1592 break;
1593 case S_DATA:
1594 DCL_TYPE($3) = POINTER;
1595 break;
1596 case S_CODE:
1597 DCL_TYPE($3) = CPOINTER;
1598 break;
1599 case S_EEPROM:
1600 DCL_TYPE($3) = EEPPOINTER;
1601 break;
1602 default:
1603 // this could be just "constant"
1604 // werror(W_PTR_TYPE_INVALID);
1608 else
1609 werror (W_PTR_TYPE_INVALID);
1610 $$->next = $3;
1614 unqualified_pointer
1615 : '*'
1617 $$ = newLink(DECLARATOR);
1618 DCL_TYPE($$)=UPOINTER;
1622 type_qualifier_list
1623 : type_qualifier
1624 | type_qualifier_list type_qualifier
1626 $$ = mergeDeclSpec($1, $2, "type_qualifier_list type_qualifier skipped");
1630 type_qualifier_list_opt
1633 $$ = 0;
1635 | type_qualifier_list
1637 $$ = $1;
1641 parameter_type_list
1642 : parameter_list
1643 | parameter_list ',' ELLIPSIS { $1->vArgs = 1;}
1646 parameter_list
1647 : parameter_declaration
1648 | parameter_list ',' parameter_declaration
1650 $3->next = $1;
1651 $$ = $3;
1655 parameter_declaration
1656 : declaration_specifiers declarator
1658 symbol *loop;
1660 if (IS_SPEC ($1) && !IS_VALID_PARAMETER_STORAGE_CLASS_SPEC ($1))
1662 werror (E_STORAGE_CLASS_FOR_PARAMETER, $2->name);
1664 pointerTypes ($2->type, $1);
1665 if (IS_SPEC ($2->etype))
1666 SPEC_NEEDSPAR($2->etype) = 0;
1667 addDecl ($2, 0, $1);
1668 for (loop = $2; loop; loop->_isparm = 1, loop = loop->next)
1670 $$ = symbolVal ($2);
1671 ignoreTypedefType = 0;
1673 | type_name
1675 $$ = newValue ();
1676 $$->type = $1;
1677 $$->etype = getSpec ($$->type);
1678 ignoreTypedefType = 0;
1682 abstract_declarator
1683 : pointer { $$ = reverseLink($1); }
1684 | direct_abstract_declarator
1685 | pointer direct_abstract_declarator { $1 = reverseLink($1); $2->next = $1; $$ = $2;
1686 if (IS_PTR($1) && IS_FUNC($2))
1687 DCL_TYPE($1) = CPOINTER;
1691 direct_abstract_declarator
1692 : '(' abstract_declarator ')' { $$ = $2; }
1693 | array_abstract_declarator
1694 | function_abstract_declarator
1697 direct_abstract_declarator_opt
1698 : { $$ = NULL; }
1699 | direct_abstract_declarator
1702 array_abstract_declarator
1703 : direct_abstract_declarator_opt '[' ']' {
1704 $$ = newLink (DECLARATOR);
1705 DCL_TYPE($$) = ARRAY;
1706 DCL_ELEM($$) = 0;
1707 if($1)
1708 $$->next = $1;
1710 | direct_abstract_declarator_opt '[' constant_expr ']'
1712 value *val;
1713 $$ = newLink (DECLARATOR);
1714 DCL_TYPE($$) = ARRAY;
1715 DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($3, true));
1716 if($1)
1717 $$->next = $1;
1721 function_abstract_declarator
1722 : '(' ')' { $$ = NULL;}
1723 | direct_abstract_declarator '(' ')' {
1724 // $1 must be a pointer to a function
1725 sym_link *p=newLink(DECLARATOR);
1726 DCL_TYPE(p) = FUNCTION;
1727 if (!$1) {
1728 // ((void (code *) ()) 0) ()
1729 $1=newLink(DECLARATOR);
1730 DCL_TYPE($1)=CPOINTER;
1731 $$ = $1;
1733 $1->next=p;
1735 | '(' parameter_type_list ')' { $$ = NULL;}
1736 | direct_abstract_declarator '('
1738 NestLevel += LEVEL_UNIT;
1739 STACK_PUSH(blockNum, currBlockno);
1740 btree_add_child(currBlockno, ++blockNo);
1741 currBlockno = blockNo;
1743 parameter_type_list ')'
1745 sym_link *p = newLink(DECLARATOR), *q;
1746 DCL_TYPE(p) = FUNCTION;
1748 FUNC_HASVARARGS(p) = IS_VARG($4);
1749 FUNC_ARGS(p) = reverseVal($4);
1751 /* nest level was incremented to take care of the parms */
1752 NestLevel -= LEVEL_UNIT;
1753 currBlockno = STACK_POP(blockNum);
1754 if (!$1)
1756 /* ((void (code *) (void)) 0) () */
1757 $1 = newLink(DECLARATOR);
1758 DCL_TYPE($1) = CPOINTER;
1759 $$ = $1;
1761 for (q = $1; q && q->next; q = q->next);
1762 q->next = p;
1766 initializer
1767 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1768 | '{' '}'
1770 if (!options.std_c23)
1771 werror(W_EMPTY_INIT_C23);
1772 // {} behaves mostly like {0}, so we emulate that, and use the isempty flag for the few cases where there is a difference.
1773 $$ = newiList(INIT_DEEP, revinit(newiList(INIT_NODE, newAst_VALUE(constIntVal("0")))));
1774 $$->isempty = true;
1776 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1777 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1780 initializer_list
1781 : designation_opt initializer { $2->designation = $1; $$ = $2; }
1782 | initializer_list ',' designation_opt initializer
1784 $4->designation = $3;
1785 $4->next = $1;
1786 $$ = $4;
1790 designation_opt
1791 : { $$ = NULL; }
1792 | designation
1795 designation
1796 : designator_list '=' { $$ = revDesignation($1); }
1799 designator_list
1800 : designator
1801 | designator_list designator { $2->next = $1; $$ = $2; }
1804 designator
1805 : '[' constant_expr ']'
1807 value *tval;
1808 int elemno;
1810 tval = constExprValue($2, true);
1811 /* if it is not a constant then Error */
1812 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL))
1814 werror (E_CONST_EXPECTED);
1815 elemno = 0; /* arbitrary fixup */
1817 else
1819 if ((elemno = (int) ulFromVal(tval)) < 0)
1821 werror (E_BAD_DESIGNATOR);
1822 elemno = 0; /* arbitrary fixup */
1825 $$ = newDesignation(DESIGNATOR_ARRAY, &elemno);
1827 | '.' identifier { $$ = newDesignation(DESIGNATOR_STRUCT,$2); }
1830 static_assert_declaration
1831 : STATIC_ASSERT '(' constant_expr ',' STRING_LITERAL ')' ';'
1833 value *val = constExprValue ($3, true);
1834 if (!val)
1835 werror (E_CONST_EXPECTED);
1836 else if (!ullFromVal(val))
1837 werror (W_STATIC_ASSERTION, $5);
1839 | STATIC_ASSERT '(' constant_expr ')' ';'
1841 value *val = constExprValue ($3, true);
1842 if (!options.std_c23)
1843 werror (E_STATIC_ASSERTION_C23);
1844 if (!val)
1845 werror (E_CONST_EXPECTED);
1846 else if (!ullFromVal(val))
1847 werror (W_STATIC_ASSERTION_2);
1851 attribute_specifier_sequence
1852 : attribute_specifier_sequence attribute_specifier
1854 $$ = $1;
1855 attribute *a;
1856 for (a = $$; a->next; a = a->next);
1857 a->next = $2;
1859 | attribute_specifier
1861 $$ = $1;
1865 attribute_specifier_sequence_opt
1866 : /* empty */
1868 $$ = 0;
1870 | attribute_specifier_sequence
1872 $$ = $1;
1876 attribute_specifier
1877 : ATTR_START attribute_list ']' ']'
1879 if (!options.std_c23)
1880 werror(E_ATTRIBUTE_C23);
1881 $$ = $2;
1885 attribute_list
1886 : attribute_opt
1888 $$ = $1;
1890 | attribute_list ',' attribute_opt
1892 $$ = $1;
1893 if ($3)
1895 attribute *a;
1896 for (a = $$; a->next; a = a->next);
1897 a->next = $3;
1902 attribute
1903 : attribute_token
1905 $$ = newAttribute ($1, 0);
1907 | attribute_token attribute_argument_clause
1909 $$ = newAttribute ($1, 0);
1913 attribute_opt
1914 : /* empty */
1916 $$ = 0;
1918 | attribute
1920 $$ = $1;
1924 attribute_token
1925 : identifier
1927 $$ = $1;
1928 $$->next = 0;
1929 werror (W_UNKNOWN_ATTRIBUTE, $1->name);
1931 | identifier TOK_SEP identifier
1933 $$ = $1;
1934 $$->next = $3;
1935 struct dbuf_s dbuf;
1936 dbuf_init (&dbuf, 64);
1937 dbuf_printf (&dbuf, "%s::%s", $1->name, $3->name);
1938 werror (W_UNKNOWN_ATTRIBUTE, dbuf_c_str (&dbuf));
1939 dbuf_destroy (&dbuf);
1943 attribute_argument_clause
1944 : '(' ')'
1945 | '(' balanced_token_sequence ')'
1948 balanced_token_sequence
1949 : balanced_token
1950 | balanced_token_sequence balanced_token
1953 balanced_token
1954 : identifier
1955 | STRING_LITERAL
1956 | CONSTANT
1959 /* C23 A.2.3 Statements */
1961 statement
1962 : labeled_statement
1963 | unlabeled_statement
1967 unlabeled_statement
1968 : expression_statement
1969 | attribute_specifier_sequence_opt primary_block
1971 $$ = $2;
1973 | attribute_specifier_sequence_opt jump_statement
1975 $$ = $2;
1977 | critical_statement
1978 | asm_statement
1981 primary_block
1982 : compound_statement
1984 $$ = $1;
1986 | selection_statement
1988 $$ = $1;
1990 | iteration_statement
1992 $$ = $1;
1996 secondary_block
1997 : statement
1999 $$ = $1;
2003 labeled_statement
2004 : label statement
2006 if ($1)
2008 $$ = $1;
2009 $1->right = $2;
2011 else
2012 $$ = newNode (BLOCK, NULL, NULL);
2016 label
2017 : identifier ':'
2019 $$ = createLabel($1,NULL);
2020 $1->isitmp = 0;
2022 | attribute_specifier_sequence_opt CASE constant_range_expr ':'
2024 if (!options.std_c2y)
2025 werror (E_CASE_RANGE_C2Y);
2027 if (STACK_EMPTY(swStk))
2028 $$ = createCaseRange(NULL,$3->left,$3->right,NULL);
2029 else
2030 $$ = createCaseRange(STACK_PEEK(swStk),$3->left,$3->right,NULL);
2032 | attribute_specifier_sequence_opt CASE constant_expr ':'
2034 if (STACK_EMPTY(swStk))
2035 $$ = createCase(NULL,$3,NULL);
2036 else
2037 $$ = createCase(STACK_PEEK(swStk),$3,NULL);
2039 | attribute_specifier_sequence_opt DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
2041 if (STACK_EMPTY(swStk))
2042 $$ = createDefault(NULL,$<asts>3,NULL);
2043 else
2044 $$ = createDefault(STACK_PEEK(swStk),$<asts>3,NULL);
2048 start_block
2049 : '{'
2051 NestLevel += LEVEL_UNIT;
2052 STACK_PUSH(blockNum, currBlockno);
2053 btree_add_child(currBlockno, ++blockNo);
2054 currBlockno = blockNo;
2055 ignoreTypedefType = 0;
2059 end_block
2060 : '}'
2062 leaveBlockScope (currBlockno);
2063 NestLevel -= LEVEL_UNIT;
2064 currBlockno = STACK_POP(blockNum);
2068 compound_statement
2069 : start_block end_block { $$ = createBlock(NULL, NULL); }
2070 | start_block block_item_list end_block
2072 $$ = $2;
2073 cleanUpLevel(StructTab, NestLevel + LEVEL_UNIT);
2077 block_item_list
2078 : statements_and_implicit { $$ = createBlock(NULL, $1); }
2079 | declaration_list { $$ = createBlock($1, NULL); }
2080 | declaration_list statements_and_implicit { $$ = createBlock($1, $2); }
2083 expression_statement
2084 : expression_opt ';'
2085 | attribute_specifier_sequence expression ';' { $$ = $2; seqPointNo++;}
2088 else_statement
2089 : ELSE statement { $$ = $2; }
2090 | { $$ = NULL; }
2093 selection_statement
2094 /* This gives us an unavoidable shift / reduce conflict, but yacc does the right thing for C */
2095 : IF '(' expression ')' { seqPointNo++;} statement else_statement
2097 noLineno++;
2098 $$ = createIf ($3, $6, $7 );
2099 $$->lineno = $3->lineno;
2100 $$->filename = $3->filename;
2101 noLineno--;
2103 | SWITCH '(' expression ')' {
2104 ast *ex;
2105 static int swLabel = 0;
2107 seqPointNo++;
2108 /* create a node for expression */
2109 ex = newNode(SWITCH,$3,NULL);
2110 STACK_PUSH(swStk,ex); /* save it in the stack */
2111 ex->values.switchVals.swNum = swLabel;
2113 /* now create the label */
2114 SNPRINTF(lbuff, sizeof(lbuff),
2115 "_swBrk_%d",swLabel++);
2116 $<sym>$ = newSymbol(lbuff,NestLevel);
2117 /* put label in the break stack */
2118 STACK_PUSH(breakStack,$<sym>$);
2120 secondary_block {
2121 /* get back the switch form the stack */
2122 $$ = STACK_POP(swStk);
2123 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
2124 STACK_POP(breakStack);
2128 iteration_statement
2129 : while '(' expression ')' { seqPointNo++;} secondary_block
2131 noLineno++;
2132 $$ = createWhile ( $1, STACK_POP(continueStack),
2133 STACK_POP(breakStack), $3, $6 );
2134 $$->lineno = $1->lineDef;
2135 $$->filename = $1->fileDef;
2136 noLineno--;
2138 | do secondary_block WHILE '(' expression ')' ';'
2140 seqPointNo++;
2141 noLineno++;
2142 $$ = createDo ( $1 , STACK_POP(continueStack),
2143 STACK_POP(breakStack), $5, $2);
2144 $$->lineno = $1->lineDef;
2145 $$->filename = $1->fileDef;
2146 noLineno--;
2148 | for '(' expression_opt ';' expression_opt ';' expression_opt ')' secondary_block
2150 noLineno++;
2152 $$ = newNode(FOR,$9,NULL);
2153 AST_FOR($$,trueLabel) = $1;
2154 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
2155 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
2156 AST_FOR($$,condLabel) = STACK_POP(forStack);
2157 AST_FOR($$,initExpr) = $3;
2158 AST_FOR($$,condExpr) = $5;
2159 AST_FOR($$,loopExpr) = $7;
2161 /* This continue label is not at the correct location, */
2162 /* but we need to create it now for proper binding. The */
2163 /* code that handles the FOR node will move it to the */
2164 /* proper location inside the for loop. */
2165 if (AST_FOR($$,continueLabel)->isref)
2166 $$->right = createLabel(AST_FOR($$,continueLabel),NULL);
2167 $$ = newNode(NULLOP,$$,createLabel(AST_FOR($$,falseLabel),NULL));
2168 noLineno--;
2170 NestLevel -= LEVEL_UNIT;
2171 currBlockno = STACK_POP(blockNum);
2173 | for '(' declaration expression_opt ';' expression_opt ')'
2175 if (!options.std_c99)
2176 werror (E_FOR_INITAL_DECLARATION_C99);
2178 if ( $3 && IS_TYPEDEF($3->etype))
2179 allocVariables ($3);
2180 ignoreTypedefType = 0;
2181 addSymChain(&$3);
2183 secondary_block
2186 noLineno++;
2188 $$ = newNode(FOR,$9,NULL);
2189 AST_FOR($$,trueLabel) = $1;
2190 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
2191 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
2192 AST_FOR($$,condLabel) = STACK_POP(forStack);
2193 AST_FOR($$,initExpr) = 0;
2194 AST_FOR($$,condExpr) = $4;
2195 AST_FOR($$,loopExpr) = $6;
2197 /* This continue label is not at the correct location, */
2198 /* but we need to create it now for proper binding. The */
2199 /* code that handles the FOR node will move it to the */
2200 /* proper location inside the for loop. */
2201 if (AST_FOR($$,continueLabel)->isref)
2202 $$->right = createLabel(AST_FOR($$,continueLabel),NULL);
2203 $$ = createBlock($3, newNode(NULLOP,$$,createLabel(AST_FOR($$,falseLabel),NULL)));
2204 cleanUpLevel(StructTab, NestLevel + LEVEL_UNIT);
2205 noLineno--;
2207 leaveBlockScope (currBlockno);
2208 NestLevel -= LEVEL_UNIT;
2209 currBlockno = STACK_POP(blockNum);
2213 jump_statement
2214 : GOTO identifier ';' {
2215 if (inCriticalBlock) {
2216 werror(E_INVALID_CRITICAL);
2217 $$ = NULL;
2218 } else {
2219 $2->islbl = 1;
2220 $$ = newAst_VALUE(symbolVal($2));
2221 $$ = newNode(GOTO,$$,NULL);
2224 | CONTINUE ';' {
2225 /* make sure continue is in context */
2226 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
2227 werror(E_BREAK_CONTEXT);
2228 $$ = NULL;
2230 else {
2231 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
2232 $$ = newNode(GOTO,$$,NULL);
2233 /* mark the continue label as referenced */
2234 STACK_PEEK(continueStack)->isref = 1;
2237 | BREAK ';' {
2238 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
2239 werror(E_BREAK_CONTEXT);
2240 $$ = NULL;
2241 } else {
2242 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
2243 $$ = newNode(GOTO,$$,NULL);
2244 STACK_PEEK(breakStack)->isref = 1;
2247 | RETURN ';' {
2248 seqPointNo++;
2249 if (inCriticalBlock) {
2250 werror(E_INVALID_CRITICAL);
2251 $$ = NULL;
2252 } else {
2253 $$ = newNode(RETURN,NULL,NULL);
2256 | RETURN expression ';' {
2257 seqPointNo++;
2258 if (inCriticalBlock) {
2259 werror(E_INVALID_CRITICAL);
2260 $$ = NULL;
2261 } else {
2262 $$ = newNode(RETURN,NULL,$2);
2267 /* C23 A.2.4 External definitions */
2269 translation_unit
2270 : external_declaration
2271 | translation_unit external_declaration
2274 external_declaration
2275 : function_definition
2277 // blockNo = 0;
2279 | declaration
2281 ignoreTypedefType = 0;
2282 if ($1 && $1->type && IS_FUNC($1->type))
2284 /* The only legal storage classes for
2285 * a function prototype (declaration)
2286 * are extern and static. extern is the
2287 * default. Thus, if this function isn't
2288 * explicitly marked static, mark it
2289 * extern.
2291 if ($1->etype && IS_SPEC($1->etype) && !SPEC_STAT($1->etype))
2293 SPEC_EXTR($1->etype) = 1;
2296 addSymChain (&$1);
2297 allocVariables ($1);
2298 cleanUpLevel (SymbolTab, 1);
2300 | addressmod
2302 /* These empty braces here are apparently required by some version of GNU bison on MS Windows. See bug #2858. */
2306 function_definition
2307 : declarator
2308 { /* function return type not specified, which is allowed in C90 (and means int), but disallowed in C99 and later */
2309 werror (W_RETURN_TYPE_OMITTED_INT);
2310 addDecl($1,0,newIntLink());
2311 $1 = createFunctionDecl($1);
2312 if ($1)
2314 if (FUNC_ISCRITICAL ($1->type))
2315 inCriticalFunction = 1;
2316 strncpyz (function_name, $1->name, sizeof (function_name) - 3);
2317 memset (function_name + sizeof (function_name) - 4, 0x00, 4);
2320 function_body
2322 // merge kr_declaration_list from auxiliary node into function declaration
2323 mergeKRDeclListIntoFuncDecl($1, (symbol *) $3->left);
2324 // discard auxiliary node and keep compound_statement as function_body
2325 $3 = $3->right;
2327 $$ = createFunction($1, $3);
2328 if ($1 && FUNC_ISCRITICAL ($1->type))
2329 inCriticalFunction = 0;
2331 | declaration_specifiers declarator
2333 sym_link *p = copyLinkChain($1);
2334 pointerTypes($2->type,p);
2335 addDecl($2,0,p);
2336 $2 = createFunctionDecl($2);
2337 if ($2)
2339 if (!strcmp ($2->name, "_sdcc_external_startup")) // The rename (and semantics change happened) in SDCC 4.2.10. Keep this warning for two major releases afterwards.
2340 werror (W__SDCC_EXTERNAL_STARTUP_DEF);
2341 if (FUNC_ISCRITICAL ($2->type))
2342 inCriticalFunction = 1;
2343 // warn for loss of calling convention for inlined functions.
2344 if (FUNC_ISINLINE ($2->type) &&
2345 ( FUNC_ISZ88DK_CALLEE ($2->type) || FUNC_ISZ88DK_FASTCALL ($2->type) ||
2346 FUNC_BANKED ($2->type) || FUNC_REGBANK ($2->type) ||
2347 FUNC_ISOVERLAY ($2->type) || FUNC_ISISR ($2->type) ))
2348 werror (W_INLINE_FUNCATTR, $2->name);
2349 strncpyz (function_name, $2->name, sizeof (function_name) - 3);
2350 memset (function_name + sizeof (function_name) - 4, 0x00, 4);
2353 function_body
2355 // merge kr_declaration_list from auxiliary node into function declaration
2356 mergeKRDeclListIntoFuncDecl($2, (symbol *) $4->left);
2357 // discard auxiliary node and keep compound_statement as function_body
2358 $4 = $4->right;
2360 $$ = createFunction($2, $4);
2361 if ($2 && FUNC_ISCRITICAL ($2->type))
2362 inCriticalFunction = 0;
2366 function_body
2367 : compound_statement
2369 // auxiliary node transports kr_declaration_list into function_definition, where the node is discarded
2370 $$ = newNode (0, NULL, $1);
2372 | kr_declaration_list compound_statement
2374 // auxiliary node transports kr_declaration_list into function_definition, where the node is discarded
2375 $$ = newNode (0, (ast *) $1, $2);
2379 /* SDCC-specific stuff */
2381 file
2382 : /* empty */
2384 werror(W_EMPTY_TRANSLATION_UNIT);
2386 | translation_unit
2392 function_attributes
2393 : function_attribute
2394 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
2397 function_attribute
2398 : USING '(' constant_expr ')' {
2399 $$ = newLink(SPECIFIER);
2400 FUNC_REGBANK($$) = (int) ulFromVal(constExprValue($3, true));
2402 | REENTRANT { $$ = newLink (SPECIFIER);
2403 FUNC_ISREENT($$)=1;
2405 | CRITICAL { $$ = newLink (SPECIFIER);
2406 FUNC_ISCRITICAL($$) = 1;
2408 | NAKED { $$ = newLink (SPECIFIER);
2409 FUNC_ISNAKED($$)=1;
2411 | JAVANATIVE { $$ = newLink (SPECIFIER);
2412 FUNC_ISJAVANATIVE($$)=1;
2414 | OVERLAY { $$ = newLink (SPECIFIER);
2415 FUNC_ISOVERLAY($$)=1;
2417 | NONBANKED {$$ = newLink (SPECIFIER);
2418 FUNC_NONBANKED($$) = 1;
2419 if (FUNC_BANKED($$)) {
2420 werror(W_BANKED_WITH_NONBANKED);
2423 | SHADOWREGS {$$ = newLink (SPECIFIER);
2424 FUNC_ISSHADOWREGS($$) = 1;
2426 | SD_WPARAM {$$ = newLink (SPECIFIER);
2427 FUNC_ISWPARAM($$) = 1;
2429 | BANKED {$$ = newLink (SPECIFIER);
2430 FUNC_BANKED($$) = 1;
2431 if (FUNC_NONBANKED($$)) {
2432 werror(W_BANKED_WITH_NONBANKED);
2435 | Interrupt_storage
2437 $$ = newLink (SPECIFIER);
2438 FUNC_INTNO($$) = $1;
2439 FUNC_ISISR($$) = 1;
2441 | TRAP
2443 $$ = newLink (SPECIFIER);
2444 FUNC_INTNO($$) = INTNO_TRAP;
2445 FUNC_ISISR($$) = 1;
2447 | SMALLC { $$ = newLink (SPECIFIER);
2448 FUNC_ISSMALLC($$) = 1;
2450 | RAISONANCE { $$ = newLink (SPECIFIER);
2451 FUNC_ISRAISONANCE($$) = 1;
2453 | IAR { $$ = newLink (SPECIFIER);
2454 FUNC_ISIAR($$) = 1;
2456 | COSMIC { $$ = newLink (SPECIFIER);
2457 FUNC_ISCOSMIC($$) = 1;
2459 | SDCCCALL '(' constant_expr ')'
2460 { $$ = newLink (SPECIFIER);
2461 FUNC_SDCCCALL($$) = ulFromVal(constExprValue ($3, true));
2463 | Z88DK_FASTCALL { $$ = newLink (SPECIFIER);
2464 FUNC_ISZ88DK_FASTCALL($$) = 1;
2466 | Z88DK_CALLEE { $$ = newLink (SPECIFIER);
2467 FUNC_ISZ88DK_CALLEE($$) = 1;
2469 | Z88DK_PARAMS_OFFSET '(' constant_expr ')'
2471 value *offset_v = constExprValue ($3, true);
2472 int offset = 0;
2473 $$ = newLink(SPECIFIER);
2474 if ( offset_v )
2475 offset = ulFromVal(offset_v);
2476 $$->funcAttrs.z88dk_params_offset = offset;
2478 | Z88DK_SHORTCALL '(' constant_expr ',' constant_expr ')'
2480 value *rst_v = constExprValue ($3, true);
2481 value *value_v = constExprValue ($5, true);
2482 int rst = -1, value = -1;
2483 $$ = newLink(SPECIFIER);
2485 if ( rst_v )
2486 rst = ulFromVal(rst_v);
2487 if ( value_v )
2488 value = ulFromVal(value_v);
2490 if ( rst < 0 || rst > 56 || ( rst % 8 ) )
2492 werror(E_SHORTCALL_INVALID_VALUE, "rst", rst);
2494 if ( value < 0 || value > 0xfff )
2496 werror(E_SHORTCALL_INVALID_VALUE, "value", value);
2498 $$->funcAttrs.z88dk_shortcall_rst = rst;
2499 $$->funcAttrs.z88dk_shortcall_val = value;
2500 FUNC_ISZ88DK_SHORTCALL($$) = 1;
2502 | PRESERVES_REGS '(' identifier_list ')'
2504 const struct symbol *regsym;
2505 $$ = newLink (SPECIFIER);
2507 for(regsym = $3; regsym; regsym = regsym->next)
2509 int regnum;
2511 if (!port->getRegByName || ((regnum = port->getRegByName(regsym->name)) < 0))
2512 werror (W_UNKNOWN_REG, regsym->name);
2513 else
2514 $$->funcAttrs.preserved_regs[regnum] = true;
2519 offsetof_member_designator
2520 : identifier { $$ = newAst_VALUE (symbolVal ($1)); }
2521 | offsetof_member_designator '.' { ignoreTypedefType = 1; } identifier
2523 ignoreTypedefType = 0;
2524 $4 = newSymbol ($4->name, NestLevel);
2525 $4->implicit = 1;
2526 $$ = newNode ('.', $1, newAst_VALUE (symbolVal ($4)));
2528 | offsetof_member_designator '[' expression ']'
2530 $$ = newNode ('[', $1, $3);
2534 string_literal_val
2535 : FUNC
2537 // essentially do $$ = newAst_VALUE (strVal("\"$function_name\""));
2539 value* val = newValue ();
2540 { // BUG: duplicate from strVal
2541 val->type = newLink (DECLARATOR);
2542 DCL_TYPE (val->type) = ARRAY;
2543 val->type->next = val->etype = newLink (SPECIFIER);
2544 SPEC_SCLS (val->etype) = S_LITERAL;
2545 SPEC_CONST (val->etype) = 1;
2546 SPEC_NOUN (val->etype) = V_CHAR;
2547 SPEC_USIGN (val->etype) = !options.signed_char;
2548 val->etype->select.s.b_implicit_sign = true;
2551 int ll = 1 + strlen(function_name);
2552 char* s = (char*) Safe_alloc(ll*sizeof(char));
2553 if(ll > 1){
2554 s = strncpy(s, function_name, ll);
2555 }else{
2556 *s = 0;
2558 SPEC_CVAL (val->etype).v_char = s;
2559 DCL_ELEM (val->type) = ll;
2560 $$ = newAst_VALUE ( val );
2562 | STRING_LITERAL { $$ = newAst_VALUE (strVal ($1)); }
2565 Interrupt_storage
2566 : INTERRUPT { $$ = INTNO_UNSPEC; }
2567 | INTERRUPT '(' constant_expr ')'
2569 value *val = constExprValue($3, true);
2570 int intno = (int) ulFromVal(val);
2571 if (val && (intno >= 0) && (intno <= INTNO_MAX))
2572 $$ = intno;
2573 else
2575 werror(E_INT_BAD_INTNO, intno);
2576 $$ = INTNO_UNSPEC;
2581 sfr_reg_bit
2582 : SBIT {
2583 $$ = newLink(SPECIFIER);
2584 SPEC_NOUN($$) = V_SBIT;
2585 SPEC_SCLS($$) = S_SBIT;
2586 SPEC_BLEN($$) = 1;
2587 SPEC_BSTR($$) = 0;
2588 ignoreTypedefType = 1;
2590 | sfr_attributes
2593 sfr_attributes
2594 : SFR {
2595 $$ = newLink(SPECIFIER);
2596 FUNC_REGBANK($$) = 0;
2597 SPEC_NOUN($$) = V_CHAR;
2598 SPEC_SCLS($$) = S_SFR;
2599 SPEC_USIGN($$) = 1;
2600 ignoreTypedefType = 1;
2602 | SFR BANKED {
2603 $$ = newLink(SPECIFIER);
2604 FUNC_REGBANK($$) = 1;
2605 SPEC_NOUN($$) = V_CHAR;
2606 SPEC_SCLS($$) = S_SFR;
2607 SPEC_USIGN($$) = 1;
2608 ignoreTypedefType = 1;
2612 sfr_attributes
2613 : SFR16 {
2614 $$ = newLink(SPECIFIER);
2615 FUNC_REGBANK($$) = 0;
2616 SPEC_NOUN($$) = V_INT;
2617 SPEC_SCLS($$) = S_SFR;
2618 SPEC_USIGN($$) = 1;
2619 ignoreTypedefType = 1;
2623 sfr_attributes
2624 : SFR32 {
2625 $$ = newLink(SPECIFIER);
2626 FUNC_REGBANK($$) = 0;
2627 SPEC_NOUN($$) = V_INT;
2628 SPEC_SCLS($$) = S_SFR;
2629 SPEC_LONG($$) = 1;
2630 SPEC_USIGN($$) = 1;
2631 ignoreTypedefType = 1;
2635 opt_stag
2636 : stag
2637 | { /* synthesize a name add to structtable */
2638 ignoreTypedefType = 0;
2639 $$ = newStruct(genSymName(NestLevel));
2640 $$->level = NestLevel;
2641 $$->block = currBlockno;
2642 $$->tagsym = NULL;
2643 //addSym (StructTab, $$, $$->tag, $$->level, currBlockno, 0);
2647 stag
2648 : identifier
2649 { /* add name to structure table */
2650 ignoreTypedefType = 0;
2651 $$ = newStruct($1->name);
2652 $$->level = NestLevel;
2653 $$->block = currBlockno;
2654 $$->tagsym = $1;
2655 //$$ = findSymWithBlock (StructTab, $1, currBlockno);
2656 //if (! $$ )
2657 // {
2658 // $$ = newStruct($1->name);
2659 // $$->level = NestLevel;
2660 // $$->tagsym = $1;
2661 // //addSym (StructTab, $$, $$->tag, $$->level, currBlockno, 0);
2662 // }
2666 opt_assign_expr
2667 : '=' constant_expr
2669 value *val;
2671 val = constExprValue($2, true);
2672 if (!val) // Not a constant expression
2674 werror (E_CONST_EXPECTED);
2675 val = constIntVal("0");
2677 else if (!IS_INT(val->type) && !IS_CHAR(val->type) && !IS_BOOL(val->type))
2679 werror(E_ENUM_NON_INTEGER);
2680 SNPRINTF(lbuff, sizeof(lbuff), "%lld", (long long int) ullFromVal(val));
2681 val = constVal(lbuff);
2683 $$ = cenum = val;
2686 if (cenum)
2688 SNPRINTF(lbuff, sizeof(lbuff), "%lld", (long long int) ullFromVal(cenum)+1);
2689 $$ = cenum = constVal(lbuff);
2691 else
2693 $$ = cenum = constCharVal(0);
2698 specifier_qualifier_list : type_specifier_list_ { $$ = finalizeSpec($1); };
2700 type_specifier_list_
2701 : type_specifier_qualifier
2702 //| type_specifier_list_ type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
2703 | type_specifier_list_ type_specifier_qualifier {
2704 /* if the decl $2 is not a specifier */
2705 /* find the spec and replace it */
2706 $$ = mergeDeclSpec($1, $2, "type_specifier_list type_specifier skipped");
2710 type_specifier_list_without_struct_or_union
2711 : type_specifier_qualifier_without_struct_or_union
2712 | type_specifier_list_without_struct_or_union type_specifier_qualifier_without_struct_or_union
2714 /* if the decl $2 is not a specifier */
2715 /* find the spec and replace it */
2716 $$ = mergeDeclSpec($1, $2, "type_specifier_list type_specifier skipped");
2720 identifier_list
2721 : identifier
2722 | identifier_list ',' identifier
2724 $3->next = $1;
2725 $$ = $3;
2729 type_name
2730 : declaration_specifiers
2732 if (IS_SPEC ($1) && !IS_VALID_PARAMETER_STORAGE_CLASS_SPEC ($1))
2734 werror (E_STORAGE_CLASS_FOR_PARAMETER, "type name");
2736 $$ = $1; ignoreTypedefType = 0;
2738 | declaration_specifiers abstract_declarator
2740 /* go to the end of the list */
2741 sym_link *p;
2743 if (IS_SPEC ($1) && !IS_VALID_PARAMETER_STORAGE_CLASS_SPEC ($1))
2745 werror (E_STORAGE_CLASS_FOR_PARAMETER, "type name");
2747 pointerTypes ($2,$1);
2748 for (p = $2; p && p->next; p = p->next)
2750 if (!p)
2752 werror(E_SYNTAX_ERROR, yytext);
2754 else
2756 p->next = $1;
2758 $$ = $2;
2759 ignoreTypedefType = 0;
2763 critical
2764 : CRITICAL {
2765 if (inCriticalFunction || inCriticalBlock)
2766 werror(E_INVALID_CRITICAL);
2767 inCriticalBlock = 1;
2768 STACK_PUSH(continueStack,NULL);
2769 STACK_PUSH(breakStack,NULL);
2770 $$ = NULL;
2774 critical_statement
2775 : critical statement {
2776 STACK_POP(breakStack);
2777 STACK_POP(continueStack);
2778 $$ = newNode(CRITICAL,$2,NULL);
2779 inCriticalBlock = 0;
2783 statements_and_implicit
2784 : statement_list
2785 | statement_list implicit_block
2787 $$ = newNode(NULLOP, $1, $2);
2788 if (!options.std_c99)
2789 werror(E_DECL_AFTER_STATEMENT_C99);
2793 declaration_after_statement
2795 NestLevel += SUBLEVEL_UNIT;
2796 STACK_PUSH(blockNum, currBlockno);
2797 btree_add_child(currBlockno, ++blockNo);
2798 currBlockno = blockNo;
2799 ignoreTypedefType = 0;
2801 declaration_list { $$ = $2; }
2804 implicit_block
2805 : declaration_after_statement statements_and_implicit
2807 leaveBlockScope (currBlockno);
2808 NestLevel -= SUBLEVEL_UNIT;
2809 currBlockno = STACK_POP(blockNum);
2810 $$ = createBlock($1, $2);
2811 cleanUpLevel(StructTab, NestLevel + SUBLEVEL_UNIT);
2813 | declaration_after_statement
2815 leaveBlockScope (currBlockno);
2816 NestLevel -= SUBLEVEL_UNIT;
2817 currBlockno = STACK_POP(blockNum);
2818 $$ = createBlock($1, NULL);
2819 cleanUpLevel(StructTab, NestLevel + SUBLEVEL_UNIT);
2823 declaration_list
2824 : declaration
2826 /* if this is typedef declare it immediately */
2827 if ( $1 && IS_TYPEDEF($1->etype)) {
2828 allocVariables ($1);
2829 $$ = NULL;
2831 else
2832 $$ = $1;
2833 ignoreTypedefType = 0;/*printf("1 %s %d %d\n", $1->name, IS_ARRAY ($1->type), DCL_ARRAY_VLA ($1->type));
2834 if (IS_ARRAY ($1->type) && DCL_ARRAY_VLA ($1->type))
2835 werror (E_VLA_OBJECT);
2836 else*/
2837 addSymChain(&$1);
2840 | declaration_list declaration
2842 symbol *sym;
2844 /* if this is a typedef */
2845 if ($2 && IS_TYPEDEF($2->etype)) {
2846 allocVariables ($2);
2847 $$ = $1;
2849 else {
2850 /* get to the end of the previous decl */
2851 if ( $1 ) {
2852 $$ = sym = $1;
2853 while (sym->next)
2854 sym = sym->next;
2855 sym->next = $2;
2857 else
2858 $$ = $2;
2860 ignoreTypedefType = 0;/*printf("2 %s %d %d\n", $1->name, IS_ARRAY ($1->type), DCL_ARRAY_VLA ($1->type));
2861 if (IS_ARRAY ($2->type) && DCL_ARRAY_VLA ($2->type))
2862 werror (E_VLA_OBJECT);
2863 else*/
2864 addSymChain(&$2);
2868 // The parameter declarations in K&R-style functions need to be handled in a special way to avoid
2869 // ambiguities in the grammer. We do this by not allowing attributes on the parameter declarations.
2870 // Otherwise, in e.g.
2871 // void f(x) [[attribute]] int x; {}
2872 // it would be unclear if the attribute applies to the type of f vs. the declaration of x.
2873 kr_declaration
2874 : declaration_specifiers init_declarator_list ';'
2876 /* add the specifier list to the id */
2877 symbol *sym , *sym1;
2879 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
2880 sym_link *lnk = copyLinkChain($1);
2881 sym_link *l0 = NULL, *l1 = NULL, *l2 = NULL;
2882 /* check illegal declaration */
2883 for (l0 = sym->type; l0 != NULL; l0 = l0->next)
2884 if (IS_PTR (l0))
2885 break;
2886 /* check if creating instances of structs with flexible arrays */
2887 for (l1 = lnk; l1 != NULL; l1 = l1->next)
2888 if (IS_STRUCT (l1) && SPEC_STRUCT (l1)->b_flexArrayMember)
2889 break;
2890 if (!options.std_c99 && l0 == NULL && l1 != NULL && SPEC_EXTR($1) != 1)
2891 werror (W_FLEXARRAY_INSTRUCT, sym->name);
2892 /* check if creating instances of function type */
2893 for (l1 = lnk; l1 != NULL; l1 = l1->next)
2894 if (IS_FUNC (l1))
2895 break;
2896 for (l2 = lnk; l2 != NULL; l2 = l2->next)
2897 if (IS_PTR (l2))
2898 break;
2899 if (l0 == NULL && l2 == NULL && l1 != NULL)
2900 werrorfl(sym->fileDef, sym->lineDef, E_TYPE_IS_FUNCTION, sym->name);
2901 /* do the pointer stuff */
2902 pointerTypes(sym->type,lnk);
2903 addDecl (sym,0,lnk);
2906 uselessDecl = true;
2907 $$ = sym1;
2911 kr_declaration_list
2912 : kr_declaration
2914 /* if this is typedef declare it immediately */
2915 if ( $1 && IS_TYPEDEF($1->etype)) {
2916 allocVariables ($1);
2917 $$ = NULL;
2918 ignoreTypedefType = 0;
2919 addSymChain(&$1);
2921 else {
2922 checkTypeSanity($1->etype, $1->name);
2923 $$ = $1;
2926 | kr_declaration_list kr_declaration
2928 symbol *sym;
2930 /* if this is a typedef */
2931 if ($2 && IS_TYPEDEF($2->etype)) {
2932 allocVariables ($2);
2933 $$ = $1;
2934 ignoreTypedefType = 0;
2935 addSymChain(&$2);
2937 else {
2938 checkTypeSanity($2->etype, $2->name);
2939 /* get to the end of the previous decl */
2940 if ( $1 ) {
2941 $$ = sym = $1;
2942 while (sym->next)
2943 sym = sym->next;
2944 sym->next = $2;
2946 else
2947 $$ = $2;
2952 statement_list
2953 : unlabeled_statement { $$ = $1; }
2954 | label { $$ = $1; }
2955 | statement_list unlabeled_statement { $$ = newNode(NULLOP,$1,$2);}
2956 | statement_list label { $$ = newNode(NULLOP,$1,$2);}
2959 while : WHILE { /* create and push the continue , break & body labels */
2960 static int Lblnum = 0;
2961 /* continue */
2962 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
2963 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
2964 /* break */
2965 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
2966 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
2967 /* body */
2968 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
2969 $$ = newSymbol(lbuff,NestLevel);
2973 do : DO { /* create and push the continue , break & body Labels */
2974 static int Lblnum = 0;
2976 /* continue */
2977 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
2978 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
2979 /* break */
2980 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
2981 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
2982 /* do body */
2983 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
2984 $$ = newSymbol (lbuff,NestLevel);
2988 for : FOR { /* create & push continue, break & body labels */
2989 static int Lblnum = 0;
2991 NestLevel += LEVEL_UNIT;
2992 STACK_PUSH(blockNum, currBlockno);
2993 btree_add_child(currBlockno, ++blockNo);
2994 currBlockno = blockNo;
2995 ignoreTypedefType = 0;
2997 /* continue */
2998 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
2999 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
3000 /* break */
3001 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
3002 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
3003 /* body */
3004 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
3005 $$ = newSymbol(lbuff,NestLevel);
3006 /* condition */
3007 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
3008 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
3012 asm_string_literal
3013 : STRING_LITERAL
3016 asm_statement
3017 : ASM '(' asm_string_literal ')' ';'
3019 ast *ex;
3021 seqPointNo++;
3022 ex = newNode(INLINEASM, NULL, NULL);
3023 ex->values.inlineasm = strdup(copyStr ($3, NULL));
3024 seqPointNo++;
3025 $$ = ex;
3027 | INLINEASM ';'
3029 ast *ex;
3031 seqPointNo++;
3032 ex = newNode(INLINEASM, NULL, NULL);
3033 ex->values.inlineasm = strdup($1);
3034 seqPointNo++;
3035 $$ = ex;
3039 addressmod
3040 : ADDRESSMOD identifier identifier ';' {
3041 symbol *sym;
3042 if ((sym = findSymWithLevel (AddrspaceTab, $3)) && sym->level == $3->level)
3043 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF);
3044 if (!findSymWithLevel (SymbolTab, $2))
3045 werror (E_ID_UNDEF, $2->name);
3046 addSym (AddrspaceTab, $3, $3->name, $3->level, $3->block, 0);
3047 sym = findSymWithLevel (AddrspaceTab, $3);
3048 sym->addressmod[0] = findSymWithLevel (SymbolTab, $2);
3049 sym->addressmod[1] = 0;
3051 | ADDRESSMOD identifier SD_CONST identifier ';' {
3052 symbol *sym;
3053 sym_link *type;
3054 if ((sym = findSymWithLevel (AddrspaceTab, $4)) && sym->level == $4->level)
3055 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF);
3056 if (!findSymWithLevel (SymbolTab, $2))
3057 werror (E_ID_UNDEF, $2->name);
3058 addSym (AddrspaceTab, $4, $4->name, $4->level, $4->block, 0);
3059 sym = findSymWithLevel (AddrspaceTab, $4);
3060 sym->addressmod[0] = findSymWithLevel (SymbolTab, $2);
3061 sym->addressmod[1] = 0;
3062 type = newLink (SPECIFIER);
3063 SPEC_CONST(type) = 1;
3064 sym->type = sym->etype = type;
3068 identifier
3069 : IDENTIFIER { $$ = newSymbol ($1, NestLevel); }