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 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
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"); }
190 $$ = newLink(SPECIFIER) ;
191 FUNC_REGBANK($$) = (int) floatFromVal($2);
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 ; }
582 { int intno = (int) floatFromVal($2);
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) = (int) floatFromVal(constExprValue($3,TRUE)) ;
606 $$=newLink(SPECIFIER);
607 SPEC_NOUN($$) = V_CHAR ;
608 ignoreTypedefType = 1;
611 $$=newLink(SPECIFIER);
612 $$->select.s._short = 1 ;
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._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_SCLS($$) = S_XDATA ;
658 $$ = newLink (SPECIFIER) ;
659 SPEC_SCLS($$) = S_CODE ;
662 $$ = newLink (SPECIFIER) ;
663 SPEC_SCLS($$) = S_EEPROM ;
666 $$ = newLink (SPECIFIER);
667 SPEC_SCLS($$) = S_DATA ;
670 $$ = newLink (SPECIFIER);
671 SPEC_SCLS($$) = S_IDATA ;
674 $$ = newLink (SPECIFIER);
675 SPEC_SCLS($$) = S_PDATA ;
678 $$=newLink(SPECIFIER);
679 SPEC_NOUN($$) = V_BIT ;
680 SPEC_SCLS($$) = S_BIT ;
683 ignoreTypedefType = 1;
686 | struct_or_union_specifier {
689 ignoreTypedefType = 1;
694 ignoreTypedefType = 1;
701 sym = findSym(TypedefTab,NULL,$1) ;
702 $$ = p = copyLinkChain(sym->type);
703 SPEC_TYPEDEF(getSpec(p)) = 0;
704 ignoreTypedefType = 1;
711 $$ = newLink(SPECIFIER) ;
712 SPEC_NOUN($$) = V_SBIT;
713 SPEC_SCLS($$) = S_SBIT;
716 ignoreTypedefType = 1;
723 $$ = newLink(SPECIFIER) ;
724 FUNC_REGBANK($$) = 0;
725 SPEC_NOUN($$) = V_CHAR;
726 SPEC_SCLS($$) = S_SFR ;
728 ignoreTypedefType = 1;
731 $$ = newLink(SPECIFIER) ;
732 FUNC_REGBANK($$) = 1;
733 SPEC_NOUN($$) = V_CHAR;
734 SPEC_SCLS($$) = S_SFR ;
736 ignoreTypedefType = 1;
742 $$ = newLink(SPECIFIER) ;
743 FUNC_REGBANK($$) = 0;
744 SPEC_NOUN($$) = V_INT;
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;
759 ignoreTypedefType = 1;
763 struct_or_union_specifier
764 : struct_or_union opt_stag
773 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
777 '{' struct_declaration_list '}'
782 // check for errors in structure members
783 for (sym=$5; sym; sym=sym->next) {
784 if (IS_ABSOLUTE(sym->etype)) {
785 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
786 SPEC_ABSA(sym->etype) = 0;
788 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
789 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
790 printTypeChainRaw (sym->type,NULL);
791 SPEC_SCLS(sym->etype) = 0;
793 for (dsym=sym->next; dsym; dsym=dsym->next) {
794 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
795 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
796 $1==STRUCT ? "struct" : "union", sym->name);
797 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
802 /* Create a structdef */
804 sdef->fields = reverseSyms($5) ; /* link the fields */
805 sdef->size = compStructSize($1,sdef); /* update size of */
806 promoteAnonStructs ($1, sdef);
808 /* Create the specifier */
809 $$ = newLink (SPECIFIER) ;
810 SPEC_NOUN($$) = V_STRUCT;
811 SPEC_STRUCT($$)= sdef ;
813 | struct_or_union stag
815 $$ = newLink(SPECIFIER) ;
816 SPEC_NOUN($$) = V_STRUCT;
817 SPEC_STRUCT($$) = $2;
826 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
832 : STRUCT { $$ = STRUCT ; }
833 | UNION { $$ = UNION ; }
838 | { /* synthesize a name add to structtable */
839 $$ = newStruct(genSymName(NestLevel)) ;
840 $$->level = NestLevel ;
841 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
845 : identifier { /* add name to structure table */
846 $$ = findSymWithBlock (StructTab,$1,currBlockno);
848 $$ = newStruct($1->name) ;
849 $$->level = NestLevel ;
850 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
855 struct_declaration_list
857 | struct_declaration_list struct_declaration
861 /* go to the end of the chain */
862 while (sym->next) sym=sym->next;
870 : type_specifier_list struct_declarator_list ';'
872 /* add this type to all the symbols */
874 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
875 sym_link *btype = copyLinkChain($1);
877 /* make the symbol one level up */
880 pointerTypes(sym->type,btype);
883 sym->etype = getSpec(sym->type);
886 addDecl (sym,0,btype);
887 /* make sure the type is complete and sane */
888 checkTypeSanity(sym->etype, sym->name);
890 ignoreTypedefType = 0;
895 struct_declarator_list
897 | struct_declarator_list ',' struct_declarator
906 | ':' constant_expr {
908 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
909 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
910 if (bitsize > (port->s.int_size * 8)) {
911 bitsize = port->s.int_size * 8;
912 werror(E_BITFLD_SIZE, bitsize);
915 bitsize = BITVAR_PAD;
916 $$->bitVar = bitsize;
918 | declarator ':' constant_expr
921 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
922 if (bitsize > (port->s.int_size * 8)) {
923 bitsize = port->s.int_size * 8;
924 werror(E_BITFLD_SIZE, bitsize);
927 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
928 $$->bitVar = BITVAR_PAD;
929 werror(W_BITFLD_NAMED);
932 $1->bitVar = bitsize;
934 | { $$ = newSymbol ("", NestLevel) ; }
939 : ENUM '{' enumerator_list '}' {
940 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
941 SPEC_SCLS(getSpec($$)) = 0;
944 | ENUM identifier '{' enumerator_list '}' {
948 csym=findSym(enumTab,$2,$2->name);
949 if ((csym && csym->level == $2->level))
951 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
952 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
955 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
956 SPEC_SCLS(getSpec(enumtype)) = 0;
959 /* add this to the enumerator table */
961 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
962 $$ = copyLinkChain(enumtype);
967 /* check the enumerator table */
968 if ((csym = findSym(enumTab,$2,$2->name)))
969 $$ = copyLinkChain(csym->type);
971 $$ = newLink(SPECIFIER) ;
972 SPEC_NOUN($$) = V_INT ;
979 | enumerator_list ',' {
981 | enumerator_list ',' enumerator
985 for (dsym=$1; dsym; dsym=dsym->next)
987 if (strcmp($3->name, dsym->name)==0)
989 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
990 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
1000 : identifier opt_assign_expr
1002 /* make the symbol one level up */
1004 $1->type = copyLinkChain($2->type);
1005 $1->etype= getSpec($1->type);
1006 SPEC_ENUM($1->etype) = 1;
1008 // do this now, so we can use it for the next enums in the list
1014 : '=' constant_expr {
1017 val = constExprValue($2,TRUE);
1018 if (!IS_INT(val->type) && !IS_CHAR(val->type))
1020 werror(E_ENUM_NON_INTEGER);
1021 SNPRINTF(lbuff, sizeof(lbuff),
1022 "%d",(int) floatFromVal(val));
1023 val = constVal(lbuff);
1029 SNPRINTF(lbuff, sizeof(lbuff),
1030 "%d",(int) floatFromVal(cenum)+1);
1031 $$ = cenum = constVal(lbuff);
1034 SNPRINTF(lbuff, sizeof(lbuff),
1036 $$ = cenum = constVal(lbuff);
1042 : declarator3 { $$ = $1 ; }
1043 | pointer declarator3
1045 addDecl ($2,0,reverseLink($1));
1051 : declarator2_function_attributes { $$ = $1 ; }
1052 | declarator2 { $$ = $1 ; }
1056 : declarator2_function_attributes { $$ = $1; }
1057 | pointer declarator2_function_attributes
1059 addDecl ($2,0,reverseLink($1));
1064 declarator2_function_attributes
1065 : function_declarator2 { $$ = $1 ; }
1066 | function_declarator2 function_attribute {
1067 // copy the functionAttributes (not the args and hasVargs !!)
1070 sym_link *funcType=$1->type;
1072 while (funcType && !IS_FUNC(funcType))
1073 funcType = funcType->next;
1076 werror (E_FUNC_ATTR);
1079 args=FUNC_ARGS(funcType);
1080 hasVargs=FUNC_HASVARARGS(funcType);
1082 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1083 sizeof($2->funcAttrs));
1085 FUNC_ARGS(funcType)=args;
1086 FUNC_HASVARARGS(funcType)=hasVargs;
1089 memset (&$2->funcAttrs, 0,
1090 sizeof($2->funcAttrs));
1099 | '(' declarator ')' { $$ = $2; }
1100 | declarator3 '[' ']'
1104 p = newLink (DECLARATOR);
1105 DCL_TYPE(p) = ARRAY ;
1109 | declarator3 '[' constant_expr ']'
1114 tval = constExprValue($3,TRUE);
1115 /* if it is not a constant then Error */
1116 p = newLink (DECLARATOR);
1117 DCL_TYPE(p) = ARRAY ;
1118 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1119 werror(E_CONST_EXPECTED) ;
1120 /* Assume a single item array to limit the cascade */
1121 /* of additional errors. */
1125 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1131 function_declarator2
1132 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1133 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1134 parameter_type_list ')'
1138 addDecl ($1,FUNCTION,NULL) ;
1140 funcType = $1->type;
1141 while (funcType && !IS_FUNC(funcType))
1142 funcType = funcType->next;
1146 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1147 FUNC_ARGS(funcType) = reverseVal($4);
1149 /* nest level was incremented to take care of the parms */
1153 // if this was a pointer (to a function)
1154 if (!IS_FUNC($1->type))
1155 cleanUpLevel(SymbolTab,NestLevel+1);
1159 | declarator2 '(' parameter_identifier_list ')'
1161 werror(E_OLD_STYLE,$1->name) ;
1162 /* assume it returns an int */
1163 $1->type = $1->etype = newIntLink();
1169 : unqualified_pointer { $$ = $1 ;}
1170 | unqualified_pointer type_specifier_list
1175 DCL_PTR_CONST($1) = SPEC_CONST($2);
1176 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1179 werror (W_PTR_TYPE_INVALID);
1181 | unqualified_pointer pointer
1185 DCL_TYPE($2)=port->unqualified_pointer;
1187 | unqualified_pointer type_specifier_list pointer
1190 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1191 DCL_PTR_CONST($1) = SPEC_CONST($2);
1192 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1193 switch (SPEC_SCLS($2)) {
1195 DCL_TYPE($3) = FPOINTER;
1198 DCL_TYPE($3) = IPOINTER ;
1201 DCL_TYPE($3) = PPOINTER ;
1204 DCL_TYPE($3) = POINTER ;
1207 DCL_TYPE($3) = CPOINTER ;
1210 DCL_TYPE($3) = EEPPOINTER;
1213 // this could be just "constant"
1214 // werror(W_PTR_TYPE_INVALID);
1219 werror (W_PTR_TYPE_INVALID);
1227 $$ = newLink(DECLARATOR);
1228 DCL_TYPE($$)=UPOINTER;
1234 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1235 | type_specifier_list type_specifier {
1236 /* if the decl $2 is not a specifier */
1237 /* find the spec and replace it */
1238 if ( !IS_SPEC($2)) {
1239 sym_link *lnk = $2 ;
1240 while (lnk && !IS_SPEC(lnk->next))
1242 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1246 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1250 parameter_identifier_list
1252 | identifier_list ',' ELIPSIS
1257 | identifier_list ',' identifier
1266 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1270 : parameter_declaration
1271 | parameter_list ',' parameter_declaration
1278 parameter_declaration
1279 : type_specifier_list declarator
1282 pointerTypes($2->type,$1);
1284 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1287 ignoreTypedefType = 0;
1292 $$->etype = getSpec($$->type);
1293 ignoreTypedefType = 0;
1298 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1299 | type_specifier_list abstract_declarator
1301 /* go to the end of the list */
1303 pointerTypes($2,$1);
1304 for ( p = $2 ; p && p->next ; p=p->next);
1306 werror(E_SYNTAX_ERROR, yytext);
1311 ignoreTypedefType = 0;
1316 : pointer { $$ = reverseLink($1); }
1317 | abstract_declarator2
1318 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1319 if (IS_PTR($1) && IS_FUNC($2))
1320 DCL_TYPE($1) = CPOINTER;
1324 abstract_declarator2
1325 : '(' abstract_declarator ')' { $$ = $2 ; }
1327 $$ = newLink (DECLARATOR);
1328 DCL_TYPE($$) = ARRAY ;
1331 | '[' constant_expr ']' {
1333 $$ = newLink (DECLARATOR);
1334 DCL_TYPE($$) = ARRAY ;
1335 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1337 | abstract_declarator2 '[' ']' {
1338 $$ = newLink (DECLARATOR);
1339 DCL_TYPE($$) = ARRAY ;
1343 | abstract_declarator2 '[' constant_expr ']'
1346 $$ = newLink (DECLARATOR);
1347 DCL_TYPE($$) = ARRAY ;
1348 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1351 | '(' ')' { $$ = NULL;}
1352 | '(' parameter_type_list ')' { $$ = NULL;}
1353 | abstract_declarator2 '(' ')' {
1354 // $1 must be a pointer to a function
1355 sym_link *p=newLink(DECLARATOR);
1356 DCL_TYPE(p) = FUNCTION;
1358 // ((void (code *) ()) 0) ()
1359 $1=newLink(DECLARATOR);
1360 DCL_TYPE($1)=CPOINTER;
1365 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1366 sym_link *p=newLink(DECLARATOR);
1367 DCL_TYPE(p) = FUNCTION;
1369 FUNC_HASVARARGS(p) = IS_VARG($4);
1370 FUNC_ARGS(p) = reverseVal($4);
1372 /* nest level was incremented to take care of the parms */
1378 // remove the symbol args (if any)
1379 cleanUpLevel(SymbolTab,NestLevel+1);
1384 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1385 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1386 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1391 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1396 | compound_statement
1397 | expression_statement
1398 | selection_statement
1399 | iteration_statement
1401 | critical_statement
1405 ex = newNode(INLINEASM,NULL,NULL);
1406 ex->values.inlineasm = strdup($1);
1415 STACK_PUSH(continueStack,NULL);
1416 STACK_PUSH(breakStack,NULL);
1422 : critical statement {
1423 STACK_POP(breakStack);
1424 STACK_POP(continueStack);
1426 $$ = newNode(CRITICAL,$2,NULL);
1431 // : identifier ':' statement { $$ = createLabel($1,$3); }
1432 : identifier ':' { $$ = createLabel($1,NULL);
1434 | CASE constant_expr ':'
1436 if (STACK_EMPTY(swStk))
1437 $$ = createCase(NULL,$2,NULL);
1439 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1441 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1443 if (STACK_EMPTY(swStk))
1444 $$ = createDefault(NULL,$<asts>2,NULL);
1446 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1452 STACK_PUSH(blockNum,currBlockno);
1453 currBlockno = ++blockNo ;
1454 ignoreTypedefType = 0;
1458 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1462 : start_block end_block { $$ = createBlock(NULL,NULL); }
1463 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1465 declaration_list { addSymChain(&$2); }
1466 end_block { $$ = createBlock($2,NULL) ; }
1468 declaration_list { addSymChain (&$2); }
1470 end_block {$$ = createBlock($2,$4) ; }
1471 | error ';' { $$ = NULL ; }
1477 /* if this is typedef declare it immediately */
1478 if ( $1 && IS_TYPEDEF($1->etype)) {
1479 allocVariables ($1);
1484 ignoreTypedefType = 0;
1487 | declaration_list declaration
1491 /* if this is a typedef */
1492 if ($2 && IS_TYPEDEF($2->etype)) {
1493 allocVariables ($2);
1497 /* get to the end of the previous decl */
1507 ignoreTypedefType = 0;
1513 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1516 expression_statement
1518 | expr ';' { $$ = $1; seqPointNo++;}
1522 : ELSE statement { $$ = $2 ; }
1528 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1531 $$ = createIf ($3, $6, $7 );
1534 | SWITCH '(' expr ')' {
1536 static int swLabel = 0 ;
1539 /* create a node for expression */
1540 ex = newNode(SWITCH,$3,NULL);
1541 STACK_PUSH(swStk,ex); /* save it in the stack */
1542 ex->values.switchVals.swNum = swLabel ;
1544 /* now create the label */
1545 SNPRINTF(lbuff, sizeof(lbuff),
1546 "_swBrk_%d",swLabel++);
1547 $<sym>$ = newSymbol(lbuff,NestLevel);
1548 /* put label in the break stack */
1549 STACK_PUSH(breakStack,$<sym>$);
1552 /* get back the switch form the stack */
1553 $$ = STACK_POP(swStk) ;
1554 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1555 STACK_POP(breakStack);
1559 while : WHILE { /* create and push the continue , break & body labels */
1560 static int Lblnum = 0 ;
1562 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1563 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1565 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1566 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1568 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1569 $$ = newSymbol(lbuff,NestLevel);
1573 do : DO { /* create and push the continue , break & body Labels */
1574 static int Lblnum = 0 ;
1577 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1578 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1580 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1581 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1583 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1584 $$ = newSymbol (lbuff,NestLevel);
1588 for : FOR { /* create & push continue, break & body labels */
1589 static int Lblnum = 0 ;
1592 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1593 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1595 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1596 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1598 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1599 $$ = newSymbol(lbuff,NestLevel);
1601 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1602 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1607 : while '(' expr ')' { seqPointNo++;} statement
1610 $$ = createWhile ( $1, STACK_POP(continueStack),
1611 STACK_POP(breakStack), $3, $6 );
1612 $$->lineno = $1->lineDef ;
1615 | do statement WHILE '(' expr ')' ';'
1619 $$ = createDo ( $1 , STACK_POP(continueStack),
1620 STACK_POP(breakStack), $5, $2);
1621 $$->lineno = $1->lineDef ;
1624 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1628 /* if break or continue statement present
1629 then create a general case loop */
1630 if (STACK_PEEK(continueStack)->isref ||
1631 STACK_PEEK(breakStack)->isref) {
1632 $$ = createFor ($1, STACK_POP(continueStack),
1633 STACK_POP(breakStack) ,
1634 STACK_POP(forStack) ,
1637 $$ = newNode(FOR,$9,NULL);
1638 AST_FOR($$,trueLabel) = $1;
1639 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1640 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1641 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1642 AST_FOR($$,initExpr) = $3;
1643 AST_FOR($$,condExpr) = $5;
1644 AST_FOR($$,loopExpr) = $7;
1652 : { $$ = NULL ; seqPointNo++; }
1653 | expr { $$ = $1 ; seqPointNo++; }
1657 : GOTO identifier ';' {
1659 $$ = newAst_VALUE(symbolVal($2));
1660 $$ = newNode(GOTO,$$,NULL);
1663 /* make sure continue is in context */
1664 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1665 werror(E_BREAK_CONTEXT);
1669 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1670 $$ = newNode(GOTO,$$,NULL);
1671 /* mark the continue label as referenced */
1672 STACK_PEEK(continueStack)->isref = 1;
1676 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1677 werror(E_BREAK_CONTEXT);
1680 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1681 $$ = newNode(GOTO,$$,NULL);
1682 STACK_PEEK(breakStack)->isref = 1;
1688 werror(E_INVALID_CRITICAL);
1691 $$ = newNode(RETURN,NULL,NULL);
1697 werror(E_INVALID_CRITICAL);
1700 $$ = newNode(RETURN,NULL,$2);
1706 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }