{
bucket *bp;
- bp = Safe_calloc (1, sizeof (bucket));
+ bp = Safe_alloc ( sizeof (bucket));
return bp;
}
checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
}
+ /* prevent overflow of the (r)name buffers */
+ if (strlen(sname)>SDCC_SYMNAME_MAX) {
+ werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
+ sname[SDCC_SYMNAME_MAX]='\0';
+ }
+
/* the symbols are always added at the head of the list */
i = hashKey (sname);
/* get a free entry */
- bp = Safe_calloc (1, sizeof (bucket));
+ bp = Safe_alloc ( sizeof (bucket));
bp->sym = sym; /* update the symbol pointer */
bp->level = level; /* update the nest level */
**/
while (bp)
{
-
if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
{
/* if this is parameter then nothing else need to be checked */
if (((symbol *) (bp->sym))->_isparm)
return (bp->sym);
- /* if levels match then block numbers hsould also match */
+ /* if levels match then block numbers should also match */
if (bp->level && bp->level == sym->level && bp->block == sym->block)
return (bp->sym);
/* if levels don't match then we are okay */
{
symbol *sym;
- sym = Safe_calloc (1, sizeof (symbol));
+ sym = Safe_alloc ( sizeof (symbol));
strcpy (sym->name, name); /* copy the name */
sym->level = scope; /* set the level */
{
sym_link *p;
- p = Safe_calloc (1, sizeof (sym_link));
+ p = Safe_alloc ( sizeof (sym_link));
return p;
}
{
structdef *s;
- s = Safe_calloc (1, sizeof (structdef));
+ s = Safe_alloc ( sizeof (structdef));
strcpy (s->tag, tag); /* copy the tag */
return s;
ptr = ptr->next;
/* could not find it */
- if (!ptr || IS_SPEC (ptr) ||
- DCL_TYPE (ptr) != UPOINTER)
+ if (!ptr || IS_SPEC (ptr))
+ return;
+
+ if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
+ pointerTypes (ptr->next, type);
return;
+ }
/* change the pointer type depending on the
storage class of the type */
}
}
- /* if the type is a unknown pointer and has
+ /* if the type is an unknown pointer and has
a tspec then take the storage class const & volatile
attribute from the tspec & make it those of this
symbol */
if (p &&
!IS_SPEC (p) &&
- DCL_TYPE (p) == UPOINTER &&
+ //DCL_TYPE (p) == UPOINTER &&
DCL_TSPEC (p))
{
if (!IS_SPEC (sym->etype))
mergeSpec (sym_link * dest, sym_link * src, char *name)
{
+ sym_link *symlink=dest;
+
+#if 0
+ if (!IS_SPEC(dest)) {
+ // This can happen for pointers, find the end type
+ while (dest && !IS_SPEC(dest))
+ dest=dest->next;
+ }
+ if (!IS_SPEC(src)) {
+ // here we have a declarator as source, reverse them
+ symlink=src;
+ src=dest;
+ dest=symlink;
+ while (dest && !IS_SPEC(dest)) {
+ // and find the specifier
+ dest=dest->next;
+ }
+ } else {
+ symlink=dest;
+ }
+#endif
+
+ if (!IS_SPEC(dest) || !IS_SPEC(src)) {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
+ exit (1);
+ }
+
if (getenv("DEBUG_mergeSpec")) {
fprintf (stderr, "mergeSpec: \"%s\"\n", name);
}
if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
SPEC_STRUCT (dest) = SPEC_STRUCT (src);
- return dest;
+ return symlink;
}
/*------------------------------------------------------------------*/
symbol *sym = symHead;
symbol *csym = NULL;
-
for (; sym != NULL; sym = sym->next)
{
changePointer(sym);
+ checkTypeSanity(sym->etype, sym->name);
/* if already exists in the symbol table then check if
- the previous was an extern definition if yes then
+ 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)
- {
-
- /* previous definition extern ? */
- if (IS_EXTERN (csym->etype))
- {
- /* do types match ? */
- if (compareType (csym->type, sym->type) != 1)
- /* no then error */
- werror (E_DUPLICATE, csym->name);
-
- /* delete current entry */
- deleteSym (SymbolTab, csym, csym->name);
- /* add new entry */
- addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
- }
- else /* not extern */
- werror (E_DUPLICATE, sym->name);
+ csym->level == sym->level) {
+
+ /* one definition extern ? */
+ if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
+ /* do types match ? */
+ if (compareType (csym->type, sym->type) != 1) {
+ /* no then error */
+ werror (E_EXTERN_MISMATCH, csym->name);
+ continue;
+ }
+ /* delete current entry */
+ deleteSym (SymbolTab, csym, csym->name);
+ } else {
+ /* not extern */
+ werror (E_DUPLICATE, sym->name);
continue;
}
+ }
- /* check if previously defined */
- if (csym && csym->level == sym->level)
- {
- /* if the previous one was declared as extern */
- /* then check the type with the current one */
- if (IS_EXTERN (csym->etype))
- {
- if (compareType (csym->type, sym->type) <= 0)
- werror (W_EXTERN_MISMATCH, csym->name);
- }
- }
+ /* add new entry */
addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
}
}
}
}
else {
- checkDecl (loop);
+ checkDecl (loop, 1);
sum += getSize (loop->type);
}
/* checkSClass - check the storage class specification */
/*------------------------------------------------------------------*/
static void
-checkSClass (symbol * sym)
+checkSClass (symbol * sym, int isProto)
{
if (getenv("DEBUG_SANITY")) {
fprintf (stderr, "checkSClass: %s \n", sym->name);
sym->ival = NULL;
}
-#if 0
- /* if this is an automatic symbol then */
- /* storage class will be ignored and */
- /* symbol will be allocated on stack/ */
- /* data depending on flag */
- if (sym->level &&
- (options.stackAuto || reentrant) &&
- (SPEC_SCLS (sym->etype) != S_AUTO &&
- SPEC_SCLS (sym->etype) != S_FIXED &&
- SPEC_SCLS (sym->etype) != S_REGISTER &&
- SPEC_SCLS (sym->etype) != S_STACK &&
- SPEC_SCLS (sym->etype) != S_XSTACK))
- {
- werror (E_AUTO_ASSUMED, sym->name);
- SPEC_SCLS (sym->etype) = S_AUTO;
- }
-#else
/* if this is an atomatic symbol */
if (sym->level && (options.stackAuto || reentrant)) {
if ((SPEC_SCLS (sym->etype) == S_AUTO ||
}
}
}
-#endif
/* automatic symbols cannot be given */
/* an absolute address ignore it */
SPEC_BSTR (sym->etype) = 0;
}
- /* variables declared in CODE space must have */
- /* initializers if not an extern */
- if (SPEC_SCLS (sym->etype) == S_CODE &&
- sym->ival == NULL &&
- !sym->level &&
- port->mem.code_ro &&
- !IS_EXTERN (sym->etype) &&
- !funcInChain (sym->type))
- werror (E_CODE_NO_INIT, sym->name);
+ if (!isProto) {
+ /* variables declared in CODE space must have */
+ /* initializers if not an extern */
+ if (SPEC_SCLS (sym->etype) == S_CODE &&
+ sym->ival == NULL &&
+ //!sym->level &&
+ port->mem.code_ro &&
+ !IS_EXTERN (sym->etype) &&
+ !funcInChain (sym->type))
+ werror (E_CODE_NO_INIT, sym->name);
+ }
/* if parameter or local variable then change */
/* the storage class to reflect where the var will go */
/* checkDecl - does semantic validation of a declaration */
/*------------------------------------------------------------------*/
int
-checkDecl (symbol * sym)
+checkDecl (symbol * sym, int isProto)
{
- checkSClass (sym); /* check the storage class */
+ checkSClass (sym, isProto); /* check the storage class */
changePointer (sym); /* change pointers if required */
/* if this is an array without any dimension
reType = getSpec (rType);
- /* if either of them unsigned then make this unsigned */
- if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
+ /* if either of them unsigned but not val then make this unsigned */
+ if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) ||
+ (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) &&
+ !IS_FLOAT (reType))
SPEC_USIGN (reType) = 1;
-
+ else
+ SPEC_USIGN (reType) = 0;
+
/* if result is a literal then make not so */
if (IS_LITERAL (reType))
SPEC_SCLS (reType) = S_REGISTER;
return rType;
}
-/*------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match */
-/*------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+/* compareType - will do type check return 1 if match, -1 if castable */
+/*--------------------------------------------------------------------*/
int
compareType (sym_link * dest, sym_link * src)
{
{
if (DCL_TYPE (src) == DCL_TYPE (dest))
return compareType (dest->next, src->next);
- else if (IS_PTR (src) && IS_PTR (dest))
+ if (IS_PTR (src) && IS_PTR (dest))
return -1;
- else if (IS_PTR (dest) && IS_ARRAY (src))
+ if (IS_PTR (dest) && IS_ARRAY (src))
return -1;
- else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
+ if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
return -1 * compareType (dest->next, src);
- else
- return 0;
+ return 0;
}
else if (IS_PTR (dest) && IS_INTEGRAL (src))
return -1;
return -1;
if (SPEC_USIGN (dest) != SPEC_USIGN (src))
- return -2;
+ return -1;
return 1;
}
void
aggregateArgToPointer (value * val)
{
+ int wasArray=IS_ARRAY(val->type);
+
if (IS_AGGREGATE (val->type))
{
/* if this is a structure */
default:
DCL_TYPE (val->type) = GPOINTER;
}
+
+ if (wasArray) {
+ /* there is NO way to specify the storage of the pointer
+ associated with an array, so we make it the default */
+ SPEC_SCLS(val->etype) = S_FIXED;
+ }
/* is there is a symbol associated then */
/* change the type of the symbol as well */
if (compareType (csym->type, sym->type) <= 0)
{
werror (E_PREV_DEF_CONFLICT, csym->name, "type");
- werror (E_CONTINUE, "previous definition type ");
+ werror (W_CONTINUE, "previous definition type ");
printTypeChain (csym->type, stderr);
fprintf (stderr, "\n");
- werror (E_CONTINUE, "current definition type ");
+ werror (W_CONTINUE, "current definition type ");
printTypeChain (sym->type, stderr);
fprintf (stderr, "\n");
return 0;
werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
}
- /* compare expected agrs with actual args */
+ /* compare expected args with actual args */
exargs = csym->args;
acargs = sym->args;
/*-----------------------------------------------------------------*/
/* printTypeChain - prints the type chain in human readable form */
/*-----------------------------------------------------------------*/
-void
-printTypeChain (sym_link * type, FILE * of)
+void
+printTypeChain (sym_link * start, FILE * of)
{
int nlr = 0;
+ sym_link * type, * search;
if (!of)
{
nlr = 1;
}
+ if (start==NULL) {
+ fprintf (of, "**err**");
+ return;
+ }
+
+ /* print the chain as it is written in the source: */
+ /* start with the last entry */
+ for (type = start; type && type->next; type = type->next)
+ ;
while (type)
{
if (IS_DECL (type))
{
- if (DCL_PTR_VOLATILE(type)) {
+ if (DCL_PTR_VOLATILE (type)) {
fprintf (of, "volatile ");
}
switch (DCL_TYPE (type))
{
case FUNCTION:
- fprintf (of, "function ");
+ fprintf (of, "function");
break;
case GPOINTER:
- fprintf (of, "_generic * ");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "generic *");
break;
case CPOINTER:
- fprintf (of, "_code * ");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "code *");
break;
case FPOINTER:
- fprintf (of, "_far * ");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "far *");
break;
case EEPPOINTER:
- fprintf (of, "_eeprom * ");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "eeprom * ");
break;
case POINTER:
- fprintf (of, "_near * ");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "near *");
break;
case IPOINTER:
- fprintf (of, "_idata *");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "idata *");
break;
case PPOINTER:
- fprintf (of, "_pdata *");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "pdata *");
break;
case UPOINTER:
- fprintf (of, " _unkown *");
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
+ fprintf (of, "unkown *");
break;
case ARRAY:
- fprintf (of, "array of ");
+ fprintf (of, "array of");
break;
}
}
case V_INT:
if (IS_LONG (type))
fprintf (of, "long ");
- fprintf (of, "int ");
+ fprintf (of, "int");
break;
case V_CHAR:
- fprintf (of, "char ");
+ fprintf (of, "char");
break;
case V_VOID:
- fprintf (of, "void ");
+ fprintf (of, "void");
break;
case V_FLOAT:
- fprintf (of, "float ");
+ fprintf (of, "float");
break;
case V_STRUCT:
break;
case V_SBIT:
- fprintf (of, "sbit ");
+ fprintf (of, "sbit");
break;
case V_BIT:
break;
case V_DOUBLE:
- fprintf (of, "double ");
+ fprintf (of, "double");
break;
default:
- fprintf (of, "unknown type ");
+ fprintf (of, "unknown type");
break;
}
}
- type = type->next;
+ /* search entry in list before "type" */
+ for (search = start; search && search->next != type;)
+ search = search->next;
+ type = search;
+ if (type)
+ fputc (' ', of);
}
if (nlr)
fprintf (of, "\n");
/*-----------------------------------------------------------------*/
/* cdbTypeInfo - print the type information for debugger */
/*-----------------------------------------------------------------*/
-void
+void
cdbTypeInfo (sym_link * type, FILE * of)
{
fprintf (of, "{%d}", getSize (type));
sym_link *__multypes[3][2];
/* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
symbol *__conv[2][3][2];
+/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
+symbol *__rlrr[2][3][2];
sym_link *floatType;
-static void
-_makeRegParam (symbol * sym)
+static char *
+_mangleFunctionName(char *in)
{
- value *val;
-
- val = sym->args; /* loop thru all the arguments */
-
- /* reset regparm for the port */
- (*port->reset_regparms) ();
- while (val)
+ if (port->getMangledFunctionName)
{
- SPEC_REGPARM (val->etype) = 1;
- val = val->next;
+ return port->getMangledFunctionName(in);
+ }
+ else
+ {
+ return in;
}
}
{
"s", "u"
};
+ const char *srlrr[] =
+ {
+ "rl", "rr"
+ };
+
+ int bwd, su, muldivmod, tofrom, rlrr;
- int bwd, su, muldivmod, tofrom;
+ if (getenv("SDCC_NO_C_SUPPORT")) {
+ /* for debugging only */
+ return;
+ }
floatType = newFloatLink ();
if (tofrom)
{
sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
- __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
+ __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
}
else
{
sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
- __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
+ __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
}
}
}
smuldivmod[muldivmod],
ssu[su],
sbwd[bwd]);
- __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+ __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
- if (bwd < port->muldiv.force_reg_param_below)
- _makeRegParam (__muldiv[muldivmod][bwd][su]);
+ }
+ }
+ }
+
+ for (rlrr = 0; rlrr < 2; rlrr++)
+ {
+ for (bwd = 0; bwd < 3; bwd++)
+ {
+ for (su = 0; su < 2; su++)
+ {
+ sprintf (buffer, "_%s%s%s",
+ srlrr[rlrr],
+ ssu[su],
+ sbwd[bwd]);
+ __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
+ SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1;
}
}
}