Added support for gsinit packing.
[fw/sdcc] / src / SDCCast.c
index 1c65e5c9e8d1d76962d88487b19cb9b5ceeb07c8..4a5a25b3353f102eb22fdadd8e2cb8fa3a8c148f 100644 (file)
@@ -180,7 +180,6 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
   /* if this is a literal then we already know the result */
   if (condAst->etype && IS_LITERAL (condAst->etype))
     {
-
       /* then depending on the expression value */
       if (floatFromVal (condAst->opval.val))
        ifxNode = newNode (GOTO,
@@ -225,7 +224,12 @@ copyAstValues (ast * dest, ast * src)
     case INLINEASM:
       dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
       strcpy (dest->values.inlineasm, src->values.inlineasm);
+      break;
 
+    case ARRAYINIT:
+       dest->values.constlist = copyLiteralList(src->values.constlist);
+       break;
+       
     case FOR:
       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
@@ -739,7 +743,7 @@ processParms (ast * func,
     }
 
   /* the parameter type must be at least castable */
-  if (checkType (defParm->type, actParm->ftype) == 0)
+  if (compareType (defParm->type, actParm->ftype) == 0)
     {
       werror (E_TYPE_MISMATCH_PARM, *parmNumber);
       werror (E_CONTINUE, "defined type ");
@@ -751,7 +755,7 @@ processParms (ast * func,
     }
 
   /* if the parameter is castable then add the cast */
-  if (checkType (defParm->type, actParm->ftype) < 0)
+  if (compareType (defParm->type, actParm->ftype) < 0)
     {
       ast *pTree = resolveSymbols (copyAst (actParm));
 
@@ -833,6 +837,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
   ast *rast = NULL;
   initList *iloop;
   int lcnt = 0, size = 0;
+  literalList *literalL;
 
   /* take care of the special   case  */
   /* array of characters can be init  */
@@ -844,51 +849,77 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
 
       return decorateType (resolveSymbols (rast));
 
-  /* not the special case             */
-  if (ilist->type != INIT_DEEP)
+    /* not the special case             */
+    if (ilist->type != INIT_DEEP)
     {
-      werror (E_INIT_STRUCT, "");
-      return NULL;
+       werror (E_INIT_STRUCT, "");
+       return NULL;
     }
 
-  iloop = ilist->init.deep;
-  lcnt = DCL_ELEM (type);
+    iloop = ilist->init.deep;
+    lcnt = DCL_ELEM (type);
 
-  for (;;)
+    if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
     {
-      ast *aSym;
-      size++;
+       ast *aSym;
 
-      aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
-      aSym = decorateType (resolveSymbols (aSym));
-      rast = createIval (aSym, type->next, iloop, rast);
-      iloop = (iloop ? iloop->next : NULL);
-      if (!iloop)
-       break;
-      /* if not array limits given & we */
-      /* are out of initialisers then   */
-      if (!DCL_ELEM (type) && !iloop)
-       break;
-
-      /* no of elements given and we    */
-      /* have generated for all of them */
-      if (!--lcnt) {
-       /* if initializers left */
-       if (iloop) {
-         // there has to be a better way
-         char *name=sym->opval.val->sym->name;
-         int lineno=sym->opval.val->sym->lineDef;
-         werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+       aSym = decorateType (resolveSymbols(sym));
+       
+       rast = newNode(ARRAYINIT, aSym, NULL);
+       rast->values.constlist = literalL;
+       
+       // Make sure size is set to length of initializer list.
+       while (iloop)
+       {
+           size++;
+           iloop = iloop->next;
+       }
+       
+       if (lcnt && size > lcnt)
+       {
+           // Array size was specified, and we have more initializers than needed.
+           char *name=sym->opval.val->sym->name;
+           int lineno=sym->opval.val->sym->lineDef;
+           
+           werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+       }
+    }
+    else
+    {
+       for (;;)
+       {
+           ast *aSym;
+           
+           aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (++size))));
+           aSym = decorateType (resolveSymbols (aSym));
+           rast = createIval (aSym, type->next, iloop, rast);
+           iloop = (iloop ? iloop->next : NULL);
+           if (!iloop)
+           {
+               break;
+           }
+           
+           /* no of elements given and we    */
+           /* have generated for all of them */
+           if (!--lcnt) 
+           {
+               // there has to be a better way
+               char *name=sym->opval.val->sym->name;
+               int lineno=sym->opval.val->sym->lineDef;
+               werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+               
+               break;
+           }
        }
-       break;
-      }
     }
 
-  /* if we have not been given a size  */
-  if (!DCL_ELEM (type))
-    DCL_ELEM (type) = size;
+    /* if we have not been given a size  */
+    if (!DCL_ELEM (type))
+    {
+       DCL_ELEM (type) = size;
+    }
 
-  return decorateType (resolveSymbols (rast));
+    return decorateType (resolveSymbols (rast));
 }
 
 
@@ -913,7 +944,6 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
        SPEC_SCLS (iexpr->etype) == S_CODE)
       && IS_ARRAY (iexpr->ftype))
     {
-
       /* for each character generate an assignment */
       /* to the array element */
       char *s = SPEC_CVAL (iexpr->etype).v_char;
@@ -2053,6 +2083,9 @@ decorateType (ast * tree)
              return decorateType (otree);
          }
 
