* src/*.c, src/pic16/{gen.c,glue.c,main.c}: applied Vangelis
[fw/sdcc] / src / SDCC.y
index ffbdb32405506b909b800afa85dd120d84ed5e63..17dacb5dcf983d4f9dcac95417b504b1497d0c16 100644 (file)
@@ -45,6 +45,8 @@ int reentrant = 0 ;
 int blockNo   = 0 ;     /* sequential block number  */
 int currBlockno=0 ;
 int inCritical= 0 ;
+int seqPointNo= 1 ;    /* sequence point number */
+int ignoreTypedefType=0;
 extern int yylex();
 int yyparse(void);
 extern int noLineno ;
@@ -60,6 +62,8 @@ STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
 value *cenum = NULL  ;  /* current enumeration  type chain*/
 bool uselessDecl = TRUE;
 
+#define YYDEBUG 1
+
 %}
 %expect 6
 
@@ -83,9 +87,10 @@ bool uselessDecl = TRUE;
 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
 %token <yyint> XOR_ASSIGN OR_ASSIGN
-%token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
-%token REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
-%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
+%token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR SFR16 SFR32
+%token AT SBIT REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
+%token NONBANKED BANKED SHADOWREGS WPARAM
+%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE FIXED16X16 CONST VOLATILE VOID BIT
 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
 %token NAKED JAVANATIVE OVERLAY
@@ -94,7 +99,7 @@ bool uselessDecl = TRUE;
 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL  ENDFUNCTION JUMPTABLE
 %token RRC RLC 
 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
-%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
+%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE RESTRICT
 
 %type <yyint>  Interrupt_storage
 %type <sym> identifier  declarator  declarator2 declarator3 enumerator_list enumerator
@@ -137,6 +142,7 @@ external_definition
                                blockNo=0;
                              }
    | declaration             { 
+                              ignoreTypedefType = 0;
                               if ($1 && $1->type
                                && IS_FUNC($1->type))
                               {
@@ -154,7 +160,7 @@ external_definition
                                        SPEC_EXTR($1->etype) = 1;
                                   }
                               }
-                               addSymChain ($1);
+                               addSymChain (&$1);
                                allocVariables ($1) ;
                               cleanUpLevel (SymbolTab,1);
                              }
@@ -205,6 +211,12 @@ function_attributes
                            werror(W_BANKED_WITH_NONBANKED);
                        }
                      }
