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 */
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;
}
/* this is a specifier */
switch (DCL_TYPE (p))
{
- case FUNCTION:
- return 2;
case ARRAY:
return DCL_ELEM (p) * getSize (p->next);
case IPOINTER:
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);
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;
{
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) = GPOINTER;
+#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;
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:
/* 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;
}
{
aggregateToPointer (val);
}
+
val = val->next;
pNum++;
}
}
if (start==NULL) {
- fprintf (of, "**err**");
+ fprintf (of, "void");
return;
}
switch (DCL_TYPE (type))
{
case FUNCTION:
- fprintf (of, "function ");
+ fprintf (of, "function %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "));
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, "[] ");
}
}
+/*-----------------------------------------------------------------*/
+/* 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 */
+/* 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) = GPOINTER;
+ break;
+ case 'g':
+ case 'x':
+ case 'p':
+ case 'd':
+ 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;
+ }
+ s++;
+ break;
+ default:
+ werror(E_INTERNAL_ERROR,"typeFromStr");
+ break;
+ }
+ if (IS_SPEC(r) && usign) {
+ SPEC_USIGN(r) = 1;
+ usign = 0;
+ }
+ s++;
+ } while (*s);
+ return r;
+}
+
/*-----------------------------------------------------------------*/
/* initCSupport - create functions for C support routines */
/*-----------------------------------------------------------------*/
}
}
}
+
+/*-----------------------------------------------------------------*/
+/* 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;
+ }
+}