added unqualified_pointer, globals_allowed & reset_labelKey to port structure
[fw/sdcc] / src / SDCCast.c
index dc1c8f9494c3672f38ec4fefc5103c66f0a4541b..116ef2c63de01c455562be2854de0f3529af9a27 100644 (file)
@@ -617,7 +617,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
 /*-----------------------------------------------------------------*/
 /* reverseParms - will reverse a parameter tree                    */
 /*-----------------------------------------------------------------*/
-void 
+static void 
 reverseParms (ast * ptree)
 {
   ast *ttree;
@@ -714,13 +714,13 @@ processParms (ast * func,
       if (IS_PTR(ftype) && !IS_GENPTR(ftype))
        {
          newType = newAst_LINK (copyLinkChain(ftype));
-         DCL_TYPE (newType->opval.lnk) = GPOINTER;
+         DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
        }
 
       if (IS_AGGREGATE (ftype))
        {
          newType = newAst_LINK (copyLinkChain (ftype));
-         DCL_TYPE (newType->opval.lnk) = GPOINTER;
+         DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
        }
       if (newType)
        {
@@ -1057,42 +1057,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
 /*-----------------------------------------------------------------*/
 /* initAggregates - initialises aggregate variables with initv     */
 /*-----------------------------------------------------------------*/
-
-/* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
-
 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
-  ast *ast;
-  symbol *newSym;
-
-  if (getenv("TRY_THE_NEW_INITIALIZER")) {
-
-    if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
-      fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
-              "with -mmcs51 and --model-large\n");
-      exit(404);
-    }
-
-    if (SPEC_OCLS(sym->etype)==xdata &&
-       getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
-
-      // copy this symbol
-      newSym=copySymbol (sym);
-      SPEC_OCLS(newSym->etype)=code;
-      sprintf (newSym->name, "%s_init__", sym->name);
-      sprintf (newSym->rname,"%s_init__", sym->rname);
-      addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
-
-      // emit it in the static segment
-      addSet(&statsg->syms, newSym);
-
-      // now memcpy() the entire array from cseg
-      ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
-                  newAst_VALUE (symbolVal (sym)), 
-                  newAst_VALUE (symbolVal (newSym)));
-      return decorateType(resolveSymbols(ast));
-    }
-  }
-  
   return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
 }
 
@@ -1124,11 +1089,6 @@ gatherAutoInit (symbol * autoChain)
        {
          symbol *newSym;
          
-         // this can only be a constant
-         if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
-           werror (E_CONST_EXPECTED);
-         }
-
          /* insert the symbol into the symbol table */
          /* with level = 0 & name = rname       */
          newSym = copySymbol (sym);
@@ -1830,48 +1790,6 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
 
 }
 
-//#define DEMAND_INTEGER_PROMOTION
-
-#ifdef DEMAND_INTEGER_PROMOTION
-
-/*-----------------------------------------------------------------*/
-/* walk a tree looking for the leaves. Add a typecast to the given */
-/* type to each value leaf node.           */
-/*-----------------------------------------------------------------*/
-void 
-pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
-{
-  if (!node || IS_CALLOP(node))
-    {
-      /* WTF? We should never get here. */
-      return;
-    }
-
-  if (!node->left && !node->right)
-    {
-      /* We're at a leaf; if it's a value, apply the typecast */
-      if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
-       {
-         *parentPtr = decorateType (newNode (CAST,
-                                        newAst_LINK (copyLinkChain (type)),
-                                             node));
-       }
-    }
-  else
-    {
-      if (node->left)
-       {
-         pushTypeCastToLeaves (type, node->left, &(node->left));
-       }
-      if (node->right)
-       {
-         pushTypeCastToLeaves (type, node->right, &(node->right));
-       }
-    }
-}
-
-#endif
-
 /*-----------------------------------------------------------------*/
 /* decorateType - compute type for this tree also does type cheking */
 /*          this is done bottom up, since type have to flow upwards */
@@ -1975,7 +1893,9 @@ decorateType (ast * tree)
     ast *dtl, *dtr;
 
     dtl = decorateType (tree->left);
-    dtr = decorateType (tree->right);
+    /* delay right side for '?' operator since conditional macro expansions might
+       rely on this */
+    dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
 
     /* this is to take care of situations
        when the tree gets rewritten */
@@ -2070,6 +1990,33 @@ decorateType (ast * tree)
                                     (tree->right->type == EX_VALUE ?
                               tree->right->opval.val : NULL));
       TETYPE (tree) = getSpec (TTYPE (tree));
+
+      /* adjust the storage class */
+      switch (DCL_TYPE(tree->left->ftype)) {
+      case POINTER:
+       break;
+      case FPOINTER:
+               SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
+       break;
+      case CPOINTER:
+               SPEC_SCLS(TETYPE(tree)) = S_CODE; 
+       break;
+      case GPOINTER:
+       break;
+      case PPOINTER:
+               SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
+       break;
+      case IPOINTER:
+               SPEC_SCLS(TETYPE(tree)) = S_IDATA;
+       break;
+      case EEPPOINTER:
+               SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
+       break;
+      case UPOINTER:
+      case ARRAY:
+      case FUNCTION:
+      }
+
       return tree;
 
 /*------------------------------------------------------------------*/
@@ -2885,6 +2832,79 @@ decorateType (ast * tree)
                               tree->opval.val->type);
       return tree;
 
