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 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
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 function_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
137 { if (!options.lessPedantic)
138 werror(W_EMPTY_SOURCE_FILE);
144 : external_definition
145 | program external_definition
149 : function_definition {
153 ignoreTypedefType = 0;
155 && IS_FUNC($1->type))
157 /* The only legal storage classes for
158 * a function prototype (declaration)
159 * are extern and static. extern is the
160 * default. Thus, if this function isn't
161 * explicitly marked static, mark it
165 && IS_SPEC($1->etype)
166 && !SPEC_STAT($1->etype))
168 SPEC_EXTR($1->etype) = 1;
172 allocVariables ($1) ;
173 cleanUpLevel (SymbolTab,1);
178 : function_declarator function_body { /* function type not specified */
179 /* assume it to be 'int' */
180 addDecl($1,0,newIntLink());
181 $$ = createFunction($1,$2);
183 | declaration_specifiers function_declarator function_body
185 pointerTypes($2->type,copyLinkChain($1));
186 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
189 $$ = createFunction($2,$3);
194 : function_attributes
195 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
199 : USING constant_expr {
200 $$ = newLink(SPECIFIER) ;
201 FUNC_REGBANK($$) = (int) ulFromVal(constExprValue($2,TRUE));
203 | REENTRANT { $$ = newLink (SPECIFIER);
206 | CRITICAL { $$ = newLink (SPECIFIER);
207 FUNC_ISCRITICAL($$) = 1;
209 | NAKED { $$ = newLink (SPECIFIER);
212 | JAVANATIVE { $$ = newLink (SPECIFIER);
213 FUNC_ISJAVANATIVE($$)=1;
215 | OVERLAY { $$ = newLink (SPECIFIER);
216 FUNC_ISOVERLAY($$)=1;
218 | NONBANKED {$$ = newLink (SPECIFIER);
219 FUNC_NONBANKED($$) = 1;
220 if (FUNC_BANKED($$)) {
221 werror(W_BANKED_WITH_NONBANKED);
224 | SHADOWREGS {$$ = newLink (SPECIFIER);
225 FUNC_ISSHADOWREGS($$) = 1;
227 | WPARAM {$$ = newLink (SPECIFIER);
228 FUNC_ISWPARAM($$) = 1;
230 | BANKED {$$ = newLink (SPECIFIER);
232 if (FUNC_NONBANKED($$)) {
233 werror(W_BANKED_WITH_NONBANKED);
236 werror(W_BANKED_WITH_STATIC);
241 $$ = newLink (SPECIFIER) ;
242 FUNC_INTNO($$) = $1 ;
249 | declaration_list compound_statement
251 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
257 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
258 | CONSTANT { $$ = newAst_VALUE($1); }
260 | '(' expr ')' { $$ = $2 ; }
264 : STRING_LITERAL { $$ = newAst_VALUE($1); }
269 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
270 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
271 $$->left->funcName = 1;}
272 | postfix_expr '(' argument_expr_list ')'
274 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
276 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
278 ignoreTypedefType = 0;
279 $4 = newSymbol($4->name,NestLevel);
281 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
282 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
284 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
286 ignoreTypedefType = 0;
287 $4 = newSymbol($4->name,NestLevel);
289 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
291 | postfix_expr INC_OP
292 { $$ = newNode(INC_OP,$1,NULL);}
293 | postfix_expr DEC_OP
294 { $$ = newNode(DEC_OP,$1,NULL); }
299 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
304 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
305 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
306 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
307 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
308 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
309 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
323 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
328 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
329 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
330 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
334 : multiplicative_expr
335 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
336 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
341 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
342 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
347 | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);}
348 | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);}
349 | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);}
350 | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);}
355 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
356 | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
361 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
366 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
371 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
376 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
377 { $$ = newNode(AND_OP,$1,$4);}
382 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
383 { $$ = newNode(OR_OP,$1,$4); }
388 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
390 $$ = newNode(':',$4,$6) ;
391 $$ = newNode('?',$1,$$) ;
397 | cast_expr assignment_operator assignment_expr
402 $$ = newNode($2,$1,$3);
405 $$ = createRMW($1, '*', $3);
408 $$ = createRMW($1, '/', $3);
411 $$ = createRMW($1, '%', $3);
414 $$ = createRMW($1, '+', $3);
417 $$ = createRMW($1, '-', $3);
420 $$ = createRMW($1, LEFT_OP, $3);
423 $$ = createRMW($1, RIGHT_OP, $3);
426 $$ = createRMW($1, '&', $3);
429 $$ = createRMW($1, '^', $3);
432 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
433 /* $$ = newNode('=',removePostIncDecOps(copyAst($1)),
434 newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
435 $$ = createRMW($1, '|', $3);
460 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
468 : declaration_specifiers ';'
471 werror(W_USELESS_DECL);
475 | declaration_specifiers init_declarator_list ';'
477 /* add the specifier list to the id */
480 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
481 sym_link *lnk = copyLinkChain($1);
482 if (options.unsigned_char && SPEC_NOUN(lnk) == V_CHAR && !lnk->select.s.b_signed)
484 /* do the pointer stuff */
485 pointerTypes(sym->type,lnk);
486 addDecl (sym,0,lnk) ;
494 declaration_specifiers
495 : storage_class_specifier { $$ = $1; }
496 | storage_class_specifier declaration_specifiers {
497 /* if the decl $2 is not a specifier */
498 /* find the spec and replace it */
501 while (lnk && !IS_SPEC(lnk->next))
503 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
507 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
509 | type_specifier { $$ = $1; }
510 | type_specifier declaration_specifiers {
511 /* if the decl $2 is not a specifier */
512 /* find the spec and replace it */
515 while (lnk && !IS_SPEC(lnk->next))
517 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
521 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
523 | function_specifier { $$ = $1; }
524 | function_specifier declaration_specifiers {
525 /* if the decl $2 is not a specifier */
526 /* find the spec and replace it */
529 while (lnk && !IS_SPEC(lnk->next))
531 lnk->next = mergeSpec($1,lnk->next, "function_specifier declaration_specifiers - skipped");
535 $$ = mergeSpec($1,$2, "function_specifier declaration_specifiers");
541 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
545 : declarator { $1->ival = NULL ; }
546 | declarator '=' initializer { $1->ival = $3 ; }
550 storage_class_specifier
552 $$ = newLink (SPECIFIER) ;
553 SPEC_TYPEDEF($$) = 1 ;
556 $$ = newLink(SPECIFIER);
560 $$ = newLink (SPECIFIER);
564 $$ = newLink (SPECIFIER) ;
565 SPEC_SCLS($$) = S_AUTO ;
568 $$ = newLink (SPECIFIER);
569 SPEC_SCLS($$) = S_REGISTER ;
575 $$ = newLink (SPECIFIER) ;
576 SPEC_INLINE($$) = 1 ;
581 : INTERRUPT { $$ = INTNO_UNSPEC ; }
582 | INTERRUPT constant_expr
583 { int intno = (int) ulFromVal(constExprValue($2,TRUE));
584 if ((intno >= 0) && (intno <= INTNO_MAX))
588 werror(E_INT_BAD_INTNO, intno);
596 | type_specifier2 AT constant_expr
598 /* add this to the storage class specifier */
599 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
600 /* now get the abs addr from value */
601 SPEC_ADDR($1) = (unsigned int) ulFromVal(constExprValue($3,TRUE)) ;
607 $$=newLink(SPECIFIER);
608 SPEC_NOUN($$) = V_CHAR ;
609 ignoreTypedefType = 1;
612 $$=newLink(SPECIFIER);
614 ignoreTypedefType = 1;
617 $$=newLink(SPECIFIER);
618 SPEC_NOUN($$) = V_INT ;
619 ignoreTypedefType = 1;
622 $$=newLink(SPECIFIER);
624 ignoreTypedefType = 1;
627 $$=newLink(SPECIFIER);
628 $$->select.s.b_signed = 1;
629 ignoreTypedefType = 1;
632 $$=newLink(SPECIFIER);
634 ignoreTypedefType = 1;
637 $$=newLink(SPECIFIER);
638 SPEC_NOUN($$) = V_VOID ;
639 ignoreTypedefType = 1;
642 $$=newLink(SPECIFIER);
646 $$=newLink(SPECIFIER);
647 SPEC_VOLATILE($$) = 1 ;
650 $$=newLink(SPECIFIER);
651 SPEC_RESTRICT($$) = 1 ;
654 $$=newLink(SPECIFIER);
655 SPEC_NOUN($$) = V_FLOAT;
656 ignoreTypedefType = 1;
659 $$=newLink(SPECIFIER);
660 SPEC_NOUN($$) = V_FIXED16X16;
661 ignoreTypedefType = 1;
664 $$ = newLink (SPECIFIER);
665 SPEC_SCLS($$) = S_XDATA ;
668 $$ = newLink (SPECIFIER) ;
669 SPEC_SCLS($$) = S_CODE ;
672 $$ = newLink (SPECIFIER) ;
673 SPEC_SCLS($$) = S_EEPROM ;
676 $$ = newLink (SPECIFIER);
677 SPEC_SCLS($$) = S_DATA ;
680 $$ = newLink (SPECIFIER);
681 SPEC_SCLS($$) = S_IDATA ;
684 $$ = newLink (SPECIFIER);
685 SPEC_SCLS($$) = S_PDATA ;
688 $$=newLink(SPECIFIER);
689 SPEC_NOUN($$) = V_BIT ;
690 SPEC_SCLS($$) = S_BIT ;
693 ignoreTypedefType = 1;
696 | struct_or_union_specifier {
699 ignoreTypedefType = 1;
704 ignoreTypedefType = 1;
711 sym = findSym(TypedefTab,NULL,$1) ;
712 $$ = p = copyLinkChain(sym ? sym->type : NULL);
713 SPEC_TYPEDEF(getSpec(p)) = 0;
714 ignoreTypedefType = 1;
721 $$ = newLink(SPECIFIER) ;
722 SPEC_NOUN($$) = V_SBIT;
723 SPEC_SCLS($$) = S_SBIT;
726 ignoreTypedefType = 1;
733 $$ = newLink(SPECIFIER) ;
734 FUNC_REGBANK($$) = 0;
735 SPEC_NOUN($$) = V_CHAR;
736 SPEC_SCLS($$) = S_SFR ;
738 ignoreTypedefType = 1;
741 $$ = newLink(SPECIFIER) ;
742 FUNC_REGBANK($$) = 1;
743 SPEC_NOUN($$) = V_CHAR;
744 SPEC_SCLS($$) = S_SFR ;
746 ignoreTypedefType = 1;
752 $$ = newLink(SPECIFIER) ;
753 FUNC_REGBANK($$) = 0;
754 SPEC_NOUN($$) = V_INT;
755 SPEC_SCLS($$) = S_SFR;
757 ignoreTypedefType = 1;
763 $$ = newLink(SPECIFIER) ;
764 FUNC_REGBANK($$) = 0;
765 SPEC_NOUN($$) = V_INT;
766 SPEC_SCLS($$) = S_SFR;
769 ignoreTypedefType = 1;
773 struct_or_union_specifier
774 : struct_or_union opt_stag
783 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
787 '{' struct_declaration_list '}'
792 // check for errors in structure members
793 for (sym=$5; sym; sym=sym->next) {
794 if (IS_ABSOLUTE(sym->etype)) {
795 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
796 SPEC_ABSA(sym->etype) = 0;
798 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
799 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
800 printTypeChainRaw (sym->type,NULL);
801 SPEC_SCLS(sym->etype) = 0;
803 for (dsym=sym->next; dsym; dsym=dsym->next) {
804 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
805 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
806 $1==STRUCT ? "struct" : "union", sym->name);
807 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
812 /* Create a structdef */
814 sdef->fields = reverseSyms($5) ; /* link the fields */
815 sdef->size = compStructSize($1,sdef); /* update size of */
816 promoteAnonStructs ($1, sdef);
818 /* Create the specifier */
819 $$ = newLink (SPECIFIER) ;
820 SPEC_NOUN($$) = V_STRUCT;
821 SPEC_STRUCT($$)= sdef ;
823 | struct_or_union stag
825 $$ = newLink(SPECIFIER) ;
826 SPEC_NOUN($$) = V_STRUCT;
827 SPEC_STRUCT($$) = $2;
836 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
842 : STRUCT { $$ = STRUCT ; }
843 | UNION { $$ = UNION ; }
848 | { /* synthesize a name add to structtable */
849 $$ = newStruct(genSymName(NestLevel)) ;
850 $$->level = NestLevel ;
851 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
855 : identifier { /* add name to structure table */
856 $$ = findSymWithBlock (StructTab,$1,currBlockno);
858 $$ = newStruct($1->name) ;
859 $$->level = NestLevel ;
860 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
865 struct_declaration_list
867 | struct_declaration_list struct_declaration
871 /* go to the end of the chain */
872 while (sym->next) sym=sym->next;
880 : type_specifier_list struct_declarator_list ';'
882 /* add this type to all the symbols */
884 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
885 sym_link *btype = copyLinkChain($1);
886 if (options.unsigned_char && SPEC_NOUN(btype) == V_CHAR && !(btype)->select.s.b_signed)
887 SPEC_USIGN(btype) = 1;
889 /* make the symbol one level up */
892 pointerTypes(sym->type,btype);
895 sym->etype = getSpec(sym->type);
898 addDecl (sym,0,btype);
899 /* make sure the type is complete and sane */
900 checkTypeSanity(sym->etype, sym->name);
902 ignoreTypedefType = 0;
907 struct_declarator_list
909 | struct_declarator_list ',' struct_declarator
918 | ':' constant_expr {
919 unsigned int bitsize;
920 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
921 bitsize = (unsigned int) ulFromVal(constExprValue($2,TRUE));
922 if (bitsize > (port->s.int_size * 8)) {
923 bitsize = port->s.int_size * 8;
924 werror(E_BITFLD_SIZE, bitsize);
927 bitsize = BITVAR_PAD;
928 $$->bitVar = bitsize;
931 | declarator ':' constant_expr
933 unsigned int bitsize;
934 bitsize = (unsigned int) ulFromVal(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) ulFromVal(val));
1033 val = constVal(lbuff);
1039 SNPRINTF(lbuff, sizeof(lbuff),
1040 "%d", (int) ulFromVal(cenum)+1);
1041 $$ = cenum = constVal(lbuff);
1044 $$ = cenum = constCharVal(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 ']'
1123 tval = constExprValue($3, TRUE);
1124 /* if it is not a constant then Error */
1125 p = newLink (DECLARATOR);
1126 DCL_TYPE(p) = ARRAY;
1128 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL))
1130 werror(E_CONST_EXPECTED);
1131 /* Assume a single item array to limit the cascade */
1132 /* of additional errors. */
1137 if ((size = (int) ulFromVal(tval)) < 0)
1139 werror(E_NEGATIVE_ARRAY_SIZE, $1->name);
1148 function_declarator2
1149 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1150 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1151 parameter_type_list ')'
1155 addDecl ($1,FUNCTION,NULL) ;
1157 funcType = $1->type;
1158 while (funcType && !IS_FUNC(funcType))
1159 funcType = funcType->next;
1163 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1164 FUNC_ARGS(funcType) = reverseVal($4);
1166 /* nest level was incremented to take care of the parms */
1170 // if this was a pointer (to a function)
1171 if (!IS_FUNC($1->type))
1172 cleanUpLevel(SymbolTab,NestLevel+1);
1176 | declarator2 '(' identifier_list ')'
1178 werror(E_OLD_STYLE,$1->name) ;
1179 /* assume it returns an int */
1180 $1->type = $1->etype = newIntLink();
1186 : unqualified_pointer { $$ = $1 ;}
1187 | unqualified_pointer type_specifier_list
1192 DCL_PTR_CONST($1) = SPEC_CONST($2);
1193 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1194 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1197 werror (W_PTR_TYPE_INVALID);
1199 | unqualified_pointer pointer
1203 DCL_TYPE($2)=port->unqualified_pointer;
1205 | unqualified_pointer type_specifier_list pointer
1208 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1209 DCL_PTR_CONST($1) = SPEC_CONST($2);
1210 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1211 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1212 switch (SPEC_SCLS($2)) {
1214 DCL_TYPE($3) = FPOINTER;
1217 DCL_TYPE($3) = IPOINTER ;
1220 DCL_TYPE($3) = PPOINTER ;
1223 DCL_TYPE($3) = POINTER ;
1226 DCL_TYPE($3) = CPOINTER ;
1229 DCL_TYPE($3) = EEPPOINTER;
1232 // this could be just "constant"
1233 // werror(W_PTR_TYPE_INVALID);
1238 werror (W_PTR_TYPE_INVALID);
1246 $$ = newLink(DECLARATOR);
1247 DCL_TYPE($$)=UPOINTER;
1253 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1254 | type_specifier_list type_specifier {
1255 /* if the decl $2 is not a specifier */
1256 /* find the spec and replace it */
1257 if ( !IS_SPEC($2)) {
1258 sym_link *lnk = $2 ;
1259 while (lnk && !IS_SPEC(lnk->next))
1261 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1265 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1271 | identifier_list ',' identifier
1280 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1284 : parameter_declaration
1285 | parameter_list ',' parameter_declaration
1292 parameter_declaration
1293 : type_specifier_list declarator
1296 pointerTypes($2->type,$1);
1297 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1300 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1303 ignoreTypedefType = 0;
1307 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1310 $$->etype = getSpec($$->type);
1311 ignoreTypedefType = 0;
1316 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1317 | type_specifier_list abstract_declarator
1319 /* go to the end of the list */
1321 pointerTypes($2,$1);
1322 for ( p = $2 ; p && p->next ; p=p->next);
1324 werror(E_SYNTAX_ERROR, yytext);
1329 ignoreTypedefType = 0;
1334 : pointer { $$ = reverseLink($1); }
1335 | abstract_declarator2
1336 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1337 if (IS_PTR($1) && IS_FUNC($2))
1338 DCL_TYPE($1) = CPOINTER;
1342 abstract_declarator2
1343 : '(' abstract_declarator ')' { $$ = $2 ; }
1345 $$ = newLink (DECLARATOR);
1346 DCL_TYPE($$) = ARRAY ;
1349 | '[' constant_expr ']' {
1351 $$ = newLink (DECLARATOR);
1352 DCL_TYPE($$) = ARRAY ;
1353 DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($2,TRUE));
1355 | abstract_declarator2 '[' ']' {
1356 $$ = newLink (DECLARATOR);
1357 DCL_TYPE($$) = ARRAY ;
1361 | abstract_declarator2 '[' constant_expr ']'
1364 $$ = newLink (DECLARATOR);
1365 DCL_TYPE($$) = ARRAY ;
1366 DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($3,TRUE));
1369 | '(' ')' { $$ = NULL;}
1370 | '(' parameter_type_list ')' { $$ = NULL;}
1371 | abstract_declarator2 '(' ')' {
1372 // $1 must be a pointer to a function
1373 sym_link *p=newLink(DECLARATOR);
1374 DCL_TYPE(p) = FUNCTION;
1376 // ((void (code *) ()) 0) ()
1377 $1=newLink(DECLARATOR);
1378 DCL_TYPE($1)=CPOINTER;
1383 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1384 sym_link *p=newLink(DECLARATOR);
1385 DCL_TYPE(p) = FUNCTION;
1387 FUNC_HASVARARGS(p) = IS_VARG($4);
1388 FUNC_ARGS(p) = reverseVal($4);
1390 /* nest level was incremented to take care of the parms */
1394 /* ((void (code *) (void)) 0) () */
1395 $1=newLink(DECLARATOR);
1396 DCL_TYPE($1)=CPOINTER;
1401 // remove the symbol args (if any)
1402 cleanUpLevel(SymbolTab,NestLevel+1);
1407 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1408 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1409 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1414 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1419 | compound_statement
1420 | expression_statement
1421 | selection_statement
1422 | iteration_statement
1424 | critical_statement
1428 ex = newNode(INLINEASM,NULL,NULL);
1429 ex->values.inlineasm = strdup($1);
1438 STACK_PUSH(continueStack,NULL);
1439 STACK_PUSH(breakStack,NULL);
1445 : critical statement {
1446 STACK_POP(breakStack);
1447 STACK_POP(continueStack);
1449 $$ = newNode(CRITICAL,$2,NULL);
1454 // : identifier ':' statement { $$ = createLabel($1,$3); }
1455 : identifier ':' { $$ = createLabel($1,NULL);
1457 | CASE constant_expr ':'
1459 if (STACK_EMPTY(swStk))
1460 $$ = createCase(NULL,$2,NULL);
1462 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1464 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1466 if (STACK_EMPTY(swStk))
1467 $$ = createDefault(NULL,$<asts>2,NULL);
1469 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1475 STACK_PUSH(blockNum,currBlockno);
1476 currBlockno = ++blockNo ;
1477 ignoreTypedefType = 0;
1481 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1485 : start_block end_block { $$ = createBlock(NULL, NULL); }
1486 | start_block statement_list end_block { $$ = createBlock(NULL, $2); }
1487 | start_block declaration_list end_block { $$ = createBlock($2, NULL); }
1489 declaration_list statement_list
1490 end_block {$$ = createBlock($2, $3); }
1491 | error ';' { $$ = NULL ; }
1497 /* if this is typedef declare it immediately */
1498 if ( $1 && IS_TYPEDEF($1->etype)) {
1499 allocVariables ($1);
1504 ignoreTypedefType = 0;
1508 | declaration_list declaration
1512 /* if this is a typedef */
1513 if ($2 && IS_TYPEDEF($2->etype)) {
1514 allocVariables ($2);
1518 /* get to the end of the previous decl */
1528 ignoreTypedefType = 0;
1535 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1538 expression_statement
1540 | expr ';' { $$ = $1; seqPointNo++;}
1544 : ELSE statement { $$ = $2 ; }
1550 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1553 $$ = createIf ($3, $6, $7 );
1554 $$->lineno = $3->lineno;
1555 $$->filename = $3->filename;
1558 | SWITCH '(' expr ')' {
1560 static int swLabel = 0 ;
1563 /* create a node for expression */
1564 ex = newNode(SWITCH,$3,NULL);
1565 STACK_PUSH(swStk,ex); /* save it in the stack */
1566 ex->values.switchVals.swNum = swLabel ;
1568 /* now create the label */
1569 SNPRINTF(lbuff, sizeof(lbuff),
1570 "_swBrk_%d",swLabel++);
1571 $<sym>$ = newSymbol(lbuff,NestLevel);
1572 /* put label in the break stack */
1573 STACK_PUSH(breakStack,$<sym>$);
1576 /* get back the switch form the stack */
1577 $$ = STACK_POP(swStk) ;
1578 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1579 STACK_POP(breakStack);
1583 while : WHILE { /* create and push the continue , break & body labels */
1584 static int Lblnum = 0 ;
1586 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1587 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1589 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1590 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1592 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1593 $$ = newSymbol(lbuff,NestLevel);
1597 do : DO { /* create and push the continue , break & body Labels */
1598 static int Lblnum = 0 ;
1601 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1602 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1604 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1605 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1607 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1608 $$ = newSymbol (lbuff,NestLevel);
1612 for : FOR { /* create & push continue, break & body labels */
1613 static int Lblnum = 0 ;
1616 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1617 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1619 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1620 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1622 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1623 $$ = newSymbol(lbuff,NestLevel);
1625 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1626 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1631 : while '(' expr ')' { seqPointNo++;} statement
1634 $$ = createWhile ( $1, STACK_POP(continueStack),
1635 STACK_POP(breakStack), $3, $6 );
1636 $$->lineno = $1->lineDef;
1637 $$->filename = $1->fileDef;
1640 | do statement WHILE '(' expr ')' ';'
1644 $$ = createDo ( $1 , STACK_POP(continueStack),
1645 STACK_POP(breakStack), $5, $2);
1646 $$->lineno = $1->lineDef;
1647 $$->filename = $1->fileDef;
1650 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1654 /* if break or continue statement present
1655 then create a general case loop */
1656 if (STACK_PEEK(continueStack)->isref ||
1657 STACK_PEEK(breakStack)->isref) {
1658 $$ = createFor ($1, STACK_POP(continueStack),
1659 STACK_POP(breakStack) ,
1660 STACK_POP(forStack) ,
1663 $$ = newNode(FOR,$9,NULL);
1664 AST_FOR($$,trueLabel) = $1;
1665 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1666 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1667 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1668 AST_FOR($$,initExpr) = $3;
1669 AST_FOR($$,condExpr) = $5;
1670 AST_FOR($$,loopExpr) = $7;
1678 : { $$ = NULL ; seqPointNo++; }
1679 | expr { $$ = $1 ; seqPointNo++; }
1683 : GOTO identifier ';' {
1685 $$ = newAst_VALUE(symbolVal($2));
1686 $$ = newNode(GOTO,$$,NULL);
1689 /* make sure continue is in context */
1690 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1691 werror(E_BREAK_CONTEXT);
1695 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1696 $$ = newNode(GOTO,$$,NULL);
1697 /* mark the continue label as referenced */
1698 STACK_PEEK(continueStack)->isref = 1;
1702 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1703 werror(E_BREAK_CONTEXT);
1706 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1707 $$ = newNode(GOTO,$$,NULL);
1708 STACK_PEEK(breakStack)->isref = 1;
1714 werror(E_INVALID_CRITICAL);
1717 $$ = newNode(RETURN,NULL,NULL);
1723 werror(E_INVALID_CRITICAL);
1726 $$ = newNode(RETURN,NULL,$2);
1732 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }