#include <at89x2051.h> replaced by #include <8051.h>
[fw/sdcc] / src / SDCCsymt.c
index 07b39065482ad52a1a113c45d9a89debf013ed6f..bf7a5809103e09b0d31a8218d12a69830267e5aa 100644 (file)
@@ -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;