* src/mcs51/ralloc.c (packRegsForAssign, reassignAliasedSym): fixed
[fw/sdcc] / src / SDCC.y
index fd2659a55df71231b4c703c7284731a73ab50e1c..71f238c05146bd60af185992f28b0a32babd9e49 100644 (file)
@@ -727,24 +727,38 @@ sfr_attributes
    ;
 
 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'");
+              werrorfl(sym->fileDef, 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");
+              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) {
-                werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, 
+                werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER, 
                        $1==STRUCT ? "struct" : "union", sym->name);
               }
             }
@@ -752,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 */
@@ -764,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");
+             }
          }
    ;
 
@@ -875,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($2->fileDef, $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 ;
@@ -921,8 +930,6 @@ enum_specifier
        $$ = newLink(SPECIFIER) ;
        SPEC_NOUN($$) = V_INT   ;
      }
-     
-     SPEC_SCLS(getSpec($$)) = 0 ;
    }
    ;
 
@@ -930,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($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
+        }
+       
+       $3->next = $1 ;
+       $$ = $3  ;
+     }
    ;
 
 enumerator
@@ -953,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 ;
                            }                           
    |                       {                              
@@ -998,21 +1021,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); 
+            }
    }     
    ;
 
@@ -1055,26 +1089,26 @@ function_declarator2
    | 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;
          }