* src/ds390/gen.c (genCall): fixed a double use of acc and b after
[fw/sdcc] / src / SDCC.y
index 7f5f7e215ca2ec80f8b437eeb18a65e6c85d2fc2..a7cf2431586c0144bae478967fb04eab35fe0e5b 100644 (file)
@@ -46,6 +46,7 @@ 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 ;
@@ -61,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
 
@@ -138,6 +141,7 @@ external_definition
                                blockNo=0;
                              }
    | declaration             { 
+                              ignoreTypedefType = 0;
                               if ($1 && $1->type
                                && IS_FUNC($1->type))
                               {
@@ -581,7 +585,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 +596,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 +639,7 @@ type_specifier2
    | FLOAT  {
                $$=newLink(SPECIFIER);
               SPEC_NOUN($$) = V_FLOAT;
+              ignoreTypedefType = 1;
             }
    | XDATA     {
                   $$ = newLink (SPECIFIER);
@@ -659,15 +671,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 +692,7 @@ type_specifier2
             sym = findSym(TypedefTab,NULL,$1) ;
             $$ = p = copyLinkChain(sym->type);
            SPEC_TYPEDEF(getSpec(p)) = 0;
+            ignoreTypedefType = 1;
          }
    | sfr_reg_bit
    ;
@@ -686,6 +702,7 @@ sfr_reg_bit
                $$ = newLink(SPECIFIER) ;
                SPEC_NOUN($$) = V_SBIT;
                SPEC_SCLS($$) = S_SBIT;
+              ignoreTypedefType = 1;
             }
    |  sfr_attributes
    ;
@@ -697,6 +714,7 @@ sfr_attributes
                SPEC_NOUN($$)    = V_CHAR;
                SPEC_SCLS($$)    = S_SFR ;
                SPEC_USIGN($$)   = 1 ;
+              ignoreTypedefType = 1;
             }
    | SFR BANKED {
                $$ = newLink(SPECIFIER) ;
@@ -704,23 +722,38 @@ sfr_attributes
                SPEC_NOUN($$)    = V_CHAR;
                SPEC_SCLS($$)    = S_SFR ;
                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 errors in structure members
-          for (sym=$4; sym; sym=sym->next) {
+          for (sym=$5; sym; sym=sym->next) {
             if (IS_ABSOLUTE(sym->etype)) {
               werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
               SPEC_ABSA(sym->etype) = 0;
             }
             if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
               werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
+              printTypeChainRaw (sym->type,NULL);
               SPEC_SCLS(sym->etype) = 0;
             }
             for (dsym=sym->next; dsym; dsym=dsym->next) {
@@ -733,7 +766,7 @@ struct_or_union_specifier
 
            /* 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  */
 
            /* Create the specifier */
@@ -745,7 +778,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");
+             }
          }
    ;
 
@@ -808,7 +851,8 @@ struct_declaration
               /* make sure the type is complete and sane */
               checkTypeSanity(sym->etype, sym->name);
           }
-           $$ = $2;
+          ignoreTypedefType = 0;
+          $$ = $2;
        }
    ;
 
@@ -855,41 +899,26 @@ struct_declarator
 
 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) {
-                werrorfl(filename, sym->lineDef, 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(filename, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
      
-     $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 ;
@@ -901,8 +930,6 @@ enum_specifier
        $$ = newLink(SPECIFIER) ;
        SPEC_NOUN($$) = V_INT   ;
      }
-     
-     SPEC_SCLS(getSpec($$)) = 0 ;
    }
    ;
 
@@ -910,10 +937,19 @@ 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(filename, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
+        }
+       
+       $3->next = $1 ;
+       $$ = $3  ;
+     }
    ;
 
 enumerator
@@ -933,8 +969,15 @@ enumerator
 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 ;
                            }                           
    |                       {                              
@@ -1032,7 +1075,8 @@ declarator2
 
 function_declarator2
    : declarator2 '('  ')'      {  addDecl ($1,FUNCTION,NULL) ;   }
-   | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
+   | declarator2 '('            { NestLevel++ ; currBlockno++;  }
+                     parameter_type_list ')'
          {
           
             addDecl ($1,FUNCTION,NULL) ;
@@ -1168,11 +1212,11 @@ parameter_type_list
        ;
 
 parameter_list
-   : parameter_declaration 
+   : parameter_declaration
    | parameter_list ',' parameter_declaration
          {
             $3->next = $1 ;
-            $$ = $3 ;      
+            $$ = $3 ;
          }
    ;
 
@@ -1185,16 +1229,18 @@ parameter_declaration
                  for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
                  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 */
@@ -1207,6 +1253,7 @@ type_name
                   p->next = $1 ;
                 }
                 $$ = $2 ;
+                ignoreTypedefType = 0;
                }   
    ;
 
@@ -1344,7 +1391,12 @@ labeled_statement
      }
    ;
 
-start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
+start_block : '{'
+              {
+               STACK_PUSH(blockNum,currBlockno);
+               currBlockno = ++blockNo ;
+               ignoreTypedefType = 0;
+             }
             ;
 
 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
@@ -1373,6 +1425,7 @@ declaration_list
        }
        else
         $$ = $1 ;
+       ignoreTypedefType = 0;
      }
 
    | declaration_list declaration
@@ -1395,6 +1448,7 @@ declaration_list
         else
           $$ = $2 ;
        }
+       ignoreTypedefType = 0;
      }
    ;