#include "common.h"
#include "newalloc.h"
+value *aggregateToPointer (value *val);
+
+void printFromToType(sym_link *from, sym_link *to) {
+ fprintf (stderr, "from type '");
+ printTypeChain (from, stderr);
+ fprintf (stderr, "'\nto type '");
+ printTypeChain (to, stderr);
+ fprintf (stderr, "'\n");
+}
+
/* noun strings */
char *nounName(sym_link *sl) {
switch (SPEC_NOUN(sl))
{
bucket *bp;
- bp = Safe_calloc (1, sizeof (bucket));
+ bp = Safe_alloc ( sizeof (bucket));
return bp;
}
bucket *bp; /* temp bucket * */
if (checkType) {
+ symbol *csym = (symbol *)sym;
+
if (getenv("DEBUG_SANITY")) {
fprintf (stderr, "addSym: %s ", sname);
}
/* make sure the type is complete and sane */
- checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
+ checkTypeSanity(csym->etype, csym->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 */
{
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;
sym_link *tail;
sym_link *t;
+ if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
+ fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
+
/* if we are passed a link then set head & tail */
if (p)
{
SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
DCL_TSPEC (p) = NULL;
}
+
+ // if there is a function in this type chain
+ if (p && funcInChain(sym->type)) {
+ processFuncArgs (sym);
+ }
+
return;
}
sym_link *
mergeSpec (sym_link * dest, sym_link * src, char *name)
{
-
- sym_link *symlink;
-
- 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;
- }
+ sym_link *symlink=dest;
if (!IS_SPEC(dest) || !IS_SPEC(src)) {
+#if 0
werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
exit (1);
- }
-
- if (getenv("DEBUG_mergeSpec")) {
- fprintf (stderr, "mergeSpec: \"%s\"\n", name);
+#else
+ werror (E_SYNTAX_ERROR, yytext);
+ // the show must go on
+ return newIntLink();
+#endif
}
if (SPEC_NOUN(src)) {
dest->select.s._signed|=src->select.s._signed;
SPEC_STAT (dest) |= SPEC_STAT (src);
SPEC_EXTR (dest) |= SPEC_EXTR (src);
+ SPEC_CONST(dest) |= SPEC_CONST (src);
SPEC_ABSA (dest) |= SPEC_ABSA (src);
- SPEC_RENT (dest) |= SPEC_RENT (src);
- SPEC_INTN (dest) |= SPEC_INTN (src);
- SPEC_BANK (dest) |= SPEC_BANK (src);
SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
- SPEC_CRTCL (dest) |= SPEC_CRTCL (src);
SPEC_ADDR (dest) |= SPEC_ADDR (src);
SPEC_OCLS (dest) = SPEC_OCLS (src);
SPEC_BLEN (dest) |= SPEC_BLEN (src);
SPEC_BSTR (dest) |= SPEC_BSTR (src);
SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
- SPEC_NONBANKED (dest) |= SPEC_NONBANKED (src);
- SPEC_NAKED (dest) |= SPEC_NAKED (src);
if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
SPEC_STRUCT (dest) = SPEC_STRUCT (src);
+ /* these are the only function attributes that will be set
+ in a specifier while parsing */
+ FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
+ FUNC_BANKED(dest) |= FUNC_BANKED(src);
+ FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
+ FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
+ FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
+ FUNC_ISISR(dest) |= FUNC_ISISR(src);
+ FUNC_INTNO(dest) |= FUNC_INTNO(src);
+ FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
+
return symlink;
}
dest->type = copyLinkChain (src->type);
dest->etype = getSpec (dest->type);
dest->next = NULL;
- dest->args = copyValueChain (src->args);
dest->key = src->key;
- dest->calleeSave = src->calleeSave;
dest->allocreq = src->allocreq;
return dest;
}
/* structElemType - returns the type info of a sturct member */
/*------------------------------------------------------------------*/
sym_link *
-structElemType (sym_link * stype, value * id, value ** argsp)
+structElemType (sym_link * stype, value * id)
{
symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
sym_link *type, *etype;
{
if (strcmp (fields->rname, id->name) == 0)
{
- if (argsp)
- {
- *argsp = fields->args;
- }
type = copyLinkChain (fields->type);
etype = getSpec (type);
SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
sum += getSize (loop->type);
}
+#if 0 // jwk: this is done now in addDecl()
/* if function then do the arguments for it */
if (funcInChain (loop->type)) {
- processFuncArgs (loop, 1);
+ processFuncArgs (loop);
}
+#endif
loop = loop->next;
if (getenv("DEBUG_SANITY")) {
fprintf (stderr, "checkSClass: %s \n", sym->name);
}
- if (strcmp(sym->name, "_testsGlobal")==0) {
- printf ("oach\n");
- }
/* type is literal can happen foe enums change
to auto */
if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
!IS_STATIC(sym->etype))
{
- if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
+ if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
{
SPEC_SCLS (sym->etype) = (options.useXstack ?
S_XSTACK : S_STACK);
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;
{
if (IS_DECL (src))
{
- if (DCL_TYPE (src) == DCL_TYPE (dest))
+ if (DCL_TYPE (src) == DCL_TYPE (dest)) {
+ if (IS_FUNC(src)) {
+ //checkFunction(src,dest);
+ }
return compareType (dest->next, src->next);
- if (IS_PTR (src) && IS_PTR (dest))
- return -1;
- if (IS_PTR (dest) && IS_ARRAY (src))
+ }
+ if (IS_PTR (src) && IS_GENPTR (dest))
return -1;
+ if (IS_PTR (dest) && IS_ARRAY (src)) {
+ value *val=aggregateToPointer (valFromType(src));
+ int res=compareType (dest, val->type);
+ Safe_free(val->type);
+ Safe_free(val);
+ //return res ? -1 : 0;
+ return res;
+ }
if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
- return -1 * compareType (dest->next, src);
+ return compareType (dest->next, src);
return 0;
}
else if (IS_PTR (dest) && IS_INTEGRAL (src))
}
/*-----------------------------------------------------------------*/
-/* aggregateArgToPointer: change an agggregate type function */
+/* aggregateToPointer: change an agggregate type function */
/* argument to a pointer to that type. */
/*-----------------------------------------------------------------*/
-void
-aggregateArgToPointer (value * val)
+value *
+aggregateToPointer (value * val)
{
if (IS_AGGREGATE (val->type))
{
DCL_TYPE (val->type) = PPOINTER;
break;
case S_FIXED:
+ DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
+
if (TARGET_IS_DS390)
{
/* The AUTO and REGISTER classes should probably
DCL_TYPE (val->type) = GPOINTER;
break;
}
- /* fall through! */
+ if (options.model==MODEL_LARGE) {
+ DCL_TYPE (val->type) = FPOINTER;
+ break;
+ }
+ break;
case S_AUTO:
case S_DATA:
case S_REGISTER:
default:
DCL_TYPE (val->type) = GPOINTER;
}
-
+
/* is there is a symbol associated then */
/* change the type of the symbol as well */
if (val->sym)
val->sym->etype = getSpec (val->sym->type);
}
}
+ return val;
}
/*------------------------------------------------------------------*/
/* checkFunction - does all kinds of check on a function */
/*------------------------------------------------------------------*/
int
-checkFunction (symbol * sym)
+checkFunction (symbol * sym, symbol *csym)
{
- symbol *csym;
value *exargs, *acargs;
value *checkValue;
int argCnt = 0;
/* check if this function is defined as calleeSaves
then mark it as such */
- sym->calleeSave = inCalleeSaveList (sym->name);
+ FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
/* if interrupt service routine */
/* then it cannot have arguments */
- if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
+ if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
{
- werror (E_INT_ARGS, sym->name);
- sym->args = NULL;
+ if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
+ werror (E_INT_ARGS, sym->name);
+ FUNC_ARGS(sym->type)=NULL;
+ }
}
- if (!(csym = findSym (SymbolTab, sym, sym->name)))
+ if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
return 1; /* not defined nothing more to check */
/* check if body already present */
- if (csym && csym->fbody)
+ if (csym && IFFUNC_HASBODY(csym->type))
{
werror (E_FUNC_BODY, sym->name);
return 0;
if (compareType (csym->type, sym->type) <= 0)
{
werror (E_PREV_DEF_CONFLICT, csym->name, "type");
- werror (W_CONTINUE, "previous definition type ");
- printTypeChain (csym->type, stderr);
- fprintf (stderr, "\n");
- werror (W_CONTINUE, "current definition type ");
- printTypeChain (sym->type, stderr);
- fprintf (stderr, "\n");
+ printFromToType(csym->type, sym->type);
return 0;
}
- if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
+ if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
{
werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
}
- if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
+ if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
{
werror (E_PREV_DEF_CONFLICT, csym->name, "using");
}
- if (SPEC_NAKED (csym->etype) != SPEC_NAKED (sym->etype))
+ if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
{
werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
}
- /* compare expected agrs with actual args */
- exargs = csym->args;
- acargs = sym->args;
+ /* compare expected args with actual args */
+ exargs = FUNC_ARGS(csym->type);
+ acargs = FUNC_ARGS(sym->type);
/* for all the expected args do */
for (argCnt = 1;
if (IS_AGGREGATE (acargs->type))
{
checkValue = copyValue (acargs);
- aggregateArgToPointer (checkValue);
+ aggregateToPointer (checkValue);
}
else
{
if (compareType (exargs->type, checkValue->type) <= 0)
{
werror (E_ARG_TYPE, argCnt);
+ printFromToType(exargs->type, checkValue->type);
return 0;
}
}
/* processFuncArgs - does some processing with function args */
/*-----------------------------------------------------------------*/
void
-processFuncArgs (symbol * func, int ignoreName)
+processFuncArgs (symbol * func)
{
value *val;
int pNum = 1;
+ sym_link *funcType=func->type;
+
+ if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
+ fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
+
+ // if this is a pointer to a function
+ if (IS_PTR(funcType)) {
+ funcType=funcType->next;
+ }
/* if this function has variable argument list */
/* then make the function a reentrant one */
- if (func->hasVargs)
- SPEC_RENT (func->etype) = 1;
+ if (IFFUNC_HASVARARGS(funcType))
+ FUNC_ISREENT(funcType)=1;
/* check if this function is defined as calleeSaves
then mark it as such */
- func->calleeSave = inCalleeSaveList (func->name);
+ FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
- val = func->args; /* loop thru all the arguments */
+ /* loop thru all the arguments */
+ val = FUNC_ARGS(funcType);
/* if it is void then remove parameters */
if (val && IS_VOID (val->type))
{
- func->args = NULL;
+ FUNC_ARGS(funcType) = NULL;
return;
}
/* mark it as a register parameter if
the function does not have VA_ARG
and as port dictates */
- if (!func->hasVargs &&
+ if (!IFFUNC_HASVARARGS(funcType) &&
(*port->reg_parm) (val->type))
{
SPEC_REGPARM (val->etype) = 1;
if (IS_AGGREGATE (val->type))
{
- aggregateArgToPointer (val);
+ aggregateToPointer (val);
}
+
val = val->next;
pNum++;
}
if (func->cdef) {
/* ignore --stack-auto for this one, we don't know how it is compiled */
/* simply trust on --int-long-reent or --float-reent */
- if (IS_RENT(func->etype)) {
+ if (IFFUNC_ISREENT(funcType)) {
return;
}
} else {
/* if this function is reentrant or */
/* automatics r 2b stacked then nothing */
- if (IS_RENT (func->etype) || options.stackAuto)
+ if (IFFUNC_ISREENT (funcType) || options.stackAuto)
return;
}
- val = func->args;
+ val = FUNC_ARGS(funcType);
pNum = 1;
while (val)
{
/*-----------------------------------------------------------------*/
/* 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, "void");
+ 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))
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, "xdata * ");
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, "[] ");
break;
}
}
else
{
+ switch (SPEC_SCLS(type))
+ {
+ case S_DATA: fprintf (of, "data "); break;
+ case S_XDATA: fprintf (of, "xdata "); break;
+ case S_SFR: fprintf (of, "sfr "); break;
+ case S_SBIT: fprintf (of, "sbit "); break;
+ case S_CODE: fprintf (of, "code "); break;
+ case S_IDATA: fprintf (of, "idata "); break;
+ case S_PDATA: fprintf (of, "pdata "); break;
+ case S_LITERAL: fprintf (of, "literal "); break;
+ case S_STACK: fprintf (of, "stack "); break;
+ case S_XSTACK: fprintf (of, "xstack "); break;
+ case S_BIT: fprintf (of, "bit "); break;
+ case S_EEPROM: fprintf (of, "eeprom "); break;
+ default: break;
+ }
+
if (SPEC_VOLATILE (type))
fprintf (of, "volatile ");
if (SPEC_USIGN (type))
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));
if is it an interrupt routine & interrupt number
and the register bank it is using */
if (isFunc)
- fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
- SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
+ fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
+ FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
/* alternate location to find this symbol @ : eg registers
or spillication */
ssu[su],
sbwd[bwd]);
__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;
+ FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
}
}
}
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;
+ FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
}
}
}