* src/SDCC.y: fixed bug #1159134: invalid duplicate declarations with
[fw/sdcc] / src / SDCC.y
1 /*-----------------------------------------------------------------------
2
3   SDCC.y - parser definition file for sdcc :
4           Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
5
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
9    later version.
10
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.
15
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.
19
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 -------------------------------------------------------------------------*/
24 %{
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include "SDCCglobl.h"
29 #include "SDCCsymt.h"
30 #include "SDCChasht.h"
31 #include "SDCCval.h"
32 #include "SDCCmem.h"
33 #include "SDCCast.h"
34 #include "port.h"
35 #include "newalloc.h"
36 #include "SDCCerr.h"
37 #include "SDCCutil.h"
38
39 extern int yyerror (char *);
40 extern FILE     *yyin;
41 int NestLevel = 0 ;     /* current NestLevel       */
42 int stackPtr  = 1 ;     /* stack pointer           */
43 int xstackPtr = 0 ;     /* xstack pointer          */
44 int reentrant = 0 ;
45 int blockNo   = 0 ;     /* sequential block number  */
46 int currBlockno=0 ;
47 int inCritical= 0 ;
48 int seqPointNo= 1 ;     /* sequence point number */
49 int ignoreTypedefType=0;
50 extern int yylex();
51 int yyparse(void);
52 extern int noLineno ;
53 char lbuff[1024];      /* local buffer */
54
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)
61
62 value *cenum = NULL  ;  /* current enumeration  type chain*/
63 bool uselessDecl = TRUE;
64
65 #define YYDEBUG 1
66
67 %}
68 %expect 6
69
70 %union {
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            */
80 }
81
82 %token <yychar> IDENTIFIER TYPE_NAME
83 %token <val> CONSTANT STRING_LITERAL
84 %token SIZEOF TYPEOF
85 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
86 %token AND_OP OR_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
100 %token RRC RLC
101 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
102 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE RESTRICT
103
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
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
130
131 %start file
132
133 %%
134
135 file
136    : /* empty */
137         { if (!options.lessPedantic)
138                     werror(W_EMPTY_SOURCE_FILE);
139         }
140    | program
141    ;
142
143 program
144    : external_definition
145    | program external_definition
146    ;
147
148 external_definition
149    : function_definition     {
150                                blockNo=0;
151                              }
152    | declaration             {
153                                ignoreTypedefType = 0;
154                                if ($1 && $1->type
155                                 && IS_FUNC($1->type))
156                                {
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
162                                     * extern.
163                                     */
164                                    if ($1->etype
165                                     && IS_SPEC($1->etype)
166                                     && !SPEC_STAT($1->etype))
167                                    {
168                                         SPEC_EXTR($1->etype) = 1;
169                                    }
170                                }
171                                addSymChain (&$1);
172                                allocVariables ($1) ;
173                                cleanUpLevel (SymbolTab,1);
174                              }
175    ;
176
177 function_definition
178    : function_declarator function_body  {   /* function type not specified */
179                                    /* assume it to be 'int'       */
180                                    addDecl($1,0,newIntLink());
181                                    $$ = createFunction($1,$2);
182                                }
183    | declaration_specifiers function_declarator function_body
184                                 {
185                                     pointerTypes($2->type,copyLinkChain($1));
186                                     if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
187                                       SPEC_USIGN($1) = 1;
188                                     addDecl($2,0,$1);
189                                     $$ = createFunction($2,$3);
190                                 }
191    ;
192
193 function_attribute
194    : function_attributes
195    | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
196    ;
197
198 function_attributes
199    :  USING constant_expr {
200                         $$ = newLink(SPECIFIER) ;
201                         FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
202                      }
203    |  REENTRANT      {  $$ = newLink (SPECIFIER);
204                         FUNC_ISREENT($$)=1;
205                      }
206    |  CRITICAL       {  $$ = newLink (SPECIFIER);
207                         FUNC_ISCRITICAL($$) = 1;
208                      }
209    |  NAKED          {  $$ = newLink (SPECIFIER);
210                         FUNC_ISNAKED($$)=1;
211                      }
212    |  JAVANATIVE     {  $$ = newLink (SPECIFIER);
213                         FUNC_ISJAVANATIVE($$)=1;
214                      }
215    |  OVERLAY        {  $$ = newLink (SPECIFIER);
216                         FUNC_ISOVERLAY($$)=1;
217                      }
218    |  NONBANKED      {$$ = newLink (SPECIFIER);
219                         FUNC_NONBANKED($$) = 1;
220                         if (FUNC_BANKED($$)) {
221                             werror(W_BANKED_WITH_NONBANKED);
222                         }
223                      }
224    |  SHADOWREGS     {$$ = newLink (SPECIFIER);
225                         FUNC_ISSHADOWREGS($$) = 1;
226                      }
227    |  WPARAM         {$$ = newLink (SPECIFIER);
228                         FUNC_ISWPARAM($$) = 1;
229                      }
230    |  BANKED         {$$ = newLink (SPECIFIER);
231                         FUNC_BANKED($$) = 1;
232                         if (FUNC_NONBANKED($$)) {
233                             werror(W_BANKED_WITH_NONBANKED);
234                         }
235                         if (SPEC_STAT($$)) {
236                             werror(W_BANKED_WITH_STATIC);
237                         }
238                      }
239    |  Interrupt_storage
240                      {
241                         $$ = newLink (SPECIFIER) ;
242                         FUNC_INTNO($$) = $1 ;
243                         FUNC_ISISR($$) = 1;
244                      }
245    ;
246
247 function_body
248    : compound_statement
249    | declaration_list compound_statement
250          {
251             werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
252             exit(1);
253          }
254    ;
255
256 primary_expr
257    : identifier      {  $$ = newAst_VALUE(symbolVal($1));  }
258    | CONSTANT        {  $$ = newAst_VALUE($1);  }
259    | string_literal
260    | '(' expr ')'    {  $$ = $2 ;                   }
261    ;
262
263 string_literal
264     : STRING_LITERAL                    { $$ = newAst_VALUE($1); }
265     ;
266
267 postfix_expr
268    : primary_expr
269    | postfix_expr '[' expr ']'          { $$ = newNode  ('[', $1, $3) ; }
270    | postfix_expr '(' ')'               { $$ = newNode  (CALL,$1,NULL);
271                                           $$->left->funcName = 1;}
272    | postfix_expr '(' argument_expr_list ')'
273           {
274             $$ = newNode  (CALL,$1,$3) ; $$->left->funcName = 1;
275           }
276    | postfix_expr '.' { ignoreTypedefType = 1; } identifier
277                       {
278                         ignoreTypedefType = 0;
279                         $4 = newSymbol($4->name,NestLevel);
280                         $4->implicit = 1;
281                         $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
282 /*                      $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ;                   */
283                       }
284    | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
285                       {
286                         ignoreTypedefType = 0;
287                         $4 = newSymbol($4->name,NestLevel);
288                         $4->implicit = 1;
289                         $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
290                       }
291    | postfix_expr INC_OP
292                       { $$ = newNode(INC_OP,$1,NULL);}
293    | postfix_expr DEC_OP
294                       { $$ = newNode(DEC_OP,$1,NULL); }
295    ;
296
297 argument_expr_list
298    : assignment_expr
299    | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
300    ;
301
302 unary_expr
303    : postfix_expr
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);  }
310    ;
311
312 unary_operator
313    : '&'    { $$ = '&' ;}
314    | '*'    { $$ = '*' ;}
315    | '+'    { $$ = '+' ;}
316    | '-'    { $$ = '-' ;}
317    | '~'    { $$ = '~' ;}
318    | '!'    { $$ = '!' ;}
319    ;
320
321 cast_expr
322    : unary_expr
323    | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
324    ;
325
326 multiplicative_expr
327    : cast_expr
328    | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
329    | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
330    | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
331    ;
332
333 additive_expr
334    : multiplicative_expr
335    | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
336    | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
337    ;
338
339 shift_expr
340    : additive_expr
341    | shift_expr LEFT_OP additive_expr  { $$ = newNode(LEFT_OP,$1,$3); }
342    | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
343    ;
344
345 relational_expr
346    : shift_expr
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);}
351    ;
352
353 equality_expr
354    : relational_expr
355    | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
356    | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
357    ;
358
359 and_expr
360    : equality_expr
361    | and_expr '&' equality_expr  { $$ = newNode('&',$1,$3);}
362    ;
363
364 exclusive_or_expr
365    : and_expr
366    | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
367    ;
368
369 inclusive_or_expr
370    : exclusive_or_expr
371    | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
372    ;
373
374 logical_and_expr
375    : inclusive_or_expr
376    | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
377                                  { $$ = newNode(AND_OP,$1,$4);}
378    ;
379
380 logical_or_expr
381    : logical_and_expr
382    | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
383                                  { $$ = newNode(OR_OP,$1,$4); }
384    ;
385
386 conditional_expr
387    : logical_or_expr
388    | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
389                      {
390                         $$ = newNode(':',$4,$6) ;
391                         $$ = newNode('?',$1,$$) ;
392                      }
393    ;
394
395 assignment_expr
396    : conditional_expr
397    | cast_expr assignment_operator assignment_expr
398                      {
399
400                              switch ($2) {
401                              case '=':
402                                      $$ = newNode($2,$1,$3);
403                                      break;
404                              case MUL_ASSIGN:
405                                      $$ = createRMW($1, '*', $3);
406                                      break;
407                              case DIV_ASSIGN:
408                                      $$ = createRMW($1, '/', $3);
409                                      break;
410                              case MOD_ASSIGN:
411                                      $$ = createRMW($1, '%', $3);
412                                      break;
413                              case ADD_ASSIGN:
414                                      $$ = createRMW($1, '+', $3);
415                                      break;
416                              case SUB_ASSIGN:
417                                      $$ = createRMW($1, '-', $3);
418                                      break;
419                              case LEFT_ASSIGN:
420                                      $$ = createRMW($1, LEFT_OP, $3);
421                                      break;
422                              case RIGHT_ASSIGN:
423                                      $$ = createRMW($1, RIGHT_OP, $3);
424                                      break;
425                              case AND_ASSIGN:
426                                      $$ = createRMW($1, '&', $3);
427                                      break;
428                              case XOR_ASSIGN:
429                                      $$ = createRMW($1, '^', $3);
430                                      break;
431                              case OR_ASSIGN:
432 /*                                   $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
433 /*                                   $$ = newNode('=',removePostIncDecOps(copyAst($1)),
434                                                       newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
435                                      $$ = createRMW($1, '|', $3);
436                                      break;
437                              default :
438                                      $$ = NULL;
439                              }
440
441                      }
442 ;
443
444 assignment_operator
445    : '='             { $$ = '=' ;}
446    | MUL_ASSIGN
447    | DIV_ASSIGN
448    | MOD_ASSIGN
449    | ADD_ASSIGN
450    | SUB_ASSIGN
451    | LEFT_ASSIGN
452    | RIGHT_ASSIGN
453    | AND_ASSIGN
454    | XOR_ASSIGN
455    | OR_ASSIGN
456    ;
457
458 expr
459    : assignment_expr
460    | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
461    ;
462
463 constant_expr
464    : conditional_expr
465    ;
466
467 declaration
468    : declaration_specifiers ';'
469       {
470          if (uselessDecl)
471            werror(W_USELESS_DECL);
472          uselessDecl = TRUE;
473          $$ = NULL ;
474       }
475    | declaration_specifiers init_declarator_list ';'
476       {
477          /* add the specifier list to the id */
478          symbol *sym , *sym1;
479
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)
483                SPEC_USIGN(lnk) = 1;
484              /* do the pointer stuff */
485              pointerTypes(sym->type,lnk);
486              addDecl (sym,0,lnk) ;
487          }
488
489          uselessDecl = TRUE;
490          $$ = sym1 ;
491       }
492    ;
493
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      */
499      if ( !IS_SPEC($2)) {
500        sym_link *lnk = $2 ;
501        while (lnk && !IS_SPEC(lnk->next))
502          lnk = lnk->next;
503        lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
504        $$ = $2 ;
505      }
506      else
507        $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
508    }
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      */
513      if ( !IS_SPEC($2)) {
514        sym_link *lnk = $2 ;
515        while (lnk && !IS_SPEC(lnk->next))
516          lnk = lnk->next;
517        lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
518        $$ = $2 ;
519      }
520      else
521        $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
522    }
523    ;
524
525 init_declarator_list
526    : init_declarator
527    | init_declarator_list ',' init_declarator      { $3->next = $1 ; $$ = $3;}
528    ;
529
530 init_declarator
531    : declarator                  { $1->ival = NULL ; }
532    | declarator '=' initializer  { $1->ival = $3   ; }
533    ;
534
535
536 storage_class_specifier
537    : TYPEDEF   {
538                   $$ = newLink (SPECIFIER) ;
539                   SPEC_TYPEDEF($$) = 1 ;
540                }
541    | EXTERN    {
542                   $$ = newLink(SPECIFIER);
543                   SPEC_EXTR($$) = 1 ;
544                }
545    | STATIC    {
546                   $$ = newLink (SPECIFIER);
547                   SPEC_STAT($$) = 1 ;
548                }
549    | AUTO      {
550                   $$ = newLink (SPECIFIER) ;
551                   SPEC_SCLS($$) = S_AUTO  ;
552                }
553    | REGISTER  {
554                   $$ = newLink (SPECIFIER);
555                   SPEC_SCLS($$) = S_REGISTER ;
556                }
557    ;
558
559 Interrupt_storage
560    : INTERRUPT { $$ = INTNO_UNSPEC ; }
561    | INTERRUPT constant_expr
562         { int intno = (int) floatFromVal(constExprValue($2,TRUE));
563           if ((intno >= 0) && (intno <= INTNO_MAX))
564             $$ = intno;
565           else
566             {
567               werror(E_INT_BAD_INTNO, intno);
568               $$ = INTNO_UNSPEC;
569             }
570         }
571    ;
572
573 type_specifier
574    : type_specifier2
575    | type_specifier2 AT constant_expr
576         {
577            /* add this to the storage class specifier  */
578            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
579            /* now get the abs addr from value */
580            SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
581         }
582    ;
583
584 type_specifier2
585    : CHAR      {
586                   $$=newLink(SPECIFIER);
587                   SPEC_NOUN($$) = V_CHAR  ;
588                   ignoreTypedefType = 1;
589                }
590    | SHORT     {
591                   $$=newLink(SPECIFIER);
592                   SPEC_SHORT($$) = 1 ;
593                   ignoreTypedefType = 1;
594                }
595    | INT       {
596                   $$=newLink(SPECIFIER);
597                   SPEC_NOUN($$) = V_INT   ;
598                   ignoreTypedefType = 1;
599                }
600    | LONG      {
601                   $$=newLink(SPECIFIER);
602                   SPEC_LONG($$) = 1       ;
603                   ignoreTypedefType = 1;
604                }
605    | SIGNED    {
606                   $$=newLink(SPECIFIER);
607                   $$->select.s.b_signed = 1;
608                   ignoreTypedefType = 1;
609                }
610    | UNSIGNED  {
611                   $$=newLink(SPECIFIER);
612                   SPEC_USIGN($$) = 1      ;
613                   ignoreTypedefType = 1;
614                }
615    | VOID      {
616                   $$=newLink(SPECIFIER);
617                   SPEC_NOUN($$) = V_VOID  ;
618                   ignoreTypedefType = 1;
619                }
620    | CONST     {
621                   $$=newLink(SPECIFIER);
622                   SPEC_CONST($$) = 1;
623                }
624    | VOLATILE  {
625                   $$=newLink(SPECIFIER);
626                   SPEC_VOLATILE($$) = 1 ;
627                }
628    | FLOAT     {
629                   $$=newLink(SPECIFIER);
630                   SPEC_NOUN($$) = V_FLOAT;
631                   ignoreTypedefType = 1;
632                }
633    | FIXED16X16 {
634                   $$=newLink(SPECIFIER);
635                   SPEC_NOUN($$) = V_FIXED16X16;
636                   ignoreTypedefType = 1;
637                }
638    | XDATA     {
639                   $$ = newLink (SPECIFIER);
640                   SPEC_SCLS($$) = S_XDATA  ;
641                }
642    | CODE      {
643                   $$ = newLink (SPECIFIER) ;
644                   SPEC_SCLS($$) = S_CODE ;
645                }
646    | EEPROM    {
647                   $$ = newLink (SPECIFIER) ;
648                   SPEC_SCLS($$) = S_EEPROM ;
649                }
650    | DATA      {
651                   $$ = newLink (SPECIFIER);
652                   SPEC_SCLS($$) = S_DATA   ;
653                }
654    | IDATA     {
655                   $$ = newLink (SPECIFIER);
656                   SPEC_SCLS($$) = S_IDATA  ;
657                }
658    | PDATA     {
659                   $$ = newLink (SPECIFIER);
660                   SPEC_SCLS($$) = S_PDATA  ;
661                }
662    | BIT       {
663                   $$=newLink(SPECIFIER);
664                   SPEC_NOUN($$) = V_BIT   ;
665                   SPEC_SCLS($$) = S_BIT   ;
666                   SPEC_BLEN($$) = 1;
667                   SPEC_BSTR($$) = 0;
668                   ignoreTypedefType = 1;
669                }
670
671    | struct_or_union_specifier  {
672                                    uselessDecl = FALSE;
673                                    $$ = $1 ;
674                                    ignoreTypedefType = 1;
675                                 }
676    | enum_specifier     {
677                            cenum = NULL ;
678                            uselessDecl = FALSE;
679                            ignoreTypedefType = 1;
680                            $$ = $1 ;
681                         }
682    | TYPE_NAME
683          {
684             symbol *sym;
685             sym_link   *p  ;
686             sym = findSym(TypedefTab,NULL,$1) ;
687             $$ = p = copyLinkChain(sym->type);
688             SPEC_TYPEDEF(getSpec(p)) = 0;
689             ignoreTypedefType = 1;
690          }
691    | sfr_reg_bit
692    ;
693
694 sfr_reg_bit
695    :  SBIT  {
696                $$ = newLink(SPECIFIER) ;
697                SPEC_NOUN($$) = V_SBIT;
698                SPEC_SCLS($$) = S_SBIT;
699                SPEC_BLEN($$) = 1;
700                SPEC_BSTR($$) = 0;
701                ignoreTypedefType = 1;
702             }
703    |  sfr_attributes
704    ;
705
706 sfr_attributes
707    : SFR    {
708                $$ = newLink(SPECIFIER) ;
709                FUNC_REGBANK($$) = 0;
710                SPEC_NOUN($$)    = V_CHAR;
711                SPEC_SCLS($$)    = S_SFR ;
712                SPEC_USIGN($$)   = 1 ;
713                ignoreTypedefType = 1;
714             }
715    | SFR BANKED {
716                $$ = newLink(SPECIFIER) ;
717                FUNC_REGBANK($$) = 1;
718                SPEC_NOUN($$)    = V_CHAR;
719                SPEC_SCLS($$)    = S_SFR ;
720                SPEC_USIGN($$)   = 1 ;
721                ignoreTypedefType = 1;
722             }
723    ;
724
725 sfr_attributes
726    : SFR16  {
727                $$ = newLink(SPECIFIER) ;
728                FUNC_REGBANK($$) = 0;
729                SPEC_NOUN($$)    = V_INT;
730                SPEC_SCLS($$)    = S_SFR;
731                SPEC_USIGN($$)   = 1 ;
732                ignoreTypedefType = 1;
733             }
734    ;
735
736 sfr_attributes
737    : SFR32  {
738                $$ = newLink(SPECIFIER) ;
739                FUNC_REGBANK($$) = 0;
740                SPEC_NOUN($$)    = V_INT;
741                SPEC_SCLS($$)    = S_SFR;
742                SPEC_LONG($$)    = 1;
743                SPEC_USIGN($$)   = 1;
744                ignoreTypedefType = 1;
745             }
746    ;
747
748 struct_or_union_specifier
749    : struct_or_union opt_stag
750         {
751            if (!$2->type)
752              {
753                $2->type = $1;
754              }
755            else
756              {
757                if ($2->type != $1)
758                  werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
759              }
760
761         }
762            '{' struct_declaration_list '}'
763         {
764            structdef *sdef ;
765            symbol *sym, *dsym;
766
767            // check for errors in structure members
768            for (sym=$5; sym; sym=sym->next) {
769              if (IS_ABSOLUTE(sym->etype)) {
770                werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
771                SPEC_ABSA(sym->etype) = 0;
772              }
773              if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
774                werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
775                printTypeChainRaw (sym->type,NULL);
776                SPEC_SCLS(sym->etype) = 0;
777              }
778              for (dsym=sym->next; dsym; dsym=dsym->next) {
779                if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
780                  werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
781                         $1==STRUCT ? "struct" : "union", sym->name);
782                  werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
783                }
784              }
785            }
786
787            /* Create a structdef   */
788            sdef = $2 ;
789            sdef->fields   = reverseSyms($5) ;   /* link the fields */
790            sdef->size  = compStructSize($1,sdef);   /* update size of  */
791            promoteAnonStructs ($1, sdef);
792
793            /* Create the specifier */
794            $$ = newLink (SPECIFIER) ;
795            SPEC_NOUN($$) = V_STRUCT;
796            SPEC_STRUCT($$)= sdef ;
797         }
798    | struct_or_union stag
799          {
800             $$ = newLink(SPECIFIER) ;
801             SPEC_NOUN($$) = V_STRUCT;
802             SPEC_STRUCT($$) = $2;
803
804            if (!$2->type)
805              {
806                $2->type = $1;
807              }
808            else
809              {
810                if ($2->type != $1)
811                  werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
812              }
813          }
814    ;
815
816 struct_or_union
817    : STRUCT          { $$ = STRUCT ; }
818    | UNION           { $$ = UNION  ; }
819    ;
820
821 opt_stag
822 : stag
823 |  {  /* synthesize a name add to structtable */
824      $$ = newStruct(genSymName(NestLevel)) ;
825      $$->level = NestLevel ;
826      addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
827 };
828
829 stag
830 :  identifier  {  /* add name to structure table */
831      $$ = findSymWithBlock (StructTab,$1,currBlockno);
832      if (! $$ ) {
833        $$ = newStruct($1->name) ;
834        $$->level = NestLevel ;
835        addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
836      }
837 };
838
839
840 struct_declaration_list
841    : struct_declaration
842    | struct_declaration_list struct_declaration
843        {
844            symbol *sym=$2;
845
846            /* go to the end of the chain */
847            while (sym->next) sym=sym->next;
848            sym->next = $1 ;
849
850            $$ = $2;
851        }
852    ;
853
854 struct_declaration
855    : type_specifier_list struct_declarator_list ';'
856        {
857            /* add this type to all the symbols */
858            symbol *sym ;
859            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
860                sym_link *btype = copyLinkChain($1);
861                if (options.unsigned_char && SPEC_NOUN(btype) == V_CHAR && !(btype)->select.s.b_signed)
862                  SPEC_USIGN(btype) = 1;
863
864                /* make the symbol one level up */
865                sym->level-- ;
866
867                pointerTypes(sym->type,btype);
868                if (!sym->type) {
869                    sym->type = btype;
870                    sym->etype = getSpec(sym->type);
871                }
872                else
873                  addDecl (sym,0,btype);
874                /* make sure the type is complete and sane */
875                checkTypeSanity(sym->etype, sym->name);
876            }
877            ignoreTypedefType = 0;
878            $$ = $2;
879        }
880    ;
881
882 struct_declarator_list
883    : struct_declarator
884    | struct_declarator_list ',' struct_declarator
885        {
886            $3->next  = $1 ;
887            $$ = $3 ;
888        }
889    ;
890
891 struct_declarator
892    : declarator
893    | ':' constant_expr  {
894                            unsigned int bitsize;
895                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
896                            bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
897                            if (bitsize > (port->s.int_size * 8)) {
898                              bitsize = port->s.int_size * 8;
899                              werror(E_BITFLD_SIZE, bitsize);
900                            }
901                            if (!bitsize)
902                              bitsize = BITVAR_PAD;
903                            $$->bitVar = bitsize;
904                         }
905    | declarator ':' constant_expr
906                         {
907                           unsigned int bitsize;
908                           bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
909                           if (bitsize > (port->s.int_size * 8)) {
910                             bitsize = port->s.int_size * 8;
911                             werror(E_BITFLD_SIZE, bitsize);
912                           }
913                           if (!bitsize) {
914                             $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
915                             $$->bitVar = BITVAR_PAD;
916                             werror(W_BITFLD_NAMED);
917                           }
918                           else
919                             $1->bitVar = bitsize;
920                         }
921    | { $$ = newSymbol ("", NestLevel) ; }
922
923    ;
924
925 enum_specifier
926    : ENUM            '{' enumerator_list '}' {
927            $$ = newEnumType ($3);       //copyLinkChain(cenum->type);
928            SPEC_SCLS(getSpec($$)) = 0;
929          }
930
931    | ENUM identifier '{' enumerator_list '}' {
932      symbol *csym ;
933      sym_link *enumtype;
934
935      csym=findSym(enumTab,$2,$2->name);
936      if ((csym && csym->level == $2->level))
937        {
938          werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
939          werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
940        }
941
942      enumtype = newEnumType ($4);       //copyLinkChain(cenum->type);
943      SPEC_SCLS(getSpec(enumtype)) = 0;
944      $2->type = enumtype;
945
946      /* add this to the enumerator table */
947      if (!csym)
948        addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
949      $$ = copyLinkChain(enumtype);
950    }
951    | ENUM identifier                         {
952      symbol *csym ;
953
954      /* check the enumerator table */
955      if ((csym = findSym(enumTab,$2,$2->name)))
956        $$ = copyLinkChain(csym->type);
957      else  {
958        $$ = newLink(SPECIFIER) ;
959        SPEC_NOUN($$) = V_INT   ;
960      }
961    }
962    ;
963
964 enumerator_list
965    : enumerator
966    | enumerator_list ',' {
967                          }
968    | enumerator_list ',' enumerator
969      {
970        symbol *dsym;
971
972        for (dsym=$1; dsym; dsym=dsym->next)
973          {
974            if (strcmp($3->name, dsym->name)==0)
975              {
976                werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
977                werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
978              }
979          }
980
981        $3->next = $1 ;
982        $$ = $3  ;
983      }
984    ;
985
986 enumerator
987    : identifier opt_assign_expr
988      {
989        /* make the symbol one level up */
990        $1->level-- ;
991        $1->type = copyLinkChain($2->type);
992        $1->etype= getSpec($1->type);
993        SPEC_ENUM($1->etype) = 1;
994        $$ = $1 ;
995        // do this now, so we can use it for the next enums in the list
996        addSymChain(&$1);
997      }
998    ;
999
1000 opt_assign_expr
1001    :  '='   constant_expr  {
1002                               value *val ;
1003
1004                               val = constExprValue($2,TRUE);
1005                               if (!IS_INT(val->type) && !IS_CHAR(val->type))
1006                                 {
1007                                   werror(E_ENUM_NON_INTEGER);
1008                                   SNPRINTF(lbuff, sizeof(lbuff),
1009                                           "%d",(int) floatFromVal(val));
1010                                   val = constVal(lbuff);
1011                                 }
1012                               $$ = cenum = val ;
1013                            }
1014    |                       {
1015                               if (cenum)  {
1016                                  SNPRINTF(lbuff, sizeof(lbuff),
1017                                           "%d",(int) floatFromVal(cenum)+1);
1018                                  $$ = cenum = constVal(lbuff);
1019                               }
1020                               else {
1021                                  $$ = cenum = constVal("0");
1022                               }
1023                            }
1024    ;
1025
1026 declarator
1027    : declarator3                        { $$ = $1 ; }
1028    | pointer declarator3
1029          {
1030              addDecl ($2,0,reverseLink($1));
1031              $$ = $2 ;
1032          }
1033    ;
1034
1035 declarator3
1036    : declarator2_function_attributes    { $$ = $1 ; }
1037    | declarator2                        { $$ = $1 ; }
1038    ;
1039
1040 function_declarator
1041    : declarator2_function_attributes    { $$ = $1; }
1042    | pointer declarator2_function_attributes
1043          {
1044              addDecl ($2,0,reverseLink($1));
1045              $$ = $2 ;
1046          }
1047    ;
1048
1049 declarator2_function_attributes
1050    : function_declarator2                 { $$ = $1 ; }
1051    | function_declarator2 function_attribute  {
1052            // copy the functionAttributes (not the args and hasVargs !!)
1053            struct value *args;
1054            unsigned hasVargs;
1055            sym_link *funcType=$1->type;
1056
1057            while (funcType && !IS_FUNC(funcType))
1058              funcType = funcType->next;
1059
1060            if (!funcType)
1061              werror (E_FUNC_ATTR);
1062            else
1063              {
1064                args=FUNC_ARGS(funcType);
1065                hasVargs=FUNC_HASVARARGS(funcType);
1066
1067                memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1068                    sizeof($2->funcAttrs));
1069
1070                FUNC_ARGS(funcType)=args;
1071                FUNC_HASVARARGS(funcType)=hasVargs;
1072
1073                // just to be sure
1074                memset (&$2->funcAttrs, 0,
1075                    sizeof($2->funcAttrs));
1076
1077                addDecl ($1,0,$2);
1078              }
1079    }
1080    ;
1081
1082 declarator2
1083    : identifier
1084    | '(' declarator ')'     { $$ = $2; }
1085    | declarator3 '[' ']'
1086          {
1087             sym_link   *p;
1088
1089             p = newLink (DECLARATOR);
1090             DCL_TYPE(p) = ARRAY ;
1091             DCL_ELEM(p) = 0     ;
1092             addDecl($1,0,p);
1093          }
1094    | declarator3 '[' constant_expr ']'
1095          {
1096             sym_link   *p ;
1097                         value *tval;
1098
1099             tval = constExprValue($3,TRUE);
1100             /* if it is not a constant then Error  */
1101             p = newLink (DECLARATOR);
1102             DCL_TYPE(p) = ARRAY ;
1103             if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1104                werror(E_CONST_EXPECTED) ;
1105                /* Assume a single item array to limit the cascade */
1106                /* of additional errors. */
1107                DCL_ELEM(p) = 1;
1108             }
1109             else {
1110                DCL_ELEM(p) = (int) floatFromVal(tval) ;
1111             }
1112             addDecl($1,0,p);
1113          }
1114    ;
1115
1116 function_declarator2
1117    : declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
1118    | declarator2 '('            { NestLevel++ ; currBlockno++;  }
1119                      parameter_type_list ')'
1120          {
1121              sym_link *funcType;
1122
1123              addDecl ($1,FUNCTION,NULL) ;
1124
1125              funcType = $1->type;
1126              while (funcType && !IS_FUNC(funcType))
1127                funcType = funcType->next;
1128
1129              assert (funcType);
1130
1131              FUNC_HASVARARGS(funcType) = IS_VARG($4);
1132              FUNC_ARGS(funcType) = reverseVal($4);
1133
1134              /* nest level was incremented to take care of the parms  */
1135              NestLevel-- ;
1136              currBlockno--;
1137
1138              // if this was a pointer (to a function)
1139              if (!IS_FUNC($1->type))
1140                cleanUpLevel(SymbolTab,NestLevel+1);
1141
1142              $$ = $1;
1143          }
1144    | declarator2 '(' identifier_list ')'
1145          {
1146            werror(E_OLD_STYLE,$1->name) ;
1147            /* assume it returns an int */
1148            $1->type = $1->etype = newIntLink();
1149            $$ = $1 ;
1150          }
1151    ;
1152
1153 pointer
1154    : unqualified_pointer { $$ = $1 ;}
1155    | unqualified_pointer type_specifier_list
1156          {
1157              $$ = $1  ;
1158              if (IS_SPEC($2)) {
1159                  DCL_TSPEC($1) = $2;
1160                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1161                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1162              }
1163              else
1164                  werror (W_PTR_TYPE_INVALID);
1165          }
1166    | unqualified_pointer pointer
1167          {
1168              $$ = $1 ;
1169              $$->next = $2 ;
1170              DCL_TYPE($2)=port->unqualified_pointer;
1171          }
1172    | unqualified_pointer type_specifier_list pointer
1173          {
1174              $$ = $1 ;
1175              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1176                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1177                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1178                  switch (SPEC_SCLS($2)) {
1179                  case S_XDATA:
1180                      DCL_TYPE($3) = FPOINTER;
1181                      break;
1182                  case S_IDATA:
1183                      DCL_TYPE($3) = IPOINTER ;
1184                      break;
1185                  case S_PDATA:
1186                      DCL_TYPE($3) = PPOINTER ;
1187                      break;
1188                  case S_DATA:
1189                      DCL_TYPE($3) = POINTER ;
1190                      break;
1191                  case S_CODE:
1192                      DCL_TYPE($3) = CPOINTER ;
1193                      break;
1194                  case S_EEPROM:
1195                      DCL_TYPE($3) = EEPPOINTER;
1196                      break;
1197                  default:
1198                    // this could be just "constant"
1199                    // werror(W_PTR_TYPE_INVALID);
1200                      ;
1201                  }
1202              }
1203              else
1204                  werror (W_PTR_TYPE_INVALID);
1205              $$->next = $3 ;
1206          }
1207    ;
1208
1209 unqualified_pointer
1210    :  '*'
1211       {
1212         $$ = newLink(DECLARATOR);
1213         DCL_TYPE($$)=UPOINTER;
1214       }
1215    ;
1216
1217 type_specifier_list
1218    : type_specifier
1219    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1220    | type_specifier_list type_specifier {
1221      /* if the decl $2 is not a specifier */
1222      /* find the spec and replace it      */
1223      if ( !IS_SPEC($2)) {
1224        sym_link *lnk = $2 ;
1225        while (lnk && !IS_SPEC(lnk->next))
1226          lnk = lnk->next;
1227        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1228        $$ = $2 ;
1229      }
1230      else
1231        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1232    }
1233    ;
1234
1235 identifier_list
1236    : identifier
1237    | identifier_list ',' identifier
1238          {
1239            $3->next = $1;
1240            $$ = $3 ;
1241          }
1242    ;
1243
1244 parameter_type_list
1245         : parameter_list
1246         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1247         ;
1248
1249 parameter_list
1250    : parameter_declaration
1251    | parameter_list ',' parameter_declaration
1252          {
1253             $3->next = $1 ;
1254             $$ = $3 ;
1255          }
1256    ;
1257
1258 parameter_declaration
1259    : type_specifier_list declarator
1260                {
1261                   symbol *loop ;
1262                   pointerTypes($2->type,$1);
1263                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1264                     SPEC_USIGN($1) = 1;
1265                   addDecl ($2,0,$1);
1266                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1267                   addSymChain (&$2);
1268                   $$ = symbolVal($2);
1269                   ignoreTypedefType = 0;
1270                }
1271    | type_name {
1272                   $$ = newValue() ;
1273                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1274                     SPEC_USIGN($1) = 1;
1275                   $$->type = $1;
1276                   $$->etype = getSpec($$->type);
1277                   ignoreTypedefType = 0;
1278                }
1279    ;
1280
1281 type_name
1282    : type_specifier_list  { $$ = $1; ignoreTypedefType = 0;}
1283    | type_specifier_list abstract_declarator
1284                {
1285                  /* go to the end of the list */
1286                  sym_link *p;
1287                  pointerTypes($2,$1);
1288                  for ( p = $2 ; p && p->next ; p=p->next);
1289                  if (!p) {
1290                    werror(E_SYNTAX_ERROR, yytext);
1291                  } else {
1292                    p->next = $1 ;
1293                  }
1294                  $$ = $2 ;
1295                  ignoreTypedefType = 0;
1296                }
1297    ;
1298
1299 abstract_declarator
1300    : pointer { $$ = reverseLink($1); }
1301    | abstract_declarator2
1302    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1303           if (IS_PTR($1) && IS_FUNC($2))
1304             DCL_TYPE($1) = CPOINTER;
1305         }
1306    ;
1307
1308 abstract_declarator2
1309    : '(' abstract_declarator ')'    { $$ = $2 ; }
1310    | '[' ']'                        {
1311                                        $$ = newLink (DECLARATOR);
1312                                        DCL_TYPE($$) = ARRAY ;
1313                                        DCL_ELEM($$) = 0     ;
1314                                     }
1315    | '[' constant_expr ']'          {
1316                                        value *val ;
1317                                        $$ = newLink (DECLARATOR);
1318                                        DCL_TYPE($$) = ARRAY ;
1319                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1320                                     }
1321    | abstract_declarator2 '[' ']'   {
1322                                        $$ = newLink (DECLARATOR);
1323                                        DCL_TYPE($$) = ARRAY ;
1324                                        DCL_ELEM($$) = 0     ;
1325                                        $$->next = $1 ;
1326                                     }
1327    | abstract_declarator2 '[' constant_expr ']'
1328                                     {
1329                                        value *val ;
1330                                        $$ = newLink (DECLARATOR);
1331                                        DCL_TYPE($$) = ARRAY ;
1332                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1333                                        $$->next = $1 ;
1334                                     }
1335    | '(' ')'                        { $$ = NULL;}
1336    | '(' parameter_type_list ')'    { $$ = NULL;}
1337    | abstract_declarator2 '(' ')' {
1338      // $1 must be a pointer to a function
1339      sym_link *p=newLink(DECLARATOR);
1340      DCL_TYPE(p) = FUNCTION;
1341      if (!$1) {
1342        // ((void (code *) ()) 0) ()
1343        $1=newLink(DECLARATOR);
1344        DCL_TYPE($1)=CPOINTER;
1345        $$ = $1;
1346      }
1347      $1->next=p;
1348    }
1349    | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1350        sym_link *p=newLink(DECLARATOR);
1351        DCL_TYPE(p) = FUNCTION;
1352
1353        FUNC_HASVARARGS(p) = IS_VARG($4);
1354        FUNC_ARGS(p) = reverseVal($4);
1355
1356        /* nest level was incremented to take care of the parms  */
1357        NestLevel-- ;
1358        currBlockno--;
1359        if (!$1) {
1360          /* ((void (code *) (void)) 0) () */
1361          $1=newLink(DECLARATOR);
1362          DCL_TYPE($1)=CPOINTER;
1363          $$ = $1;
1364        }
1365        $1->next=p;
1366
1367        // remove the symbol args (if any)
1368        cleanUpLevel(SymbolTab,NestLevel+1);
1369    }
1370    ;
1371
1372 initializer
1373    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1374    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1375    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1376    ;
1377
1378 initializer_list
1379    : initializer
1380    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1381    ;
1382
1383 statement
1384    : labeled_statement
1385    | compound_statement
1386    | expression_statement
1387    | selection_statement
1388    | iteration_statement
1389    | jump_statement
1390    | critical_statement
1391    | INLINEASM  ';'      {
1392                             ast *ex;
1393                             seqPointNo++;
1394                             ex = newNode(INLINEASM,NULL,NULL);
1395                             ex->values.inlineasm = strdup($1);
1396                             seqPointNo++;
1397                             $$ = ex;
1398                          }
1399    ;
1400
1401 critical
1402    : CRITICAL   {
1403                    inCritical++;
1404                    STACK_PUSH(continueStack,NULL);
1405                    STACK_PUSH(breakStack,NULL);
1406                    $$ = NULL;
1407                 }
1408    ;
1409
1410 critical_statement
1411    : critical statement  {
1412                    STACK_POP(breakStack);
1413                    STACK_POP(continueStack);
1414                    inCritical--;
1415                    $$ = newNode(CRITICAL,$2,NULL);
1416                 }
1417    ;
1418
1419 labeled_statement
1420 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }
1421    : identifier ':'                    {  $$ = createLabel($1,NULL);
1422                                           $1->isitmp = 0;  }
1423    | CASE constant_expr ':'
1424      {
1425        if (STACK_EMPTY(swStk))
1426          $$ = createCase(NULL,$2,NULL);
1427        else
1428          $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1429      }
1430    | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1431      {
1432        if (STACK_EMPTY(swStk))
1433          $$ = createDefault(NULL,$<asts>2,NULL);
1434        else
1435          $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1436      }
1437    ;
1438
1439 start_block : '{'
1440               {
1441                 STACK_PUSH(blockNum,currBlockno);
1442                 currBlockno = ++blockNo ;
1443                 ignoreTypedefType = 0;
1444               }
1445             ;
1446
1447 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }
1448             ;
1449
1450 compound_statement
1451    : start_block end_block                    { $$ = createBlock(NULL, NULL); }
1452    | start_block statement_list end_block     { $$ = createBlock(NULL, $2); }
1453    | start_block declaration_list end_block   { $$ = createBlock($2, NULL); }
1454    | start_block
1455           declaration_list statement_list
1456      end_block                                {$$ = createBlock($2, $3); }
1457    | error ';'                                { $$ = NULL ; }
1458    ;
1459
1460 declaration_list
1461    : declaration
1462      {
1463        /* if this is typedef declare it immediately */
1464        if ( $1 && IS_TYPEDEF($1->etype)) {
1465          allocVariables ($1);
1466          $$ = NULL ;
1467        }
1468        else
1469          $$ = $1 ;
1470        ignoreTypedefType = 0;
1471        addSymChain(&$1);
1472      }
1473
1474    | declaration_list declaration
1475      {
1476        symbol   *sym;
1477
1478        /* if this is a typedef */
1479        if ($2 && IS_TYPEDEF($2->etype)) {
1480          allocVariables ($2);
1481          $$ = $1 ;
1482        }
1483        else {
1484                                 /* get to the end of the previous decl */
1485          if ( $1 ) {
1486            $$ = sym = $1 ;
1487            while (sym->next)
1488              sym = sym->next ;
1489            sym->next = $2;
1490          }
1491          else
1492            $$ = $2 ;
1493        }
1494        ignoreTypedefType = 0;
1495        addSymChain(&$2);
1496      }
1497    ;
1498
1499 statement_list
1500    : statement
1501    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1502    ;
1503
1504 expression_statement
1505    : ';'                { $$ = NULL;}
1506    | expr ';'           { $$ = $1; seqPointNo++;}
1507    ;
1508
1509 else_statement
1510    :  ELSE  statement   { $$ = $2  ; }
1511    |                    { $$ = NULL;}
1512    ;
1513
1514
1515 selection_statement
1516    : IF '(' expr ')' { seqPointNo++;} statement else_statement
1517                            {
1518                               noLineno++ ;
1519                               $$ = createIf ($3, $6, $7 );
1520                               noLineno--;
1521                            }
1522    | SWITCH '(' expr ')'   {
1523                               ast *ex ;
1524                               static   int swLabel = 0 ;
1525
1526                               seqPointNo++;
1527                               /* create a node for expression  */
1528                               ex = newNode(SWITCH,$3,NULL);
1529                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1530                               ex->values.switchVals.swNum = swLabel ;
1531
1532                               /* now create the label */
1533                               SNPRINTF(lbuff, sizeof(lbuff),
1534                                        "_swBrk_%d",swLabel++);
1535                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1536                               /* put label in the break stack  */
1537                               STACK_PUSH(breakStack,$<sym>$);
1538                            }
1539      statement             {
1540                               /* get back the switch form the stack  */
1541                               $$ = STACK_POP(swStk)  ;
1542                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1543                               STACK_POP(breakStack);
1544                            }
1545         ;
1546
1547 while : WHILE  {  /* create and push the continue , break & body labels */
1548                   static int Lblnum = 0 ;
1549                   /* continue */
1550                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1551                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1552                   /* break */
1553                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1554                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1555                   /* body */
1556                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1557                   $$ = newSymbol(lbuff,NestLevel);
1558                }
1559    ;
1560
1561 do : DO {  /* create and push the continue , break & body Labels */
1562            static int Lblnum = 0 ;
1563
1564            /* continue */
1565            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1566            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1567            /* break */
1568            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1569            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1570            /* do body */
1571            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1572            $$ = newSymbol (lbuff,NestLevel);
1573         }
1574    ;
1575
1576 for : FOR { /* create & push continue, break & body labels */
1577             static int Lblnum = 0 ;
1578
1579             /* continue */
1580             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1581             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1582             /* break    */
1583             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1584             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1585             /* body */
1586             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1587             $$ = newSymbol(lbuff,NestLevel);
1588             /* condition */
1589             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1590             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1591           }
1592    ;
1593
1594 iteration_statement
1595    : while '(' expr ')' { seqPointNo++;}  statement
1596                          {
1597                            noLineno++ ;
1598                            $$ = createWhile ( $1, STACK_POP(continueStack),
1599                                               STACK_POP(breakStack), $3, $6 );
1600                            $$->lineno = $1->lineDef ;
1601                            noLineno-- ;
1602                          }
1603    | do statement   WHILE '(' expr ')' ';'
1604                         {
1605                           seqPointNo++;
1606                           noLineno++ ;
1607                           $$ = createDo ( $1 , STACK_POP(continueStack),
1608                                           STACK_POP(breakStack), $5, $2);
1609                           $$->lineno = $1->lineDef ;
1610                           noLineno-- ;
1611                         }
1612    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement
1613                         {
1614                           noLineno++ ;
1615
1616                           /* if break or continue statement present
1617                              then create a general case loop */
1618                           if (STACK_PEEK(continueStack)->isref ||
1619                               STACK_PEEK(breakStack)->isref) {
1620                               $$ = createFor ($1, STACK_POP(continueStack),
1621                                               STACK_POP(breakStack) ,
1622                                               STACK_POP(forStack)   ,
1623                                               $3 , $5 , $7, $9 );
1624                           } else {
1625                               $$ = newNode(FOR,$9,NULL);
1626                               AST_FOR($$,trueLabel) = $1;
1627                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1628                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1629                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1630                               AST_FOR($$,initExpr)   = $3;
1631                               AST_FOR($$,condExpr)   = $5;
1632                               AST_FOR($$,loopExpr)   = $7;
1633                           }
1634
1635                           noLineno-- ;
1636                         }
1637 ;
1638
1639 expr_opt
1640         :                       { $$ = NULL ; seqPointNo++; }
1641         |       expr            { $$ = $1 ; seqPointNo++; }
1642         ;
1643
1644 jump_statement
1645    : GOTO identifier ';'   {
1646                               $2->islbl = 1;
1647                               $$ = newAst_VALUE(symbolVal($2));
1648                               $$ = newNode(GOTO,$$,NULL);
1649                            }
1650    | CONTINUE ';'          {
1651        /* make sure continue is in context */
1652        if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1653            werror(E_BREAK_CONTEXT);
1654            $$ = NULL;
1655        }
1656        else {
1657            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1658            $$ = newNode(GOTO,$$,NULL);
1659            /* mark the continue label as referenced */
1660            STACK_PEEK(continueStack)->isref = 1;
1661        }
1662    }
1663    | BREAK ';'             {
1664        if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1665            werror(E_BREAK_CONTEXT);
1666            $$ = NULL;
1667        } else {
1668            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1669            $$ = newNode(GOTO,$$,NULL);
1670            STACK_PEEK(breakStack)->isref = 1;
1671        }
1672    }
1673    | RETURN ';'            {
1674        seqPointNo++;
1675        if (inCritical) {
1676            werror(E_INVALID_CRITICAL);
1677            $$ = NULL;
1678        } else {
1679            $$ = newNode(RETURN,NULL,NULL);
1680        }
1681    }
1682    | RETURN expr ';'       {
1683        seqPointNo++;
1684        if (inCritical) {
1685            werror(E_INVALID_CRITICAL);
1686            $$ = NULL;
1687        } else {
1688            $$ = newNode(RETURN,NULL,$2);
1689        }
1690    }
1691    ;
1692
1693 identifier
1694    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1695    ;
1696 %%
1697