+      /*------------------------------------------------------------------*/
+      /*----------------------------*/
+      /*             typeof         */
+      /*----------------------------*/
+    case TYPEOF:
+       /* return typeof enum value */
+       tree->type = EX_VALUE;
+       {
+           int typeofv = 0;
+           if (IS_SPEC(tree->right->ftype)) {
+               switch (SPEC_NOUN(tree->right->ftype)) {
+               case V_INT:
+                   if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
+                   else typeofv = TYPEOF_INT;
+                   break;
+               case V_FLOAT:
+                   typeofv = TYPEOF_FLOAT;
+                   break;
+               case V_CHAR:
+                   typeofv = TYPEOF_CHAR;
+                   break;
+               case V_VOID:
+                   typeofv = TYPEOF_VOID;
+                   break;
+               case V_STRUCT:
+                   typeofv = TYPEOF_STRUCT;
+                   break;
+               case V_BIT:
+                   typeofv = TYPEOF_BIT;
+                   break;
+               case V_SBIT:
+                   typeofv = TYPEOF_SBIT;
+                   break;
+               default:
+                   break;
+               }
+           } else {
+               switch (DCL_TYPE(tree->right->ftype)) {
+               case POINTER:
+                   typeofv = TYPEOF_POINTER;
+                   break;
+               case FPOINTER:
+                   typeofv = TYPEOF_FPOINTER;
+                   break;
+               case CPOINTER:
+                   typeofv = TYPEOF_CPOINTER;
+                   break;
+               case GPOINTER:
+                   typeofv = TYPEOF_GPOINTER;
+                   break;
+               case PPOINTER:
+                   typeofv = TYPEOF_PPOINTER;
+                   break;
+               case IPOINTER:
+                   typeofv = TYPEOF_IPOINTER;
+                   break;
+               case ARRAY:
+                   typeofv = TYPEOF_ARRAY;
+                   break;
+               case FUNCTION:
+                   typeofv = TYPEOF_FUNCTION;
+                   break;
+               default:
+                   break;
+               }
+           }
+           sprintf (buffer, "%d", typeofv);
+           tree->opval.val = constVal (buffer);
+           tree->right = tree->left = NULL;
+           TETYPE (tree) = getSpec (TTYPE (tree) =
+                                    tree->opval.val->type);
+       }
+       return tree;
       /*------------------------------------------------------------------*/
       /*----------------------------*/
       /* conditional operator  '?'  */
