* src/pic16/genarith.c (genAddLit): fix structure access (#1888004)
[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 function_specifier
113 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
114 %type <lnk> function_attribute function_attributes enum_specifier
115 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
116 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
117 %type <sdef> stag opt_stag
118 %type <asts> primary_expr
119 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
120 %type <asts> additive_expr shift_expr relational_expr equality_expr
121 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
122 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
123 %type <asts> expr argument_expr_list function_definition expr_opt
124 %type <asts> statement_list statement labeled_statement compound_statement
125 %type <asts> expression_statement selection_statement iteration_statement
126 %type <asts> jump_statement function_body else_statement string_literal
127 %type <asts> critical_statement
128 %type <ilist> initializer initializer_list
129 %type <yyint> unary_operator assignment_operator struct_or_union
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) ulFromVal(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    | function_specifier                             { $$ = $1; }
524    | function_specifier declaration_specifiers          {
525      /* if the decl $2 is not a specifier */
526      /* find the spec and replace it      */
527      if ( !IS_SPEC($2)) {
528        sym_link *lnk = $2 ;
529        while (lnk && !IS_SPEC(lnk->next))
530          lnk = lnk->next;
531        lnk->next = mergeSpec($1,lnk->next, "function_specifier declaration_specifiers - skipped");
532        $$ = $2 ;
533      }
534      else
535        $$ = mergeSpec($1,$2, "function_specifier declaration_specifiers");
536    }
537    ;
538
539 init_declarator_list
540    : init_declarator
541    | init_declarator_list ',' init_declarator      { $3->next = $1 ; $$ = $3;}
542    ;
543
544 init_declarator
545    : declarator                  { $1->ival = NULL ; }
546    | declarator '=' initializer  { $1->ival = $3   ; }
547    ;
548
549
550 storage_class_specifier
551    : TYPEDEF   {
552                   $$ = newLink (SPECIFIER) ;
553                   SPEC_TYPEDEF($$) = 1 ;
554                }
555    | EXTERN    {
556                   $$ = newLink(SPECIFIER);
557                   SPEC_EXTR($$) = 1 ;
558                }
559    | STATIC    {
560                   $$ = newLink (SPECIFIER);
561                   SPEC_STAT($$) = 1 ;
562                }
563    | AUTO      {
564                   $$ = newLink (SPECIFIER) ;
565                   SPEC_SCLS($$) = S_AUTO  ;
566                }
567    | REGISTER  {
568                   $$ = newLink (SPECIFIER);
569                   SPEC_SCLS($$) = S_REGISTER ;
570                }
571    ;
572
573 function_specifier
574    : INLINE   {
575                   $$ = newLink (SPECIFIER) ;
576                   SPEC_INLINE($$) = 1 ;
577                }
578    ;
579
580 Interrupt_storage
581    : INTERRUPT { $$ = INTNO_UNSPEC ; }
582    | INTERRUPT constant_expr
583         { int intno = (int) ulFromVal(constExprValue($2,TRUE));
584           if ((intno >= 0) && (intno <= INTNO_MAX))
585             $$ = intno;
586           else
587             {
588               werror(E_INT_BAD_INTNO, intno);
589               $$ = INTNO_UNSPEC;
590             }
591         }
592    ;
593
594 type_specifier
595    : type_specifier2
596    | type_specifier2 AT constant_expr
597         {
598            /* add this to the storage class specifier  */
599            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
600            /* now get the abs addr from value */
601            SPEC_ADDR($1) = (unsigned int) ulFromVal(constExprValue($3,TRUE)) ;
602         }
603    ;
604
605 type_specifier2
606    : CHAR      {
607                   $$=newLink(SPECIFIER);
608                   SPEC_NOUN($$) = V_CHAR  ;
609                   ignoreTypedefType = 1;
610                }
611    | SHORT     {
612                   $$=newLink(SPECIFIER);
613                   SPEC_SHORT($$) = 1 ;
614                   ignoreTypedefType = 1;
615                }
616    | INT       {
617                   $$=newLink(SPECIFIER);
618                   SPEC_NOUN($$) = V_INT   ;
619                   ignoreTypedefType = 1;
620                }
621    | LONG      {
622                   $$=newLink(SPECIFIER);
623                   SPEC_LONG($$) = 1       ;
624                   ignoreTypedefType = 1;
625                }
626    | SIGNED    {
627                   $$=newLink(SPECIFIER);
628                   $$->select.s.b_signed = 1;
629                   ignoreTypedefType = 1;
630                }
631    | UNSIGNED  {
632                   $$=newLink(SPECIFIER);
633                   SPEC_USIGN($$) = 1      ;
634                   ignoreTypedefType = 1;
635                }
636    | VOID      {
637                   $$=newLink(SPECIFIER);
638                   SPEC_NOUN($$) = V_VOID  ;
639                   ignoreTypedefType = 1;
640                }
641    | CONST     {
642                   $$=newLink(SPECIFIER);
643                   SPEC_CONST($$) = 1;
644                }
645    | VOLATILE  {
646                   $$=newLink(SPECIFIER);
647                   SPEC_VOLATILE($$) = 1 ;
648                }
649    | RESTRICT  {
650                   $$=newLink(SPECIFIER);
651                   SPEC_RESTRICT($$) = 1 ;
652                }
653    | FLOAT     {
654                   $$=newLink(SPECIFIER);
655                   SPEC_NOUN($$) = V_FLOAT;
656                   ignoreTypedefType = 1;
657                }
658    | FIXED16X16 {
659                   $$=newLink(SPECIFIER);
660                   SPEC_NOUN($$) = V_FIXED16X16;
661                   ignoreTypedefType = 1;
662                }
663    | XDATA     {
664                   $$ = newLink (SPECIFIER);
665                   SPEC_SCLS($$) = S_XDATA  ;
666                }
667    | CODE      {
668                   $$ = newLink (SPECIFIER) ;
669                   SPEC_SCLS($$) = S_CODE ;
670                }
671    | EEPROM    {
672                   $$ = newLink (SPECIFIER) ;
673                   SPEC_SCLS($$) = S_EEPROM ;
674                }
675    | DATA      {
676                   $$ = newLink (SPECIFIER);
677                   SPEC_SCLS($$) = S_DATA   ;
678                }
679    | IDATA     {
680                   $$ = newLink (SPECIFIER);
681                   SPEC_SCLS($$) = S_IDATA  ;
682                }
683    | PDATA     {
684                   $$ = newLink (SPECIFIER);
685                   SPEC_SCLS($$) = S_PDATA  ;
686                }
687    | BIT       {
688                   $$=newLink(SPECIFIER);
689                   SPEC_NOUN($$) = V_BIT   ;
690                   SPEC_SCLS($$) = S_BIT   ;
691                   SPEC_BLEN($$) = 1;
692                   SPEC_BSTR($$) = 0;
693                   ignoreTypedefType = 1;
694                }
695
696    | struct_or_union_specifier  {
697                                    uselessDecl = FALSE;
698                                    $$ = $1 ;
699                                    ignoreTypedefType = 1;
700                                 }
701    | enum_specifier     {
702                            cenum = NULL ;
703                            uselessDecl = FALSE;
704                            ignoreTypedefType = 1;
705                            $$ = $1 ;
706                         }
707    | TYPE_NAME
708          {
709             symbol *sym;
710             sym_link   *p  ;
711             sym = findSym(TypedefTab,NULL,$1) ;
712             $$ = p = copyLinkChain(sym ? sym->type : NULL);
713             SPEC_TYPEDEF(getSpec(p)) = 0;
714             ignoreTypedefType = 1;
715          }
716    | sfr_reg_bit
717    ;
718
719 sfr_reg_bit
720    :  SBIT  {
721                $$ = newLink(SPECIFIER) ;
722                SPEC_NOUN($$) = V_SBIT;
723                SPEC_SCLS($$) = S_SBIT;
724                SPEC_BLEN($$) = 1;
725                SPEC_BSTR($$) = 0;
726                ignoreTypedefType = 1;
727             }
728    |  sfr_attributes
729    ;
730
731 sfr_attributes
732    : SFR    {
733                $$ = newLink(SPECIFIER) ;
734                FUNC_REGBANK($$) = 0;
735                SPEC_NOUN($$)    = V_CHAR;
736                SPEC_SCLS($$)    = S_SFR ;
737                SPEC_USIGN($$)   = 1 ;
738                ignoreTypedefType = 1;
739             }
740    | SFR BANKED {
741                $$ = newLink(SPECIFIER) ;
742                FUNC_REGBANK($$) = 1;
743                SPEC_NOUN($$)    = V_CHAR;
744                SPEC_SCLS($$)    = S_SFR ;
745                SPEC_USIGN($$)   = 1 ;
746                ignoreTypedefType = 1;
747             }
748    ;
749
750 sfr_attributes
751    : SFR16  {
752                $$ = newLink(SPECIFIER) ;
753                FUNC_REGBANK($$) = 0;
754                SPEC_NOUN($$)    = V_INT;
755                SPEC_SCLS($$)    = S_SFR;
756                SPEC_USIGN($$)   = 1 ;
757                ignoreTypedefType = 1;
758             }
759    ;
760
761 sfr_attributes
762    : SFR32  {
763                $$ = newLink(SPECIFIER) ;
764                FUNC_REGBANK($$) = 0;
765                SPEC_NOUN($$)    = V_INT;
766                SPEC_SCLS($$)    = S_SFR;
767                SPEC_LONG($$)    = 1;
768                SPEC_USIGN($$)   = 1;
769                ignoreTypedefType = 1;
770             }
771    ;
772
773 struct_or_union_specifier
774    : struct_or_union opt_stag
775         {
776            if (!$2->type)
777              {
778                $2->type = $1;
779              }
780            else
781              {
782                if ($2->type != $1)
783                  werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
784              }
785
786         }
787            '{' struct_declaration_list '}'
788         {
789            structdef *sdef ;
790            symbol *sym, *dsym;
791
792            // check for errors in structure members
793            for (sym=$5; sym; sym=sym->next) {
794              if (IS_ABSOLUTE(sym->etype)) {
795                werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
796                SPEC_ABSA(sym->etype) = 0;
797              }
798              if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
799                werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
800                printTypeChainRaw (sym->type,NULL);
801                SPEC_SCLS(sym->etype) = 0;
802              }
803              for (dsym=sym->next; dsym; dsym=dsym->next) {
804                if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
805                  werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
806                         $1==STRUCT ? "struct" : "union", sym->name);
807                  werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
808                }
809              }
810            }
811
812            /* Create a structdef   */
813            sdef = $2 ;
814            sdef->fields   = reverseSyms($5) ;   /* link the fields */
815            sdef->size  = compStructSize($1,sdef);   /* update size of  */
816            promoteAnonStructs ($1, sdef);
817
818            /* Create the specifier */
819            $$ = newLink (SPECIFIER) ;
820            SPEC_NOUN($$) = V_STRUCT;
821            SPEC_STRUCT($$)= sdef ;
822         }
823    | struct_or_union stag
824          {
825             $$ = newLink(SPECIFIER) ;
826             SPEC_NOUN($$) = V_STRUCT;
827             SPEC_STRUCT($$) = $2;
828
829            if (!$2->type)
830              {
831                $2->type = $1;
832              }
833            else
834              {
835                if ($2->type != $1)
836                  werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
837              }
838          }
839    ;
840
841 struct_or_union
842    : STRUCT          { $$ = STRUCT ; }
843    | UNION           { $$ = UNION  ; }
844    ;
845
846 opt_stag
847 : stag
848 |  {  /* synthesize a name add to structtable */
849      $$ = newStruct(genSymName(NestLevel)) ;
850      $$->level = NestLevel ;
851      addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
852 };
853
854 stag
855 :  identifier  {  /* add name to structure table */
856      $$ = findSymWithBlock (StructTab,$1,currBlockno);
857      if (! $$ ) {
858        $$ = newStruct($1->name) ;
859        $$->level = NestLevel ;
860        addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
861      }
862 };
863
864
865 struct_declaration_list
866    : struct_declaration
867    | struct_declaration_list struct_declaration
868        {
869            symbol *sym=$2;
870
871            /* go to the end of the chain */
872            while (sym->next) sym=sym->next;
873            sym->next = $1 ;
874
875            $$ = $2;
876        }
877    ;
878
879 struct_declaration
880    : type_specifier_list struct_declarator_list ';'
881        {
882            /* add this type to all the symbols */
883            symbol *sym ;
884            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
885                sym_link *btype = copyLinkChain($1);
886                if (options.unsigned_char && SPEC_NOUN(btype) == V_CHAR && !(btype)->select.s.b_signed)
887                  SPEC_USIGN(btype) = 1;
888
889                /* make the symbol one level up */
890                sym->level-- ;
891
892                pointerTypes(sym->type,btype);
893                if (!sym->type) {
894                    sym->type = btype;
895                    sym->etype = getSpec(sym->type);
896                }
897                else
898                  addDecl (sym,0,btype);
899                /* make sure the type is complete and sane */
900                checkTypeSanity(sym->etype, sym->name);
901            }
902            ignoreTypedefType = 0;
903            $$ = $2;
904        }
905    ;
906
907 struct_declarator_list
908    : struct_declarator
909    | struct_declarator_list ',' struct_declarator
910        {
911            $3->next  = $1 ;
912            $$ = $3 ;
913        }
914    ;
915
916 struct_declarator
917    : declarator
918    | ':' constant_expr  {
919                            unsigned int bitsize;
920                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
921                            bitsize = (unsigned int) ulFromVal(constExprValue($2,TRUE));
922                            if (bitsize > (port->s.int_size * 8)) {
923                              bitsize = port->s.int_size * 8;
924                              werror(E_BITFLD_SIZE, bitsize);
925                            }
926                            if (!bitsize)
927                              bitsize = BITVAR_PAD;
928                            $$->bitVar = bitsize;
929                         }
930    | declarator ':' constant_expr
931                         {
932                           unsigned int bitsize;
933                           bitsize = (unsigned int) ulFromVal(constExprValue($3,TRUE));
934                           if (bitsize > (port->s.int_size * 8)) {
935                             bitsize = port->s.int_size * 8;
936                             werror(E_BITFLD_SIZE, bitsize);
937                           }
938                           if (!bitsize) {
939                             $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
940                             $$->bitVar = BITVAR_PAD;
941                             werror(W_BITFLD_NAMED);
942                           }
943                           else
944                             $1->bitVar = bitsize;
945                         }
946    | { $$ = newSymbol ("", NestLevel) ; }
947
948    ;
949
950 enum_specifier
951    : ENUM            '{' enumerator_list '}' {
952            $$ = newEnumType ($3);       //copyLinkChain(cenum->type);
953            SPEC_SCLS(getSpec($$)) = 0;
954          }
955
956    | ENUM identifier '{' enumerator_list '}' {
957      symbol *csym ;
958      sym_link *enumtype;
959
960      csym=findSym(enumTab,$2,$2->name);
961      if ((csym && csym->level == $2->level))
962        {
963          werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
964          werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
965        }
966
967      enumtype = newEnumType ($4);       //copyLinkChain(cenum->type);
968      SPEC_SCLS(getSpec(enumtype)) = 0;
969      $2->type = enumtype;
970
971      /* add this to the enumerator table */
972      if (!csym)
973        addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
974      $$ = copyLinkChain(enumtype);
975    }
976    | ENUM identifier                         {
977      symbol *csym ;
978
979      /* check the enumerator table */
980      if ((csym = findSym(enumTab,$2,$2->name)))
981        $$ = copyLinkChain(csym->type);
982      else  {
983        $$ = newLink(SPECIFIER) ;
984        SPEC_NOUN($$) = V_INT   ;
985      }
986    }
987    ;
988
989 enumerator_list
990     : enumerator
991     | enumerator_list ','
992     | enumerator_list ',' enumerator
993       {
994         $3->next = $1 ;
995         $$ = $3  ;
996       }
997     ;
998
999 enumerator
1000     : identifier opt_assign_expr
1001       {
1002         symbol *sym;
1003
1004         /* make the symbol one level up */
1005         $1->level-- ;
1006         // check if the symbol at the same level already exists
1007         if ((sym = findSymWithLevel (SymbolTab, $1)) &&
1008           sym->level == $1->level)
1009           {
1010             werrorfl ($1->fileDef, $1->lineDef, E_DUPLICATE_MEMBER, "enum", $1->name);
1011             werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF);
1012           }
1013         $1->type = copyLinkChain ($2->type);
1014         $1->etype= getSpec ($1->type);
1015         SPEC_ENUM ($1->etype) = 1;
1016         $$ = $1 ;
1017         // do this now, so we can use it for the next enums in the list
1018         addSymChain (&$1);
1019       }
1020     ;
1021
1022 opt_assign_expr
1023    :  '='   constant_expr  {
1024                               value *val ;
1025
1026                               val = constExprValue($2,TRUE);
1027                               if (!IS_INT(val->type) && !IS_CHAR(val->type))
1028                                 {
1029                                   werror(E_ENUM_NON_INTEGER);
1030                                   SNPRINTF(lbuff, sizeof(lbuff),
1031                                           "%d", (int) ulFromVal(val));
1032                                   val = constVal(lbuff);
1033                                 }
1034                               $$ = cenum = val ;
1035                            }
1036    |                       {
1037                               if (cenum)  {
1038                                  SNPRINTF(lbuff, sizeof(lbuff),
1039                                           "%d", (int) ulFromVal(cenum)+1);
1040                                  $$ = cenum = constVal(lbuff);
1041                               }
1042                               else {
1043                                  $$ = cenum = constCharVal(0);
1044                               }
1045                            }
1046    ;
1047
1048 declarator
1049    : declarator3                        { $$ = $1 ; }
1050    | pointer declarator3
1051          {
1052              addDecl ($2,0,reverseLink($1));
1053              $$ = $2 ;
1054          }
1055    ;
1056
1057 declarator3
1058    : declarator2_function_attributes    { $$ = $1 ; }
1059    | declarator2                        { $$ = $1 ; }
1060    ;
1061
1062 function_declarator
1063    : declarator2_function_attributes    { $$ = $1; }
1064    | pointer declarator2_function_attributes
1065          {
1066              addDecl ($2,0,reverseLink($1));
1067              $$ = $2 ;
1068          }
1069    ;
1070
1071 declarator2_function_attributes
1072    : function_declarator2                 { $$ = $1 ; }
1073    | function_declarator2 function_attribute  {
1074            // copy the functionAttributes (not the args and hasVargs !!)
1075            struct value *args;
1076            unsigned hasVargs;
1077            sym_link *funcType=$1->type;
1078
1079            while (funcType && !IS_FUNC(funcType))
1080              funcType = funcType->next;
1081
1082            if (!funcType)
1083              werror (E_FUNC_ATTR);
1084            else
1085              {
1086                args=FUNC_ARGS(funcType);
1087                hasVargs=FUNC_HASVARARGS(funcType);
1088
1089                memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1090                    sizeof($2->funcAttrs));
1091
1092                FUNC_ARGS(funcType)=args;
1093                FUNC_HASVARARGS(funcType)=hasVargs;
1094
1095                // just to be sure
1096                memset (&$2->funcAttrs, 0,
1097                    sizeof($2->funcAttrs));
1098
1099                addDecl ($1,0,$2);
1100              }
1101    }
1102    ;
1103
1104 declarator2
1105    : identifier
1106    | '(' declarator ')'     { $$ = $2; }
1107    | declarator3 '[' ']'
1108          {
1109             sym_link   *p;
1110
1111             p = newLink (DECLARATOR);
1112             DCL_TYPE(p) = ARRAY ;
1113             DCL_ELEM(p) = 0     ;
1114             addDecl($1,0,p);
1115          }
1116    | declarator3 '[' constant_expr ']'
1117          {
1118             sym_link *p;
1119             value *tval;
1120             int size;
1121
1122             tval = constExprValue($3, TRUE);
1123             /* if it is not a constant then Error  */
1124             p = newLink (DECLARATOR);
1125             DCL_TYPE(p) = ARRAY;
1126
1127             if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL))
1128               {
1129                 werror(E_CONST_EXPECTED);
1130                 /* Assume a single item array to limit the cascade */
1131                 /* of additional errors. */
1132                 size = 1;
1133               }
1134             else
1135               {
1136                 if ((size = (int) ulFromVal(tval)) < 0)
1137                   {
1138                     werror(E_NEGATIVE_ARRAY_SIZE, $1->name);
1139                     size = 1;
1140                   }
1141               }
1142             DCL_ELEM(p) = size;
1143             addDecl($1, 0, p);
1144          }
1145    ;
1146
1147 function_declarator2
1148    : declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
1149    | declarator2 '('            { NestLevel++ ; currBlockno++;  }
1150                      parameter_type_list ')'
1151          {
1152              sym_link *funcType;
1153
1154              addDecl ($1,FUNCTION,NULL) ;
1155
1156              funcType = $1->type;
1157              while (funcType && !IS_FUNC(funcType))
1158                funcType = funcType->next;
1159
1160              assert (funcType);
1161
1162              FUNC_HASVARARGS(funcType) = IS_VARG($4);
1163              FUNC_ARGS(funcType) = reverseVal($4);
1164
1165              /* nest level was incremented to take care of the parms  */
1166              NestLevel-- ;
1167              currBlockno--;
1168
1169              // if this was a pointer (to a function)
1170              if (!IS_FUNC($1->type))
1171                cleanUpLevel(SymbolTab,NestLevel+1);
1172
1173              $$ = $1;
1174          }
1175    | declarator2 '(' identifier_list ')'
1176          {
1177            werror(E_OLD_STYLE,$1->name) ;
1178            /* assume it returns an int */
1179            $1->type = $1->etype = newIntLink();
1180            $$ = $1 ;
1181          }
1182    ;
1183
1184 pointer
1185    : unqualified_pointer { $$ = $1 ;}
1186    | unqualified_pointer type_specifier_list
1187          {
1188              $$ = $1  ;
1189              if (IS_SPEC($2)) {
1190                  DCL_TSPEC($1) = $2;
1191                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1192                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1193                  DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1194              }
1195              else
1196                  werror (W_PTR_TYPE_INVALID);
1197          }
1198    | unqualified_pointer pointer
1199          {
1200              $$ = $1 ;
1201              $$->next = $2 ;
1202              DCL_TYPE($2)=port->unqualified_pointer;
1203          }
1204    | unqualified_pointer type_specifier_list pointer
1205          {
1206              $$ = $1 ;
1207              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1208                  DCL_PTR_CONST($1) = SPEC_CONST($2);
1209                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1210                  DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2);
1211                  switch (SPEC_SCLS($2)) {
1212                  case S_XDATA:
1213                      DCL_TYPE($3) = FPOINTER;
1214                      break;
1215                  case S_IDATA:
1216                      DCL_TYPE($3) = IPOINTER ;
1217                      break;
1218                  case S_PDATA:
1219                      DCL_TYPE($3) = PPOINTER ;
1220                      break;
1221                  case S_DATA:
1222                      DCL_TYPE($3) = POINTER ;
1223                      break;
1224                  case S_CODE:
1225                      DCL_TYPE($3) = CPOINTER ;
1226                      break;
1227                  case S_EEPROM:
1228                      DCL_TYPE($3) = EEPPOINTER;
1229                      break;
1230                  default:
1231                    // this could be just "constant"
1232                    // werror(W_PTR_TYPE_INVALID);
1233                      ;
1234                  }
1235              }
1236              else
1237                  werror (W_PTR_TYPE_INVALID);
1238              $$->next = $3 ;
1239          }
1240    ;
1241
1242 unqualified_pointer
1243    :  '*'
1244       {
1245         $$ = newLink(DECLARATOR);
1246         DCL_TYPE($$)=UPOINTER;
1247       }
1248    ;
1249
1250 type_specifier_list
1251    : type_specifier
1252    //| type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1253    | type_specifier_list type_specifier {
1254      /* if the decl $2 is not a specifier */
1255      /* find the spec and replace it      */
1256      if ( !IS_SPEC($2)) {
1257        sym_link *lnk = $2 ;
1258        while (lnk && !IS_SPEC(lnk->next))
1259          lnk = lnk->next;
1260        lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1261        $$ = $2 ;
1262      }
1263      else
1264        $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1265    }
1266    ;
1267
1268 identifier_list
1269    : identifier
1270    | identifier_list ',' identifier
1271          {
1272            $3->next = $1;
1273            $$ = $3 ;
1274          }
1275    ;
1276
1277 parameter_type_list
1278         : parameter_list
1279         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1280         ;
1281
1282 parameter_list
1283    : parameter_declaration
1284    | parameter_list ',' parameter_declaration
1285          {
1286             $3->next = $1 ;
1287             $$ = $3 ;
1288          }
1289    ;
1290
1291 parameter_declaration
1292    : type_specifier_list declarator
1293                {
1294                   symbol *loop ;
1295                   pointerTypes($2->type,$1);
1296                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1297                     SPEC_USIGN($1) = 1;
1298                   addDecl ($2,0,$1);
1299                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1300                   addSymChain (&$2);
1301                   $$ = symbolVal($2);
1302                   ignoreTypedefType = 0;
1303                }
1304    | type_name {
1305                   $$ = newValue() ;
1306                   if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1307                     SPEC_USIGN($1) = 1;
1308                   $$->type = $1;
1309                   $$->etype = getSpec($$->type);
1310                   ignoreTypedefType = 0;
1311                }
1312    ;
1313
1314 type_name
1315    : type_specifier_list  { $$ = $1; ignoreTypedefType = 0;}
1316    | type_specifier_list abstract_declarator
1317                {
1318                  /* go to the end of the list */
1319                  sym_link *p;
1320                  pointerTypes($2,$1);
1321                  for ( p = $2 ; p && p->next ; p=p->next);
1322                  if (!p) {
1323                    werror(E_SYNTAX_ERROR, yytext);
1324                  } else {
1325                    p->next = $1 ;
1326                  }
1327                  $$ = $2 ;
1328                  ignoreTypedefType = 0;
1329                }
1330    ;
1331
1332 abstract_declarator
1333    : pointer { $$ = reverseLink($1); }
1334    | abstract_declarator2
1335    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1336           if (IS_PTR($1) && IS_FUNC($2))
1337             DCL_TYPE($1) = CPOINTER;
1338         }
1339    ;
1340
1341 abstract_declarator2
1342    : '(' abstract_declarator ')'    { $$ = $2 ; }
1343    | '[' ']'                        {
1344                                        $$ = newLink (DECLARATOR);
1345                                        DCL_TYPE($$) = ARRAY ;
1346                                        DCL_ELEM($$) = 0     ;
1347                                     }
1348    | '[' constant_expr ']'          {
1349                                        value *val ;
1350                                        $$ = newLink (DECLARATOR);
1351                                        DCL_TYPE($$) = ARRAY ;
1352                                        DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($2,TRUE));
1353                                     }
1354    | abstract_declarator2 '[' ']'   {
1355                                        $$ = newLink (DECLARATOR);
1356                                        DCL_TYPE($$) = ARRAY ;
1357                                        DCL_ELEM($$) = 0     ;
1358                                        $$->next = $1 ;
1359                                     }
1360    | abstract_declarator2 '[' constant_expr ']'
1361                                     {
1362                                        value *val ;
1363                                        $$ = newLink (DECLARATOR);
1364                                        DCL_TYPE($$) = ARRAY ;
1365                                        DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($3,TRUE));
1366                                        $$->next = $1 ;
1367                                     }
1368    | '(' ')'                        { $$ = NULL;}
1369    | '(' parameter_type_list ')'    { $$ = NULL;}
1370    | abstract_declarator2 '(' ')' {
1371      // $1 must be a pointer to a function
1372      sym_link *p=newLink(DECLARATOR);
1373      DCL_TYPE(p) = FUNCTION;
1374      if (!$1) {
1375        // ((void (code *) ()) 0) ()
1376        $1=newLink(DECLARATOR);
1377        DCL_TYPE($1)=CPOINTER;
1378        $$ = $1;
1379      }
1380      $1->next=p;
1381    }
1382    | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1383        sym_link *p=newLink(DECLARATOR);
1384        DCL_TYPE(p) = FUNCTION;
1385
1386        FUNC_HASVARARGS(p) = IS_VARG($4);
1387        FUNC_ARGS(p) = reverseVal($4);
1388
1389        /* nest level was incremented to take care of the parms  */
1390        NestLevel-- ;
1391        currBlockno--;
1392        if (!$1) {
1393          /* ((void (code *) (void)) 0) () */
1394          $1=newLink(DECLARATOR);
1395          DCL_TYPE($1)=CPOINTER;
1396          $$ = $1;
1397        }
1398        $1->next=p;
1399
1400        // remove the symbol args (if any)
1401        cleanUpLevel(SymbolTab,NestLevel+1);
1402    }
1403    ;
1404
1405 initializer
1406    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1407    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1408    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1409    ;
1410
1411 initializer_list
1412    : initializer
1413    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1414    ;
1415
1416 statement
1417    : labeled_statement
1418    | compound_statement
1419    | expression_statement
1420    | selection_statement
1421    | iteration_statement
1422    | jump_statement
1423    | critical_statement
1424    | INLINEASM  ';'      {
1425                             ast *ex;
1426                             seqPointNo++;
1427                             ex = newNode(INLINEASM,NULL,NULL);
1428                             ex->values.inlineasm = strdup($1);
1429                             seqPointNo++;
1430                             $$ = ex;
1431                          }
1432    ;
1433
1434 critical
1435    : CRITICAL   {
1436                    inCritical++;
1437                    STACK_PUSH(continueStack,NULL);
1438                    STACK_PUSH(breakStack,NULL);
1439                    $$ = NULL;
1440                 }
1441    ;
1442
1443 critical_statement
1444    : critical statement  {
1445                    STACK_POP(breakStack);
1446                    STACK_POP(continueStack);
1447                    inCritical--;
1448                    $$ = newNode(CRITICAL,$2,NULL);
1449                 }
1450    ;
1451
1452 labeled_statement
1453 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }
1454    : identifier ':'                    {  $$ = createLabel($1,NULL);
1455                                           $1->isitmp = 0;  }
1456    | CASE constant_expr ':'
1457      {
1458        if (STACK_EMPTY(swStk))
1459          $$ = createCase(NULL,$2,NULL);
1460        else
1461          $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1462      }
1463    | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1464      {
1465        if (STACK_EMPTY(swStk))
1466          $$ = createDefault(NULL,$<asts>2,NULL);
1467        else
1468          $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1469      }
1470    ;
1471
1472 start_block : '{'
1473               {
1474                 STACK_PUSH(blockNum,currBlockno);
1475                 currBlockno = ++blockNo ;
1476                 ignoreTypedefType = 0;
1477               }
1478             ;
1479
1480 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }
1481             ;
1482
1483 compound_statement
1484    : start_block end_block                    { $$ = createBlock(NULL, NULL); }
1485    | start_block statement_list end_block     { $$ = createBlock(NULL, $2); }
1486    | start_block declaration_list end_block   { $$ = createBlock($2, NULL); }
1487    | start_block
1488           declaration_list statement_list
1489      end_block                                {$$ = createBlock($2, $3); }
1490    | error ';'                                { $$ = NULL ; }
1491    ;
1492
1493 declaration_list
1494    : declaration
1495      {
1496        /* if this is typedef declare it immediately */
1497        if ( $1 && IS_TYPEDEF($1->etype)) {
1498          allocVariables ($1);
1499          $$ = NULL ;
1500        }
1501        else
1502          $$ = $1 ;
1503        ignoreTypedefType = 0;
1504        addSymChain(&$1);
1505      }
1506
1507    | declaration_list declaration
1508      {
1509        symbol   *sym;
1510
1511        /* if this is a typedef */
1512        if ($2 && IS_TYPEDEF($2->etype)) {
1513          allocVariables ($2);
1514          $$ = $1 ;
1515        }
1516        else {
1517                                 /* get to the end of the previous decl */
1518          if ( $1 ) {
1519            $$ = sym = $1 ;
1520            while (sym->next)
1521              sym = sym->next ;
1522            sym->next = $2;
1523          }
1524          else
1525            $$ = $2 ;
1526        }
1527        ignoreTypedefType = 0;
1528        addSymChain(&$2);
1529      }
1530    ;
1531
1532 statement_list
1533    : statement
1534    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1535    ;
1536
1537 expression_statement
1538    : ';'                { $$ = NULL;}
1539    | expr ';'           { $$ = $1; seqPointNo++;}
1540    ;
1541
1542 else_statement
1543    :  ELSE  statement   { $$ = $2  ; }
1544    |                    { $$ = NULL;}
1545    ;
1546
1547
1548 selection_statement
1549    : IF '(' expr ')' { seqPointNo++;} statement else_statement
1550                            {
1551                               noLineno++ ;
1552                               $$ = createIf ($3, $6, $7 );
1553                               noLineno--;
1554                            }
1555    | SWITCH '(' expr ')'   {
1556                               ast *ex ;
1557                               static   int swLabel = 0 ;
1558
1559                               seqPointNo++;
1560                               /* create a node for expression  */
1561                               ex = newNode(SWITCH,$3,NULL);
1562                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1563                               ex->values.switchVals.swNum = swLabel ;
1564
1565                               /* now create the label */
1566                               SNPRINTF(lbuff, sizeof(lbuff),
1567                                        "_swBrk_%d",swLabel++);
1568                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1569                               /* put label in the break stack  */
1570                               STACK_PUSH(breakStack,$<sym>$);
1571                            }
1572      statement             {
1573                               /* get back the switch form the stack  */
1574                               $$ = STACK_POP(swStk)  ;
1575                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1576                               STACK_POP(breakStack);
1577                            }
1578         ;
1579
1580 while : WHILE  {  /* create and push the continue , break & body labels */
1581                   static int Lblnum = 0 ;
1582                   /* continue */
1583                   SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1584                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1585                   /* break */
1586                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1587                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1588                   /* body */
1589                   SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1590                   $$ = newSymbol(lbuff,NestLevel);
1591                }
1592    ;
1593
1594 do : DO {  /* create and push the continue , break & body Labels */
1595            static int Lblnum = 0 ;
1596
1597            /* continue */
1598            SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1599            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1600            /* break */
1601            SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1602            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1603            /* do body */
1604            SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1605            $$ = newSymbol (lbuff,NestLevel);
1606         }
1607    ;
1608
1609 for : FOR { /* create & push continue, break & body labels */
1610             static int Lblnum = 0 ;
1611
1612             /* continue */
1613             SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1614             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1615             /* break    */
1616             SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1617             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1618             /* body */
1619             SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1620             $$ = newSymbol(lbuff,NestLevel);
1621             /* condition */
1622             SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1623             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1624           }
1625    ;
1626
1627 iteration_statement
1628    : while '(' expr ')' { seqPointNo++;}  statement
1629                          {
1630                            noLineno++ ;
1631                            $$ = createWhile ( $1, STACK_POP(continueStack),
1632                                               STACK_POP(breakStack), $3, $6 );
1633                            $$->lineno = $1->lineDef ;
1634                            noLineno-- ;
1635                          }
1636    | do statement   WHILE '(' expr ')' ';'
1637                         {
1638                           seqPointNo++;
1639                           noLineno++ ;
1640                           $$ = createDo ( $1 , STACK_POP(continueStack),
1641                                           STACK_POP(breakStack), $5, $2);
1642                           $$->lineno = $1->lineDef ;
1643                           noLineno-- ;
1644                         }
1645    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement
1646                         {
1647                           noLineno++ ;
1648
1649                           /* if break or continue statement present
1650                              then create a general case loop */
1651                           if (STACK_PEEK(continueStack)->isref ||
1652                               STACK_PEEK(breakStack)->isref) {
1653                               $$ = createFor ($1, STACK_POP(continueStack),
1654                                               STACK_POP(breakStack) ,
1655                                               STACK_POP(forStack)   ,
1656                                               $3 , $5 , $7, $9 );
1657                           } else {
1658                               $$ = newNode(FOR,$9,NULL);
1659                               AST_FOR($$,trueLabel) = $1;
1660                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1661                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1662                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1663                               AST_FOR($$,initExpr)   = $3;
1664                               AST_FOR($$,condExpr)   = $5;
1665                               AST_FOR($$,loopExpr)   = $7;
1666                           }
1667
1668                           noLineno-- ;
1669                         }
1670 ;
1671
1672 expr_opt
1673         :                       { $$ = NULL ; seqPointNo++; }
1674         |       expr            { $$ = $1 ; seqPointNo++; }
1675         ;
1676
1677 jump_statement
1678    : GOTO identifier ';'   {
1679                               $2->islbl = 1;
1680                               $$ = newAst_VALUE(symbolVal($2));
1681                               $$ = newNode(GOTO,$$,NULL);
1682                            }
1683    | CONTINUE ';'          {
1684        /* make sure continue is in context */
1685        if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1686            werror(E_BREAK_CONTEXT);
1687            $$ = NULL;
1688        }
1689        else {
1690            $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1691            $$ = newNode(GOTO,$$,NULL);
1692            /* mark the continue label as referenced */
1693            STACK_PEEK(continueStack)->isref = 1;
1694        }
1695    }
1696    | BREAK ';'             {
1697        if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1698            werror(E_BREAK_CONTEXT);
1699            $$ = NULL;
1700        } else {
1701            $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1702            $$ = newNode(GOTO,$$,NULL);
1703            STACK_PEEK(breakStack)->isref = 1;
1704        }
1705    }
1706    | RETURN ';'            {
1707        seqPointNo++;
1708        if (inCritical) {
1709            werror(E_INVALID_CRITICAL);
1710            $$ = NULL;
1711        } else {
1712            $$ = newNode(RETURN,NULL,NULL);
1713        }
1714    }
1715    | RETURN expr ';'       {
1716        seqPointNo++;
1717        if (inCritical) {
1718            werror(E_INVALID_CRITICAL);
1719            $$ = NULL;
1720        } else {
1721            $$ = newNode(RETURN,NULL,$2);
1722        }
1723    }
1724    ;
1725
1726 identifier
1727    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1728    ;
1729 %%