* src/SDCCast.c (processParams): added new type flow and restructured
[fw/sdcc] / src / SDCCsymt.c
index 78d03f4ff85f258ae6e4040f926f1bc17acd6790..d3bfee79b661bfee51ab05509da4d5798c60753d 100644 (file)
@@ -1554,9 +1554,16 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
     SPEC_NOUN (reType) = V_INT;
 
   if (   (   (   SPEC_USIGN (etype1)
-             && (getSize (etype1) >= getSize (reType)))
+              /* if this operand is promoted to a larger
+                type don't check it's signedness */
+             && (getSize (etype1) >= getSize (reType))
+             /* We store signed literals in the range 0...255 as
+                'unsigned char'. If there was no promotion to 'signed int'
+                they must not force an unsigned operation: */
+             && !(IS_CHAR (etype1) && IS_LITERAL (etype1)))
          || (   SPEC_USIGN (etype2)
-             && (getSize (etype2) >= getSize (reType))))
+             && (getSize (etype2) >= getSize (reType))
+             && !(IS_CHAR (etype2) && IS_LITERAL (etype2))))
       && !IS_FLOAT (reType))
     SPEC_USIGN (reType) = 1;
   else
@@ -2227,10 +2234,13 @@ processFuncArgs (symbol * func)
          val->sym->etype = getSpec (val->sym->type);
          val->sym->_isparm = 1;
          strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
+         #if 0
+         /* ?? static functions shouldn't imply static parameters - EEP */
          if (IS_SPEC(func->etype)) {
            SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
              SPEC_STAT (func->etype);
          }
+         #endif
          addSymChain (val->sym);
 
        }
@@ -2242,10 +2252,14 @@ processFuncArgs (symbol * func)
          val->sym->_isparm = 1;
          SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
            (options.model != MODEL_SMALL ? xdata : data);
+         
+         #if 0
+         /* ?? static functions shouldn't imply static parameters - EEP */
          if (IS_SPEC(func->etype)) {
            SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
              SPEC_STAT (func->etype);
          }
+         #endif
        }
       if (!isinSet(operKeyReset, val->sym)) {
        addSet (&operKeyReset, val->sym);
@@ -3000,3 +3014,63 @@ sym_link *validateLink(sym_link  *l,
     exit(-1);
     return l; // never reached, makes compiler happy.
 }
+
+/*--------------------------------------------------------------------*/
+/* newEnumType - create an integer type compatible with enumerations  */
+/*--------------------------------------------------------------------*/
+sym_link *
+newEnumType (symbol *enumlist)
+{
+  int min, max, v;
+  symbol *sym;
+  sym_link *type;
+
+  if (!enumlist)
+    {
+      type = newLink (SPECIFIER);
+      SPEC_NOUN (type) = V_INT;
+      return type;
+    }
+      
+  /* Determine the range of the enumerated values */
+  sym = enumlist;
+  min = max = (int) floatFromVal (valFromType (sym->type));
+  for (sym = sym->next; sym; sym = sym->next)
+    {
+      v = (int) floatFromVal (valFromType (sym->type));
+      if (v<min)
+        min = v;
+      if (v>max)
+        max = v;
+    }
+
+  /* Determine the smallest integer type that is compatible with this range */
+  type = newLink (SPECIFIER);
+  if (min>=0 && max<=255)
+    {
+      SPEC_NOUN (type) = V_CHAR;
+      SPEC_USIGN (type) = 1;
+    }
+  else if (min>=-128 && max<=127)
+    {
+      SPEC_NOUN (type) = V_CHAR;
+    }
+  else if (min>=0 && max<=65535)
+    {
+      SPEC_NOUN (type) = V_INT;
+      SPEC_USIGN (type) = 1;
+    }
+  else if (min>=-32768 && max<=32767)
+    {
+      SPEC_NOUN (type) = V_INT;
+    }
+  else
+    {
+      SPEC_NOUN (type) = V_INT;
+      SPEC_LONG (type) = 1;
+      if (min>=0)
+        SPEC_USIGN (type) = 1;
+    }
+  
+  return type;    
+}