{
symbol *sym = symHead;
symbol *csym = NULL;
+ int error = 0;
for (; sym != NULL; sym = sym->next)
{
changePointer(sym);
checkTypeSanity(sym->etype, sym->name);
+ if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype)))
+ checkDecl (sym, 0);
+
/* if already exists in the symbol table then check if
one of them is an extern definition if yes then
then check if the type match, if the types match then
delete the current entry and add the new entry */
if ((csym = findSymWithLevel (SymbolTab, sym)) &&
csym->level == sym->level) {
-
- /* one definition extern ? */
- if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
- /* do types match ? */
- //checkDecl (sym, IS_EXTERN (sym->etype));
- if (compareTypeExact (csym->type, sym->type, sym->level) != 1) {
- /* no then error */
- werror (E_EXTERN_MISMATCH, csym->name);
- printFromToType (csym->type, sym->type);
- continue;
+
+ /* If the previous definition was for an array with incomplete */
+ /* type, and the new definition has completed the type, update */
+ /* the original type to match */
+ if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
+ && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
+ {
+ if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
+ DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
}
- } else {
- /* not extern */
- //checkDecl (sym, 0);
- if (compareTypeExact (csym->type, sym->type, sym->level) != 1) {
- werror (E_DUPLICATE, sym->name);
- printFromToType (csym->type, sym->type);
- continue;
+
+ #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;
+ if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
+ error = 1;
+
+ if (error) {
+ /* one definition extern ? */
+ if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
+ werror (E_EXTERN_MISMATCH, sym->name);
+ else
+ werror (E_DUPLICATE, sym->name);
+ 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;
}
+
+ if (csym->ival && !sym->ival)
+ sym->ival = csym->ival;
+
/* delete current entry */
deleteSym (SymbolTab, csym, csym->name);
deleteFromSeg(csym);
}
-
+
/* add new entry */
addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
}
}
}
}
-
+
/* 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;
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 ( ( ( SPEC_USIGN (etype1)
+ /* 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))
+ && !(IS_CHAR (etype2) && IS_LITERAL (etype2))))
+ && !IS_FLOAT (reType))
SPEC_USIGN (reType) = 1;
else
SPEC_USIGN (reType) = 0;
if (DCL_PTR_VOLATILE (src) != DCL_PTR_VOLATILE (dest))
return 0;
if (IS_FUNC(src))
- return compareTypeExact (dest->next, src->next, -1);
+ {
+ value *exargs, *acargs, *checkValue;
+
+ /* verify function return type */
+ if (!compareTypeExact (dest->next, src->next, -1))
+ return 0;
+ if (FUNC_ISISR (dest) != FUNC_ISISR (src))
+ return 0;
+ if (FUNC_REGBANK (dest) != FUNC_REGBANK (src))
+ return 0;
+ if (IFFUNC_ISNAKED (dest) != IFFUNC_ISNAKED (src))
+ return 0;
+ #if 0
+ if (IFFUNC_ISREENT (dest) != IFFUNC_ISREENT (src) && argCnt>1)
+ return 0;
+ #endif
+
+ /* compare expected args with actual args */
+ exargs = FUNC_ARGS(dest);
+ acargs = FUNC_ARGS(src);
+
+ /* for all the expected args do */
+ for (; exargs && acargs; exargs = exargs->next, acargs = acargs->next)
+ {
+ //checkTypeSanity(acargs->etype, acargs->name);
+
+ if (IS_AGGREGATE (acargs->type))
+ {
+ checkValue = copyValue (acargs);
+ aggregateToPointer (checkValue);
+ }
+ else
+ checkValue = acargs;
+
+ #if 0
+ if (!compareTypeExact (exargs->type, checkValue->type, -1))
+ return 0;
+ #endif
+ }
+
+ /* if one them ended we have a problem */
+ if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
+ (!exargs && acargs && !IS_VOID (acargs->type)))
+ return 0;
+ return 1;
+ }
return compareTypeExact (dest->next, src->next, level);
}
return 0;
return 0;
if (SPEC_STAT (dest) != SPEC_STAT (src))
return 0;
-
+ if (SPEC_ABSA (dest) != SPEC_ABSA (src))
+ return 0;
+ if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
+ return 0;
+
destScls = SPEC_SCLS (dest);
srcScls = SPEC_SCLS (src);
}
}
- #if 0
if (srcScls != destScls)
{
+ #if 0
printf ("level = %d\n", level);
printf ("SPEC_SCLS (src) = %d, SPEC_SCLS (dest) = %d\n",
SPEC_SCLS (src), SPEC_SCLS (dest));
printf ("srcScls = %d, destScls = %d\n",srcScls, destScls);
+ #endif
return 0;
}
- #endif
return 1;
}
fprintf (stderr, "checkFunction: %s ", sym->name);
}
+ if (!IS_DECL(sym->type) || DCL_TYPE(sym->type)!=FUNCTION)
+ {
+ werror(E_SYNTAX_ERROR, sym->name);
+ return 0;
+ }
+
/* make sure the type is complete and sane */
checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
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;
+}