{
case V_INT: {
if (SPEC_LONG(sl)) return "long";
- if (SPEC_SHORT(sl)) return "short";
+ if (sl->select.s._short) return "short";
return "int";
}
case V_FLOAT: return "float";
void *sym,
char *sname,
int level,
- int block)
+ int block,
+ int checkType)
{
int i; /* index into the hash Table */
bucket *bp; /* temp bucket * */
- checkTypeSanity(((symbol *)sym)->etype, sname);
+ if (checkType) {
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "addSym: %s ", sname);
+ }
+ /* make sure the type is complete and sane */
+ checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
+ }
/* the symbols are always added at the head of the list */
i = hashKey (sname);
{
if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
{
- sym->etype = mergeSpec (sym->etype, head);
+ sym->etype = mergeSpec (sym->etype, head, sym->name);
}
else
{
checkTypeSanity: prevent the user from doing e.g.:
unsigned float uf;
------------------------------------------------------------------*/
-void checkTypeSanity(sym_link *dest, char *name) {
+void checkTypeSanity(sym_link *etype, char *name) {
char *noun;
- if (!dest) {
- //printf ("sanity check skipped for %s\n", name);
+ if (!etype) {
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
+ }
+ return;
+ }
+
+ if (!IS_SPEC(etype)) {
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
+ }
return;
}
- noun=nounName(dest);
+ noun=nounName(etype);
- //printf ("checking sanity for %s\n", name);
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype);
+ }
- if ((SPEC_NOUN(dest)==V_CHAR ||
- SPEC_NOUN(dest)==V_FLOAT ||
- SPEC_NOUN(dest)==V_DOUBLE ||
- SPEC_NOUN(dest)==V_VOID) &&
- (SPEC_SHORT(dest) || SPEC_LONG(dest))) {
+ if ((SPEC_NOUN(etype)==V_CHAR ||
+ SPEC_NOUN(etype)==V_FLOAT ||
+ SPEC_NOUN(etype)==V_DOUBLE ||
+ SPEC_NOUN(etype)==V_VOID) &&
+ (etype->select.s._short || SPEC_LONG(etype))) {
// long or short for char float double or void
werror (E_LONG_OR_SHORT_INVALID, noun, name);
}
- if ((SPEC_NOUN(dest)==V_FLOAT ||
- SPEC_NOUN(dest)==V_DOUBLE ||
- SPEC_NOUN(dest)==V_VOID) &&
- (SPEC_SIGNED(dest) || SPEC_USIGN(dest))) {
+ if ((SPEC_NOUN(etype)==V_FLOAT ||
+ SPEC_NOUN(etype)==V_DOUBLE ||
+ SPEC_NOUN(etype)==V_VOID) &&
+ (etype->select.s._signed || SPEC_USIGN(etype))) {
// signed or unsigned for float double or void
werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
}
- if (SPEC_SIGNED(dest) && SPEC_USIGN(dest)) {
+
+ // special case for "short"
+ if (etype->select.s._short) {
+ SPEC_NOUN(etype) = options.shortisint ? V_INT : V_CHAR;
+ etype->select.s._short = 0;
+ }
+
+ /* if no noun e.g.
+ "const a;" or "data b;" or "signed s" or "long l"
+ assume an int */
+ if (!SPEC_NOUN(etype)) {
+ SPEC_NOUN(etype)=V_INT;
+ }
+
+ if (etype->select.s._signed && SPEC_USIGN(etype)) {
// signed AND unsigned
werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
}
- if (SPEC_SHORT(dest) && SPEC_LONG(dest)) {
+ if (etype->select.s._short && SPEC_LONG(etype)) {
// short AND long
werror (E_LONG_AND_SHORT_INVALID, noun, name);
}
/* mergeSpec - merges two specifiers and returns the new one */
/*------------------------------------------------------------------*/
sym_link *
-mergeSpec (sym_link * dest, sym_link * src)
+mergeSpec (sym_link * dest, sym_link * src, char *name)
{
- /* we shouldn't redeclare the type */
- if ((SPEC_NOUN (dest) && SPEC_NOUN (src)) &&
- (SPEC_NOUN(dest) != SPEC_NOUN(src))) {
- werror(E_TWO_OR_MORE_DATA_TYPES, yylval.yychar);
+ if (getenv("DEBUG_mergeSpec")) {
+ fprintf (stderr, "mergeSpec: \"%s\"\n", name);
}
- /* if noun different then src overrides */
- if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest))
- SPEC_NOUN (dest) = SPEC_NOUN (src);
+ if (SPEC_NOUN(src)) {
+ if (!SPEC_NOUN(dest)) {
+ SPEC_NOUN(dest)=SPEC_NOUN(src);
+ } else {
+ /* we shouldn't redeclare the type */
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "mergeSpec: ");
+ }
+ werror(E_TWO_OR_MORE_DATA_TYPES, name);
+ }
+ }
+
+ if (SPEC_SCLS(src)) {
+ /* if destination has no storage class */
+ if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
+ SPEC_SCLS (dest) = SPEC_SCLS (src);
+ } else {
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "mergeSpec: ");
+ }
+ werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
+ }
+ }
- /* if destination has no storage class */
- if (!SPEC_SCLS (dest) ||
- ((SPEC_SCLS(dest) == S_CONSTANT || SPEC_SCLS(dest) == S_REGISTER) &&
- SPEC_SCLS (src)))
- SPEC_SCLS (dest) = SPEC_SCLS (src);
- /* special case for const */
/* copy all the specifications */
+
+ // we really should do:
+#if 0
+ if (SPEC_what(src)) {
+ if (SPEC_what(dest)) {
+ werror(W_DUPLICATE_SPEC, "what");
+ }
+ SPEC_what(dst)|=SPEC_what(src);
+ }
+#endif
+ // but there are more important thing right now
+
SPEC_LONG (dest) |= SPEC_LONG (src);
- SPEC_SHORT (dest) |= SPEC_SHORT (src);
+ dest->select.s._short|=src->select.s._short;
SPEC_USIGN (dest) |= SPEC_USIGN (src);
- SPEC_SIGNED (dest) |= SPEC_SIGNED (src);
+ dest->select.s._signed|=src->select.s._signed;
SPEC_STAT (dest) |= SPEC_STAT (src);
SPEC_EXTR (dest) |= SPEC_EXTR (src);
SPEC_ABSA (dest) |= SPEC_ABSA (src);
switch (SPEC_NOUN (p))
{ /* depending on the specifier type */
case V_INT:
- return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE));
+ return (IS_LONG (p) ? LONGSIZE : INTSIZE);
case V_FLOAT:
return FLOATSIZE;
case V_CHAR:
switch (SPEC_NOUN (p))
{ /* depending on the specifier type */
case V_INT:
- return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8));
+ return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
case V_FLOAT:
return FLOATSIZE * 8;
case V_CHAR:
{
/* previous definition extern ? */
- if (1 || IS_EXTERN (csym->etype))
+ if (IS_EXTERN (csym->etype))
{
/* do types match ? */
if (checkType (csym->type, sym->type) != 1)
/* delete current entry */
deleteSym (SymbolTab, csym, csym->name);
/* add new entry */
- addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
+ addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
}
else /* not extern */
werror (E_DUPLICATE, sym->name);
werror (W_EXTERN_MISMATCH, csym->name);
}
}
- addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
+ addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
}
}
static void
checkSClass (symbol * sym)
{
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "checkSClass: %s \n", sym->name);
+ }
+ if (strcmp(sym->name, "_testsGlobal")==0) {
+ printf ("oach\n");
+ }
+
/* type is literal can happen foe 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 */
sym->ival = NULL;
}
}
-
+
/* if absolute address given then it mark it as
volatile */
if (IS_ABSOLUTE (sym->etype))
SPEC_VOLATILE (sym->etype) = 1;
-
+
/* global variables declared const put into code */
if (sym->level == 0 &&
- SPEC_SCLS (sym->etype) == S_CONSTANT)
- {
- SPEC_SCLS (sym->etype) = S_CODE;
- SPEC_CONST (sym->etype) = 1;
- }
-
+ SPEC_CONST (sym->etype)) {
+ 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;
-
+
/* if bit variable then no storage class can be */
/* specified since bit is already a storage */
SPEC_SCLS (sym->etype) != S_FIXED &&
SPEC_SCLS (sym->etype) != S_REGISTER &&
SPEC_SCLS (sym->etype) != S_STACK &&
- SPEC_SCLS (sym->etype) != S_XSTACK &&
- SPEC_SCLS (sym->etype) != S_CONSTANT))
+ SPEC_SCLS (sym->etype) != S_XSTACK))
{
werror (E_AUTO_ASSUMED, sym->name);
SPEC_SCLS (sym->etype) = S_AUTO;
}
-
+
/* automatic symbols cannot be given */
/* an absolute address ignore it */
if (sym->level &&
SPEC_NOUN (src) == V_VOID)
return -1;
- /* char === to short */
- if (SPEC_NOUN (dest) == V_CHAR &&
- SPEC_NOUN (src) == V_INT &&
- SPEC_SHORT (src))
- return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
-
- if (SPEC_NOUN (src) == V_CHAR &&
- SPEC_NOUN (dest) == V_INT &&
- SPEC_SHORT (dest))
- return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
-
/* if they are both bitfields then if the lengths
and starts don't match */
if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
if (SPEC_LONG (dest) != SPEC_LONG (src))
return -1;
- if (SPEC_SHORT (dest) != SPEC_SHORT (src))
- return -1;
-
if (SPEC_USIGN (dest) != SPEC_USIGN (src))
return -2;
}
/*------------------------------------------------------------------*/
-/* inCalleeSaveList - return 1 if found in calle save list */
+/* inCalleeSaveList - return 1 if found in callee save list */
/*------------------------------------------------------------------*/
bool
inCalleeSaveList (char *s)
{
symbol *csym;
value *exargs, *acargs;
+ value *checkValue;
int argCnt = 0;
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "checkFunction: %s ", sym->name);
+ }
+
+ /* make sure the type is complete and sane */
+ checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
+
/* if not type then some kind of error */
if (!sym->type)
return 0;
if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
{
werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
- return 0;
}
if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
{
werror (E_PREV_DEF_CONFLICT, csym->name, "using");
- return 0;
+ }
+
+ if (SPEC_NAKED (csym->etype) != SPEC_NAKED (sym->etype))
+ {
+ werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
}
/* compare expected agrs with actual args */
exargs && acargs;
exargs = exargs->next, acargs = acargs->next, argCnt++)
{
- value *checkValue;
+ if (getenv("DEBUG_SANITY")) {
+ fprintf (stderr, "checkFunction: %s ", exargs->name);
+ }
+ /* make sure the type is complete and sane */
+ checkTypeSanity(exargs->etype, exargs->name);
+
/* If the actual argument is an array, any prototype
* will have modified it to a pointer. Duplicate that
* change here.
/* replace with this defition */
sym->cdef = csym->cdef;
deleteSym (SymbolTab, csym, csym->name);
- addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
+ addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
if (IS_EXTERN (csym->etype) && !
IS_EXTERN (sym->etype))
{
case V_INT:
if (IS_LONG (type))
fprintf (of, "long ");
- if (IS_SHORT (type))
- fprintf (of, "short ");
fprintf (of, "int ");
break;
case V_INT:
if (IS_LONG (type))
fprintf (of, "SL");
- else if (IS_SHORT (type))
- fprintf (of, "SS");
else
fprintf (of, "SI");
break;