1 /*-----------------------------------------------------------------------
3 SDCC.y - parser definition file for sdcc :
4 Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 #include "SDCCglobl.h"
30 #include "SDCChasht.h"
39 extern int yyerror (char *);
41 int NestLevel = 0 ; /* current NestLevel */
42 int stackPtr = 1 ; /* stack pointer */
43 int xstackPtr = 0 ; /* xstack pointer */
45 int blockNo = 0 ; /* sequential block number */
48 int seqPointNo= 1 ; /* sequence point number */
49 int ignoreTypedefType=0;
53 char lbuff[1024]; /* local buffer */
55 /* break & continue stacks */
56 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
58 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
59 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
60 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
62 value *cenum = NULL ; /* current enumeration type chain*/
63 bool uselessDecl = TRUE;
71 symbol *sym ; /* symbol table pointer */
72 structdef *sdef; /* structure definition */
73 char yychar[SDCC_NAME_MAX+1];
74 sym_link *lnk ; /* declarator or specifier */
75 int yyint; /* integer value returned */
76 value *val ; /* for integer constant */
77 initList *ilist; /* initial list */
78 const char *yyinline; /* inlined assembler code */
79 ast *asts; /* expression tree */
82 %token <yychar> IDENTIFIER TYPE_NAME
83 %token <val> CONSTANT STRING_LITERAL
85 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
87 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
88 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
89 %token <yyint> XOR_ASSIGN OR_ASSIGN
90 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR SFR16 SFR32
91 %token AT SBIT REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
92 %token NONBANKED BANKED SHADOWREGS WPARAM
93 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE FIXED16X16 CONST VOLATILE VOID BIT
94 %token STRUCT UNION ENUM RANGE FAR
95 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
96 %token NAKED JAVANATIVE OVERLAY
97 %token <yyinline> INLINEASM
98 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT GETABIT GETBYTE GETWORD
99 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
101 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
102 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE RESTRICT
104 %type <yyint> Interrupt_storage
105 %type <sym> identifier identifier_or_typename declarator declarator2 declarator3
106 %type <sym> enumerator_list enumerator
107 %type <sym> struct_declarator function_declarator function_declarator2
108 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
109 %type <sym> declaration init_declarator_list init_declarator
110 %type <sym> declaration_list identifier_list
111 %type <sym> declarator2_function_attributes while do for critical
112 %type <lnk> pointer type_specifier_list type_specifier type_name
113 %type <lnk> storage_class_specifier struct_or_union_specifier function_specifier
114 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
115 %type <lnk> function_attribute function_attributes enum_specifier
116 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
117 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
118 %type <sdef> stag opt_stag
119 %type <asts> primary_expr
120 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
121 %type <asts> additive_expr shift_expr relational_expr equality_expr
122 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
123 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
124 %type <asts> expr argument_expr_list function_definition expr_opt
125 %type <asts> statement_list statement labeled_statement compound_statement
126 %type <asts> expression_statement selection_statement iteration_statement
127 %type <asts> jump_statement function_body else_statement string_literal
128 %type <asts> critical_statement
129 %type <ilist> initializer initializer_list
130 %type <yyint> unary_operator assignment_operator struct_or_union
138 { if (!options.lessPedantic)
139 werror(W_EMPTY_SOURCE_FILE);
145 : external_definition
146 | program external_definition
150 : function_definition {
154 ignoreTypedefType = 0;
156 && IS_FUNC($1->type))
158 /* The only legal storage classes for
159 * a function prototype (declaration)
160 * are extern and static. extern is the
161 * default. Thus, if this function isn't
162 * explicitly marked static, mark it
166 && IS_SPEC($1->etype)
167 && !SPEC_STAT($1->etype))
169 SPEC_EXTR($1->etype) = 1;
173 allocVariables ($1) ;
174 cleanUpLevel (SymbolTab,1);
179 : function_declarator function_body { /* function type not specified */
180 /* assume it to be 'int' */
181 addDecl($1,0,newIntLink());
182 $$ = createFunction($1,$2);
184 | declaration_specifiers function_declarator function_body
186 pointerTypes($2->type,copyLinkChain($1));
187 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
190 $$ = createFunction($2,$3);
195 : function_attributes
196 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
200 : USING constant_expr {
201 $$ = newLink(SPECIFIER) ;
202 FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
204 | REENTRANT { $$ = newLink (SPECIFIER);
207 | CRITICAL { $$ = newLink (SPECIFIER);
208 FUNC_ISCRITICAL($$) = 1;
210 | NAKED { $$ = newLink (SPECIFIER);
213 | JAVANATIVE { $$ = newLink (SPECIFIER);
214 FUNC_ISJAVANATIVE($$)=1;
216 | OVERLAY { $$ = newLink (SPECIFIER);
217 FUNC_ISOVERLAY($$)=1;
219 | NONBANKED {$$ = newLink (SPECIFIER);
220 FUNC_NONBANKED($$) = 1;
221 if (FUNC_BANKED($$)) {
222 werror(W_BANKED_WITH_NONBANKED);
225 | SHADOWREGS {$$ = newLink (SPECIFIER);
226 FUNC_ISSHADOWREGS($$) = 1;
228 | WPARAM {$$ = newLink (SPECIFIER);
229 FUNC_ISWPARAM($$) = 1;
231 | BANKED {$$ = newLink (SPECIFIER);
233 if (FUNC_NONBANKED($$)) {
234 werror(W_BANKED_WITH_NONBANKED);
237 werror(W_BANKED_WITH_STATIC);
242 $$ = newLink (SPECIFIER) ;
243 FUNC_INTNO($$) = $1 ;
250 | declaration_list compound_statement
252 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
258 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
259 | CONSTANT { $$ = newAst_VALUE($1); }
261 | '(' expr ')' { $$ = $2 ; }
265 : STRING_LITERAL { $$ = newAst_VALUE($1); }
270 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
271 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
272 $$->left->funcName = 1;}
273 | postfix_expr '(' argument_expr_list ')'
275 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
277 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
279 ignoreTypedefType = 0;
280 $4 = newSymbol($4->name,NestLevel);
282 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
283 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
285 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
287 ignoreTypedefType = 0;
288 $4 = newSymbol($4->name,NestLevel);
290 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
292 | postfix_expr INC_OP
293 { $$ = newNode(INC_OP,$1,NULL);}
294 | postfix_expr DEC_OP
295 { $$ = newNode(DEC_OP,$1,NULL); }
300 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
305 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
306 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
307 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
308 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
309 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
310 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
324 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
329 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
330 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
331 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
335 : multiplicative_expr
336 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
337 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
342 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
343 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
348 | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);}
349 | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);}
350 | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);}
351 | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);}
356 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
357 | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
362 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
367 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
372 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
377 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
378 { $$ = newNode(AND_OP,$1,$4);}
383 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
384 { $$ = newNode(OR_OP,$1,$4); }
389 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
391 $$ = newNode(':',$4,$6) ;
392 $$ = newNode('?',$1,$$) ;
398 | cast_expr assignment_operator assignment_expr
403 $$ = newNode($2,$1,$3);
406 $$ = createRMW($1, '*', $3);
409 $$ = createRMW($1, '/', $3);
412 $$ = createRMW($1, '%', $3);
415 $$ = createRMW($1, '+', $3);
418 $$ = createRMW($1, '-', $3);
421 $$ = createRMW($1, LEFT_OP, $3);
424 $$ = createRMW($1, RIGHT_OP, $3);
427 $$ = createRMW($1, '&', $3);
430 $$ = createRMW($1, '^', $3);
433 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
434 /* $$ = newNode('=',removePostIncDecOps(copyAst($1)),
435 newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
436 $$ = createRMW($1, '|', $3);
461 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
469 : declaration_specifiers ';'
472 werror(W_USELESS_DECL);
476 | declaration_specifiers init_declarator_list ';'
478 /* add the specifier list to the id */
481 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
482 sym_link *lnk = copyLinkChain($1);
483 if (options.unsigned_char && SPEC_NOUN(lnk) == V_CHAR && !lnk->select.s.b_signed)
485 /* do the pointer stuff */
486 pointerTypes(sym->type,lnk);
487 addDecl (sym,0,lnk) ;
495 declaration_specifiers
496 : storage_class_specifier { $$ = $1; }
497 | storage_class_specifier declaration_specifiers {
498 /* if the decl $2 is not a specifier */
499 /* find the spec and replace it */
502 while (lnk && !IS_SPEC(lnk->next))
504 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
508 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
510 | type_specifier { $$ = $1; }
511 | type_specifier declaration_specifiers {
512 /* if the decl $2 is not a specifier */
513 /* find the spec and replace it */
516 while (lnk && !IS_SPEC(lnk->next))
518 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
522 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
524 | function_specifier { $$ = $1; }
525 | function_specifier declaration_specifiers {
526 /* if the decl $2 is not a specifier */
527 /* find the spec and replace it */
530 while (lnk && !IS_SPEC(lnk->next))
532 lnk->next = mergeSpec($1,lnk->next, "function_specifier declaration_specifiers - skipped");
536 $$ = mergeSpec($1,$2, "function_specifier declaration_specifiers");
542 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
546 : declarator { $1->ival = NULL ; }
547 | declarator '=' initializer { $1->ival = $3 ; }
551 storage_class_specifier
553 $$ = newLink (SPECIFIER) ;
554 SPEC_TYPEDEF($$) = 1 ;
557 $$ = newLink(SPECIFIER);
561 $$ = newLink (SPECIFIER);
565 $$ = newLink (SPECIFIER) ;
566 SPEC_SCLS($$) = S_AUTO ;
569 $$ = newLink (SPECIFIER);
570 SPEC_SCLS($$) = S_REGISTER ;
576 $$ = newLink (SPECIFIER) ;
577 SPEC_INLINE($$) = 1 ;
582 : INTERRUPT { $$ = INTNO_UNSPEC ; }
583 | INTERRUPT constant_expr
584 { int intno = (int) floatFromVal(constExprValue($2,TRUE));
585 if ((intno >= 0) && (intno <= INTNO_MAX))
589 werror(E_INT_BAD_INTNO, intno);
597 | type_specifier2 AT constant_expr
599 /* add this to the storage class specifier */
600 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
601 /* now get the abs addr from value */
602 SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
608 $$=newLink(SPECIFIER);
609 SPEC_NOUN($$) = V_CHAR ;
610 ignoreTypedefType = 1;
613 $$=newLink(SPECIFIER);
615 ignoreTypedefType = 1;
618 $$=newLink(SPECIFIER);
619 SPEC_NOUN($$) = V_INT ;
620 ignoreTypedefType = 1;
623 $$=newLink(SPECIFIER);
625 ignoreTypedefType = 1;
628 $$=newLink(SPECIFIER);
629 $$->select.s.b_signed = 1;
630 ignoreTypedefType = 1;
633 $$=newLink(SPECIFIER);
635 ignoreTypedefType = 1;
638 $$=newLink(SPECIFIER);
639 SPEC_NOUN($$) = V_VOID ;
640 ignoreTypedefType = 1;
643 $$=newLink(SPECIFIER);
647 $$=newLink(SPECIFIER);
648 SPEC_VOLATILE($$) = 1 ;
651 $$=newLink(SPECIFIER);
652 SPEC_RESTRICT($$) = 1 ;
655 $$=newLink(SPECIFIER);
656 SPEC_NOUN($$) = V_FLOAT;
657 ignoreTypedefType = 1;
660 $$=newLink(SPECIFIER);
661 SPEC_NOUN($$) = V_FIXED16X16;
662 ignoreTypedefType = 1;
665 $$ = newLink (SPECIFIER);
666 SPEC_SCLS($$) = S_XDATA ;
669 $$ = newLink (SPECIFIER) ;
670 SPEC_SCLS($$) = S_CODE ;
673 $$ = newLink (SPECIFIER) ;
674 SPEC_SCLS($$) = S_EEPROM ;
677 $$ = newLink (SPECIFIER);
678 SPEC_SCLS($$) = S_DATA ;
681 $$ = newLink (SPECIFIER);
682 SPEC_SCLS($$) = S_IDATA ;
685 $$ = newLink (SPECIFIER);
686 SPEC_SCLS($$) = S_PDATA ;
689 $$=newLink(SPECIFIER);
690 SPEC_NOUN($$) = V_BIT ;
691 SPEC_SCLS($$) = S_BIT ;
694 ignoreTypedefType = 1;
697 | struct_or_union_specifier {
700 ignoreTypedefType = 1;
705 ignoreTypedefType = 1;
712 sym = findSym(TypedefTab,NULL,$1) ;
713 $$ = p = copyLinkChain(sym->type);
714 SPEC_TYPEDEF(getSpec(p)) = 0;
715 ignoreTypedefType = 1;
722 $$ = newLink(SPECIFIER) ;
723 SPEC_NOUN($$) = V_SBIT;
724 SPEC_SCLS($$) = S_SBIT;
727 ignoreTypedefType = 1;
734 $$ = newLink(SPECIFIER) ;
735 FUNC_REGBANK($$) = 0;
736 SPEC_NOUN($$) = V_CHAR;
737 SPEC_SCLS($$) = S_SFR ;
739 ignoreTypedefType = 1;
742 $$ = newLink(SPECIFIER) ;
743 FUNC_REGBANK($$) = 1;
744 SPEC_NOUN($$) = V_CHAR;
745 SPEC_SCLS($$) = S_SFR ;
747 ignoreTypedefType = 1;
753 $$ = newLink(SPECIFIER) ;
754 FUNC_REGBANK($$) = 0;
755 SPEC_NOUN($$) = V_INT;
756 SPEC_SCLS($$) = S_SFR;
758 ignoreTypedefType = 1;
764 $$ = newLink(SPECIFIER) ;
765 FUNC_REGBANK($$) = 0;
766 SPEC_NOUN($$) = V_INT;
767 SPEC_SCLS($$) = S_SFR;
770 ignoreTypedefType = 1;
774 struct_or_union_specifier
775 : struct_or_union opt_stag
784 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
788 '{' struct_declaration_list '}'
793 // check for errors in structure members
794 for (sym=$5; sym; sym=sym->next) {
795 if (IS_ABSOLUTE(sym->etype)) {
796 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
797 SPEC_ABSA(sym->etype) = 0;
799 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
800 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
801 printTypeChainRaw (sym->type,NULL);
802 SPEC_SCLS(sym->etype) = 0;
804 for (dsym=sym->next; dsym; dsym=dsym->next) {
805 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
806 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
807 $1==STRUCT ? "struct" : "union", sym->name);
808 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
813 /* Create a structdef */
815 sdef->fields = reverseSyms($5) ; /* link the fields */
816 sdef->size = compStructSize($1,sdef); /* update size of */
817 promoteAnonStructs ($1, sdef);
819 /* Create the specifier */
820 $$ = newLink (SPECIFIER) ;
821 SPEC_NOUN($$) = V_STRUCT;
822 SPEC_STRUCT($$)= sdef ;
824 | struct_or_union stag
826 $$ = newLink(SPECIFIER) ;
827 SPEC_NOUN($$) = V_STRUCT;
828 SPEC_STRUCT($$) = $2;
837 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
843 : STRUCT { $$ = STRUCT ; }
844 | UNION { $$ = UNION ; }
849 | { /* synthesize a name add to structtable */
850 $$ = newStruct(genSymName(NestLevel)) ;
851 $$->level = NestLevel ;
852 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
856 : identifier { /* add name to structure table */
857 $$ = findSymWithBlock (StructTab,$1,currBlockno);
859 $$ = newStruct($1->name) ;
860 $$->level = NestLevel ;
861 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
866 struct_declaration_list
868 | struct_declaration_list struct_declaration
872 /* go to the end of the chain */
873 while (sym->next) sym=sym->next;
881 : type_specifier_list struct_declarator_list ';'
883 /* add this type to all the symbols */
885 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
886 sym_link *btype = copyLinkChain($1);
887 if (options.unsigned_char && SPEC_NOUN(btype) == V_CHAR && !(btype)->select.s.b_signed)
888 SPEC_USIGN(btype) = 1;
890 /* make the symbol one level up */
893 pointerTypes(sym->type,btype);
896 sym->etype = getSpec(sym->type);
899 addDecl (sym,0,btype);
900 /* make sure the type is complete and sane */
901 checkTypeSanity(sym->etype, sym->name);
903 ignoreTypedefType = 0;
908 struct_declarator_list
910 | struct_declarator_list ',' struct_declarator
919 | ':' constant_expr {
920 unsigned int bitsize;
921 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
922 bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
923 if (bitsize > (port->s.int_size * 8)) {
924 bitsize = port->s.int_size * 8;
925 werror(E_BITFLD_SIZE, bitsize);
928 bitsize = BITVAR_PAD;
929 $$->bitVar = bitsize;
931 | declarator ':' constant_expr
933 unsigned int bitsize;
934 bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
935 if (bitsize > (port->s.int_size * 8)) {
936 bitsize = port->s.int_size * 8;
937 werror(E_BITFLD_SIZE, bitsize);
940 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
941 $$->bitVar = BITVAR_PAD;
942 werror(W_BITFLD_NAMED);
945 $1->bitVar = bitsize;
947 | { $$ = newSymbol ("", NestLevel) ; }
952 : ENUM '{' enumerator_list '}' {
953 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
954 SPEC_SCLS(getSpec($$)) = 0;
957 | ENUM identifier '{' enumerator_list '}' {
961 csym=findSym(enumTab,$2,$2->name);
962 if ((csym && csym->level == $2->level))
964 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
965 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
968 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
969 SPEC_SCLS(getSpec(enumtype)) = 0;
972 /* add this to the enumerator table */
974 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
975 $$ = copyLinkChain(enumtype);
980 /* check the enumerator table */
981 if ((csym = findSym(enumTab,$2,$2->name)))
982 $$ = copyLinkChain(csym->type);
984 $$ = newLink(SPECIFIER) ;
985 SPEC_NOUN($$) = V_INT ;
992 | enumerator_list ','
993 | enumerator_list ',' enumerator
1001 : identifier opt_assign_expr
1005 /* make the symbol one level up */
1007 // check if the symbol at the same level already exists
1008 if ((sym = findSymWithLevel (SymbolTab, $1)) &&
1009 sym->level == $1->level)
1011 werrorfl ($1->fileDef, $1->lineDef, E_DUPLICATE_MEMBER, "enum", $1->name);
1012 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF);
1014 $1->type = copyLinkChain ($2->type);
1015 $1->etype= getSpec ($1->type);
1016 SPEC_ENUM ($1->etype) = 1;
1018 // do this now, so we can use it for the next enums in the list
1024 : '=' constant_expr {
1027 val = constExprValue($2,TRUE);
1028 if (!IS_INT(val->type) && !IS_CHAR(val->type))
1030 werror(E_ENUM_NON_INTEGER);
1031 SNPRINTF(lbuff, sizeof(lbuff),
1032 "%d",(int) floatFromVal(val));
1033 val = constVal(lbuff);
1039 SNPRINTF(lbuff, sizeof(lbuff),
1040 "%d",(int) floatFromVal(cenum)+1);
1041 $$ = cenum = constVal(lbuff);
1044 $$ = cenum = constVal("0");
1050 : declarator3 { $$ = $1 ; }
1051 | pointer declarator3
1053 addDecl ($2,0,reverseLink($1));
1059 : declarator2_function_attributes { $$ = $1 ; }
1060 | declarator2 { $$ = $1 ; }
1064 : declarator2_function_attributes { $$ = $1; }
1065 | pointer declarator2_function_attributes
1067 addDecl ($2,0,reverseLink($1));
1072 declarator2_function_attributes
1073 : function_declarator2 { $$ = $1 ; }
1074 | function_declarator2 function_attribute {
1075 // copy the functionAttributes (not the args and hasVargs !!)
1078 sym_link *funcType=$1->type;
1080 while (funcType && !IS_FUNC(funcType))
1081 funcType = funcType->next;
1084 werror (E_FUNC_ATTR);
1087 args=FUNC_ARGS(funcType);
1088 hasVargs=FUNC_HASVARARGS(funcType);
1090 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1091 sizeof($2->funcAttrs));
1093 FUNC_ARGS(funcType)=args;
1094 FUNC_HASVARARGS(funcType)=hasVargs;
1097 memset (&$2->funcAttrs, 0,
1098 sizeof($2->funcAttrs));
1107 | '(' declarator ')' { $$ = $2; }
1108 | declarator3 '[' ']'
1112 p = newLink (DECLARATOR);
1113 DCL_TYPE(p) = ARRAY ;
1117 | declarator3 '[' constant_expr ']'
1122 tval = constExprValue($3,TRUE);
1123 /* if it is not a constant then Error */
1124 p = newLink (DECLARATOR);
1125 DCL_TYPE(p) = ARRAY ;
1126 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1127 werror(E_CONST_EXPECTED) ;
1128 /* Assume a single item array to limit the cascade */
1129 /* of additional errors. */
1133 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1139 function_declarator2
1140 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1141 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1142 parameter_type_list ')'
1146 addDecl ($1,FUNCTION,NULL) ;
1148 funcType = $1->type;
1149 while (funcType && !IS_FUNC(funcType))
1150 funcType = funcType->next;
1154 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1155 FUNC_ARGS(funcType) = reverseVal($4);
1157 /* nest level was incremented to take care of the parms */
1161 // if this was a pointer (to a function)
1162 if (!IS_FUNC($1->type))
1163 cleanUpLevel(SymbolTab,NestLevel+1);
1167 | declarator2 '(' identifier_list ')'
1169 werror(E_OLD_STYLE,$1->name) ;
1170 /* assume it returns an int */
1171 $1->type = $1->etype = newIntLink();
1177 : unqualified_pointer { $$ = $1 ;}
1178 | unqualified_pointer type_specifier_list
1183 DCL_PTR_CONST($1) = SPEC_CONST($2);
1184 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1185 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1188 werror (W_PTR_TYPE_INVALID);
1190 | unqualified_pointer pointer
1194 DCL_TYPE($2)=port->unqualified_pointer;
1196 | unqualified_pointer type_specifier_list pointer
1199 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1200 DCL_PTR_CONST($1) = SPEC_CONST($2);
1201 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1202 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1203 switch (SPEC_SCLS($2)) {
1205 DCL_TYPE($3) = FPOINTER;
1208 DCL_TYPE($3) = IPOINTER ;
1211 DCL_TYPE($3) = PPOINTER ;
1214 DCL_TYPE($3) = POINTER ;
1217 DCL_TYPE($3) = CPOINTER ;
1220 DCL_TYPE($3) = EEPPOINTER;
1223 // this could be just "constant"
1224 // werror(W_PTR_TYPE_INVALID);
1229 werror (W_PTR_TYPE_INVALID);
1237 $$ = newLink(DECLARATOR);
1238 DCL_TYPE($$)=UPOINTER;
1244 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1245 | type_specifier_list type_specifier {
1246 /* if the decl $2 is not a specifier */
1247 /* find the spec and replace it */
1248 if ( !IS_SPEC($2)) {
1249 sym_link *lnk = $2 ;
1250 while (lnk && !IS_SPEC(lnk->next))
1252 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1256 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1262 | identifier_list ',' identifier
1271 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1275 : parameter_declaration
1276 | parameter_list ',' parameter_declaration
1283 parameter_declaration
1284 : type_specifier_list declarator
1287 pointerTypes($2->type,$1);
1288 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1291 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1294 ignoreTypedefType = 0;
1298 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1301 $$->etype = getSpec($$->type);
1302 ignoreTypedefType = 0;
1307 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1308 | type_specifier_list abstract_declarator
1310 /* go to the end of the list */
1312 pointerTypes($2,$1);
1313 for ( p = $2 ; p && p->next ; p=p->next);
1315 werror(E_SYNTAX_ERROR, yytext);
1320 ignoreTypedefType = 0;
1325 : pointer { $$ = reverseLink($1); }
1326 | abstract_declarator2
1327 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1328 if (IS_PTR($1) && IS_FUNC($2))
1329 DCL_TYPE($1) = CPOINTER;
1333 abstract_declarator2
1334 : '(' abstract_declarator ')' { $$ = $2 ; }
1336 $$ = newLink (DECLARATOR);
1337 DCL_TYPE($$) = ARRAY ;
1340 | '[' constant_expr ']' {
1342 $$ = newLink (DECLARATOR);
1343 DCL_TYPE($$) = ARRAY ;
1344 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1346 | abstract_declarator2 '[' ']' {
1347 $$ = newLink (DECLARATOR);
1348 DCL_TYPE($$) = ARRAY ;
1352 | abstract_declarator2 '[' constant_expr ']'
1355 $$ = newLink (DECLARATOR);
1356 DCL_TYPE($$) = ARRAY ;
1357 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1360 | '(' ')' { $$ = NULL;}
1361 | '(' parameter_type_list ')' { $$ = NULL;}
1362 | abstract_declarator2 '(' ')' {
1363 // $1 must be a pointer to a function
1364 sym_link *p=newLink(DECLARATOR);
1365 DCL_TYPE(p) = FUNCTION;
1367 // ((void (code *) ()) 0) ()
1368 $1=newLink(DECLARATOR);
1369 DCL_TYPE($1)=CPOINTER;
1374 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1375 sym_link *p=newLink(DECLARATOR);
1376 DCL_TYPE(p) = FUNCTION;
1378 FUNC_HASVARARGS(p) = IS_VARG($4);
1379 FUNC_ARGS(p) = reverseVal($4);
1381 /* nest level was incremented to take care of the parms */
1385 /* ((void (code *) (void)) 0) () */
1386 $1=newLink(DECLARATOR);
1387 DCL_TYPE($1)=CPOINTER;
1392 // remove the symbol args (if any)
1393 cleanUpLevel(SymbolTab,NestLevel+1);
1398 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1399 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1400 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1405 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1410 | compound_statement
1411 | expression_statement
1412 | selection_statement
1413 | iteration_statement
1415 | critical_statement
1419 ex = newNode(INLINEASM,NULL,NULL);
1420 ex->values.inlineasm = strdup($1);
1429 STACK_PUSH(continueStack,NULL);
1430 STACK_PUSH(breakStack,NULL);
1436 : critical statement {
1437 STACK_POP(breakStack);
1438 STACK_POP(continueStack);
1440 $$ = newNode(CRITICAL,$2,NULL);
1445 // : identifier ':' statement { $$ = createLabel($1,$3); }
1446 : identifier ':' { $$ = createLabel($1,NULL);
1448 | CASE constant_expr ':'
1450 if (STACK_EMPTY(swStk))
1451 $$ = createCase(NULL,$2,NULL);
1453 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1455 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1457 if (STACK_EMPTY(swStk))
1458 $$ = createDefault(NULL,$<asts>2,NULL);
1460 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1466 STACK_PUSH(blockNum,currBlockno);
1467 currBlockno = ++blockNo ;
1468 ignoreTypedefType = 0;
1472 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1476 : start_block end_block { $$ = createBlock(NULL, NULL); }
1477 | start_block statement_list end_block { $$ = createBlock(NULL, $2); }
1478 | start_block declaration_list end_block { $$ = createBlock($2, NULL); }
1480 declaration_list statement_list
1481 end_block {$$ = createBlock($2, $3); }
1482 | error ';' { $$ = NULL ; }
1488 /* if this is typedef declare it immediately */
1489 if ( $1 && IS_TYPEDEF($1->etype)) {
1490 allocVariables ($1);
1495 ignoreTypedefType = 0;
1499 | declaration_list declaration
1503 /* if this is a typedef */
1504 if ($2 && IS_TYPEDEF($2->etype)) {
1505 allocVariables ($2);
1509 /* get to the end of the previous decl */
1519 ignoreTypedefType = 0;
1526 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1529 expression_statement
1531 | expr ';' { $$ = $1; seqPointNo++;}
1535 : ELSE statement { $$ = $2 ; }
1541 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1544 $$ = createIf ($3, $6, $7 );
1547 | SWITCH '(' expr ')' {
1549 static int swLabel = 0 ;
1552 /* create a node for expression */
1553 ex = newNode(SWITCH,$3,NULL);
1554 STACK_PUSH(swStk,ex); /* save it in the stack */
1555 ex->values.switchVals.swNum = swLabel ;
1557 /* now create the label */
1558 SNPRINTF(lbuff, sizeof(lbuff),
1559 "_swBrk_%d",swLabel++);
1560 $<sym>$ = newSymbol(lbuff,NestLevel);
1561 /* put label in the break stack */
1562 STACK_PUSH(breakStack,$<sym>$);
1565 /* get back the switch form the stack */
1566 $$ = STACK_POP(swStk) ;
1567 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1568 STACK_POP(breakStack);
1572 while : WHILE { /* create and push the continue , break & body labels */
1573 static int Lblnum = 0 ;
1575 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1576 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1578 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1579 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1581 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1582 $$ = newSymbol(lbuff,NestLevel);
1586 do : DO { /* create and push the continue , break & body Labels */
1587 static int Lblnum = 0 ;
1590 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1591 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1593 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1594 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1596 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1597 $$ = newSymbol (lbuff,NestLevel);
1601 for : FOR { /* create & push continue, break & body labels */
1602 static int Lblnum = 0 ;
1605 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1606 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1608 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1609 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1611 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1612 $$ = newSymbol(lbuff,NestLevel);
1614 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1615 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1620 : while '(' expr ')' { seqPointNo++;} statement
1623 $$ = createWhile ( $1, STACK_POP(continueStack),
1624 STACK_POP(breakStack), $3, $6 );
1625 $$->lineno = $1->lineDef ;
1628 | do statement WHILE '(' expr ')' ';'
1632 $$ = createDo ( $1 , STACK_POP(continueStack),
1633 STACK_POP(breakStack), $5, $2);
1634 $$->lineno = $1->lineDef ;
1637 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1641 /* if break or continue statement present
1642 then create a general case loop */
1643 if (STACK_PEEK(continueStack)->isref ||
1644 STACK_PEEK(breakStack)->isref) {
1645 $$ = createFor ($1, STACK_POP(continueStack),
1646 STACK_POP(breakStack) ,
1647 STACK_POP(forStack) ,
1650 $$ = newNode(FOR,$9,NULL);
1651 AST_FOR($$,trueLabel) = $1;
1652 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1653 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1654 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1655 AST_FOR($$,initExpr) = $3;
1656 AST_FOR($$,condExpr) = $5;
1657 AST_FOR($$,loopExpr) = $7;
1665 : { $$ = NULL ; seqPointNo++; }
1666 | expr { $$ = $1 ; seqPointNo++; }
1670 : GOTO identifier ';' {
1672 $$ = newAst_VALUE(symbolVal($2));
1673 $$ = newNode(GOTO,$$,NULL);
1676 /* make sure continue is in context */
1677 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1678 werror(E_BREAK_CONTEXT);
1682 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1683 $$ = newNode(GOTO,$$,NULL);
1684 /* mark the continue label as referenced */
1685 STACK_PEEK(continueStack)->isref = 1;
1689 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1690 werror(E_BREAK_CONTEXT);
1693 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1694 $$ = newNode(GOTO,$$,NULL);
1695 STACK_PEEK(breakStack)->isref = 1;
1701 werror(E_INVALID_CRITICAL);
1704 $$ = newNode(RETURN,NULL,NULL);
1710 werror(E_INVALID_CRITICAL);
1713 $$ = newNode(RETURN,NULL,$2);
1719 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }
1722 identifier_or_typename
1727 sym = findSym(TypedefTab,NULL,$1) ;
1728 $$ = p = copyLinkChain(sym->type);
1729 SPEC_TYPEDEF(getSpec(p)) = 0;
1730 ignoreTypedefType = 1;