X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=bf7a5809103e09b0d31a8218d12a69830267e5aa;hb=7366919ac40a593a5ebd3148197722410968ead8;hp=07b39065482ad52a1a113c45d9a89debf013ed6f;hpb=74bfe960542de56b1479c755682e23e9686abebf;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 07b39065..bf7a5809 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -103,8 +103,14 @@ addSym (bucket ** stab, int i; /* index into the hash Table */ bucket *bp; /* temp bucket * */ + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "addSym: %s ", sname); + } /* Make sure sym is a symbol and not a structdef */ - if (StructTab!=stab) checkTypeSanity(((symbol *)sym)->etype, sname); + if (1 || StructTab!=stab) { + /* 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); @@ -452,38 +458,67 @@ addDecl (symbol * sym, int type, sym_link * p) 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; } - noun=nounName(dest); + if (!IS_SPEC(etype)) { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name); + } + return; + } - //printf ("checking sanity for %s\n", name); + noun=nounName(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 (getenv("DEBUG_SANITY")) { + fprintf (stderr, "checking sanity for %s\n", name); + } + + if ((SPEC_NOUN(etype)==V_CHAR || + SPEC_NOUN(etype)==V_FLOAT || + SPEC_NOUN(etype)==V_DOUBLE || + SPEC_NOUN(etype)==V_VOID) && + (SPEC_SHORT(etype) || 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) && + (SPEC_SIGNED(etype) || 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)) { + + if (!SPEC_NOUN(etype)) { + // special case for just "signed" or "unsigned" or "long" + if (SPEC_SIGNED(etype) || SPEC_USIGN(etype) || SPEC_LONG(etype)) { + SPEC_NOUN(etype)=V_INT; + } + // special case for just "short" + if (SPEC_SHORT(etype)) { + SPEC_NOUN(etype)=V_CHAR; // or maybe V_INT + SPEC_SHORT(etype)=0; + } + } + + // if still no noun (e.g. "const a;" or "data b;") assume an int + if (!SPEC_NOUN(etype)) { + SPEC_NOUN(etype)=V_INT; + } + + if (SPEC_SIGNED(etype) && SPEC_USIGN(etype)) { // signed AND unsigned werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name); } - if (SPEC_SHORT(dest) && SPEC_LONG(dest)) { + if (SPEC_SHORT(etype) && SPEC_LONG(etype)) { // short AND long werror (E_LONG_AND_SHORT_INVALID, noun, name); } @@ -497,23 +532,43 @@ sym_link * mergeSpec (sym_link * dest, sym_link * src) { - /* 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 (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, yylval.yychar); + } + } + } + + 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, yylval.yychar); + } } - /* if noun different then src overrides */ - if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest)) - SPEC_NOUN (dest) = SPEC_NOUN (src); - - /* 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); SPEC_USIGN (dest) |= SPEC_USIGN (src); @@ -877,7 +932,7 @@ addSymChain (symbol * symHead) { /* previous definition extern ? */ - if (1 || IS_EXTERN (csym->etype)) + if (IS_EXTERN (csym->etype)) { /* do types match ? */ if (checkType (csym->type, sym->type) != 1) @@ -1544,6 +1599,13 @@ checkFunction (symbol * sym) value *exargs, *acargs; 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;