+   |  SHADOWREGS     {$$ = newLink (SPECIFIER);
+                        FUNC_ISSHADOWREGS($$) = 1;
+                     }
+   |  WPARAM         {$$ = newLink (SPECIFIER);
+                        FUNC_ISWPARAM($$) = 1;
+                     }
    |  BANKED         {$$ = newLink (SPECIFIER);
                         FUNC_BANKED($$) = 1;
                        if (FUNC_NONBANKED($$)) {
@@ -227,7 +239,6 @@ function_body
    | declaration_list compound_statement
          {
             werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
-           fprintf(stderr, "case 1\n");
            exit(1);
          }
    ;
@@ -252,18 +263,20 @@ postfix_expr
           {       
            $$ = newNode  (CALL,$1,$3) ; $$->left->funcName = 1;
          }
-   | postfix_expr '.' identifier       
+   | postfix_expr '.' { ignoreTypedefType = 1; } identifier       
                      {    
-                       $3 = newSymbol($3->name,NestLevel);
-                       $3->implicit = 1;
-                       $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
-/*                     $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ;                   */
+                       ignoreTypedefType = 0;
+                       $4 = newSymbol($4->name,NestLevel);
+                       $4->implicit = 1;
+                       $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
+/*                     $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ;                   */
                      }
-   | postfix_expr PTR_OP identifier    
+   | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier    
                       { 
-                       $3 = newSymbol($3->name,NestLevel);
-                       $3->implicit = 1;                       
-                       $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
+                       ignoreTypedefType = 0;
+                       $4 = newSymbol($4->name,NestLevel);
+                       $4->implicit = 1;                       
+                       $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
                      }
    | postfix_expr INC_OP   
                       {        $$ = newNode(INC_OP,$1,NULL);}
@@ -374,28 +387,28 @@ inclusive_or_expr
 
 logical_and_expr
    : inclusive_or_expr
-   | logical_and_expr AND_OP inclusive_or_expr 
-                                 { $$ = newNode(AND_OP,$1,$3);}
+   | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr 
+                                 { $$ = newNode(AND_OP,$1,$4);}
    ;
 
 logical_or_expr
    : logical_and_expr
-   | logical_or_expr OR_OP logical_and_expr  
-                                 { $$ = newNode(OR_OP,$1,$3); }
+   | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr  
+                                 { $$ = newNode(OR_OP,$1,$4); }
    ;
 
 conditional_expr
    : logical_or_expr
-   | logical_or_expr '?' logical_or_expr ':' conditional_expr  
+   | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr  
                      {
-                        $$ = newNode(':',$3,$5) ;
+                        $$ = newNode(':',$4,$6) ;
                         $$ = newNode('?',$1,$$) ;
                      }                        
    ;
 
 assignment_expr
    : conditional_expr
-   | unary_expr assignment_operator assignment_expr   
+   | cast_expr assignment_operator assignment_expr   
                      { 
                                 
                             switch ($2) {
@@ -466,7 +479,7 @@ assignment_operator
 
 expr
    : assignment_expr
-   | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
+   | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
    ;
 
 constant_expr
@@ -581,7 +594,7 @@ type_specifier
    : type_specifier2
    | type_specifier2 AT constant_expr
         {
-           /* add this to the storage class specifier  */
+          /* add this to the storage class specifier  */
            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
            /* now get the abs addr from value */
            SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
@@ -592,30 +605,37 @@ type_specifier2
    : CHAR   {
                $$=newLink(SPECIFIER);
                SPEC_NOUN($$) = V_CHAR  ;
+              ignoreTypedefType = 1;
             }
    | SHORT  {
                $$=newLink(SPECIFIER);
               $$->select.s._short = 1 ;
+              ignoreTypedefType = 1;
             }
    | INT    {
                $$=newLink(SPECIFIER);
                SPEC_NOUN($$) = V_INT   ;
+              ignoreTypedefType = 1;
             }
    | LONG   {
                $$=newLink(SPECIFIER);
               SPEC_LONG($$) = 1       ;
+              ignoreTypedefType = 1;
             }
    | SIGNED {
                $$=newLink(SPECIFIER);
                $$->select.s._signed = 1;
+              ignoreTypedefType = 1;
             }
    | UNSIGNED  {
                $$=newLink(SPECIFIER);
                SPEC_USIGN($$) = 1      ;
+              ignoreTypedefType = 1;
             }
    | VOID   {
                $$=newLink(SPECIFIER);
                SPEC_NOUN($$) = V_VOID  ;
+              ignoreTypedefType = 1;
             }
    | CONST  {
                $$=newLink(SPECIFIER);
@@ -628,6 +648,12 @@ type_specifier2
    | FLOAT  {
                $$=newLink(SPECIFIER);
               SPEC_NOUN($$) = V_FLOAT;
+              ignoreTypedefType = 1;
+            }
+   | FIXED16X16  {
+               $$=newLink(SPECIFIER);
+              SPEC_NOUN($$) = V_FIXED16X16;
+              ignoreTypedefType = 1;
             }
    | XDATA     {
                   $$ = newLink (SPECIFIER);
@@ -659,15 +685,18 @@ type_specifier2
               SPEC_SCLS($$) = S_BIT   ;
               SPEC_BLEN($$) = 1;
               SPEC_BSTR($$) = 0;
+              ignoreTypedefType = 1;
             }
 
    | struct_or_union_specifier  {
                                    uselessDecl = FALSE;
                                    $$ = $1 ;
+                                  ignoreTypedefType = 1;
                                 }
    | enum_specifier     {                           
                            cenum = NULL ;
                            uselessDecl = FALSE;
+                           ignoreTypedefType = 1;
                            $$ = $1 ;                              
                         }
    | TYPE_NAME    
@@ -677,6 +706,7 @@ type_specifier2
             sym = findSym(TypedefTab,NULL,$1) ;
             $$ = p = copyLinkChain(sym->type);
            SPEC_TYPEDEF(getSpec(p)) = 0;
+            ignoreTypedefType = 1;
          }
    | sfr_reg_bit
    ;
@@ -686,6 +716,9 @@ sfr_reg_bit
                $$ = newLink(SPECIFIER) ;
                SPEC_NOUN($$) = V_SBIT;
                SPEC_SCLS($$) = S_SBIT;
+              SPEC_BLEN($$) = 1;
+              SPEC_BSTR($$) = 0;
+              ignoreTypedefType = 1;
             }
    |  sfr_attributes
    ;
@@ -697,6 +730,7 @@ sfr_attributes
                SPEC_NOUN($$)    = V_CHAR;
                SPEC_SCLS($$)    = S_SFR ;
                SPEC_USIGN($$)   = 1 ;
+              ignoreTypedefType = 1;
             }
    | SFR BANKED {
                $$ = newLink(SPECIFIER) ;
@@ -704,30 +738,78 @@ sfr_attributes
                SPEC_NOUN($$)    = V_CHAR;
                SPEC_SCLS($$)    = S_SFR ;
                SPEC_USIGN($$)   = 1 ;
+              ignoreTypedefType = 1;
+            }
+   ;
+
+sfr_attributes
+   : SFR16  {
+               $$ = newLink(SPECIFIER) ;
+               FUNC_REGBANK($$) = 0;
+               SPEC_NOUN($$)    = V_INT;
+               SPEC_SCLS($$)    = S_SFR;
+               SPEC_USIGN($$)   = 1 ;
+               ignoreTypedefType = 1;
+            }
+   ;
+
+sfr_attributes
+   : SFR32  {
+               $$ = newLink(SPECIFIER) ;
+               FUNC_REGBANK($$) = 0;
+               SPEC_NOUN($$)    = V_INT;
+               SPEC_SCLS($$)    = S_SFR;
+               SPEC_LONG($$)    = 1;
+               SPEC_USIGN($$)   = 1;
+               ignoreTypedefType = 1;
             }
    ;
 
 struct_or_union_specifier
-   : struct_or_union opt_stag '{' struct_declaration_list '}'
+   : struct_or_union opt_stag
+        {
+           if (!$2->type)
+             {
+               $2->type = $1;
+             }
+           else
+             {
+               if ($2->type != $1)
+                 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
+             }
+
+       }
+           '{' struct_declaration_list '}'
         {
            structdef *sdef ;
           symbol *sym, *dsym;
 
-          // check for duplicate structure members
-          for (sym=$4; sym; sym=sym->next) {
+          // check for errors in structure members
+          for (sym=$5; sym; sym=sym->next) {
+            if (IS_ABSOLUTE(sym->etype)) {
+              werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
+              SPEC_ABSA(sym->etype) = 0;
+            }
+            if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
+              werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
+              printTypeChainRaw (sym->type,NULL);
+              SPEC_SCLS(sym->etype) = 0;
+            }
             for (dsym=sym->next; dsym; dsym=dsym->next) {
-              if (strcmp(sym->name, dsym->name)==0) {
-                werror(E_DUPLICATE_MEMBER, 
+              if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
+                werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER, 
                        $1==STRUCT ? "struct" : "union", sym->name);
+                werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
               }
             }
           }
 
            /* Create a structdef   */     
            sdef = $2 ;
-           sdef->fields   = reverseSyms($4) ;   /* link the fields */
+           sdef->fields   = reverseSyms($5) ;   /* link the fields */
            sdef->size  = compStructSize($1,sdef);   /* update size of  */
-
+          promoteAnonStructs ($1, sdef);
+          
            /* Create the specifier */
            $$ = newLink (SPECIFIER) ;
            SPEC_NOUN($$) = V_STRUCT;
@@ -737,7 +819,17 @@ struct_or_union_specifier
          {
             $$ = newLink(SPECIFIER) ;
             SPEC_NOUN($$) = V_STRUCT;
-            SPEC_STRUCT($$) = $2 ;
+            SPEC_STRUCT($$) = $2;
+
+           if (!$2->type)
+             {
+               $2->type = $1;
+             }
+           else
+             {
+               if ($2->type != $1)
+                 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
+             }
          }
    ;
 
@@ -785,21 +877,23 @@ struct_declaration
            /* add this type to all the symbols */
            symbol *sym ;
            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
+              sym_link *btype = copyLinkChain($1);
               
               /* make the symbol one level up */
               sym->level-- ;
 
-              pointerTypes(sym->type,copyLinkChain($1));
+              pointerTypes(sym->type,btype);
               if (!sym->type) {
-                  sym->type = copyLinkChain($1);
+                  sym->type = btype;
                   sym->etype = getSpec(sym->type);
               }
               else
-                addDecl (sym,0,copyLinkChain($1));
+                addDecl (sym,0,btype);
               /* make sure the type is complete and sane */
               checkTypeSanity(sym->etype, sym->name);
           }
-           $$ = $2;
+          ignoreTypedefType = 0;
+          $$ = $2;
        }
    ;
 
@@ -842,45 +936,35 @@ struct_declarator
                          else
                            $1->bitVar = bitsize;
                         }
+   | { $$ = newSymbol ("", NestLevel) ; }
+   
    ;
 
 enum_specifier
    : ENUM            '{' enumerator_list '}' {
-           symbol *sym, *dsym;
-          char _error=0;
-
-          // check for duplicate enums
-          for (sym=$3; sym; sym=sym->next) {
-            for (dsym=sym->next; dsym; dsym=dsym->next) {
-              if (strcmp(sym->name, dsym->name)==0) {
-                werror(E_DUPLICATE_MEMBER, "enum", sym->name);
-                _error++;
-              }
-            }
-          }
-          if (_error==0) {
-            $$ = copyLinkChain(cenum->type);
-          } else {
-            $$ = newIntLink();
-            SPEC_NOUN($$)=0;
-          }
+          $$ = newEnumType ($3);       //copyLinkChain(cenum->type);
+          SPEC_SCLS(getSpec($$)) = 0;
          }
 
    | ENUM identifier '{' enumerator_list '}' {
      symbol *csym ;
+     sym_link *enumtype;
+
+     csym=findSym(enumTab,$2,$2->name);
+     if ((csym && csym->level == $2->level))
+       {
+         werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
+         werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
+       }
      
-     $2->type = copyLinkChain(cenum->type);
-     $2->etype = getSpec($2->type);
-     /* add this to the enumerator table */
-     if (!(csym=findSym(enumTab,$2,$2->name)) && 
-        (csym && csym->level == $2->level))
-       werror(E_DUPLICATE_TYPEDEF,csym->name);
+     enumtype = newEnumType ($4);      //copyLinkChain(cenum->type);
+     SPEC_SCLS(getSpec(enumtype)) = 0;
+     $2->type = enumtype;
      
-     addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
-     //addSymChain ($4);
-     //allocVariables (reverseSyms($4));
-     $$ = copyLinkChain(cenum->type);
-     SPEC_SCLS(getSpec($$)) = 0 ;
+     /* add this to the enumerator table */
+     if (!csym)
+       addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
+     $$ = copyLinkChain(enumtype);
    }
    | ENUM identifier                         {
      symbol *csym ;
@@ -892,8 +976,6 @@ enum_specifier
        $$ = newLink(SPECIFIER) ;
        SPEC_NOUN($$) = V_INT   ;
      }
-     
-     SPEC_SCLS(getSpec($$)) = 0 ;
    }
    ;
 
