X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=ed9c4fb5bfef072be5a6be12c3b4123861881872;hb=24db07e65dc37c465c586f173fcf7d591d5bd7bc;hp=be8444e8cfef6957cd3e854f31d718e69a685f2c;hpb=0de080001628cebd436f7fbb070234c83c6bff64;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index be8444e8..ed9c4fb5 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -115,11 +115,13 @@ addSym (bucket ** stab, 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 */ @@ -369,7 +371,7 @@ pointerTypes (sym_link * ptr, sym_link * type) DCL_TYPE (ptr) = EEPPOINTER; break; default: - DCL_TYPE (ptr) = GPOINTER; + DCL_TYPE (ptr) = port->unqualified_pointer; break; } /* the storage class of type ends here */ @@ -383,7 +385,7 @@ pointerTypes (sym_link * ptr, sym_link * type) while (ptr) { if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER) - DCL_TYPE (ptr) = GPOINTER; + DCL_TYPE (ptr) = port->unqualified_pointer; ptr = ptr->next; } @@ -392,7 +394,7 @@ pointerTypes (sym_link * ptr, sym_link * type) while (type) { if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER) - DCL_TYPE (type) = GPOINTER; + DCL_TYPE (type) = port->unqualified_pointer; type = type->next; } @@ -408,6 +410,9 @@ addDecl (symbol * sym, int type, sym_link * p) 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) { @@ -470,6 +475,12 @@ addDecl (symbol * sym, int type, sym_link * 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; } @@ -610,7 +621,10 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) 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); @@ -622,6 +636,9 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) 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); @@ -771,10 +788,14 @@ getSize (sym_link * p) /* 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: @@ -782,6 +803,7 @@ getSize (sym_link * p) case EEPPOINTER: case FPOINTER: case CPOINTER: + case FUNCTION: return (FPTRSIZE); case GPOINTER: return (GPTRSIZE); @@ -830,8 +852,6 @@ bitsForType (sym_link * p) /* this is a specifier */ switch (DCL_TYPE (p)) { - case FUNCTION: - return 2; case ARRAY: return DCL_ELEM (p) * getSize (p->next) * 8; case IPOINTER: @@ -841,6 +861,7 @@ bitsForType (sym_link * p) case EEPPOINTER: case FPOINTER: case CPOINTER: + case FUNCTION: return (FPTRSIZE * 8); case GPOINTER: return (GPTRSIZE * 8); @@ -971,6 +992,7 @@ addSymChain (symbol * symHead) } /* delete current entry */ deleteSym (SymbolTab, csym, csym->name); + deleteFromSeg(csym); } else { /* not extern */ werror (E_DUPLICATE, sym->name); @@ -1009,25 +1031,27 @@ structElemType (sym_link * stype, value * id) 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(); } /*------------------------------------------------------------------*/ @@ -1097,11 +1121,6 @@ compStructSize (int su, structdef * sdef) 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 */ @@ -1154,13 +1173,22 @@ checkSClass (symbol * sym, int isProto) } /* 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; } @@ -1282,7 +1310,7 @@ changePointer (symbol * sym) 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; } @@ -1399,11 +1427,11 @@ computeType (sym_link * type1, sym_link * type2) 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); @@ -1530,6 +1558,7 @@ inCalleeSaveList (char *s) { 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; @@ -1571,23 +1600,26 @@ aggregateToPointer (value * val) 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: @@ -1603,7 +1635,7 @@ aggregateToPointer (value * val) 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 */ @@ -1657,7 +1689,7 @@ checkFunction (symbol * sym, symbol *csym) /* 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 */ @@ -1669,6 +1701,26 @@ checkFunction (symbol * sym, symbol *csym) } } + 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 + sprintf (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; + strcpy (acargs->sym->rname, acargs->name); + } 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 */ @@ -1747,6 +1799,7 @@ checkFunction (symbol * sym, symbol *csym) /* 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)) @@ -1760,20 +1813,23 @@ checkFunction (symbol * sym, symbol *csym) /* 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 @@ -1796,19 +1852,24 @@ processFuncArgs (symbol * func, int ignoreName) /* 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++; } @@ -1836,7 +1897,6 @@ processFuncArgs (symbol * func, int ignoreName) /* synthesize a variable name */ if (!val->sym) { - sprintf (val->name, "_%s_PARM_%d", func->name, pNum++); val->sym = newSymbol (val->name, 1); SPEC_OCLS (val->etype) = port->mem.default_local_map; @@ -1906,7 +1966,7 @@ printTypeChain (sym_link * start, FILE * of) } if (start==NULL) { - fprintf (of, "**err**"); + fprintf (of, "void"); return; } @@ -1924,51 +1984,57 @@ printTypeChain (sym_link * start, FILE * of) 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; } } @@ -1997,7 +2063,6 @@ printTypeChain (sym_link * start, FILE * of) fprintf (of, "unsigned "); if (SPEC_CONST (type)) fprintf (of, "const "); - switch (SPEC_NOUN (type)) { case V_INT: @@ -2308,6 +2373,111 @@ _mangleFunctionName(char *in) } } +/*-----------------------------------------------------------------*/ +/* 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 */ /*-----------------------------------------------------------------*/ @@ -2342,7 +2512,7 @@ initCSupport () for (bwd = 0; bwd < 3; bwd++) { - sym_link *l; + sym_link *l = NULL; switch (bwd) { case 0: @@ -2382,12 +2552,12 @@ initCSupport () 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); + __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); + __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent); } } } @@ -2425,3 +2595,21 @@ initCSupport () } } } + +/*-----------------------------------------------------------------*/ +/* 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 */ + } +}