X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=35360f205052fbecca4a9b47538cd5220e1a60bc;hb=5f4c7aeda2b5672d87d0805103a394b62e3904c2;hp=20ee30adcab89f68e804eb10fa79a439d9f49173;hpb=c5eb990ef4c01a86da8fef5329e90c5e693c1a26;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 20ee30ad..35360f20 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -25,6 +25,7 @@ #include "newalloc.h" value *aggregateToPointer (value *val); +void printTypeChainRaw (sym_link * start, FILE * of); void printFromToType(sym_link *from, sym_link *to) { fprintf (stderr, "from type '"); @@ -48,6 +49,7 @@ char *nounName(sym_link *sl) { case V_VOID: return "void"; case V_STRUCT: return "struct"; case V_LABEL: return "label"; + case V_BITFIELD: return "bitfield"; case V_BIT: return "bit"; case V_SBIT: return "sbit"; case V_DOUBLE: return "double"; @@ -138,7 +140,7 @@ addSym (bucket ** stab, 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) @@ -287,10 +289,10 @@ newSymbol (char *name, int scope) 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 */ + sym->lineDef = mylineno; /* set the line number */ return sym; } @@ -298,11 +300,12 @@ newSymbol (char *name, int scope) /* newLink - creates a new link (declarator,specifier) */ /*------------------------------------------------------------------*/ sym_link * -newLink () +newLink (SYM_LINK_CLASS select) { sym_link *p; p = Safe_alloc ( sizeof (sym_link)); + p->class=select; return p; } @@ -317,9 +320,40 @@ newStruct (char *tag) s = Safe_alloc ( sizeof (structdef)); - strcpy (s->tag, tag); /* copy the tag */ + strncpyz (s->tag, tag, sizeof(s->tag)); /* copy the tag */ return s; } + +/*------------------------------------------------------------------*/ +/* sclsFromPtr - Return the storage class a pointer points into. */ +/* S_FIXED is returned for generic pointers or other */ +/* unexpected cases */ +/*------------------------------------------------------------------*/ +STORAGE_CLASS +sclsFromPtr(sym_link *ptr) +{ + switch (DCL_TYPE (ptr)) + { + case POINTER: + return S_DATA; + case GPOINTER: + return S_FIXED; + case FPOINTER: + return S_XDATA; + case CPOINTER: + return S_CODE; + case IPOINTER: + return S_IDATA; + case PPOINTER: + return S_PDATA; + case EEPPOINTER: + return S_EEPROM; + case FUNCTION: + return S_CODE; + default: + return S_FIXED; + } +} /*------------------------------------------------------------------*/ /* pointerTypes - do the computation for the pointer types */ @@ -347,8 +381,6 @@ pointerTypes (sym_link * ptr, sym_link * type) storage class of the type */ if (IS_SPEC (type)) { - DCL_PTR_CONST (ptr) = SPEC_CONST (type); - DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type); switch (SPEC_SCLS (type)) { case S_XDATA: @@ -364,7 +396,6 @@ pointerTypes (sym_link * ptr, sym_link * type) DCL_TYPE (ptr) = POINTER; break; case S_CODE: - DCL_PTR_CONST (ptr) = port->mem.code_ro; DCL_TYPE (ptr) = CPOINTER; break; case S_EEPROM: @@ -375,9 +406,7 @@ pointerTypes (sym_link * ptr, sym_link * type) break; } /* the storage class of type ends here */ - SPEC_SCLS (type) = - SPEC_CONST (type) = - SPEC_VOLATILE (type) = 0; + SPEC_SCLS (type) = 0; } /* now change all the remaining unknown pointers @@ -397,7 +426,6 @@ pointerTypes (sym_link * ptr, sym_link * type) DCL_TYPE (type) = port->unqualified_pointer; type = type->next; } - } /*------------------------------------------------------------------*/ @@ -422,7 +450,7 @@ addDecl (symbol * sym, int type, sym_link * p) } else { - head = tail = newLink (); + head = tail = newLink (DECLARATOR); DCL_TYPE (head) = type; } @@ -467,12 +495,9 @@ addDecl (symbol * sym, int type, sym_link * p) { if (!IS_SPEC (sym->etype)) { - sym->etype = sym->etype->next = newLink (); - sym->etype->class = SPECIFIER; + sym->etype = sym->etype->next = newLink (SPECIFIER); } SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p)); - SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p)); - SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p)); DCL_TSPEC (p) = NULL; } @@ -508,7 +533,7 @@ void checkTypeSanity(sym_link *etype, char *name) { noun=nounName(etype); if (getenv("DEBUG_SANITY")) { - fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype); + fprintf (stderr, "checking sanity for %s %p\n", name, etype); } if ((SPEC_NOUN(etype)==V_CHAR || @@ -557,8 +582,6 @@ void checkTypeSanity(sym_link *etype, char *name) { sym_link * mergeSpec (sym_link * dest, sym_link * src, char *name) { - sym_link *symlink=dest; - if (!IS_SPEC(dest) || !IS_SPEC(src)) { #if 0 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator"); @@ -642,24 +665,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) FUNC_INTNO(dest) |= FUNC_INTNO(src); FUNC_REGBANK(dest) |= FUNC_REGBANK(src); - return symlink; -} - -/*------------------------------------------------------------------*/ -/* cloneSpec - copies the entire spec and returns a new spec */ -/*------------------------------------------------------------------*/ -sym_link * -cloneSpec (sym_link * src) -{ - sym_link *spec; - - /* go thru chain till we find the specifier */ - while (src && src->class != SPECIFIER) - src = src->next; - - spec = newLink (); - memcpy (spec, src, sizeof (sym_link)); - return spec; + return dest; } /*------------------------------------------------------------------*/ @@ -671,7 +677,7 @@ genSymName (int level) 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; } @@ -698,8 +704,7 @@ newCharLink () { sym_link *p; - p = newLink (); - p->class = SPECIFIER; + p = newLink (SPECIFIER); SPEC_NOUN (p) = V_CHAR; return p; @@ -713,8 +718,7 @@ newFloatLink () { sym_link *p; - p = newLink (); - p->class = SPECIFIER; + p = newLink (SPECIFIER); SPEC_NOUN (p) = V_FLOAT; return p; @@ -728,8 +732,7 @@ newLongLink () { sym_link *p; - p = newLink (); - p->class = SPECIFIER; + p = newLink (SPECIFIER); SPEC_NOUN (p) = V_INT; SPEC_LONG (p) = 1; @@ -744,8 +747,7 @@ newIntLink () { sym_link *p; - p = newLink (); - p->class = SPECIFIER; + p = newLink (SPECIFIER); SPEC_NOUN (p) = V_INT; return p; @@ -777,8 +779,9 @@ getSize (sym_link * p) case V_LABEL: return 0; case V_SBIT: - return BITSIZE; case V_BIT: + return BITSIZE; + case V_BITFIELD: return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0)); default: return 0; @@ -841,8 +844,9 @@ bitsForType (sym_link * p) case V_LABEL: return 0; case V_SBIT: - return 1; case V_BIT: + return 1; + case V_BITFIELD: return SPEC_BLEN (p); default: return 0; @@ -990,14 +994,16 @@ addSymChain (symbol * symHead) werror (E_EXTERN_MISMATCH, csym->name); continue; } - /* delete current entry */ - deleteSym (SymbolTab, csym, csym->name); - deleteFromSeg(csym); } 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 */ @@ -1022,7 +1028,7 @@ funcInChain (sym_link * lnk) } /*------------------------------------------------------------------*/ -/* structElemType - returns the type info of a sturct member */ +/* structElemType - returns the type info of a struct member */ /*------------------------------------------------------------------*/ sym_link * structElemType (sym_link * stype, value * id) @@ -1042,6 +1048,10 @@ structElemType (sym_link * stype, value * id) etype = getSpec (type); SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? SPEC_SCLS (etype) : SPEC_SCLS (petype)); + if (IS_SPEC (type)) + SPEC_CONST (type) |= SPEC_CONST (stype); + else + DCL_PTR_CONST (type) |= SPEC_CONST (stype); return type; } fields = fields->next; @@ -1086,56 +1096,89 @@ compStructSize (int su, structdef * sdef) while (loop) { /* create the internal name for this variable */ - sprintf (loop->rname, "_%s", loop->name); - loop->offset = (su == UNION ? sum = 0 : sum); + SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name); + if (su == UNION) { + sum = 0; + bitOffset = 0; + } SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0); /* if this is a bit field */ if (loop->bitVar) { /* change it to a unsigned bit */ - SPEC_NOUN (loop->etype) = V_BIT; + SPEC_NOUN (loop->etype) = V_BITFIELD; SPEC_USIGN (loop->etype) = 1; - /* check if this fit into the remaining */ - /* bits of this byte else align it to the */ - /* next byte boundary */ - if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) { - SPEC_BSTR (loop->etype) = bitOffset; - if ((bitOffset += (loop->bitVar % 8)) == 8) - sum++; - } - else /* does not fit */ { - bitOffset = 0; - SPEC_BSTR (loop->etype) = bitOffset; - sum += (loop->bitVar / 8); - bitOffset += (loop->bitVar % 8); + SPEC_BLEN (loop->etype) = loop->bitVar; + + if (loop->bitVar == BITVAR_PAD) { + /* A zero length bitfield forces padding */ + SPEC_BSTR (loop->etype) = bitOffset; + SPEC_BLEN (loop->etype) = 0; + bitOffset = 8; + loop->offset = sum; } - /* if this is the last field then pad */ - if (!loop->next && bitOffset && bitOffset != 8) { - bitOffset = 0; - sum++; + else { + if (bitOffset == 8) { + bitOffset = 0; + sum++; + } + /* check if this fit into the remaining */ + /* bits of this byte else align it to the */ + /* next byte boundary */ + if (loop->bitVar <= (8 - bitOffset)) { + /* fits into current byte */ + loop->offset = sum; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + } + else if (!bitOffset) { + /* does not fit, but is already byte aligned */ + loop->offset = sum; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + } + else { + /* does not fit; need to realign first */ + sum++; + loop->offset = (su == UNION ? sum = 0 : sum); + bitOffset = 0; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + } + while (bitOffset>8) { + bitOffset -= 8; + sum++; + } } } else { + /* This is a non-bit field. Make sure we are */ + /* byte aligned first */ + if (bitOffset) { + sum++; + loop->offset = (su == UNION ? sum = 0 : sum); + bitOffset = 0; + } + loop->offset = sum; checkDecl (loop, 1); sum += getSize (loop->type); } loop = loop->next; - /* if this is not a bitfield but the */ - /* previous one was and did not take */ - /* the whole byte then pad the rest */ - if ((loop && !loop->bitVar) && bitOffset) { - bitOffset = 0; - sum++; - } - /* if union then size = sizeof larget field */ - if (su == UNION) + if (su == UNION) { + /* For UNION, round up after each field */ + sum += ((bitOffset+7)/8); usum = max (usum, sum); + } } + + /* For STRUCT, round up after all fields processed */ + if (su != UNION) + sum += ((bitOffset+7)/8); return (su == UNION ? usum : sum); } @@ -1146,58 +1189,77 @@ compStructSize (int su, structdef * sdef) static void checkSClass (symbol * sym, int isProto) { + sym_link *t; + if (getenv("DEBUG_SANITY")) { fprintf (stderr, "checkSClass: %s \n", sym->name); } - /* type is literal can happen foe enums change + /* type is literal can happen for enums change to auto */ if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype)) SPEC_SCLS (sym->etype) = S_AUTO; - /* if sfr or sbit then must also be */ - /* volatile the initial value will be xlated */ - /* to an absolute address */ + /* if sfr or sbit then must also be volatile */ if (SPEC_SCLS (sym->etype) == S_SBIT || SPEC_SCLS (sym->etype) == S_SFR) { SPEC_VOLATILE (sym->etype) = 1; - /* if initial value given */ - if (sym->ival) - { - SPEC_ABSA (sym->etype) = 1; - SPEC_ADDR (sym->etype) = - (int) list2int (sym->ival); - sym->ival = NULL; - } } /* if absolute address given then it mark it as volatile -- except in the PIC port */ -#if !OPT_DISABLE_PIC +#if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16 /* The PIC port uses a different peep hole optimizer based on "pCode" */ - if (!TARGET_IS_PIC) + if (!TARGET_IS_PIC && !TARGET_IS_PIC16) #endif if (IS_ABSOLUTE (sym->etype)) SPEC_VOLATILE (sym->etype) = 1; + /* If code memory is read only, then pointers to code memory */ + /* implicitly point to constants -- make this explicit */ + t = sym->type; + while (t && t->next) { + if (IS_CODEPTR(t) && port->mem.code_ro) { + if (IS_SPEC(t->next)) { + SPEC_CONST (t->next) = 1; + } else { + DCL_PTR_CONST (t->next) = 1; + } + } + t = t->next; + } /* global variables declared const put into code */ /* if no other storage class specified */ if (sym->level == 0 && - SPEC_CONST (sym->etype) && - SPEC_SCLS(sym->etype) == S_FIXED) { - SPEC_SCLS (sym->etype) = S_CODE; + SPEC_SCLS(sym->etype) == S_FIXED && + !IS_FUNC(sym->type)) { + /* find the first non-array link */ + t = sym->type; + while (IS_ARRAY(t)) + t = t->next; + if (IS_CONSTANT (t)) { + SPEC_SCLS (sym->etype) = S_CODE; + } } - + /* global variable in code space is a constant */ if (sym->level == 0 && SPEC_SCLS (sym->etype) == S_CODE && - port->mem.code_ro) - SPEC_CONST (sym->etype) = 1; - + port->mem.code_ro) { + /* find the first non-array link */ + t = sym->type; + while (IS_ARRAY(t)) + t = t->next; + if (IS_SPEC(t)) { + SPEC_CONST (t) = 1; + } else { + DCL_PTR_CONST (t) = 1; + } + } /* if bit variable then no storage class can be */ /* specified since bit is already a storage */ @@ -1218,7 +1280,7 @@ checkSClass (symbol * sym, int isProto) sym->ival = NULL; } - /* if this is an atomatic symbol */ + /* if this is an automatic symbol */ if (sym->level && (options.stackAuto || reentrant)) { if ((SPEC_SCLS (sym->etype) == S_AUTO || SPEC_SCLS (sym->etype) == S_FIXED || @@ -1249,6 +1311,7 @@ checkSClass (symbol * sym, int isProto) if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) && (SPEC_NOUN (sym->etype) == V_BIT || SPEC_NOUN (sym->etype) == V_SBIT || + SPEC_NOUN (sym->etype) == V_BITFIELD || SPEC_SCLS (sym->etype) == S_SFR)) werror (E_BIT_ARRAY, sym->name); @@ -1288,7 +1351,8 @@ checkSClass (symbol * sym, int isProto) * control this allcoation, but the code was originally that way, and * changing it for non-390 ports breaks the compiler badly. */ - bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack; + bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? + 1 : options.useXstack; SPEC_SCLS (sym->etype) = (useXdata ? S_XDATA : S_FIXED); } @@ -1343,11 +1407,11 @@ copyLinkChain (sym_link * p) sym_link *head, *curr, *loop; curr = p; - head = loop = (curr ? newLink () : (void *) NULL); + head = loop = (curr ? newLink (p->class) : (void *) NULL); while (curr) { memcpy (loop, curr, sizeof (sym_link)); /* copy it */ - loop->next = (curr->next ? newLink () : (void *) NULL); + loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL); loop = loop->next; curr = curr->next; } @@ -1439,15 +1503,18 @@ computeType (sym_link * type1, sym_link * type2) rType = copyLinkChain (type2); reType = getSpec (rType); +#if 0 + if (SPEC_NOUN (reType) == V_CHAR) + SPEC_NOUN (reType) = V_INT; +#endif /* 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))) && + if ((SPEC_USIGN (etype1) || 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; @@ -1458,7 +1525,7 @@ computeType (sym_link * type1, sym_link * type2) /*--------------------------------------------------------------------*/ /* compareType - will do type check return 1 if match, -1 if castable */ /*--------------------------------------------------------------------*/ -int +int compareType (sym_link * dest, sym_link * src) { if (!dest && !src) @@ -1481,6 +1548,9 @@ compareType (sym_link * dest, sym_link * src) } return compareType (dest->next, src->next); } + if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) { + return 1; + } if (IS_PTR (src) && IS_GENPTR (dest)) return -1; if (IS_PTR (dest) && IS_ARRAY (src)) { @@ -1488,7 +1558,6 @@ compareType (sym_link * dest, sym_link * 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)) @@ -1553,17 +1622,18 @@ compareType (sym_link * dest, sym_link * src) /*------------------------------------------------------------------*/ /* inCalleeSaveList - return 1 if found in callee save list */ /*------------------------------------------------------------------*/ -bool -inCalleeSaveList (char *s) +static int +calleeCmp(void *p1, void *p2) { - 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; + return (strcmp((char *)p1, (char *)(p2)) == 0); +} - return 0; +bool +inCalleeSaveList(char *s) +{ + if (options.all_callee_saves) + return 1; + return isinSetWith(options.calleeSavesSet, s, calleeCmp); } /*-----------------------------------------------------------------*/ @@ -1583,7 +1653,7 @@ aggregateToPointer (value * val) sym_link *p = val->type; werror (W_STRUCT_AS_ARG, val->name); - val->type = newLink (); + val->type = newLink (DECLARATOR); val->type->next = p; } @@ -1601,23 +1671,8 @@ aggregateToPointer (value * val) if (SPEC_OCLS(val->etype)) { DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype)); } 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) = port->unqualified_pointer; - break; - } - if (options.model==MODEL_LARGE) { - DCL_TYPE (val->type) = FPOINTER; - break; - } -#endif } break; case S_AUTO: @@ -1708,18 +1763,19 @@ checkFunction (symbol * sym, symbol *csym) // 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); + 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; - strcpy (acargs->sym->rname, acargs->name); + 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); } } + argCnt--; if (!csym && !(csym = findSym (SymbolTab, sym, sym->name))) return 1; /* not defined nothing more to check */ @@ -1753,6 +1809,17 @@ checkFunction (symbol * sym, symbol *csym) { werror (E_PREV_DEF_CONFLICT, csym->name, "_naked"); } + + /* Really, reentrant should match regardless of argCnt, but */ + /* this breaks some existing code (the fp lib functions). If */ + /* the first argument is always passed the same way, this */ + /* lax checking is ok (but may not be true for in future ports) */ + if (IFFUNC_ISREENT (csym->type) != IFFUNC_ISREENT (sym->type) + && argCnt>1) + { + //printf("argCnt = %d\n",argCnt); + werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant"); + } /* compare expected args with actual args */ exargs = FUNC_ARGS(csym->type); @@ -1809,6 +1876,29 @@ checkFunction (symbol * sym, symbol *csym) return 1; } +/*------------------------------------------------------------------*/ +/* cdbStructBlock - calls struct printing for a blcks */ +/*------------------------------------------------------------------*/ +void cdbStructBlock (int block) +{ + int i; + bucket **table = StructTab; + bucket *chain; + + /* go thru the entire table */ + for (i = 0; i < 256; i++) + { + for (chain = table[i]; chain; chain = chain->next) + { + if (chain->block >= block) + { + if(debugFile) + debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL); + } + } + } +} + /*-----------------------------------------------------------------*/ /* processFuncArgs - does some processing with function args */ /*-----------------------------------------------------------------*/ @@ -1897,29 +1987,38 @@ processFuncArgs (symbol * func) /* 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); - SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) = - SPEC_STAT (func->etype); + strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname)); + if (IS_SPEC(func->etype)) { + 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 (IS_SPEC(func->etype)) { + 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; } } @@ -1957,7 +2056,9 @@ void printTypeChain (sym_link * start, FILE * of) { int nlr = 0; + value *args; sym_link * type, * search; + STORAGE_CLASS scls; if (!of) { @@ -1970,16 +2071,47 @@ printTypeChain (sym_link * start, FILE * of) return; } - /* print the chain as it is written in the source: */ - /* start with the last entry */ + /* Print the chain as it is written in the source: */ + /* start with the last entry. */ + /* However, the storage class at the end of the */ + /* chain reall applies to the first in the chain! */ + for (type = start; type && type->next; type = type->next) ; + if (IS_SPEC (type)) + scls=SPEC_SCLS(type); + else + scls=0; while (type) { + if (type==start) { + switch (scls) + { + 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 (IS_DECL (type)) { - if (DCL_PTR_VOLATILE (type)) { - fprintf (of, "volatile "); + if (!IS_FUNC(type)) { + if (DCL_PTR_VOLATILE (type)) { + fprintf (of, "volatile-"); + } + if (DCL_PTR_CONST (type)) { + fprintf (of, "const-"); + } } switch (DCL_TYPE (type)) { @@ -1987,47 +2119,39 @@ printTypeChain (sym_link * start, FILE * of) fprintf (of, "function %s %s", (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "), (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " ")); + fprintf (of, "( "); + for (args = FUNC_ARGS(type); + args; + args=args->next) { + printTypeChain(args->type, of); + if (args->next) + fprintf(of, ", "); + } + fprintf (of, ") "); 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, "unknown* "); break; case ARRAY: if (DCL_ELEM(type)) { @@ -2040,34 +2164,17 @@ printTypeChain (sym_link * start, FILE * of) } 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)) - fprintf (of, "unsigned "); + fprintf (of, "volatile-"); if (SPEC_CONST (type)) - fprintf (of, "const "); + fprintf (of, "const-"); + if (SPEC_USIGN (type)) + fprintf (of, "unsigned-"); switch (SPEC_NOUN (type)) { case V_INT: if (IS_LONG (type)) - fprintf (of, "long "); + fprintf (of, "long-"); fprintf (of, "int"); break; @@ -2092,7 +2199,11 @@ printTypeChain (sym_link * start, FILE * of) break; case V_BIT: - fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type)); + fprintf (of, "bit"); + break; + + case V_BITFIELD: + fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type)); break; case V_DOUBLE: @@ -2104,217 +2215,187 @@ printTypeChain (sym_link * start, FILE * of) break; } } - /* search entry in list before "type" */ - for (search = start; search && search->next != type;) - search = search->next; - type = search; - if (type) - fputc (' ', of); + /* 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 */ -/*-----------------------------------------------------------------*/ +/*--------------------------------------------------------------------*/ +/* printTypeChainRaw - prints the type chain in human readable form */ +/* in the raw data structure ordering */ +/*--------------------------------------------------------------------*/ void -cdbTypeInfo (sym_link * type, FILE * of) +printTypeChainRaw (sym_link * start, FILE * of) { - fprintf (of, "{%d}", getSize (type)); + int nlr = 0; + value *args; + sym_link * type; + + if (!of) + { + of = stdout; + nlr = 1; + } + + if (start==NULL) { + fprintf (of, "void"); + return; + } + + type = start; + while (type) { if (IS_DECL (type)) { + if (!IS_FUNC(type)) { + if (DCL_PTR_VOLATILE (type)) { + fprintf (of, "volatile-"); + } + if (DCL_PTR_CONST (type)) { + fprintf (of, "const-"); + } + } switch (DCL_TYPE (type)) { case FUNCTION: - fprintf (of, "DF,"); + fprintf (of, "function %s %s", + (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "), + (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " ")); + fprintf (of, "( "); + for (args = FUNC_ARGS(type); + args; + args=args->next) { + printTypeChain(args->type, of); + if (args->next) + fprintf(of, ", "); + } + fprintf (of, ") "); break; case GPOINTER: - fprintf (of, "DG,"); + fprintf (of, "generic* "); break; case CPOINTER: - fprintf (of, "DC,"); + fprintf (of, "code* "); break; case FPOINTER: - fprintf (of, "DX,"); + fprintf (of, "xdata* "); + break; + case EEPPOINTER: + fprintf (of, "eeprom* "); break; case POINTER: - fprintf (of, "DD,"); + fprintf (of, "near* "); break; case IPOINTER: - fprintf (of, "DI,"); + fprintf (of, "idata* "); break; case PPOINTER: - fprintf (of, "DP,"); + fprintf (of, "pdata* "); break; - case EEPPOINTER: - fprintf (of, "DA,"); + case UPOINTER: + fprintf (of, "unknown* "); break; case ARRAY: - fprintf (of, "DA%d,", DCL_ELEM (type)); - break; - default: + if (DCL_ELEM(type)) { + fprintf (of, "[%d] ", DCL_ELEM(type)); + } else { + fprintf (of, "[] "); + } break; } + if (DCL_TSPEC(type)) + { + fprintf (of, "{"); + printTypeChainRaw(DCL_TSPEC(type), of); + fprintf (of, "}"); + } } - else + else if (IS_SPEC (type)) { + 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_CONST (type)) + fprintf (of, "const-"); + if (SPEC_USIGN (type)) + fprintf (of, "unsigned-"); switch (SPEC_NOUN (type)) { case V_INT: if (IS_LONG (type)) - fprintf (of, "SL"); - else - fprintf (of, "SI"); + fprintf (of, "long-"); + fprintf (of, "int"); break; case V_CHAR: - fprintf (of, "SC"); + fprintf (of, "char"); break; case V_VOID: - fprintf (of, "SV"); + fprintf (of, "void"); break; case V_FLOAT: - fprintf (of, "SF"); + fprintf (of, "float"); break; case V_STRUCT: - fprintf (of, "ST%s", SPEC_STRUCT (type)->tag); + fprintf (of, "struct %s", SPEC_STRUCT (type)->tag); break; case V_SBIT: - fprintf (of, "SX"); + fprintf (of, "sbit"); break; case V_BIT: - fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type)); + fprintf (of, "bit"); break; - default: + case V_BITFIELD: + fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type)); break; - } - fputs (":", of); - if (SPEC_USIGN (type)) - fputs ("U", of); - else - fputs ("S", of); - } - type = type->next; - } -} -/*-----------------------------------------------------------------*/ -/* cdbSymbol - prints a symbol & its type information for debugger */ -/*-----------------------------------------------------------------*/ -void -cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc) -{ - memmap *map; - if (!sym) - return; - if (!of) - of = stdout; + case V_DOUBLE: + fprintf (of, "double"); + break; - if (isFunc) - fprintf (of, "F:"); - else - fprintf (of, "S:"); /* symbol record */ - /* if this is not a structure symbol then - we need to figure out the scope information */ - if (!isStructSym) - { - if (!sym->level) - { - /* global */ - if (IS_STATIC (sym->etype)) - fprintf (of, "F%s$", moduleName); /* scope is file */ - else - fprintf (of, "G$"); /* scope is global */ + default: + fprintf (of, "unknown type"); + break; + } } else - /* symbol is local */ - fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-")); - } - else - fprintf (of, "S$"); /* scope is structure */ - - /* print the name, & mangled name */ - fprintf (of, "%s$%d$%d(", sym->name, - sym->level, sym->block); - - cdbTypeInfo (sym->type, of); - fprintf (of, "),"); - - /* print the address space */ - map = SPEC_OCLS (sym->etype); - fprintf (of, "%c,%d,%d", - (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype)); - - /* if assigned to registers then output register names */ - /* if this is a function then print - if is it an interrupt routine & interrupt number - and the register bank it is using */ - if (isFunc) - 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 */ - - if (!isStructSym) - fprintf (of, "\n"); -} - -/*-----------------------------------------------------------------*/ -/* cdbStruct - print a structure for debugger */ -/*-----------------------------------------------------------------*/ -void -cdbStruct (structdef * sdef, int block, FILE * of, - int inStruct, char *tag) -{ - symbol *sym; - - fprintf (of, "T:"); - /* if block # then must have function scope */ - fprintf (of, "F%s$", moduleName); - fprintf (of, "%s[", (tag ? tag : sdef->tag)); - for (sym = sdef->fields; sym; sym = sym->next) - { - fprintf (of, "({%d}", sym->offset); - cdbSymbol (sym, of, TRUE, FALSE); - fprintf (of, ")"); + fprintf (of, "NOT_SPEC_OR_DECL"); + type = type->next; + if (type) + fputc (' ', of); } - fprintf (of, "]"); - if (!inStruct) + if (nlr) fprintf (of, "\n"); } -/*------------------------------------------------------------------*/ -/* cdbStructBlock - calls struct printing for a blcks */ -/*------------------------------------------------------------------*/ -void -cdbStructBlock (int block, FILE * of) -{ - int i; - bucket **table = StructTab; - bucket *chain; - wassert (of); - - /* go thru the entire table */ - for (i = 0; i < 256; i++) - { - for (chain = table[i]; chain; chain = chain->next) - { - if (chain->block >= block) - { - cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL); - } - } - } -} /*-----------------------------------------------------------------*/ /* powof2 - returns power of two for the number if number is pow 2 */ @@ -2394,7 +2475,7 @@ _mangleFunctionName(char *in) /*-----------------------------------------------------------------*/ sym_link *typeFromStr (char *s) { - sym_link *r = newLink(); + sym_link *r = newLink(DECLARATOR); int usign = 0; do { @@ -2436,10 +2517,9 @@ sym_link *typeFromStr (char *s) case 'd': case 'F': assert(*(s+1)=='*'); - nr = newLink(); + nr = newLink(DECLARATOR); nr->next = r; r = nr; - r->class = DECLARATOR ; switch (*s) { case 'g': DCL_TYPE(r) = GPOINTER; @@ -2455,10 +2535,9 @@ sym_link *typeFromStr (char *s) break; case 'F': DCL_TYPE(r) = FUNCTION; - nr = newLink(); + nr = newLink(DECLARATOR); nr->next = r; r = nr; - r->class = DECLARATOR ; DCL_TYPE(r) = CPOINTER; break; } @@ -2512,7 +2591,7 @@ initCSupport () for (bwd = 0; bwd < 3; bwd++) { - sym_link *l; + sym_link *l = NULL; switch (bwd) { case 0: @@ -2551,25 +2630,27 @@ initCSupport () { if (tofrom) { - sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]); + 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]); + 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 (muldivmod = 0; muldivmod < 3; muldivmod++) { for (bwd = 0; bwd < 3; bwd++) { for (su = 0; su < 2; su++) { - sprintf (buffer, "_%s%s%s", + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", smuldivmod[muldivmod], ssu[su], sbwd[bwd]); @@ -2579,13 +2660,67 @@ initCSupport () } } + muluint() and mulsint() resp. mululong() and mulslong() return the same result. + Therefore they've been merged into mulint() and mullong(). +*/ + + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + for (muldivmod = 1; muldivmod < 3; muldivmod++) + { + /* div and mod */ + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } + } + } + /* mul only */ + muldivmod = 0; + /* byte */ + bwd = 0; + for (su = 0; su < 2; su++) + { + /* muluchar and mulschar are still separate functions, because e.g. the z80 + port is sign/zero-extending to int before calling mulint() */ + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } + /* signed only */ + su = 0; + /* word and doubleword */ + for (bwd = 1; bwd < 3; bwd++) + { + /* mul, int/long */ + SNPRINTF (buffer, sizeof(buffer), + "_%s%s", + smuldivmod[muldivmod], + sbwd[bwd]); + __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1; + /* signed = unsigned */ + __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0]; + } + for (rlrr = 0; rlrr < 2; rlrr++) { for (bwd = 0; bwd < 3; 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]); @@ -2613,3 +2748,23 @@ void initBuiltIns() FUNC_ISREENT(sym->type) = 0; /* can never be reentrant */ } } + +sym_link *validateLink(sym_link *l, + const char *macro, + const char *args, + const char select, + const char *file, + unsigned line) +{ + if (l && l->class==select) + { + return l; + } + fprintf(stderr, + "Internal error: validateLink failed in %s(%s) @ %s:%u:" + " expected %s, got %s\n", + macro, args, file, line, + DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link"); + exit(-1); + return l; // never reached, makes compiler happy. +}