+#if 0 
+         // we can't do this because of "(int & 0xff) << 3"
+
          /* if right or left is literal then result of that type */
          if (IS_LITERAL (RTYPE (tree)))
            {
@@ -2077,6 +2110,11 @@ decorateType (ast * tree)
                  TETYPE (tree) = getSpec (TTYPE (tree));
                }
            }
+#else
+         TTYPE (tree) =
+           computeType (LTYPE (tree), RTYPE (tree));
+         TETYPE (tree) = getSpec (TTYPE (tree));
+#endif
          LRVAL (tree) = RRVAL (tree) = 1;
          return tree;
        }
@@ -2725,7 +2763,7 @@ decorateType (ast * tree)
       /* if they are pointers they must be castable */
       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
        {
-         if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+         if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
            {
              werror (E_COMPARE_OP);
              fprintf (stderr, "comparing type ");
@@ -2742,7 +2780,7 @@ decorateType (ast * tree)
          if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
                (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
 
-           if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
              {
                werror (E_COMPARE_OP);
                fprintf (stderr, "comparing type ");
@@ -2791,14 +2829,15 @@ decorateType (ast * tree)
       /* conditional operator  '?'  */
 /*----------------------------*/
     case '?':
-      /* the type is one on the left */
-      TTYPE (tree) = LTYPE (tree);
+      /* the type is value of the colon operator (on the right) */
+      assert(IS_COLON_OP(tree->right));
+      TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
     case ':':
       /* if they don't match we have a problem */
-      if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+      if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
        {
          werror (E_TYPE_MISMATCH, "conditional operator", " ");
          goto errorTreeReturn;
@@ -2963,7 +3002,7 @@ decorateType (ast * tree)
        }
 
       /* they should either match or be castable */
-      if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+      if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
        {
          werror (E_TYPE_MISMATCH, "assignment", " ");
          fprintf (stderr, "type --> '");
@@ -3053,7 +3092,7 @@ decorateType (ast * tree)
       if (!tree->right)
        goto voidcheck;
 
-      if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
+      if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
        {
          werror (E_RETURN_MISMATCH);
          goto errorTreeReturn;
@@ -3068,7 +3107,7 @@ decorateType (ast * tree)
        }
 
       /* if there is going to be a casing required then add it */
-      if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
+      if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
        {
 #if 0 && defined DEMAND_INTEGER_PROMOTION
          if (IS_INTEGRAL (currFunc->type->next))
@@ -4164,7 +4203,7 @@ skipall:
   addSet (&operKeyReset, name);
   applyToSet (operKeyReset, resetParmKey);
 
-  if (options.debug && !options.nodebug)
+  if (options.debug)
     cdbStructBlock (1, cdbFile);
 
   cleanUpLevel (LabelTab, 0);