__rlrr array lacking extern
[fw/sdcc] / src / SDCCast.c
index e76c932eefa9753782cd578ddf955fad1d329c88..5607e136faf83037aa25a9fcfdd4da7eda113534 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));
@@ -462,6 +466,7 @@ resolveSymbols (ast * tree)
              tree->opval.val->etype = tree->opval.val->etype;
              tree->opval.val->type = tree->opval.val->sym->type;
              werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
+             allocVariables (tree->opval.val->sym);
            }
          else
            {
@@ -611,6 +616,14 @@ processParms (ast * func,
   if (!defParm && !actParm)
     return 0;
 
+  if (defParm) {
+    if (getenv("DEBUG_SANITY")) {
+      fprintf (stderr, "addSym: %s ", defParm->name);
+    }
+    /* make sure the type is complete and sane */
+    checkTypeSanity(defParm->etype, defParm->name);
+  }
+
   /* if the function is being called via a pointer &   */
   /* it has not been defined a reentrant then we cannot */
   /* have parameters                                   */
@@ -731,7 +744,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 ");
@@ -743,7 +756,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));
 
@@ -825,6 +838,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  */
@@ -836,51 +850,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++;
-
-      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;
+       ast *aSym;
 
-      /* 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));
 }
 
 
@@ -905,7 +945,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;
@@ -983,6 +1022,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
     /* if type is SPECIFIER */
   if (IS_SPEC (type))
     rast = createIvalType (sym, type, ilist);
+  
   if (wid)
     return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
   else
@@ -992,9 +1032,42 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
 /*-----------------------------------------------------------------*/
 /* initAggregates - initialises aggregate variables with initv     */
 /*-----------------------------------------------------------------*/
-ast *
-initAggregates (symbol * sym, initList * ival, ast * wid)
-{
+
+/* 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");
+      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);
 }
 
@@ -1027,14 +1100,14 @@ gatherAutoInit (symbol * autoChain)
          symbol *newSym;
          
          // this can only be a constant
-         if (!IS_LITERAL(sym->ival->init.node->etype)) {
+         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);
-         addSym (SymbolTab, newSym, newSym->name, 0, 0);
+         addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
 
          /* now lift the code to main */
          if (IS_AGGREGATE (sym->type))
@@ -1130,8 +1203,8 @@ processBlockVars (ast * tree, int *stack, int action)
 
       if (action == ALLOCATE)
        {
-         autoInit = gatherAutoInit (tree->values.sym);
          *stack += allocVariables (tree->values.sym);
+         autoInit = gatherAutoInit (tree->values.sym);
 
          /* if there are auto inits then do them */
          if (autoInit)
@@ -1384,11 +1457,25 @@ astHasSymbol (ast * tree, symbol * sym)
       else
        return FALSE;
     }
-
+  
   return astHasSymbol (tree->left, sym) ||
     astHasSymbol (tree->right, sym);
 }
 
+/*-----------------------------------------------------------------*/
+/* astHasDeref - return true if the ast has an indirect access     */
+/*-----------------------------------------------------------------*/
+static bool 
+astHasDeref (ast * tree)
+{
+  if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
+    return FALSE;
+
+  if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
+  
+  return astHasDeref (tree->left) || astHasDeref (tree->right);
+}
+
 /*-----------------------------------------------------------------*/
 /* isConformingBody - the loop body has to conform to a set of rules */
 /* for the loop to be considered reversible read on for rules      */
@@ -1539,6 +1626,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
       if (astHasVolatile (pbody->left))
        return FALSE;
+      
+      if (astHasDeref(pbody->right)) return FALSE;
 
       return isConformingBody (pbody->left, sym, body) &&
        isConformingBody (pbody->right, sym, body);
@@ -1705,7 +1794,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
 
 }
 
-#define DEMAND_INTEGER_PROMOTION
+//#define DEMAND_INTEGER_PROMOTION
 
 #ifdef DEMAND_INTEGER_PROMOTION
 
@@ -2045,6 +2134,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)))
            {
@@ -2069,6 +2161,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;
        }
@@ -2717,7 +2814,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 ");
@@ -2734,7 +2831,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 ");
@@ -2783,14 +2880,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;
@@ -2955,7 +3053,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 --> '");
@@ -3045,7 +3143,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;
@@ -3060,7 +3158,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))
@@ -3332,7 +3430,7 @@ createLabel (symbol * label, ast * stmnt)
   if ((csym = findSym (LabelTab, NULL, name)))
     werror (E_DUPLICATE_LABEL, label->name);
   else
-    addSym (LabelTab, label, name, label->level, 0);
+    addSym (LabelTab, label, name, label->level, 0, 0);
 
   label->islbl = 1;
   label->key = labelKey++;
@@ -4156,7 +4254,7 @@ skipall:
   addSet (&operKeyReset, name);
   applyToSet (operKeyReset, resetParmKey);
 
-  if (options.debug && !options.nodebug)
+  if (options.debug)
     cdbStructBlock (1, cdbFile);
 
   cleanUpLevel (LabelTab, 0);