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 */
bp->sym = sym; /* update the symbol pointer */
bp->level = level; /* update the nest level */
bp->block = block;
- strcpy (bp->name, sname); /* copy the name into place */
+ strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
/* if this is the first entry */
if (stab[i] == NULL)
sym = Safe_alloc ( sizeof (symbol));
- strcpy (sym->name, name); /* copy the name */
+ strncpyz (sym->name, name, sizeof(sym->name)); /* copy the name */
sym->level = scope; /* set the level */
sym->block = currBlockno;
sym->lineDef = yylineno; /* set the line number */
s = Safe_alloc ( sizeof (structdef));
- strcpy (s->tag, tag); /* copy the tag */
+ strncpyz (s->tag, tag, sizeof(s->tag)); /* copy the tag */
return s;
}
DCL_TYPE (ptr) = EEPPOINTER;
break;
default:
- DCL_TYPE (ptr) = GPOINTER;
+ DCL_TYPE (ptr) = port->unqualified_pointer;
break;
}
/* the storage class of type ends here */
while (ptr)
{
if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
- DCL_TYPE (ptr) = GPOINTER;
+ DCL_TYPE (ptr) = port->unqualified_pointer;
ptr = ptr->next;
}
while (type)
{
if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
- DCL_TYPE (type) = GPOINTER;
+ DCL_TYPE (type) = port->unqualified_pointer;
type = type->next;
}
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;
}
SPEC_BLEN (dest) |= SPEC_BLEN (src);
SPEC_BSTR (dest) |= SPEC_BSTR (src);
SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
-
+ SPEC_ENUM (dest) |= SPEC_ENUM (src);
+ if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
+ SPEC_ARGREG(dest) = SPEC_ARGREG(src);
+
if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
SPEC_STRUCT (dest) = SPEC_STRUCT (src);
FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
FUNC_ISISR(dest) |= FUNC_ISISR(src);
+ FUNC_ISJAVANATIVE(dest) |= FUNC_ISJAVANATIVE(src);
+ FUNC_ISBUILTIN(dest) |= FUNC_ISBUILTIN(src);
+ FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
FUNC_INTNO(dest) |= FUNC_INTNO(src);
FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
static int gCount = 0;
static char gname[SDCC_NAME_MAX + 1];
- sprintf (gname, "__%04d%04d", level, gCount++);
+ SNPRINTF (gname, sizeof(gname), "__%04d%04d", level, gCount++);
return gname;
}
/* this is a specifier */
switch (DCL_TYPE (p))
{
- case FUNCTION:
- return 2;
case ARRAY:
- return DCL_ELEM (p) * getSize (p->next);
+ if (DCL_ELEM(p)) {
+ return DCL_ELEM (p) * getSize (p->next);
+ } else {
+ // werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ // "can not tell the size of an array[]");
+ return 0;
+ }
case IPOINTER:
case PPOINTER:
case POINTER:
case EEPPOINTER:
case FPOINTER:
case CPOINTER:
+ case FUNCTION:
return (FPTRSIZE);
case GPOINTER:
return (GPTRSIZE);
/* this is a specifier */
switch (DCL_TYPE (p))
{
- case FUNCTION:
- return 2;
case ARRAY:
return DCL_ELEM (p) * getSize (p->next) * 8;
case IPOINTER:
case EEPPOINTER:
case FPOINTER:
case CPOINTER:
+ case FUNCTION:
return (FPTRSIZE * 8);
case GPOINTER:
return (GPTRSIZE * 8);
werror (E_EXTERN_MISMATCH, csym->name);
continue;
}
- /* delete current entry */
- deleteSym (SymbolTab, csym, csym->name);
} else {
/* not extern */
- werror (E_DUPLICATE, sym->name);
- continue;
+ if (compareType (csym->type, sym->type) != 1) {
+ werror (E_DUPLICATE, sym->name);
+ continue;
+ }
}
+ /* delete current entry */
+ deleteSym (SymbolTab, csym, csym->name);
+ deleteFromSeg(csym);
}
/* add new entry */
sym_link *type, *etype;
sym_link *petype = getSpec (stype);
- if (!fields || !id)
- return NULL;
+ if (fields && id) {
+
+ /* look for the id */
+ while (fields)
+ {
+ if (strcmp (fields->rname, id->name) == 0)
+ {
+ type = copyLinkChain (fields->type);
+ etype = getSpec (type);
+ SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
+ SPEC_SCLS (etype) : SPEC_SCLS (petype));
+ return type;
+ }
+ fields = fields->next;
+ }
+ }
- /* look for the id */
- while (fields)
- {
- if (strcmp (fields->rname, id->name) == 0)
- {
- type = copyLinkChain (fields->type);
- etype = getSpec (type);
- SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
- SPEC_SCLS (etype) : SPEC_SCLS (petype));
- return type;
- }
- fields = fields->next;
- }
werror (E_NOT_MEMBER, id->name);
-
- return NULL;
+
+ // the show must go on
+ return newIntLink();
}
/*------------------------------------------------------------------*/
while (loop) {
/* create the internal name for this variable */
- sprintf (loop->rname, "_%s", loop->name);
+ SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
loop->offset = (su == UNION ? sum = 0 : sum);
SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
sum += getSize (loop->type);
}
- /* if function then do the arguments for it */
- if (funcInChain (loop->type)) {
- processFuncArgs (loop, 1);
- }
-
loop = loop->next;
/* if this is not a bitfield but the */
}
/* if absolute address given then it mark it as
- volatile */
- if (IS_ABSOLUTE (sym->etype))
- SPEC_VOLATILE (sym->etype) = 1;
+ volatile -- except in the PIC port */
+
+#if !OPT_DISABLE_PIC
+ /* The PIC port uses a different peep hole optimizer based on "pCode" */
+ if (!TARGET_IS_PIC)
+#endif
+
+ if (IS_ABSOLUTE (sym->etype))
+ SPEC_VOLATILE (sym->etype) = 1;
+
/* global variables declared const put into code */
+ /* if no other storage class specified */
if (sym->level == 0 &&
- SPEC_CONST (sym->etype)) {
+ SPEC_CONST (sym->etype) &&
+ SPEC_SCLS(sym->etype) == S_FIXED) {
SPEC_SCLS (sym->etype) = S_CODE;
}
for (p = sym->type; p; p = p->next)
{
if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
- DCL_TYPE (p) = GPOINTER;
+ DCL_TYPE (p) = port->unqualified_pointer;
if (IS_PTR (p) && IS_FUNC (p->next))
DCL_TYPE (p) = CPOINTER;
}
else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
rType = copyLinkChain (type1);
else
- /* if one of them is a pointer then that
+ /* if one of them is a pointer or array then that
prevails */
- if (IS_PTR (type1))
+ if (IS_PTR (type1) || IS_ARRAY (type1))
rType = copyLinkChain (type1);
- else if (IS_PTR (type2))
+ else if (IS_PTR (type2) || IS_ARRAY (type2))
rType = copyLinkChain (type2);
else if (getSize (type1) > getSize (type2))
rType = copyLinkChain (type1);
{
int i;
+ if (options.all_callee_saves) return 1;
for (i = 0; options.calleeSaves[i]; i++)
if (strcmp (options.calleeSaves[i], s) == 0)
return 1;
case S_FIXED:
if (SPEC_OCLS(val->etype)) {
DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
- break;
- }
-
- if (TARGET_IS_DS390)
- {
+ } else {
+#if 1
+ // this happens for (external) function parameters
+ DCL_TYPE (val->type) = port->unqualified_pointer;
+#else
+ if (TARGET_IS_DS390) {
/* The AUTO and REGISTER classes should probably
* also become generic pointers, but I haven't yet
* devised a test case for that.
*/
- DCL_TYPE (val->type) = GPOINTER;
+ DCL_TYPE (val->type) = port->unqualified_pointer;
break;
}
- if (options.model==MODEL_LARGE) {
- DCL_TYPE (val->type) = FPOINTER;
- break;
+ if (options.model==MODEL_LARGE) {
+ DCL_TYPE (val->type) = FPOINTER;
+ break;
+ }
+#endif
}
- /* fall through! */
+ break;
case S_AUTO:
case S_DATA:
case S_REGISTER:
DCL_TYPE (val->type) = EEPPOINTER;
break;
default:
- DCL_TYPE (val->type) = GPOINTER;
+ DCL_TYPE (val->type) = port->unqualified_pointer;
}
/* is there is a symbol associated then */
/* check if this function is defined as calleeSaves
then mark it as such */
- FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
+ FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
/* if interrupt service routine */
/* then it cannot have arguments */
}
}
+ for (argCnt=1, acargs = FUNC_ARGS(sym->type);
+ acargs;
+ acargs=acargs->next, argCnt++) {
+ if (!acargs->sym) {
+ // this can happen for reentrant functions
+ werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
+ // the show must go on: synthesize a name and symbol
+ SNPRINTF (acargs->name, sizeof(acargs->name), "_%s_PARM_%d", sym->name, argCnt);
+ acargs->sym = newSymbol (acargs->name, 1);
+ SPEC_OCLS (acargs->etype) = istack;
+ acargs->sym->type = copyLinkChain (acargs->type);
+ acargs->sym->etype = getSpec (acargs->sym->type);
+ acargs->sym->_isparm = 1;
+ strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
+ } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) {
+ // synthesized name
+ werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
+ }
+ }
+
if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
return 1; /* not defined nothing more to check */
/* replace with this defition */
sym->cdef = csym->cdef;
deleteSym (SymbolTab, csym, csym->name);
+ deleteFromSeg(csym);
addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
if (IS_EXTERN (csym->etype) && !
IS_EXTERN (sym->etype))
/* 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 (DCL_TYPE(funcType)==CPOINTER) {
+ if (IS_PTR(funcType)) {
funcType=funcType->next;
}
/* if this function has variable argument list */
/* then make the function a reentrant one */
- if (IFFUNC_HASVARARGS(funcType))
+ if (IFFUNC_HASVARARGS(funcType) || (options.stackAuto && !func->cdef))
FUNC_ISREENT(funcType)=1;
/* check if this function is defined as calleeSaves
/* change it to pointer to the same type */
while (val)
{
+ int argreg = 0;
/* mark it as a register parameter if
the function does not have VA_ARG
and as port dictates */
if (!IFFUNC_HASVARARGS(funcType) &&
- (*port->reg_parm) (val->type))
+ (argreg = (*port->reg_parm) (val->type)))
{
SPEC_REGPARM (val->etype) = 1;
+ SPEC_ARGREG(val->etype) = argreg;
+ } else if (IFFUNC_ISREENT(funcType)) {
+ FUNC_HASSTACKPARM(funcType) = 1;
}
if (IS_AGGREGATE (val->type))
{
aggregateToPointer (val);
}
+
val = val->next;
pNum++;
}
/* synthesize a variable name */
if (!val->sym)
{
-
- sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
+ SNPRINTF (val->name, sizeof(val->name),
+ "_%s_PARM_%d", func->name, pNum++);
val->sym = newSymbol (val->name, 1);
SPEC_OCLS (val->etype) = port->mem.default_local_map;
val->sym->type = copyLinkChain (val->type);
val->sym->etype = getSpec (val->sym->type);
val->sym->_isparm = 1;
- strcpy (val->sym->rname, val->name);
+ strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
SPEC_STAT (func->etype);
addSymChain (val->sym);
else /* symbol name given create synth name */
{
- sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
- strcpy (val->sym->rname, val->name);
+ SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++);
+ strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
val->sym->_isparm = 1;
SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
(options.model != MODEL_SMALL ? xdata : data);
SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
SPEC_STAT (func->etype);
}
+ if (!isinSet(operKeyReset, val->sym)) {
+ addSet (&operKeyReset, val->sym);
+ applyToSet (operKeyReset, resetParmKey);
+ }
val = val->next;
}
}
}
if (start==NULL) {
- fprintf (of, "**err**");
+ fprintf (of, "void");
return;
}
switch (DCL_TYPE (type))
{
case FUNCTION:
- fprintf (of, "function ");
+ fprintf (of, "function %s %s",
+ (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
+ (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
break;
case GPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* generic ");
+ fprintf (of, "generic * ");
break;
case CPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* code ");
+ fprintf (of, "code * ");
break;
case FPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* xdata ");
+ fprintf (of, "xdata * ");
break;
case EEPPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* eeprom ");
+ fprintf (of, "eeprom * ");
break;
case POINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* near ");
+ fprintf (of, "near *");
break;
case IPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* idata ");
+ fprintf (of, "idata * ");
break;
case PPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* pdata ");
+ fprintf (of, "pdata * ");
break;
case UPOINTER:
if (DCL_PTR_CONST (type))
fprintf (of, "const ");
- fprintf (of, "* unkown ");
+ fprintf (of, "unkown * ");
break;
case ARRAY:
- fprintf (of, "[] ");
+ if (DCL_ELEM(type)) {
+ fprintf (of, "[%d] ", DCL_ELEM(type));
+ } else {
+ fprintf (of, "[] ");
+ }
break;
}
}
fprintf (of, "unsigned ");
if (SPEC_CONST (type))
fprintf (of, "const ");
-
switch (SPEC_NOUN (type))
{
case V_INT:
}
}
+/*-----------------------------------------------------------------*/
+/* typeFromStr - create a typechain from an encoded string */
+/* basic types - 'c' - char */
+/* 's' - short */
+/* 'i' - int */
+/* 'l' - long */
+/* 'f' - float */
+/* 'v' - void */
+/* '*' - pointer - default (GPOINTER) */
+/* modifiers - 'u' - unsigned */
+/* pointer modifiers - 'g' - generic */
+/* 'x' - xdata */
+/* 'p' - code */
+/* 'd' - data */
+/* 'F' - function */
+/* examples : "ig*" - generic int * */
+/* "cx*" - char xdata * */
+/* "ui" - unsigned int */
+/*-----------------------------------------------------------------*/
+sym_link *typeFromStr (char *s)
+{
+ sym_link *r = newLink();
+ int usign = 0;
+
+ do {
+ sym_link *nr;
+ switch (*s) {
+ case 'u' :
+ usign = 1;
+ s++;
+ continue ;
+ break ;
+ case 'c':
+ r->class = SPECIFIER;
+ SPEC_NOUN(r) = V_CHAR;
+ break;
+ case 's':
+ case 'i':
+ r->class = SPECIFIER;
+ SPEC_NOUN(r) = V_INT;
+ break;
+ case 'l':
+ r->class = SPECIFIER;
+ SPEC_NOUN(r) = V_INT;
+ SPEC_LONG(r) = 1;
+ break;
+ case 'f':
+ r->class = SPECIFIER;
+ SPEC_NOUN(r) = V_FLOAT;
+ break;
+ case 'v':
+ r->class = SPECIFIER;
+ SPEC_NOUN(r) = V_VOID;
+ break;
+ case '*':
+ DCL_TYPE(r) = port->unqualified_pointer;
+ break;
+ case 'g':
+ case 'x':
+ case 'p':
+ case 'd':
+ case 'F':
+ assert(*(s+1)=='*');
+ nr = newLink();
+ nr->next = r;
+ r = nr;
+ r->class = DECLARATOR ;
+ switch (*s) {
+ case 'g':
+ DCL_TYPE(r) = GPOINTER;
+ break;
+ case 'x':
+ DCL_TYPE(r) = FPOINTER;
+ break;
+ case 'p':
+ DCL_TYPE(r) = CPOINTER;
+ break;
+ case 'd':
+ DCL_TYPE(r) = POINTER;
+ break;
+ case 'F':
+ DCL_TYPE(r) = FUNCTION;
+ nr = newLink();
+ nr->next = r;
+ r = nr;
+ r->class = DECLARATOR ;
+ DCL_TYPE(r) = CPOINTER;
+ break;
+ }
+ s++;
+ break;
+ default:
+ werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "typeFromStr: unknown type");
+ break;
+ }
+ if (IS_SPEC(r) && usign) {
+ SPEC_USIGN(r) = 1;
+ usign = 0;
+ }
+ s++;
+ } while (*s);
+ return r;
+}
+
/*-----------------------------------------------------------------*/
/* initCSupport - create functions for C support routines */
/*-----------------------------------------------------------------*/
for (bwd = 0; bwd < 3; bwd++)
{
- sym_link *l;
+ sym_link *l = NULL;
switch (bwd)
{
case 0:
{
if (tofrom)
{
- sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
- __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
+ SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
+ __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
}
else
{
- sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
- __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
+ SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
+ __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
}
}
}
{
for (su = 0; su < 2; su++)
{
- sprintf (buffer, "_%s%s%s",
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s%s",
smuldivmod[muldivmod],
ssu[su],
sbwd[bwd]);
{
for (su = 0; su < 2; su++)
{
- sprintf (buffer, "_%s%s%s",
+ SNPRINTF (buffer, sizeof(buffer),
+ "_%s%s%s",
srlrr[rlrr],
ssu[su],
sbwd[bwd]);
}
}
}
+
+/*-----------------------------------------------------------------*/
+/* initBuiltIns - create prototypes for builtin functions */
+/*-----------------------------------------------------------------*/
+void initBuiltIns()
+{
+ int i;
+ symbol *sym;
+
+ if (!port->builtintable) return ;
+
+ for (i = 0 ; port->builtintable[i].name ; i++) {
+ sym = funcOfTypeVarg(port->builtintable[i].name,port->builtintable[i].rtype,
+ port->builtintable[i].nParms,port->builtintable[i].parm_types);
+ FUNC_ISBUILTIN(sym->type) = 1;
+ FUNC_ISREENT(sym->type) = 0; /* can never be reentrant */
+ }
+}