fix big endian hosts
[fw/sdcc] / src / SDCC.y
index 644ecc5196dce307a181e688905d42c00e4498a2..9b6492e9891ecb20e8eec10c4967f13c8ae6c707 100644 (file)
@@ -57,6 +57,7 @@ STACK_DCL(swStk   ,ast   *,MAX_NEST_LEVEL)
 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
 
 value *cenum = NULL  ;  /* current enumeration  type chain*/
+bool uselessDecl = TRUE;
 
 %}
 %expect 6
@@ -92,6 +93,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %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
 
 %type <yyint>  Interrupt_storage
 %type <sym> identifier  declarator  declarator2 enumerator_list enumerator
@@ -458,7 +460,13 @@ constant_expr
    ;
 
 declaration
-   : declaration_specifiers ';'  { $$ = NULL ; }
+   : declaration_specifiers ';'
+      {
+         if (uselessDecl)
+           werror(W_USELESS_DECL);
+         uselessDecl = TRUE;
+         $$ = NULL ;
+      }
    | declaration_specifiers init_declarator_list ';'
       {
          /* add the specifier list to the id */
@@ -471,6 +479,7 @@ declaration
             addDecl (sym,0,lnk) ;
         }
         
+         uselessDecl = TRUE;
         $$ = sym1 ;
       }
    ;
@@ -541,7 +550,17 @@ storage_class_specifier
    ;
 
 Interrupt_storage
-   : INTERRUPT CONSTANT  { $$ = (int) floatFromVal($2) ;  }
+   : INTERRUPT { $$ = INTNO_UNSPEC ; }
+   | INTERRUPT CONSTANT
+        { int intno = (int) floatFromVal($2);
+          if ((intno >= 0) && (intno <= INTNO_MAX))
+            $$ = intno;
+          else
+            {
+              werror(E_INT_BAD_INTNO, intno);
+              $$ = INTNO_UNSPEC;
+            }
+        }
    ;
 
 type_specifier
@@ -628,9 +647,13 @@ type_specifier2
               SPEC_BSTR($$) = 0;
             }
 
-   | struct_or_union_specifier
+   | struct_or_union_specifier  {
+                                   uselessDecl = FALSE;
+                                   $$ = $1 ;
+                                }
    | enum_specifier     {                           
                            cenum = NULL ;
+                           uselessDecl = FALSE;
                            $$ = $1 ;                              
                         }
    | TYPE_NAME    
@@ -765,13 +788,33 @@ struct_declarator_list
 
 struct_declarator
    : declarator 
-   | ':' constant_expr  {  
+   | ':' constant_expr  {
+                           int bitsize;
                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
-                           $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
+                           bitsize= (int) floatFromVal(constExprValue($2,TRUE));
+                           if (bitsize > (port->s.int_size * 8)) {
+                             bitsize = port->s.int_size * 8;
+                             werror(E_BITFLD_SIZE, bitsize);
+                           }
+                           if (!bitsize)
+                             bitsize = BITVAR_PAD;
+                           $$->bitVar = bitsize;
                         }                        
    | declarator ':' constant_expr 
-                        { 
-                         $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));                     
+                        {
+                          int bitsize;
+                          bitsize= (int) floatFromVal(constExprValue($3,TRUE));
+                          if (bitsize > (port->s.int_size * 8)) {
+                            bitsize = port->s.int_size * 8;
+                            werror(E_BITFLD_SIZE, bitsize);
+                          }
+                          if (!bitsize) {
+                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
+                            $$->bitVar = BITVAR_PAD;
+                            werror(W_BITFLD_NAMED);
+                          }
+                         else
+                           $1->bitVar = bitsize;
                         }
    ;
 
@@ -885,22 +928,32 @@ declarator
 declarator2_function_attributes
    : declarator2                 { $$ = $1 ; } 
    | 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));
-
-       FUNC_ARGS(funcType)=args;
-       FUNC_HASVARARGS(funcType)=hasVargs;
-
-       // just to be sure
-       memset (&$2->funcAttrs, 0,
-              sizeof($2->funcAttrs));
-       
-       addDecl ($1,0,$2); 
+       if ((! $1) || (! IS_FUNC($1->etype)))
+         {
+           // function_attribute is only allowed if declarator2 was
+           // an actual function
+           werror(E_FUNC_ATTR);
+           $$=$1;
+         }
+       else
+         {
+           // 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));
+
+           FUNC_ARGS(funcType)=args;
+           FUNC_HASVARARGS(funcType)=hasVargs;
+
+           // just to be sure
+           memset (&$2->funcAttrs, 0,
+              sizeof($2->funcAttrs));
+           
+           addDecl ($1,0,$2); 
+         }
    }     
    ;
 
@@ -1110,7 +1163,10 @@ type_name
 abstract_declarator
    : pointer { $$ = reverseLink($1); }
    | abstract_declarator2
-   | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
+   | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
+         if (IS_PTR($1) && IS_FUNC($2))
+           DCL_TYPE($1) = CPOINTER;
+       } 
    ;
 
 abstract_declarator2
@@ -1154,22 +1210,21 @@ abstract_declarator2
      }
      $1->next=p;
    }
-   | abstract_declarator2 '(' parameter_type_list ')' {
-     if (!IS_VOID($3->etype)) {
-       // this is nonsense, so let's just burp something
-       werror(E_TOO_FEW_PARMS);
-     } else {
-       // $1 must be a pointer to a function
+   | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
        sym_link *p=newLink(DECLARATOR);
        DCL_TYPE(p) = FUNCTION;
-       if (!$1) {
-        // ((void (code *) (void)) 0) ()
-        $1=newLink(DECLARATOR);
-        DCL_TYPE($1)=CPOINTER;
-        $$ = $1;
-       }
-       $1->next=p;
-     }
+          
+       FUNC_HASVARARGS(p) = IS_VARG($4);
+       FUNC_ARGS(p) = reverseVal($4);
+            
+       /* nest level was incremented to take care of the parms  */
+       NestLevel-- ;
+       currBlockno--;
+       p->next = $1;
+       $$ = p;
+
+       // remove the symbol args (if any)
+       cleanUpLevel(SymbolTab,NestLevel+1);
    }
    ;