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);
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);
}
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);
{
/* previous definition extern ? */
- if (1 || IS_EXTERN (csym->etype))
+ if (IS_EXTERN (csym->etype))
{
/* do types match ? */
if (checkType (csym->type, sym->type) != 1)
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;