@@ -901,10 +983,22 @@ enumerator_list
    : enumerator
    | enumerator_list ',' {
                          }
-   | enumerator_list ',' enumerator {
-                                       $3->next = $1 ;
-                                       $$ = $3  ;
-                                    }
+   | enumerator_list ',' enumerator
+     {
+       symbol *dsym;
+       
+       for (dsym=$1; dsym; dsym=dsym->next)
+         {
+          if (strcmp($3->name, dsym->name)==0)
+            {
+              werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
+              werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
+            }
+        }
+       
+       $3->next = $1 ;
+       $$ = $3  ;
+     }
    ;
 
 enumerator
@@ -917,15 +1011,22 @@ enumerator
        SPEC_ENUM($1->etype) = 1;
        $$ = $1 ;
        // do this now, so we can use it for the next enums in the list
-       addSymChain($1);
+       addSymChain(&$1);
      }
    ;
 
 opt_assign_expr
    :  '='   constant_expr  {
                               value *val ;
-                                                       
-                              val = constExprValue($2,TRUE);                         
+
+                              val = constExprValue($2,TRUE);
+                             if (!IS_INT(val->type) && !IS_CHAR(val->type))
+                               {
+                                 werror(E_ENUM_NON_INTEGER);
+                                 SNPRINTF(lbuff, sizeof(lbuff), 
+                                         "%d",(int) floatFromVal(val));
+                                 val = constVal(lbuff);
+                               }
                               $$ = cenum = val ;
                            }                           
    |                       {                              
@@ -969,21 +1070,32 @@ declarator2_function_attributes
    : function_declarator2                { $$ = $1 ; } 
    | function_declarator2 function_attribute  { 
            // copy the functionAttributes (not the args and hasVargs !!)
-           sym_link *funcType=$1->etype;
-           struct value *args=FUNC_ARGS(funcType);
-           unsigned hasVargs=FUNC_HASVARARGS(funcType);
-
-           memcpy (&funcType->funcAttrs, &$2->funcAttrs, 
-              sizeof($2->funcAttrs));
+           struct value *args;
+           unsigned hasVargs;
+           sym_link *funcType=$1->type;
 
-           FUNC_ARGS(funcType)=args;
-           FUNC_HASVARARGS(funcType)=hasVargs;
-
-           // just to be sure
-           memset (&$2->funcAttrs, 0,
-              sizeof($2->funcAttrs));
+          while (funcType && !IS_FUNC(funcType))
+            funcType = funcType->next;
+          
+          if (!funcType)
+            werror (E_FUNC_ATTR);
+          else
+            {
+              args=FUNC_ARGS(funcType);
+               hasVargs=FUNC_HASVARARGS(funcType);
+
+               memcpy (&funcType->funcAttrs, &$2->funcAttrs, 
+                  sizeof($2->funcAttrs));
+
+               FUNC_ARGS(funcType)=args;
+               FUNC_HASVARARGS(funcType)=hasVargs;
+
+               // just to be sure
+               memset (&$2->funcAttrs, 0,
+                  sizeof($2->funcAttrs));
            
-           addDecl ($1,0,$2); 
+               addDecl ($1,0,$2); 
+            }
    }     
    ;
 
@@ -1023,35 +1135,35 @@ declarator2
 
 function_declarator2
    : declarator2 '('  ')'      {  addDecl ($1,FUNCTION,NULL) ;   }
-   | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
+   | declarator2 '('            { NestLevel++ ; currBlockno++;  }
+                     parameter_type_list ')'
          {
+             sym_link *funcType;
           
             addDecl ($1,FUNCTION,NULL) ;
+
+            funcType = $1->type;
+            while (funcType && !IS_FUNC(funcType))
+              funcType = funcType->next;
           
-            FUNC_HASVARARGS($1->type) = IS_VARG($4);
-            FUNC_ARGS($1->type) = reverseVal($4);
+            assert (funcType);
+            
+            FUNC_HASVARARGS(funcType) = IS_VARG($4);
+            FUNC_ARGS(funcType) = reverseVal($4);
             
             /* nest level was incremented to take care of the parms  */
             NestLevel-- ;
             currBlockno--;
 
             // if this was a pointer (to a function)
-            if (IS_PTR($1->type)) {
-              // move the args and hasVargs to the function
-              FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
-              FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
-              memset (&$1->type->funcAttrs, 0,
-                      sizeof($1->type->funcAttrs));
-              // remove the symbol args (if any)
+            if (!IS_FUNC($1->type))
               cleanUpLevel(SymbolTab,NestLevel+1);
-            }
             
             $$ = $1;
          }
    | declarator2 '(' parameter_identifier_list ')'
          {        
           werror(E_OLD_STYLE,$1->name) ;         
-          fprintf(stderr, "case 2\n");
           /* assume it returns an int */
           $1->type = $1->etype = newIntLink();
           $$ = $1 ;
@@ -1160,11 +1272,11 @@ parameter_type_list
        ;
 
 parameter_list
-   : parameter_declaration 
+   : parameter_declaration
    | parameter_list ',' parameter_declaration
          {
             $3->next = $1 ;
-            $$ = $3 ;      
+            $$ = $3 ;
          }
    ;
 
@@ -1175,18 +1287,20 @@ parameter_declaration
                  pointerTypes($2->type,$1);
                   addDecl ($2,0,$1);             
                  for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
-                 addSymChain ($2);
+                 addSymChain (&$2);
                  $$ = symbolVal($2);
+                 ignoreTypedefType = 0;
                }
    | type_name { 
                   $$ = newValue() ; 
                   $$->type = $1;
                   $$->etype = getSpec($$->type);
+                  ignoreTypedefType = 0;
                }
    ;
 
 type_name
-   : type_specifier_list  { $$ = $1 ;}
+   : type_specifier_list  { $$ = $1; ignoreTypedefType = 0;}
    | type_specifier_list abstract_declarator 
                {
                 /* go to the end of the list */
@@ -1199,6 +1313,7 @@ type_name
                   p->next = $1 ;
                 }
                 $$ = $2 ;
+                ignoreTypedefType = 0;
                }   
    ;
 
