More strcpy() strcat() sprintf() squashing
[fw/sdcc] / src / SDCC.y
index 42dd761bc380e383ea7114db71efaa467c707bf9..ab27ae5aef46627737cd0b49f172fb09241e318f 100644 (file)
@@ -34,6 +34,7 @@
 #include "port.h"
 #include "newalloc.h"
 #include "SDCCerr.h"
+#include "SDCCutil.h"
 
 extern int yyerror (char *);
 extern FILE    *yyin;
@@ -74,7 +75,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 
 %token <yychar> IDENTIFIER TYPE_NAME
 %token <val>   CONSTANT   STRING_LITERAL
-%token SIZEOF 
+%token SIZEOF TYPEOF 
 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
 %token AND_OP OR_OP 
 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
@@ -85,7 +86,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %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
-%token NAKED
+%token NAKED JAVANATIVE OVERLAY
 %token <yyinline> INLINEASM
 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL  ENDFUNCTION JUMPTABLE
@@ -179,7 +180,6 @@ function_attributes
                         $$ = newLink() ;
                         $$->class = SPECIFIER   ;
                        FUNC_REGBANK($$) = (int) floatFromVal($2);
-                        //FUNC_RBANK($$) = 1;
                      }
    |  REENTRANT      {  $$ = newLink ();
                         $$->class = SPECIFIER   ;
@@ -193,6 +193,14 @@ function_attributes
                         $$->class = SPECIFIER   ;
                        FUNC_ISNAKED($$)=1;
                      }
+   |  JAVANATIVE     {  $$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                       FUNC_ISJAVANATIVE($$)=1;
+                     }
+   |  OVERLAY        {  $$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                       FUNC_ISOVERLAY($$)=1;
+                     }
    |  NONBANKED      {$$ = newLink ();
                         $$->class = SPECIFIER   ;
                         FUNC_NONBANKED($$) = 1;
@@ -279,6 +287,7 @@ unary_expr
    | unary_operator cast_expr { $$ = newNode($1,$2,NULL)    ;  }
    | SIZEOF unary_expr        { $$ = newNode(SIZEOF,NULL,$2);  }
    | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
+   | TYPEOF unary_expr        { $$ = newNode(TYPEOF,NULL,$2);  }
    ;
               
 unary_operator
@@ -398,34 +407,34 @@ assignment_expr
                                     $$ = newNode($2,$1,$3);
                                     break;
                             case MUL_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case DIV_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case MOD_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case ADD_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case SUB_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case LEFT_ASSIGN:
-                                    $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case RIGHT_ASSIGN:
-                                    $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case AND_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case XOR_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             case OR_ASSIGN:
-                                    $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
+                                    $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
                                     break;
                             default :
                                     $$ = NULL;
@@ -791,8 +800,8 @@ struct_declarator
 
 enum_specifier
    : ENUM            '{' enumerator_list '}' {
-                                                addSymChain ($3);
-                                                allocVariables(reverseSyms($3)) ;
+                                                //addSymChain ($3);
+                                                //allocVariables(reverseSyms($3)) ;
                                                 $$ = copyLinkChain(cenum->type);
                                              }
    | ENUM identifier '{' enumerator_list '}' {
@@ -806,8 +815,8 @@ enum_specifier
                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
 
                                                 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
-                                               addSymChain ($4);
-                                                allocVariables (reverseSyms($4));
+                                               //addSymChain ($4);
+                                                //allocVariables (reverseSyms($4));
                                                 $$ = copyLinkChain(cenum->type);
                                                 SPEC_SCLS(getSpec($$)) = 0 ;
                                              }
@@ -838,15 +847,17 @@ enumerator_list
    ;
 
 enumerator
-   : identifier opt_assign_expr  {
-                                    /* make the symbol one level up */
-                                    $1->level-- ;
-                                    $1->type = copyLinkChain($2->type); 
-                                    $1->etype= getSpec($1->type);
-                                   SPEC_ENUM($1->etype) = 1;
-                                    $$ = $1 ;
-
-                                 }
+   : identifier opt_assign_expr  
+     {
+       /* make the symbol one level up */
+       $1->level-- ;
+       $1->type = copyLinkChain($2->type); 
+       $1->etype= getSpec($1->type);
+       SPEC_ENUM($1->etype) = 1;
+       $$ = $1 ;
+       // do this now, so we can use it for the next enums in the list
+       addSymChain($1);
+     }
    ;
 
 opt_assign_expr
@@ -858,11 +869,13 @@ opt_assign_expr
                            }                           
    |                       {                              
                               if (cenum)  {
-                                 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
+                                 SNPRINTF(lbuff, sizeof(lbuff), 
+                                         "%d",(int) floatFromVal(cenum)+1);
                                  $$ = cenum = constVal(lbuff);
                               }
                               else {
-                                 sprintf(lbuff,"%d",0);
+                                 SNPRINTF(lbuff, sizeof(lbuff), 
+                                         "%d",0);
                                  $$ = cenum = constVal(lbuff);
                               }   
                            }
