/* 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;
}
break;
}
/* the storage class of type ends here */
- SPEC_SCLS (type) =
+ SPEC_SCLS (type) =
SPEC_CONST (type) =
SPEC_VOLATILE (type) = 0;
}
}
else
{
- head = tail = newLink ();
+ head = tail = newLink (DECLARATOR);
DCL_TYPE (head) = type;
}
{
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));
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 ||
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");
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;
}
/*------------------------------------------------------------------*/
{
sym_link *p;
- p = newLink ();
- p->class = SPECIFIER;
+ p = newLink (SPECIFIER);
SPEC_NOUN (p) = V_CHAR;
return p;
{
sym_link *p;
- p = newLink ();
- p->class = SPECIFIER;
+ p = newLink (SPECIFIER);
SPEC_NOUN (p) = V_FLOAT;
return p;
{
sym_link *p;
- p = newLink ();
- p->class = SPECIFIER;
+ p = newLink (SPECIFIER);
SPEC_NOUN (p) = V_INT;
SPEC_LONG (p) = 1;
{
sym_link *p;
- p = newLink ();
- p->class = SPECIFIER;
+ p = newLink (SPECIFIER);
SPEC_NOUN (p) = V_INT;
return p;
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
/* 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_FIXED &&
+ !IS_FUNC(sym->type)) {
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) {
+ if (IS_SPEC(sym->type)) {
+ SPEC_CONST (sym->type) = 1;
+ } else {
+ DCL_PTR_CONST (sym->type) = 1;
+ }
+ }
/* if bit variable then no storage class can be */
/* specified since bit is already a storage */
* 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);
}
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;
}
}
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)) {
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))
sym_link *p = val->type;
werror (W_STRUCT_AS_ARG, val->name);
- val->type = newLink ();
+ val->type = newLink (DECLARATOR);
val->type->next = p;
}
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:
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 */
/*-----------------------------------------------------------------*/
val->sym->etype = getSpec (val->sym->type);
val->sym->_isparm = 1;
strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
- 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);
+ }
addSymChain (val->sym);
}
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);
{
int nlr = 0;
sym_link * type, * search;
+ STORAGE_CLASS scls;
if (!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)
;
+ scls=SPEC_SCLS(type);
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))
{
(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:
if (DCL_ELEM(type)) {
}
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;
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 */
-/*-----------------------------------------------------------------*/
-void
-cdbTypeInfo (sym_link * type, FILE * of)
-{
- fprintf (of, "{%d}", getSize (type));
- while (type)
- {
- if (IS_DECL (type))
- {
- switch (DCL_TYPE (type))
- {
- case FUNCTION:
- fprintf (of, "DF,");
- break;
- case GPOINTER:
- fprintf (of, "DG,");
- break;
- case CPOINTER:
- fprintf (of, "DC,");
- break;
- case FPOINTER:
- fprintf (of, "DX,");
- break;
- case POINTER:
- fprintf (of, "DD,");
- break;
- case IPOINTER:
- fprintf (of, "DI,");
- break;
- case PPOINTER:
- fprintf (of, "DP,");
- break;
- case EEPPOINTER:
- fprintf (of, "DA,");
- break;
- case ARRAY:
- fprintf (of, "DA%d,", DCL_ELEM (type));
- break;
- default:
- break;
- }
- }
- else
- {
- switch (SPEC_NOUN (type))
- {
- case V_INT:
- if (IS_LONG (type))
- fprintf (of, "SL");
- else
- fprintf (of, "SI");
- break;
-
- case V_CHAR:
- fprintf (of, "SC");
- break;
-
- case V_VOID:
- fprintf (of, "SV");
- break;
-
- case V_FLOAT:
- fprintf (of, "SF");
- break;
-
- case V_STRUCT:
- fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
- break;
-
- case V_SBIT:
- fprintf (of, "SX");
- break;
-
- case V_BIT:
- fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
- break;
-
- default:
- 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;
-
- 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 */
- }
- 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, "]");
- if (!inStruct)
- 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 */
/*-----------------------------------------------------------------*/
sym_link *typeFromStr (char *s)
{
- sym_link *r = newLink();
+ sym_link *r = newLink(DECLARATOR);
int usign = 0;
do {
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;
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;
}
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.
+}