@@ -2894,13 +2914,14 @@ decorateType (ast * tree)
       assert(IS_COLON_OP(tree->right));
       /* if already known then replace the tree : optimizer will do it
         but faster to do it here */
-      if (IS_LITERAL (LTYPE(tree))) {
+      if (IS_LITERAL (LTYPE(tree))) {    
          if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
-             return tree->right->left ;
+             return decorateType(tree->right->left) ;
          } else {
-             return tree->right->right ;
+             return decorateType(tree->right->right) ;
          }
       } else {
+         tree->right = decorateType(tree->right);
          TTYPE (tree) = RTYPE(tree);
          TETYPE (tree) = getSpec (TTYPE (tree));
       }
@@ -3122,7 +3143,8 @@ decorateType (ast * tree)
        goto errorTreeReturn;
       }
 
-      if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
+      if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
+         !IFFUNC_ISBUILTIN(LTYPE(tree)))
        {
          //FUNC_ARGS(tree->left->ftype) = 
          //reverseVal (FUNC_ARGS(tree->left->ftype));
@@ -3986,6 +4008,63 @@ optimizeCompare (ast * root)
   vright = (root->right->type == EX_VALUE ?
            root->right->opval.val : NULL);
 
+  //#define EXPERIMENTAL
+#ifdef EXPERIMENTAL
+  /* if left is unsigned and right is literal */
+  if (vleft && vright && 
+      IS_UNSIGNED(vleft->etype) &&
+      IS_LITERAL(vright->etype)) {
+    double dval=floatFromVal(vright);
+    int op=root->opval.op;
+
+    fprintf (stderr,"op: '");
+    switch (op) {
+    case LE_OP: fprintf (stderr, "<= '"); break;
+    case EQ_OP: fprintf (stderr, "== '"); break;
+    case GE_OP: fprintf (stderr, ">= '"); break;
+    default: fprintf (stderr, "%c '", op); break;
+    }
+    fprintf (stderr, "%f\n", dval);
+
+    switch (op)
+      {
+      case EQ_OP:
+      case LE_OP:
+      case '<':
+       if (dval<0 || (op=='<' && dval==0)) {
+         // unsigned is never < 0
+         werror (W_IF_NEVER_TRUE);
+         optExpr = newAst_VALUE (constVal("0"));
+         return decorateType (optExpr);
+       }
+       if (dval==0) {
+         if (op==LE_OP) {
+           // change this into a cheaper EQ_OP
+           fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
+           root->opval.op=EQ_OP;
+           return root;
+         }
+       }
+       break;
+      case GE_OP:
+      case '>':
+       if (dval>0 || (op==GE_OP && dval==0)) {
+         // unsigned is never < 0
+         werror (W_IF_ALWAYS_TRUE);
+         optExpr = newAst_VALUE (constVal("1"));
+         return decorateType (optExpr);
+       }
+       if (dval==0) {
+         if (op=='>') {
+           // change this into a cheaper reversed EQ_OP
+           fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
+           root->opval.op=EQ_OP;
+         }
+       }
+      }
+  }
+#endif
+
   /* if left is a BITVAR in BITSPACE */
   /* and right is a LITERAL then opt- */
   /* imize else do nothing       */
@@ -4160,10 +4239,6 @@ createFunction (symbol * name, ast * body)
   name->lastLine = yylineno;
   currFunc = name;
 
-#if 0 // jwk: this is now done in addDecl()
-  processFuncArgs (currFunc);
-#endif
-
   /* set the stack pointer */
   /* PENDING: check this for the mcs51 */
   stackPtr = -port->stack.direction * port->stack.call_overhead;
@@ -4248,7 +4323,7 @@ skipall:
 
   /* we are done freeup memory & cleanup */
   noLineno--;
-  labelKey = 1;
+  if (port->reset_labelKey) labelKey = 1;
   name->key = 0;
   FUNC_HASBODY(name->type) = 1;
   addSet (&operKeyReset, name);