sym->level = scope; /* set the level */
sym->block = currBlockno;
sym->lineDef = mylineno; /* set the line number */
+ sym->fileDef = currFname;
return sym;
}
DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
}
+ #if 0
+ /* If only one of the definitions used the "at" keyword, copy */
+ /* the address to the other. */
+ if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
+ && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
+ {
+ SPEC_ABSA (sym->etype) = 1;
+ SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
+ }
+ if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
+ && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
+ {
+ SPEC_ABSA (csym->etype) = 1;
+ SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
+ }
+ #endif
+
error = 0;
if (csym->ival && sym->ival)
error = 1;
werror (E_EXTERN_MISMATCH, sym->name);
else
werror (E_DUPLICATE, sym->name);
- printFromToType (csym->type, sym->type);
+ fprintf (stderr, "from type '");
+ printTypeChain (csym->type, stderr);
+ if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
+ fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
+ fprintf (stderr, "'\nto type '");
+ printTypeChain (sym->type, stderr);
+ if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
+ fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
+ fprintf (stderr, "'\n");
continue;
}
}
}
}
-
+
/* automatic symbols cannot be given */
/* an absolute address ignore it */
if (sym->level &&
/* computeType - computes the resultant type from two types */
/*------------------------------------------------------------------*/
sym_link *
-computeType (sym_link * type1, sym_link * type2)
+computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
{
sym_link *rType;
sym_link *reType;
sym_link *etype1 = getSpec (type1);
- sym_link *etype2 = getSpec (type2);
+ sym_link *etype2;
+
+ etype2 = type2 ? getSpec (type2) : type1;
/* if one of them is a float then result is a float */
/* here we assume that the types passed are okay */
rType = copyLinkChain (type2);
reType = getSpec (rType);
-#if 0
- if (SPEC_NOUN (reType) == V_CHAR)
+
+ /* avoid conflicting types */
+ reType->select.s._signed = 0;
+
+ if (IS_CHAR (reType) && promoteCharToInt)
SPEC_NOUN (reType) = V_INT;
-#endif
- /* if either of them unsigned but not val then make this unsigned */
- if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) &&
- !IS_FLOAT (reType))
+ if (!IS_FLOAT (reType)
+ && ( ( SPEC_USIGN (etype1)
+ /* if this operand is promoted to a larger
+ type don't check it's signedness */
+ && (getSize (etype1) >= getSize (reType))
+ /* char has to handled as it would have
+ been promoted to int */
+ && !IS_CHAR (etype1))
+ /* same for 2nd operand */
+ || ( SPEC_USIGN (etype2)
+ && (getSize (etype2) >= getSize (reType))
+ && !IS_CHAR (etype2))
+ /* if both are unsigned char and not promoted
+ let the result be unsigned too */
+ || ( SPEC_USIGN (etype1)
+ && SPEC_USIGN (etype2)
+ && IS_CHAR (etype1)
+ && IS_CHAR (etype2)
+ && !promoteCharToInt)))
SPEC_USIGN (reType) = 1;
else
SPEC_USIGN (reType) = 0;
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);
}
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);
/*-----------------------------------------------------------------*/
/* powof2 - returns power of two for the number if number is pow 2 */
/*-----------------------------------------------------------------*/
-int
-powof2 (unsigned long num)
+int
+powof2 (TYPE_UDWORD num)
{
int nshifts = 0;
int n1s = 0;
static char *
_mangleFunctionName(char *in)
{
- if (port->getMangledFunctionName)
+ if (port->getMangledFunctionName)
{
return port->getMangledFunctionName(in);
}
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;
+}