@@ -1290,8 +1405,11 @@ statement
    | jump_statement
    | critical_statement
    | INLINEASM  ';'      {
-                            ast *ex = newNode(INLINEASM,NULL,NULL);
+                            ast *ex;
+                           seqPointNo++;
+                           ex = newNode(INLINEASM,NULL,NULL);
                            ex->values.inlineasm = strdup($1);
+                           seqPointNo++;
                            $$ = ex;
                          } 
    ;
@@ -1316,12 +1434,30 @@ critical_statement
       
 labeled_statement
 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
-   : identifier ':'                    {  $$ = createLabel($1,NULL);  }   
-   | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
-   | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
+   : identifier ':'                    {  $$ = createLabel($1,NULL);
+                                         $1->isitmp = 0;  }   
+   | CASE constant_expr ':'
+     {
+       if (STACK_EMPTY(swStk))
+         $$ = createCase(NULL,$2,NULL);
+       else
+         $$ = createCase(STACK_PEEK(swStk),$2,NULL);
+     }
+   | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
+     {
+       if (STACK_EMPTY(swStk))
+         $$ = createDefault(NULL,$<asts>2,NULL);
+       else
+         $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
+     }
    ;
 
-start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
+start_block : '{'
+              {
+               STACK_PUSH(blockNum,currBlockno);
+               currBlockno = ++blockNo ;
+               ignoreTypedefType = 0;
+             }
             ;
 
 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
