X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=c65c3e2f965da328d1853bce5a27131d975d9ff4;hb=f96e7d4df901d66ed8f5025c20cc5976115d0a54;hp=8031d9fce9013670b908847798febf6a74f6f26d;hpb=5db7b152dddfeac2395417a253993f63e21e0fe5;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 8031d9fc..c65c3e2f 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -438,6 +438,7 @@ pointerTypes (sym_link * ptr, sym_link * type) void addDecl (symbol * sym, int type, sym_link * p) { + static sym_link *empty = NULL; sym_link *head; sym_link *tail; sym_link *t; @@ -445,6 +446,9 @@ addDecl (symbol * sym, int type, sym_link * p) if (getenv("SDCC_DEBUG_FUNCTION_POINTERS")) fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p); + if (empty == NULL) + empty = newLink(SPECIFIER); + /* if we are passed a link then set head & tail */ if (p) { @@ -464,28 +468,28 @@ addDecl (symbol * sym, int type, sym_link * p) sym->type = head; sym->etype = tail; } + else if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail) + { + sym->etype = mergeSpec (sym->etype, head, sym->name); + } + else if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail) + { + t = sym->type; + while (t->next != sym->etype) + t = t->next; + t->next = head; + tail->next = sym->etype; + } + else if (IS_FUNC (sym->type) && IS_SPEC (sym->type->next) && + !memcmp(sym->type->next, empty, sizeof(sym_link))) + { + sym->type->next = head; + sym->etype = tail; + } else { - if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail) - { - sym->etype = mergeSpec (sym->etype, head, sym->name); - } - else - { - if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail) - { - t = sym->type; - while (t->next != sym->etype) - t = t->next; - t->next = head; - tail->next = sym->etype; - } - else - { - sym->etype->next = head; - sym->etype = tail; - } - } + sym->etype->next = head; + sym->etype = tail; } /* if the type is an unknown pointer and has @@ -1587,6 +1591,7 @@ checkSClass (symbol * sym, int isProto) //!sym->level && port->mem.code_ro && !IS_EXTERN (sym->etype) && + !SPEC_ABSA (sym->etype) && !funcInChain (sym->type)) werror (E_CODE_NO_INIT, sym->name); } @@ -3125,7 +3130,7 @@ printTypeChainRaw (sym_link * start, FILE * of) /* powof2 - returns power of two for the number if number is pow 2 */ /*-----------------------------------------------------------------*/ int -powof2 (TYPE_UDWORD num) +powof2 (TYPE_TARGET_ULONG num) { int nshifts = 0; int n1s = 0; @@ -3456,17 +3461,50 @@ initCSupport () { 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; + /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */ + if (!TARGET_IS_PIC16 || muldivmod != 1 || bwd != 0 || su != 0) + { + 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; + } } } } + + if (TARGET_IS_PIC16) + { + /* PIC16 port wants __divschar/__modschar to return an int, so that both + * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly + * (first one would have to be sign extended, second one must not be). + * Similarly, modschar should be handled, but the iCode introduces cast + * here and forces '% : s8 x s8 -> s8' ... */ + su = 0; bwd = 0; + for (muldivmod = 1; muldivmod < 2; muldivmod++) { + SNPRINTF (buffer, sizeof(buffer), + "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType ( + _mangleFunctionName(buffer), + __multypes[1][su], + __multypes[bwd][su], + 2, + options.intlong_rent); + FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1; + } + } + /* mul only */ muldivmod = 0; /* byte */