Added support fun for long shifts
[fw/sdcc] / src / SDCCast.c
index e5b321cad83b0c5533cdb6fe35939a4a653b4fec..a28cf06f54f7dbc9f475e0352584c6aa74aac17a 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,
@@ -611,6 +610,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                                   */
@@ -641,6 +648,7 @@ processParms (ast * func,
   if (!defParm && actParm && func->hasVargs)
     {
       ast *newType = NULL;
+      sym_link *ftype;
 
       if (IS_CAST_OP (actParm)
          || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
@@ -649,25 +657,39 @@ processParms (ast * func,
          return 0;
        }
 
+      /* The ternary ('?') operator is weird: the ftype of the 
+       * operator is the type of the condition, but it will return a 
+       * (possibly) different type. 
+       */
+      if (IS_TERNARY_OP(actParm))
+      {
+          assert(IS_COLON_OP(actParm->right));
+          assert(actParm->right->left);
+          ftype = actParm->right->left->ftype;
+      }
+      else
+      {
+          ftype = actParm->ftype;
+      }
+          
       /* If it's a small integer, upcast to int. */
-      if (IS_INTEGRAL (actParm->ftype)
-         && getSize (actParm->ftype) < (unsigned) INTSIZE)
+      if (IS_INTEGRAL (ftype)
+         && (getSize (ftype) < (unsigned) INTSIZE))
        {
-         newType = newAst_LINK (INTTYPE);
+         newType = newAst_LINK(INTTYPE);
        }
 
-      if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
+      if (IS_PTR(ftype) && !IS_GENPTR(ftype))
        {
-         newType = newAst_LINK (copyLinkChain (actParm->ftype));
+         newType = newAst_LINK (copyLinkChain(ftype));
          DCL_TYPE (newType->opval.lnk) = GPOINTER;
        }
 
-      if (IS_AGGREGATE (actParm->ftype))
+      if (IS_AGGREGATE (ftype))
        {
-         newType = newAst_LINK (copyLinkChain (actParm->ftype));
+         newType = newAst_LINK (copyLinkChain (ftype));
          DCL_TYPE (newType->opval.lnk) = GPOINTER;
        }
-
       if (newType)
        {
          /* cast required; change this op to a cast. */
@@ -716,7 +738,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 ");
@@ -728,7 +750,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));
 
@@ -849,8 +871,16 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
 
       /* no of elements given and we    */
       /* have generated for all of them */
-      if (!--lcnt)
+      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);
+       }
        break;
+      }
     }
 
   /* if we have not been given a size  */
@@ -1002,11 +1032,16 @@ gatherAutoInit (symbol * autoChain)
          SPEC_SCLS (sym->etype) != S_CODE)
        {
          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);
-         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))
@@ -2017,6 +2052,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)))
            {
@@ -2041,6 +2079,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;
        }
@@ -2271,19 +2314,17 @@ decorateType (ast * tree)
        }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      /* promote result to int if left & right are char / short 
+      /* promote result to int if left & right are char
         this will facilitate hardware multiplies 8bit x 8bit = 16bit */
-      if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) && 
-          (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
-             TETYPE (tree) = getSpec (TTYPE (tree) =
-                                      computeType (LTYPE (tree),
-                                                   RTYPE (tree)));
-             SPEC_NOUN(TETYPE(tree)) = V_INT;
-             SPEC_SHORT(TETYPE(tree))=0;
+      if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
+       TETYPE (tree) = getSpec (TTYPE (tree) =
+                                computeType (LTYPE (tree),
+                                             RTYPE (tree)));
+       SPEC_NOUN(TETYPE(tree)) = V_INT;
       } else {
-             TETYPE (tree) = getSpec (TTYPE (tree) =
-                                      computeType (LTYPE (tree),
-                                                   RTYPE (tree)));
+       TETYPE (tree) = getSpec (TTYPE (tree) =
+                                computeType (LTYPE (tree),
+                                             RTYPE (tree)));
       }
       return tree;
 
@@ -2605,6 +2646,9 @@ decorateType (ast * tree)
          werror (E_CAST_ILLEGAL);
          goto errorTreeReturn;
        }
+      
+      /* make sure the type is complete and sane */
+      checkTypeSanity(LETYPE(tree), "(cast)");
 
       /* if the right is a literal replace the tree */
       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
@@ -2688,7 +2732,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 ");
@@ -2705,7 +2749,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 ");
@@ -2754,14 +2798,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;
@@ -2926,7 +2971,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 --> '");
@@ -3016,7 +3061,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;
@@ -3031,7 +3076,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))
@@ -3139,6 +3184,9 @@ sizeofOp (sym_link * type)
 {
   char buff[10];
 
+  /* make sure the type is complete and sane */
+  checkTypeSanity(type, "(sizeof)");
+
   /* get the size and convert it to character  */
   sprintf (buff, "%d", getSize (type));
 
@@ -3300,7 +3348,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++;
@@ -4124,7 +4172,7 @@ skipall:
   addSet (&operKeyReset, name);
   applyToSet (operKeyReset, resetParmKey);
 
-  if (options.debug && !options.nodebug)
+  if (options.debug)
     cdbStructBlock (1, cdbFile);
 
   cleanUpLevel (LabelTab, 0);