* device/lib/printf_large.c: removed inline assembly for portability and
[fw/sdcc] / src / SDCC.y
index a7cf2431586c0144bae478967fb04eab35fe0e5b..3e3c7b3eba875d405f0c2b20f98c77329d954d17 100644 (file)
@@ -89,6 +89,7 @@ bool uselessDecl = TRUE;
 %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 SHADOWREGS WPARAM
 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
@@ -210,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($$)) {
@@ -256,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);}
@@ -399,7 +408,7 @@ conditional_expr
 
 assignment_expr
    : conditional_expr
-   | unary_expr assignment_operator assignment_expr   
+   | cast_expr assignment_operator assignment_expr   
                      { 
                                 
                             switch ($2) {
@@ -702,6 +711,8 @@ sfr_reg_bit
                $$ = newLink(SPECIFIER) ;
                SPEC_NOUN($$) = V_SBIT;
                SPEC_SCLS($$) = S_SBIT;
+              SPEC_BLEN($$) = 1;
+              SPEC_BSTR($$) = 0;
               ignoreTypedefType = 1;
             }
    |  sfr_attributes
@@ -748,18 +759,19 @@ struct_or_union_specifier
           // check for errors in structure members
           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, 
+              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);
               }
             }
           }
@@ -768,7 +780,8 @@ struct_or_union_specifier
            sdef = $2 ;
            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;
@@ -895,6 +908,8 @@ struct_declarator
                          else
                            $1->bitVar = bitsize;
                         }
+   | { $$ = newSymbol ("", NestLevel) ; }
+   
    ;
 
 enum_specifier
@@ -909,7 +924,10 @@ enum_specifier
 
      csym=findSym(enumTab,$2,$2->name);
      if ((csym && csym->level == $2->level))
-       werrorfl(filename, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
+       {
+         werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
+         werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
+       }
      
      enumtype = newEnumType ($4);      //copyLinkChain(cenum->type);
      SPEC_SCLS(getSpec(enumtype)) = 0;
@@ -944,7 +962,10 @@ enumerator_list
        for (dsym=$1; dsym; dsym=dsym->next)
          {
           if (strcmp($3->name, dsym->name)==0)
-            werrorfl(filename, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
+            {
+              werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
+              werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
+            }
         }
        
        $3->next = $1 ;
@@ -1021,21 +1042,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); 
+            }
    }     
    ;
 
@@ -1078,26 +1110,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;
          }
@@ -1374,20 +1406,21 @@ critical_statement
       
 labeled_statement
 //   : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
-   : identifier ':'                    {  $$ = createLabel($1,NULL);  }   
-   | CASE constant_expr ':' statement
+   : identifier ':'                    {  $$ = createLabel($1,NULL);
+                                         $1->isitmp = 0;  }   
+   | CASE constant_expr ':'
      {
        if (STACK_EMPTY(swStk))
-         $$ = createCase(NULL,$2,$4);
+         $$ = createCase(NULL,$2,NULL);
        else
-         $$ = createCase(STACK_PEEK(swStk),$2,$4);
+         $$ = createCase(STACK_PEEK(swStk),$2,NULL);
      }
-   | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
+   | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
      {
        if (STACK_EMPTY(swStk))
-         $$ = createDefault(NULL,$<asts>2,$4);
+         $$ = createDefault(NULL,$<asts>2,NULL);
        else
-         $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
+         $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
      }
    ;