@@ -1331,10 +1467,10 @@ compound_statement
    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
    | start_block 
-          declaration_list                    { addSymChain($2); }
+          declaration_list                    { addSymChain(&$2); }
      end_block                                { $$ = createBlock($2,NULL) ;  }
    | start_block 
-          declaration_list                    {  addSymChain ($2); }
+          declaration_list                    {  addSymChain (&$2); }
           statement_list   
      end_block                                {$$ = createBlock($2,$4)   ;  }
    | error ';'                               { $$ = NULL ; }
@@ -1350,6 +1486,7 @@ declaration_list
        }
        else
         $$ = $1 ;
+       ignoreTypedefType = 0;
      }
 
    | declaration_list declaration
@@ -1372,6 +1509,7 @@ declaration_list
         else
           $$ = $2 ;
        }
+       ignoreTypedefType = 0;
      }
    ;
 
@@ -1382,7 +1520,7 @@ statement_list
 
 expression_statement
    : ';'                { $$ = NULL;}
-   | expr ';' 
+   | expr ';'           { $$ = $1; seqPointNo++;} 
    ;
 
 else_statement
@@ -1392,11 +1530,17 @@ else_statement
 
   
 selection_statement
-   : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
+   : IF '(' expr ')' { seqPointNo++;} statement else_statement
+                           {
+                             noLineno++ ;
+                             $$ = createIf ($3, $6, $7 );
+                             noLineno--;
+                          }
    | SWITCH '(' expr ')'   { 
                               ast *ex ;                              
                               static   int swLabel = 0 ;
 
+                             seqPointNo++;
                               /* create a node for expression  */
                               ex = newNode(SWITCH,$3,NULL);
                               STACK_PUSH(swStk,ex);   /* save it in the stack */
@@ -1465,16 +1609,17 @@ for : FOR { /* create & push continue, break & body labels */
    ;
 
 iteration_statement  
-   : while '(' expr ')'  statement 
+   : while '(' expr ')' { seqPointNo++;}  statement 
                          { 
                           noLineno++ ;
                           $$ = createWhile ( $1, STACK_POP(continueStack),
-                                             STACK_POP(breakStack), $3, $5 ); 
+                                             STACK_POP(breakStack), $3, $6 ); 
                           $$->lineno = $1->lineDef ;
                           noLineno-- ;
                         }
    | do statement   WHILE '(' expr ')' ';' 
                         { 
+                         seqPointNo++; 
                          noLineno++ ; 
                          $$ = createDo ( $1 , STACK_POP(continueStack), 
                                          STACK_POP(breakStack), $5, $2);
@@ -1509,8 +1654,8 @@ iteration_statement
 ;
 
 expr_opt
-       :                       { $$ = NULL ; }
-       |       expr
+       :                       { $$ = NULL ; seqPointNo++; }
+       |       expr            { $$ = $1 ; seqPointNo++; }
        ;
 
 jump_statement          
@@ -1521,7 +1666,7 @@ jump_statement
                            }
    | CONTINUE ';'          {  
        /* make sure continue is in context */
-       if (STACK_PEEK(continueStack) == NULL) {
+       if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
           werror(E_BREAK_CONTEXT);
           $$ = NULL;
        }
@@ -1533,7 +1678,7 @@ jump_statement
        }
    }
    | BREAK ';'             { 
-       if (STACK_PEEK(breakStack) == NULL) {
+       if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
           werror(E_BREAK_CONTEXT);
           $$ = NULL;
        } else {
@@ -1543,6 +1688,7 @@ jump_statement
        }
    }
    | RETURN ';'            {
+       seqPointNo++;
        if (inCritical) {
           werror(E_INVALID_CRITICAL);
           $$ = NULL;
@@ -1551,6 +1697,7 @@ jump_statement
        }
    }
    | RETURN expr ';'       {
+       seqPointNo++;
        if (inCritical) {
           werror(E_INVALID_CRITICAL);
           $$ = NULL;