@@ -880,7 +893,7 @@ declarator
 declarator2_function_attributes
    : declarator2                 { $$ = $1 ; } 
    | declarator2 function_attribute  { 
-       // do the functionAttributes (not the args and hasVargs !!)
+       // copy the functionAttributes (not the args and hasVargs !!)
        sym_link *funcType=$1->etype;
        struct value *args=FUNC_ARGS(funcType);
        unsigned hasVargs=FUNC_HASVARARGS(funcType);
@@ -974,7 +987,7 @@ pointer
          {
             $$ = $1 ;          
             $$->next = $2 ;
-            DCL_TYPE($2)=GPOINTER;
+            DCL_TYPE($2)=port->unqualified_pointer;
         }
    | unqualified_pointer type_specifier_list pointer
          {
@@ -1003,7 +1016,9 @@ pointer
                     DCL_TYPE($3) = EEPPOINTER;
                     break;
                 default:
-                    werror(W_PTR_TYPE_INVALID);
+                  // this could be just "constant" 
+                  // werror(W_PTR_TYPE_INVALID);
+                    ;
                 }
             }
             else 
@@ -1090,9 +1105,13 @@ type_name
                 /* go to the end of the list */
                 sym_link *p;
                 pointerTypes($2,$1);
-                for ( p = $2 ; p->next ; p=p->next);
-                  p->next = $1 ;
-                  $$ = $2 ;
+                for ( p = $2 ; p && p->next ; p=p->next);
+                if (!p) {
+                  werror(E_SYNTAX_ERROR, yytext);
+                } else {
+                  p->next = $1 ;
+                }
+                $$ = $2 ;
                }   
    ;
 
@@ -1135,6 +1154,12 @@ abstract_declarator2
      // $1 must be a pointer to a function
      sym_link *p=newLink();
      DCL_TYPE(p) = FUNCTION;
+     if (!$1) {
+       // ((void (code *) ()) 0) ()
+       $1=newLink();
+       DCL_TYPE($1)=CPOINTER;
+       $$ = $1;
+     }
      $1->next=p;
    }
    | abstract_declarator2 '(' parameter_type_list ')' {
@@ -1145,9 +1170,16 @@ abstract_declarator2
        // $1 must be a pointer to a function
        sym_link *p=newLink();
        DCL_TYPE(p) = FUNCTION;
+       if (!$1) {
+        // ((void (code *) (void)) 0) ()
+        $1=newLink();
+        DCL_TYPE($1)=CPOINTER;
+        $$ = $1;
+       }
        $1->next=p;
      }
    }
+   ;
 
 initializer
    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
@@ -1169,8 +1201,7 @@ statement
    | jump_statement
    | INLINEASM  ';'      {
                             ast *ex = newNode(INLINEASM,NULL,NULL);
-                           ex->values.inlineasm = malloc(strlen($1)+1);
-                           strcpy(ex->values.inlineasm,$1);                        
+                           ex->values.inlineasm = strdup($1);
                            $$ = ex;
                          } 
    ;
@@ -1264,7 +1295,8 @@ selection_statement
                               ex->values.switchVals.swNum = swLabel ;
                                  
                               /* now create the label */
-                              sprintf(lbuff,"_swBrk_%d",swLabel++);
+                              SNPRINTF(lbuff, sizeof(lbuff), 
+                                      "_swBrk_%d",swLabel++);
                               $<sym>$  =  newSymbol(lbuff,NestLevel);
                               /* put label in the break stack  */
                               STACK_PUSH(breakStack,$<sym>$);   
@@ -1280,45 +1312,49 @@ selection_statement
 while : WHILE  {  /* create and push the continue , break & body labels */
                   static int Lblnum = 0 ;
                  /* continue */
-                  sprintf (lbuff,"_whilecontinue_%d",Lblnum);
+                  SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
                  STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
                  /* break */
-                 sprintf (lbuff,"_whilebreak_%d",Lblnum);
+                 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
                  STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
                  /* body */
-                 sprintf (lbuff,"_whilebody_%d",Lblnum++);
+                 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
                  $$ = newSymbol(lbuff,NestLevel);
                }
+   ;
 
 do : DO {  /* create and push the continue , break & body Labels */
            static int Lblnum = 0 ;
 
           /* continue */
-          sprintf(lbuff,"_docontinue_%d",Lblnum);
+          SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
           STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
           /* break */
-          sprintf (lbuff,"_dobreak_%d",Lblnum);
+          SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
           STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
           /* do body */
-          sprintf (lbuff,"_dobody_%d",Lblnum++);
+          SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
           $$ = newSymbol (lbuff,NestLevel);       
         }
+   ;
+
 for : FOR { /* create & push continue, break & body labels */
             static int Lblnum = 0 ;
          
             /* continue */
-           sprintf (lbuff,"_forcontinue_%d",Lblnum);
+           SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
            /* break    */
-           sprintf (lbuff,"_forbreak_%d",Lblnum);
+           SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
            /* body */
-           sprintf (lbuff,"_forbody_%d",Lblnum);
+           SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
            $$ = newSymbol(lbuff,NestLevel);
            /* condition */
-           sprintf (lbuff,"_forcond_%d",Lblnum++);
+           SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
            STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
           }
+   ;
 
 iteration_statement  
    : while '(' expr ')'  statement