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 ELIPSIS 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 declarator declarator2 declarator3 enumerator_list enumerator
106 %type <sym> struct_declarator function_declarator function_declarator2
107 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
108 %type <sym> declaration init_declarator_list init_declarator
109 %type <sym> declaration_list identifier_list parameter_identifier_list
110 %type <sym> declarator2_function_attributes while do for critical
111 %type <lnk> pointer type_specifier_list type_specifier type_name
112 %type <lnk> storage_class_specifier struct_or_union_specifier
113 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
114 %type <lnk> function_attribute function_attributes enum_specifier
115 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
116 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
117 %type <sdef> stag opt_stag
118 %type <asts> primary_expr
119 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
120 %type <asts> additive_expr shift_expr relational_expr equality_expr
121 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
122 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
123 %type <asts> expr argument_expr_list function_definition expr_opt
124 %type <asts> statement_list statement labeled_statement compound_statement
125 %type <asts> expression_statement selection_statement iteration_statement
126 %type <asts> jump_statement function_body else_statement string_literal
127 %type <asts> critical_statement
128 %type <ilist> initializer initializer_list
129 %type <yyint> unary_operator assignment_operator struct_or_union
136 : external_definition
137 | file external_definition
141 : function_definition {
145 ignoreTypedefType = 0;
147 && IS_FUNC($1->type))
149 /* The only legal storage classes for
150 * a function prototype (declaration)
151 * are extern and static. extern is the
152 * default. Thus, if this function isn't
153 * explicitly marked static, mark it
157 && IS_SPEC($1->etype)
158 && !SPEC_STAT($1->etype))
160 SPEC_EXTR($1->etype) = 1;
164 allocVariables ($1) ;
165 cleanUpLevel (SymbolTab,1);
170 : function_declarator function_body { /* function type not specified */
171 /* assume it to be 'int' */
172 addDecl($1,0,newIntLink());
173 $$ = createFunction($1,$2);
175 | declaration_specifiers function_declarator function_body
177 pointerTypes($2->type,copyLinkChain($1));
179 $$ = createFunction($2,$3);
184 : function_attributes
185 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
189 : USING constant_expr {
190 $$ = newLink(SPECIFIER) ;
191 FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
193 | REENTRANT { $$ = newLink (SPECIFIER);
196 | CRITICAL { $$ = newLink (SPECIFIER);
197 FUNC_ISCRITICAL($$) = 1;
199 | NAKED { $$ = newLink (SPECIFIER);
202 | JAVANATIVE { $$ = newLink (SPECIFIER);
203 FUNC_ISJAVANATIVE($$)=1;
205 | OVERLAY { $$ = newLink (SPECIFIER);
206 FUNC_ISOVERLAY($$)=1;
208 | NONBANKED {$$ = newLink (SPECIFIER);
209 FUNC_NONBANKED($$) = 1;
210 if (FUNC_BANKED($$)) {
211 werror(W_BANKED_WITH_NONBANKED);
214 | SHADOWREGS {$$ = newLink (SPECIFIER);
215 FUNC_ISSHADOWREGS($$) = 1;
217 | WPARAM {$$ = newLink (SPECIFIER);
218 FUNC_ISWPARAM($$) = 1;
220 | BANKED {$$ = newLink (SPECIFIER);
222 if (FUNC_NONBANKED($$)) {
223 werror(W_BANKED_WITH_NONBANKED);
226 werror(W_BANKED_WITH_STATIC);
231 $$ = newLink (SPECIFIER) ;
232 FUNC_INTNO($$) = $1 ;
239 | declaration_list compound_statement
241 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
247 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
248 | CONSTANT { $$ = newAst_VALUE($1); }
250 | '(' expr ')' { $$ = $2 ; }
254 : STRING_LITERAL { $$ = newAst_VALUE($1); }
259 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
260 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
261 $$->left->funcName = 1;}
262 | postfix_expr '(' argument_expr_list ')'
264 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
266 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
268 ignoreTypedefType = 0;
269 $4 = newSymbol($4->name,NestLevel);
271 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
272 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
274 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
276 ignoreTypedefType = 0;
277 $4 = newSymbol($4->name,NestLevel);
279 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
281 | postfix_expr INC_OP
282 { $$ = newNode(INC_OP,$1,NULL);}
283 | postfix_expr DEC_OP
284 { $$ = newNode(DEC_OP,$1,NULL); }
289 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
294 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
295 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
296 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
297 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
298 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
299 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
313 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
318 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
319 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
320 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
324 : multiplicative_expr
325 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
326 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
331 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
332 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
337 | relational_expr '<' shift_expr {
339 newNode('!',newNode(GE_OP,$1,$3),NULL) :
340 newNode('<', $1,$3));
342 | relational_expr '>' shift_expr {
344 newNode('!',newNode(LE_OP,$1,$3),NULL) :
347 | relational_expr LE_OP shift_expr {
349 newNode('!', newNode('>', $1 , $3 ), NULL) :
350 newNode(LE_OP,$1,$3));
352 | relational_expr GE_OP shift_expr {
354 newNode('!', newNode('<', $1 , $3 ), NULL) :
355 newNode(GE_OP,$1,$3));
361 | equality_expr EQ_OP relational_expr {
363 newNode('!',newNode(NE_OP,$1,$3),NULL) :
364 newNode(EQ_OP,$1,$3));
366 | equality_expr NE_OP relational_expr {
368 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
369 newNode(NE_OP,$1,$3));
375 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
380 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
385 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
390 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
391 { $$ = newNode(AND_OP,$1,$4);}
396 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
397 { $$ = newNode(OR_OP,$1,$4); }
402 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
404 $$ = newNode(':',$4,$6) ;
405 $$ = newNode('?',$1,$$) ;
411 | cast_expr assignment_operator assignment_expr
416 $$ = newNode($2,$1,$3);
419 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
420 newNode('*',removePreIncDecOps(copyAst($1)),$3));
423 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
424 newNode('/',removePreIncDecOps(copyAst($1)),$3));
427 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
428 newNode('%',removePreIncDecOps(copyAst($1)),$3));
431 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
432 newNode('+',removePreIncDecOps(copyAst($1)),$3));
435 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
436 newNode('-',removePreIncDecOps(copyAst($1)),$3));
439 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
440 newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
443 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
444 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
447 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
448 newNode('&',removePreIncDecOps(copyAst($1)),$3));
451 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
452 newNode('^',removePreIncDecOps(copyAst($1)),$3));
455 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
456 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
457 newNode('|',removePreIncDecOps(copyAst($1)),$3));
482 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
490 : declaration_specifiers ';'
493 werror(W_USELESS_DECL);
497 | declaration_specifiers init_declarator_list ';'
499 /* add the specifier list to the id */
502 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
503 sym_link *lnk = copyLinkChain($1);
504 /* do the pointer stuff */
505 pointerTypes(sym->type,lnk);
506 addDecl (sym,0,lnk) ;
514 declaration_specifiers
515 : storage_class_specifier { $$ = $1; }
516 | storage_class_specifier declaration_specifiers {
517 /* if the decl $2 is not a specifier */
518 /* find the spec and replace it */
521 while (lnk && !IS_SPEC(lnk->next))
523 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
527 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
529 | type_specifier { $$ = $1; }
530 | type_specifier declaration_specifiers {
531 /* if the decl $2 is not a specifier */
532 /* find the spec and replace it */
535 while (lnk && !IS_SPEC(lnk->next))
537 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
541 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
547 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
551 : declarator { $1->ival = NULL ; }
552 | declarator '=' initializer { $1->ival = $3 ; }
556 storage_class_specifier
558 $$ = newLink (SPECIFIER) ;
559 SPEC_TYPEDEF($$) = 1 ;
562 $$ = newLink(SPECIFIER);
566 $$ = newLink (SPECIFIER);
570 $$ = newLink (SPECIFIER) ;
571 SPEC_SCLS($$) = S_AUTO ;
574 $$ = newLink (SPECIFIER);
575 SPEC_SCLS($$) = S_REGISTER ;
580 : INTERRUPT { $$ = INTNO_UNSPEC ; }
581 | INTERRUPT constant_expr
582 { int intno = (int) floatFromVal(constExprValue($2,TRUE));
583 if ((intno >= 0) && (intno <= INTNO_MAX))
587 werror(E_INT_BAD_INTNO, intno);
595 | type_specifier2 AT constant_expr
597 /* add this to the storage class specifier */
598 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
599 /* now get the abs addr from value */
600 SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
606 $$=newLink(SPECIFIER);
607 SPEC_NOUN($$) = V_CHAR ;
608 ignoreTypedefType = 1;
611 $$=newLink(SPECIFIER);
613 ignoreTypedefType = 1;
616 $$=newLink(SPECIFIER);
617 SPEC_NOUN($$) = V_INT ;
618 ignoreTypedefType = 1;
621 $$=newLink(SPECIFIER);
623 ignoreTypedefType = 1;
626 $$=newLink(SPECIFIER);
627 $$->select.s.b_signed = 1;
628 ignoreTypedefType = 1;
631 $$=newLink(SPECIFIER);
633 ignoreTypedefType = 1;
636 $$=newLink(SPECIFIER);
637 SPEC_NOUN($$) = V_VOID ;
638 ignoreTypedefType = 1;
641 $$=newLink(SPECIFIER);
645 $$=newLink(SPECIFIER);
646 SPEC_VOLATILE($$) = 1 ;
649 $$=newLink(SPECIFIER);
650 SPEC_NOUN($$) = V_FLOAT;
651 ignoreTypedefType = 1;
654 $$=newLink(SPECIFIER);
655 SPEC_NOUN($$) = V_FIXED16X16;
656 ignoreTypedefType = 1;
659 $$ = newLink (SPECIFIER);
660 SPEC_SCLS($$) = S_XDATA ;
663 $$ = newLink (SPECIFIER) ;
664 SPEC_SCLS($$) = S_CODE ;
667 $$ = newLink (SPECIFIER) ;
668 SPEC_SCLS($$) = S_EEPROM ;
671 $$ = newLink (SPECIFIER);
672 SPEC_SCLS($$) = S_DATA ;
675 $$ = newLink (SPECIFIER);
676 SPEC_SCLS($$) = S_IDATA ;
679 $$ = newLink (SPECIFIER);
680 SPEC_SCLS($$) = S_PDATA ;
683 $$=newLink(SPECIFIER);
684 SPEC_NOUN($$) = V_BIT ;
685 SPEC_SCLS($$) = S_BIT ;
688 ignoreTypedefType = 1;
691 | struct_or_union_specifier {
694 ignoreTypedefType = 1;
699 ignoreTypedefType = 1;
706 sym = findSym(TypedefTab,NULL,$1) ;
707 $$ = p = copyLinkChain(sym->type);
708 SPEC_TYPEDEF(getSpec(p)) = 0;
709 ignoreTypedefType = 1;
716 $$ = newLink(SPECIFIER) ;
717 SPEC_NOUN($$) = V_SBIT;
718 SPEC_SCLS($$) = S_SBIT;
721 ignoreTypedefType = 1;
728 $$ = newLink(SPECIFIER) ;
729 FUNC_REGBANK($$) = 0;
730 SPEC_NOUN($$) = V_CHAR;
731 SPEC_SCLS($$) = S_SFR ;
733 ignoreTypedefType = 1;
736 $$ = newLink(SPECIFIER) ;
737 FUNC_REGBANK($$) = 1;
738 SPEC_NOUN($$) = V_CHAR;
739 SPEC_SCLS($$) = S_SFR ;
741 ignoreTypedefType = 1;
747 $$ = newLink(SPECIFIER) ;
748 FUNC_REGBANK($$) = 0;
749 SPEC_NOUN($$) = V_INT;
750 SPEC_SCLS($$) = S_SFR;
752 ignoreTypedefType = 1;
758 $$ = newLink(SPECIFIER) ;
759 FUNC_REGBANK($$) = 0;
760 SPEC_NOUN($$) = V_INT;
761 SPEC_SCLS($$) = S_SFR;
764 ignoreTypedefType = 1;
768 struct_or_union_specifier
769 : struct_or_union opt_stag
778 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
782 '{' struct_declaration_list '}'
787 // check for errors in structure members
788 for (sym=$5; sym; sym=sym->next) {
789 if (IS_ABSOLUTE(sym->etype)) {
790 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
791 SPEC_ABSA(sym->etype) = 0;
793 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
794 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
795 printTypeChainRaw (sym->type,NULL);
796 SPEC_SCLS(sym->etype) = 0;
798 for (dsym=sym->next; dsym; dsym=dsym->next) {
799 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
800 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
801 $1==STRUCT ? "struct" : "union", sym->name);
802 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
807 /* Create a structdef */
809 sdef->fields = reverseSyms($5) ; /* link the fields */
810 sdef->size = compStructSize($1,sdef); /* update size of */
811 promoteAnonStructs ($1, sdef);
813 /* Create the specifier */
814 $$ = newLink (SPECIFIER) ;
815 SPEC_NOUN($$) = V_STRUCT;
816 SPEC_STRUCT($$)= sdef ;
818 | struct_or_union stag
820 $$ = newLink(SPECIFIER) ;
821 SPEC_NOUN($$) = V_STRUCT;
822 SPEC_STRUCT($$) = $2;
831 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
837 : STRUCT { $$ = STRUCT ; }
838 | UNION { $$ = UNION ; }
843 | { /* synthesize a name add to structtable */
844 $$ = newStruct(genSymName(NestLevel)) ;
845 $$->level = NestLevel ;
846 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
850 : identifier { /* add name to structure table */
851 $$ = findSymWithBlock (StructTab,$1,currBlockno);
853 $$ = newStruct($1->name) ;
854 $$->level = NestLevel ;
855 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
860 struct_declaration_list
862 | struct_declaration_list struct_declaration
866 /* go to the end of the chain */
867 while (sym->next) sym=sym->next;
875 : type_specifier_list struct_declarator_list ';'
877 /* add this type to all the symbols */
879 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
880 sym_link *btype = copyLinkChain($1);
882 /* make the symbol one level up */
885 pointerTypes(sym->type,btype);
888 sym->etype = getSpec(sym->type);
891 addDecl (sym,0,btype);
892 /* make sure the type is complete and sane */
893 checkTypeSanity(sym->etype, sym->name);
895 ignoreTypedefType = 0;
900 struct_declarator_list
902 | struct_declarator_list ',' struct_declarator
911 | ':' constant_expr {
912 unsigned int bitsize;
913 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
914 bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
915 if (bitsize > (port->s.int_size * 8)) {
916 bitsize = port->s.int_size * 8;
917 werror(E_BITFLD_SIZE, bitsize);
920 bitsize = BITVAR_PAD;
921 $$->bitVar = bitsize;
923 | declarator ':' constant_expr
925 unsigned int bitsize;
926 bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
927 if (bitsize > (port->s.int_size * 8)) {
928 bitsize = port->s.int_size * 8;
929 werror(E_BITFLD_SIZE, bitsize);
932 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
933 $$->bitVar = BITVAR_PAD;
934 werror(W_BITFLD_NAMED);
937 $1->bitVar = bitsize;
939 | { $$ = newSymbol ("", NestLevel) ; }
944 : ENUM '{' enumerator_list '}' {
945 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
946 SPEC_SCLS(getSpec($$)) = 0;
949 | ENUM identifier '{' enumerator_list '}' {
953 csym=findSym(enumTab,$2,$2->name);
954 if ((csym && csym->level == $2->level))
956 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
957 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
960 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
961 SPEC_SCLS(getSpec(enumtype)) = 0;
964 /* add this to the enumerator table */
966 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
967 $$ = copyLinkChain(enumtype);
972 /* check the enumerator table */
973 if ((csym = findSym(enumTab,$2,$2->name)))
974 $$ = copyLinkChain(csym->type);
976 $$ = newLink(SPECIFIER) ;
977 SPEC_NOUN($$) = V_INT ;
984 | enumerator_list ',' {
986 | enumerator_list ',' enumerator
990 for (dsym=$1; dsym; dsym=dsym->next)
992 if (strcmp($3->name, dsym->name)==0)
994 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
995 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
1005 : identifier opt_assign_expr
1007 /* make the symbol one level up */
1009 $1->type = copyLinkChain($2->type);
1010 $1->etype= getSpec($1->type);
1011 SPEC_ENUM($1->etype) = 1;
1013 // do this now, so we can use it for the next enums in the list
1019 : '=' constant_expr {
1022 val = constExprValue($2,TRUE);
1023 if (!IS_INT(val->type) && !IS_CHAR(val->type))
1025 werror(E_ENUM_NON_INTEGER);
1026 SNPRINTF(lbuff, sizeof(lbuff),
1027 "%d",(int) floatFromVal(val));
1028 val = constVal(lbuff);
1034 SNPRINTF(lbuff, sizeof(lbuff),
1035 "%d",(int) floatFromVal(cenum)+1);
1036 $$ = cenum = constVal(lbuff);
1039 SNPRINTF(lbuff, sizeof(lbuff),
1041 $$ = cenum = constVal(lbuff);
1047 : declarator3 { $$ = $1 ; }
1048 | pointer declarator3
1050 addDecl ($2,0,reverseLink($1));
1056 : declarator2_function_attributes { $$ = $1 ; }
1057 | declarator2 { $$ = $1 ; }
1061 : declarator2_function_attributes { $$ = $1; }
1062 | pointer declarator2_function_attributes
1064 addDecl ($2,0,reverseLink($1));
1069 declarator2_function_attributes
1070 : function_declarator2 { $$ = $1 ; }
1071 | function_declarator2 function_attribute {
1072 // copy the functionAttributes (not the args and hasVargs !!)
1075 sym_link *funcType=$1->type;
1077 while (funcType && !IS_FUNC(funcType))
1078 funcType = funcType->next;
1081 werror (E_FUNC_ATTR);
1084 args=FUNC_ARGS(funcType);
1085 hasVargs=FUNC_HASVARARGS(funcType);
1087 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1088 sizeof($2->funcAttrs));
1090 FUNC_ARGS(funcType)=args;
1091 FUNC_HASVARARGS(funcType)=hasVargs;
1094 memset (&$2->funcAttrs, 0,
1095 sizeof($2->funcAttrs));
1104 | '(' declarator ')' { $$ = $2; }
1105 | declarator3 '[' ']'
1109 p = newLink (DECLARATOR);
1110 DCL_TYPE(p) = ARRAY ;
1114 | declarator3 '[' constant_expr ']'
1119 tval = constExprValue($3,TRUE);
1120 /* if it is not a constant then Error */
1121 p = newLink (DECLARATOR);
1122 DCL_TYPE(p) = ARRAY ;
1123 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1124 werror(E_CONST_EXPECTED) ;
1125 /* Assume a single item array to limit the cascade */
1126 /* of additional errors. */
1130 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1136 function_declarator2
1137 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1138 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1139 parameter_type_list ')'
1143 addDecl ($1,FUNCTION,NULL) ;
1145 funcType = $1->type;
1146 while (funcType && !IS_FUNC(funcType))
1147 funcType = funcType->next;
1151 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1152 FUNC_ARGS(funcType) = reverseVal($4);
1154 /* nest level was incremented to take care of the parms */
1158 // if this was a pointer (to a function)
1159 if (!IS_FUNC($1->type))
1160 cleanUpLevel(SymbolTab,NestLevel+1);
1164 | declarator2 '(' parameter_identifier_list ')'
1166 werror(E_OLD_STYLE,$1->name) ;
1167 /* assume it returns an int */
1168 $1->type = $1->etype = newIntLink();
1174 : unqualified_pointer { $$ = $1 ;}
1175 | unqualified_pointer type_specifier_list
1180 DCL_PTR_CONST($1) = SPEC_CONST($2);
1181 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1184 werror (W_PTR_TYPE_INVALID);
1186 | unqualified_pointer pointer
1190 DCL_TYPE($2)=port->unqualified_pointer;
1192 | unqualified_pointer type_specifier_list pointer
1195 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1196 DCL_PTR_CONST($1) = SPEC_CONST($2);
1197 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1198 switch (SPEC_SCLS($2)) {
1200 DCL_TYPE($3) = FPOINTER;
1203 DCL_TYPE($3) = IPOINTER ;
1206 DCL_TYPE($3) = PPOINTER ;
1209 DCL_TYPE($3) = POINTER ;
1212 DCL_TYPE($3) = CPOINTER ;
1215 DCL_TYPE($3) = EEPPOINTER;
1218 // this could be just "constant"
1219 // werror(W_PTR_TYPE_INVALID);
1224 werror (W_PTR_TYPE_INVALID);
1232 $$ = newLink(DECLARATOR);
1233 DCL_TYPE($$)=UPOINTER;
1239 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1240 | type_specifier_list type_specifier {
1241 /* if the decl $2 is not a specifier */
1242 /* find the spec and replace it */
1243 if ( !IS_SPEC($2)) {
1244 sym_link *lnk = $2 ;
1245 while (lnk && !IS_SPEC(lnk->next))
1247 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1251 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1255 parameter_identifier_list
1257 | identifier_list ',' ELIPSIS
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);
1289 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1292 ignoreTypedefType = 0;
1297 $$->etype = getSpec($$->type);
1298 ignoreTypedefType = 0;
1303 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1304 | type_specifier_list abstract_declarator
1306 /* go to the end of the list */
1308 pointerTypes($2,$1);
1309 for ( p = $2 ; p && p->next ; p=p->next);
1311 werror(E_SYNTAX_ERROR, yytext);
1316 ignoreTypedefType = 0;
1321 : pointer { $$ = reverseLink($1); }
1322 | abstract_declarator2
1323 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1324 if (IS_PTR($1) && IS_FUNC($2))
1325 DCL_TYPE($1) = CPOINTER;
1329 abstract_declarator2
1330 : '(' abstract_declarator ')' { $$ = $2 ; }
1332 $$ = newLink (DECLARATOR);
1333 DCL_TYPE($$) = ARRAY ;
1336 | '[' constant_expr ']' {
1338 $$ = newLink (DECLARATOR);
1339 DCL_TYPE($$) = ARRAY ;
1340 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1342 | abstract_declarator2 '[' ']' {
1343 $$ = newLink (DECLARATOR);
1344 DCL_TYPE($$) = ARRAY ;
1348 | abstract_declarator2 '[' constant_expr ']'
1351 $$ = newLink (DECLARATOR);
1352 DCL_TYPE($$) = ARRAY ;
1353 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1356 | '(' ')' { $$ = NULL;}
1357 | '(' parameter_type_list ')' { $$ = NULL;}
1358 | abstract_declarator2 '(' ')' {
1359 // $1 must be a pointer to a function
1360 sym_link *p=newLink(DECLARATOR);
1361 DCL_TYPE(p) = FUNCTION;
1363 // ((void (code *) ()) 0) ()
1364 $1=newLink(DECLARATOR);
1365 DCL_TYPE($1)=CPOINTER;
1370 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1371 sym_link *p=newLink(DECLARATOR);
1372 DCL_TYPE(p) = FUNCTION;
1374 FUNC_HASVARARGS(p) = IS_VARG($4);
1375 FUNC_ARGS(p) = reverseVal($4);
1377 /* nest level was incremented to take care of the parms */
1381 /* ((void (code *) (void)) 0) () */
1382 $1=newLink(DECLARATOR);
1383 DCL_TYPE($1)=CPOINTER;
1388 // remove the symbol args (if any)
1389 cleanUpLevel(SymbolTab,NestLevel+1);
1394 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1395 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1396 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1401 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1406 | compound_statement
1407 | expression_statement
1408 | selection_statement
1409 | iteration_statement
1411 | critical_statement
1415 ex = newNode(INLINEASM,NULL,NULL);
1416 ex->values.inlineasm = strdup($1);
1425 STACK_PUSH(continueStack,NULL);
1426 STACK_PUSH(breakStack,NULL);
1432 : critical statement {
1433 STACK_POP(breakStack);
1434 STACK_POP(continueStack);
1436 $$ = newNode(CRITICAL,$2,NULL);
1441 // : identifier ':' statement { $$ = createLabel($1,$3); }
1442 : identifier ':' { $$ = createLabel($1,NULL);
1444 | CASE constant_expr ':'
1446 if (STACK_EMPTY(swStk))
1447 $$ = createCase(NULL,$2,NULL);
1449 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1451 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1453 if (STACK_EMPTY(swStk))
1454 $$ = createDefault(NULL,$<asts>2,NULL);
1456 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1462 STACK_PUSH(blockNum,currBlockno);
1463 currBlockno = ++blockNo ;
1464 ignoreTypedefType = 0;
1468 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1472 : start_block end_block { $$ = createBlock(NULL,NULL); }
1473 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1475 declaration_list { addSymChain(&$2); }
1476 end_block { $$ = createBlock($2,NULL) ; }
1478 declaration_list { addSymChain (&$2); }
1480 end_block {$$ = createBlock($2,$4) ; }
1481 | error ';' { $$ = NULL ; }
1487 /* if this is typedef declare it immediately */
1488 if ( $1 && IS_TYPEDEF($1->etype)) {
1489 allocVariables ($1);
1494 ignoreTypedefType = 0;
1497 | declaration_list declaration
1501 /* if this is a typedef */
1502 if ($2 && IS_TYPEDEF($2->etype)) {
1503 allocVariables ($2);
1507 /* get to the end of the previous decl */
1517 ignoreTypedefType = 0;
1523 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1526 expression_statement
1528 | expr ';' { $$ = $1; seqPointNo++;}
1532 : ELSE statement { $$ = $2 ; }
1538 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1541 $$ = createIf ($3, $6, $7 );
1544 | SWITCH '(' expr ')' {
1546 static int swLabel = 0 ;
1549 /* create a node for expression */
1550 ex = newNode(SWITCH,$3,NULL);
1551 STACK_PUSH(swStk,ex); /* save it in the stack */
1552 ex->values.switchVals.swNum = swLabel ;
1554 /* now create the label */
1555 SNPRINTF(lbuff, sizeof(lbuff),
1556 "_swBrk_%d",swLabel++);
1557 $<sym>$ = newSymbol(lbuff,NestLevel);
1558 /* put label in the break stack */
1559 STACK_PUSH(breakStack,$<sym>$);
1562 /* get back the switch form the stack */
1563 $$ = STACK_POP(swStk) ;
1564 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1565 STACK_POP(breakStack);
1569 while : WHILE { /* create and push the continue , break & body labels */
1570 static int Lblnum = 0 ;
1572 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1573 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1575 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1576 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1578 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1579 $$ = newSymbol(lbuff,NestLevel);
1583 do : DO { /* create and push the continue , break & body Labels */
1584 static int Lblnum = 0 ;
1587 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1588 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1590 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1591 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1593 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1594 $$ = newSymbol (lbuff,NestLevel);
1598 for : FOR { /* create & push continue, break & body labels */
1599 static int Lblnum = 0 ;
1602 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1603 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1605 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1606 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1608 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1609 $$ = newSymbol(lbuff,NestLevel);
1611 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1612 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1617 : while '(' expr ')' { seqPointNo++;} statement
1620 $$ = createWhile ( $1, STACK_POP(continueStack),
1621 STACK_POP(breakStack), $3, $6 );
1622 $$->lineno = $1->lineDef ;
1625 | do statement WHILE '(' expr ')' ';'
1629 $$ = createDo ( $1 , STACK_POP(continueStack),
1630 STACK_POP(breakStack), $5, $2);
1631 $$->lineno = $1->lineDef ;
1634 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1638 /* if break or continue statement present
1639 then create a general case loop */
1640 if (STACK_PEEK(continueStack)->isref ||
1641 STACK_PEEK(breakStack)->isref) {
1642 $$ = createFor ($1, STACK_POP(continueStack),
1643 STACK_POP(breakStack) ,
1644 STACK_POP(forStack) ,
1647 $$ = newNode(FOR,$9,NULL);
1648 AST_FOR($$,trueLabel) = $1;
1649 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1650 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1651 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1652 AST_FOR($$,initExpr) = $3;
1653 AST_FOR($$,condExpr) = $5;
1654 AST_FOR($$,loopExpr) = $7;
1662 : { $$ = NULL ; seqPointNo++; }
1663 | expr { $$ = $1 ; seqPointNo++; }
1667 : GOTO identifier ';' {
1669 $$ = newAst_VALUE(symbolVal($2));
1670 $$ = newNode(GOTO,$$,NULL);
1673 /* make sure continue is in context */
1674 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1675 werror(E_BREAK_CONTEXT);
1679 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1680 $$ = newNode(GOTO,$$,NULL);
1681 /* mark the continue label as referenced */
1682 STACK_PEEK(continueStack)->isref = 1;
1686 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1687 werror(E_BREAK_CONTEXT);
1690 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1691 $$ = newNode(GOTO,$$,NULL);
1692 STACK_PEEK(breakStack)->isref = 1;
1698 werror(E_INVALID_CRITICAL);
1701 $$ = newNode(RETURN,NULL,NULL);
1707 werror(E_INVALID_CRITICAL);
1710 $$ = newNode(RETURN,NULL,$2);
1716 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }