#include "common.h"
#include "newalloc.h"
+#include "dbuf_string.h"
#include "SDCCsymt.h"
void
addDecl (symbol * sym, int type, sym_link * p)
{
+ static sym_link *empty = NULL;
sym_link *head;
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 (empty == NULL)
+ empty = newLink(SPECIFIER);
+
/* if we are passed a link then set head & tail */
if (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
SPEC_CONST(dest) |= SPEC_CONST (src);
SPEC_ABSA (dest) |= SPEC_ABSA (src);
SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
+ SPEC_RESTRICT (dest) |= SPEC_RESTRICT (src);
SPEC_ADDR (dest) |= SPEC_ADDR (src);
SPEC_OCLS (dest) = SPEC_OCLS (src);
SPEC_BLEN (dest) |= SPEC_BLEN (src);
fprintf (stderr, "checkSClass: %s \n", sym->name);
}
- /* type is literal can happen for enums change
- to auto */
+ /* 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;
SPEC_VOLATILE (sym->etype) = 1;
}
+ /* make sure restrict is only used with pointers */
+ if (SPEC_RESTRICT (sym->etype))
+ {
+ werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
+ SPEC_RESTRICT (sym->etype) = 0;
+ }
+ t = sym->type;
+ while (t)
+ {
+ if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !IS_PTR (t))
+ {
+ werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
+ DCL_PTR_RESTRICT (t) = 0;
+ break;
+ }
+ t = t->next;
+ }
+
/* if absolute address given then it mark it as
volatile -- except in the PIC port */
//!sym->level &&
port->mem.code_ro &&
!IS_EXTERN (sym->etype) &&
+ !SPEC_ABSA (sym->etype) &&
!funcInChain (sym->type))
werror (E_CODE_NO_INIT, sym->name);
}
&& ( (SPEC_USIGN (etype1)
/* if this operand is promoted to a larger type,
then it will be promoted to a signed type */
- && !(getSize (etype1) < getSize (reType))
+ && !(bitsForType (etype1) < bitsForType (reType))
/* char require special handling */
&& !IS_CHAR (etype1))
|| /* same for 2nd operand */
(SPEC_USIGN (etype2)
- && !(getSize (etype2) < getSize (reType))
+ && !(bitsForType (etype2) < bitsForType (reType))
&& !IS_CHAR (etype2))
|| /* if both are 'unsigned char' and not promoted
let the result be unsigned too */
void
printTypeChain (sym_link * start, FILE * of)
{
+ struct dbuf_s dbuf;
int nlr = 0;
- value *args;
- sym_link * type, * search;
- STORAGE_CLASS scls;
if (!of)
{
nlr = 1;
}
+ dbuf_init (&dbuf, 1024);
+ dbuf_printTypeChain (start, &dbuf);
+ dbuf_write_and_destroy (&dbuf, of);
+
+ if (nlr)
+ putc ('\n', of);
+}
+
+void
+dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
+{
+ value *args;
+ sym_link * type, * search;
+ STORAGE_CLASS scls;
+
if (start==NULL) {
- fprintf (of, "void");
+ dbuf_append_str (dbuf, "void");
return;
}
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;
+ case S_DATA: dbuf_append_str (dbuf, "data-"); break;
+ case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break;
+ case S_SFR: dbuf_append_str (dbuf, "sfr-"); break;
+ case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break;
+ case S_CODE: dbuf_append_str (dbuf, "code-"); break;
+ case S_IDATA: dbuf_append_str (dbuf, "idata-"); break;
+ case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break;
+ case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break;
+ case S_STACK: dbuf_append_str (dbuf, "stack-"); break;
+ case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break;
+ case S_BIT: dbuf_append_str (dbuf, "bit-"); break;
+ case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break;
default: break;
}
}
{
if (!IS_FUNC(type)) {
if (DCL_PTR_VOLATILE (type)) {
- fprintf (of, "volatile-");
+ dbuf_append_str (dbuf, "volatile-");
}
if (DCL_PTR_CONST (type)) {
- fprintf (of, "const-");
+ dbuf_append_str (dbuf, "const-");
}
}
switch (DCL_TYPE (type))
{
case FUNCTION:
- fprintf (of, "function %s %s",
+ dbuf_printf (dbuf, "function %s %s",
(IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
(IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
- fprintf (of, "( ");
+ dbuf_append_str (dbuf, "( ");
for (args = FUNC_ARGS(type);
args;
args=args->next) {
- printTypeChain(args->type, of);
+ dbuf_printTypeChain(args->type, dbuf);
if (args->next)
- fprintf(of, ", ");
+ dbuf_append_str (dbuf, ", ");
}
- fprintf (of, ") ");
+ dbuf_append_str (dbuf, ") ");
break;
case GPOINTER:
- fprintf (of, "generic* ");
+ dbuf_append_str (dbuf, "generic* ");
break;
case CPOINTER:
- fprintf (of, "code* ");
+ dbuf_append_str (dbuf, "code* ");
break;
case FPOINTER:
- fprintf (of, "xdata* ");
+ dbuf_append_str (dbuf, "xdata* ");
break;
case EEPPOINTER:
- fprintf (of, "eeprom* ");
+ dbuf_append_str (dbuf, "eeprom* ");
break;
case POINTER:
- fprintf (of, "near* ");
+ dbuf_append_str (dbuf, "near* ");
break;
case IPOINTER:
- fprintf (of, "idata* ");
+ dbuf_append_str (dbuf, "idata* ");
break;
case PPOINTER:
- fprintf (of, "pdata* ");
+ dbuf_append_str (dbuf, "pdata* ");
break;
case UPOINTER:
- fprintf (of, "unknown* ");
+ dbuf_append_str (dbuf, "unknown* ");
break;
case ARRAY:
if (DCL_ELEM(type)) {
- fprintf (of, "[%d] ", DCL_ELEM(type));
+ dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type));
} else {
- fprintf (of, "[] ");
+ dbuf_append_str (dbuf, "[] ");
}
break;
}
else
{
if (SPEC_VOLATILE (type))
- fprintf (of, "volatile-");
+ dbuf_append_str (dbuf, "volatile-");
if (SPEC_CONST (type))
- fprintf (of, "const-");
+ dbuf_append_str (dbuf, "const-");
if (SPEC_USIGN (type))
- fprintf (of, "unsigned-");
+ dbuf_append_str (dbuf, "unsigned-");
switch (SPEC_NOUN (type))
{
case V_INT:
if (IS_LONG (type))
- fprintf (of, "long-");
- fprintf (of, "int");
+ dbuf_append_str (dbuf, "long-");
+ dbuf_append_str (dbuf, "int");
break;
case V_CHAR:
- fprintf (of, "char");
+ dbuf_append_str (dbuf, "char");
break;
case V_VOID:
- fprintf (of, "void");
+ dbuf_append_str (dbuf, "void");
break;
case V_FLOAT:
- fprintf (of, "float");
+ dbuf_append_str (dbuf, "float");
break;
case V_FIXED16X16:
- fprintf (of, "fixed16x16");
+ dbuf_append_str (dbuf, "fixed16x16");
break;
case V_STRUCT:
- fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
+ dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
break;
case V_SBIT:
- fprintf (of, "sbit");
+ dbuf_append_str (dbuf, "sbit");
break;
case V_BIT:
- fprintf (of, "bit");
+ dbuf_append_str (dbuf, "bit");
break;
case V_BITFIELD:
- fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
+ dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
break;
case V_DOUBLE:
- fprintf (of, "double");
+ dbuf_append_str (dbuf, "double");
break;
default:
- fprintf (of, "unknown type");
+ dbuf_append_str (dbuf, "unknown type");
break;
}
}
search = search->next;
type = search;
if (type)
- fputc (' ', of);
+ dbuf_append_char(dbuf, ' ');
}
- if (nlr)
- fprintf (of, "\n");
}
/*--------------------------------------------------------------------*/
/* 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;
{
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 */
" expected %s, got %s\n",
macro, args, file, line,
DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
- exit(-1);
+ exit(EXIT_FAILURE);
return l; // never reached, makes compiler happy.
}