* device/include/pic16/{pic18f2480.h, pic18f2580.h, pic18f4423.h,
[fw/sdcc] / src / SDCCsymt.c
index ab99e717b98978c45eb5bc8d5a5b49c8ce34b380..94ad4d70705893e2e8879f845a49f35395165c9f 100644 (file)
@@ -81,7 +81,7 @@ initSymt ()
 
 }
 /*-----------------------------------------------------------------*/
-/* newBucket - allocates & returns a new bucket        */
+/* newBucket - allocates & returns a new bucket                    */
 /*-----------------------------------------------------------------*/
 bucket *
 newBucket ()
@@ -118,7 +118,7 @@ addSym (bucket ** stab,
         int checkType)
 {
   int i;                        /* index into the hash Table */
-  bucket *bp;                   /* temp bucket    *         */
+  bucket *bp;                   /* temp bucket    *          */
 
   if (checkType) {
     symbol *csym = (symbol *)sym;
@@ -141,8 +141,8 @@ addSym (bucket ** stab,
   /* get a free entry */
   bp = Safe_alloc ( sizeof (bucket));
 
-  bp->sym = sym;                /* update the symbol pointer  */
-  bp->level = level;            /* update the nest level      */
+  bp->sym = sym;                /* update the symbol pointer */
+  bp->level = level;            /* update the nest level     */
   bp->block = block;
   strncpyz (bp->name, sname, sizeof(bp->name)); /* copy the name into place */
 
@@ -163,7 +163,7 @@ addSym (bucket ** stab,
 }
 
 /*-----------------------------------------------------------------*/
-/* deleteSym - deletes a symbol from the hash Table  entry     */
+/* deleteSym - deletes a symbol from the hash Table entry          */
 /*-----------------------------------------------------------------*/
 void
 deleteSym (bucket ** stab, void *sym, char *sname)
@@ -203,7 +203,7 @@ deleteSym (bucket ** stab, void *sym, char *sname)
 }
 
 /*-----------------------------------------------------------------*/
-/* findSym - finds a symbol in a table           */
+/* findSym - finds a symbol in a table                             */
 /*-----------------------------------------------------------------*/
 void *
 findSym (bucket ** stab, void *sym, const char *sname)
@@ -690,9 +690,9 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   return dest;
 }
 
-/*------------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
 /* genSymName - generates and returns a name used for anonymous vars */
-/*------------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
 char *
 genSymName (int level)
 {
@@ -747,7 +747,7 @@ newFloatLink ()
 }
 
 /*------------------------------------------------------------------*/
-/* newFixed16x16Link - a new Float type                                  */
+/* newFixed16x16Link - a new Float type                             */
 /*------------------------------------------------------------------*/
 sym_link *
 newFixed16x16Link ()
@@ -1007,7 +1007,7 @@ copySymbol (symbol * src)
 }
 
 /*------------------------------------------------------------------*/
-/* reverseSyms - reverses the links for a symbol chain      */
+/* reverseSyms - reverses the links for a symbol chain              */
 /*------------------------------------------------------------------*/
 symbol *
 reverseSyms (symbol * sym)
@@ -1032,7 +1032,7 @@ reverseSyms (symbol * sym)
 }
 
 /*------------------------------------------------------------------*/
-/* reverseLink - reverses the links for a type chain        */
+/* reverseLink - reverses the links for a type chain                */
 /*------------------------------------------------------------------*/
 sym_link *
 reverseLink (sym_link * type)
@@ -1082,10 +1082,7 @@ addSymChain (symbol ** symHead)
             DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
         }
 
-      /* if already exists in the symbol table
-         then check if the type match;
-         if yes then if at least one is not extern
-         set the new symbol to non extern  */
+      /* if already exists in the symbol table on the same level */
       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
           csym->level == sym->level)
         {
@@ -1096,9 +1093,9 @@ addSymChain (symbol ** symHead)
             error = 1;
           else
             {
-              /* If the previous definition was for an array with incomplete */
-              /* type, and the new definition has completed the type, update */
-              /* the original type to match */
+              /* If the previous definition was for an array with incomplete
+                 type, and the new definition has completed the type, update
+                 the original type to match */
               if (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
                   && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
                 {
@@ -1155,12 +1152,12 @@ addSymChain (symbol ** symHead)
           if (csym->ival && !sym->ival)
             sym->ival = csym->ival;
 
-          if (!sym->cdef && IS_EXTERN (sym->etype))
+          if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype))
             {
-              /* set the new symbol to not extern if not a compiler defined function
-                and at least one is non extern */
+              /* if none of symbols is a compiler defined function
+                 and at least one is not extern
+                 then set the new symbol to non extern */
               SPEC_EXTR(sym->etype) = SPEC_EXTR(csym->etype);
-              sym->cdef = csym->cdef;
             }
 
           /* delete current entry */
@@ -1216,6 +1213,8 @@ structElemType (sym_link * stype, value * id)
             etype = getSpec (type);
             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
+            SPEC_OCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
+                                 SPEC_OCLS (etype) : SPEC_OCLS (petype));
             if (IS_SPEC (type))
               SPEC_CONST (type) |= SPEC_CONST (stype);
             else
@@ -1688,14 +1687,14 @@ changePointer (sym_link * p)
 }
 
 /*------------------------------------------------------------------*/
-/* checkDecl - does semantic validation of a declaration                   */
+/* checkDecl - does semantic validation of a declaration            */
 /*------------------------------------------------------------------*/
 int
 checkDecl (symbol * sym, int isProto)
 {
 
-  checkSClass (sym, isProto);           /* check the storage class      */
-  changePointer (sym->type);          /* change pointers if required */
+  checkSClass (sym, isProto);        /* check the storage class     */
+  changePointer (sym->type);         /* change pointers if required */
 
   /* if this is an array without any dimension
      then update the dimension from the initial value */
@@ -1872,7 +1871,7 @@ computeType (sym_link * type1, sym_link * type2,
   /* if both are bitvars choose the larger one */
   else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
     rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
-            copyLinkChain (type1) : copyLinkChain (type1);
+            copyLinkChain (type1) : copyLinkChain (type2);
 
   /* if only one of them is a bit variable then the other one prevails */
   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
@@ -2047,8 +2046,28 @@ computeType (sym_link * type1, sym_link * type2,
   return rType;
 }
 
+int
+comparePtrType (sym_link * dest, sym_link * src, bool bMustCast)
+{
+  int res;
+
+  if (IS_VOID (src->next) && IS_VOID (dest->next))
+    return bMustCast ? -1 : 1;
+  if ((IS_VOID (src->next) && !IS_VOID (dest->next)) ||
+      (!IS_VOID (src->next) && IS_VOID (dest->next)) )
+    return -1;
+  res = compareType (dest->next, src->next);
+  if (res == 1)
+    return bMustCast ? -1 : 1;
+  else if (res == -2)
+    return -2;
+  else
+    return 0;
+}
+
 /*--------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match, -1 if castable */
+/* compareType - will do type check return 1 if match, 0 if no match, */
+/*               -1 if castable, -2 if only signedness differs        */
 /*--------------------------------------------------------------------*/
 int
 compareType (sym_link * dest, sym_link * src)
@@ -2074,7 +2093,7 @@ compareType (sym_link * dest, sym_link * src)
                 return -1;
               if (IS_FUNC (dest->next) && IS_VOID(src->next))
                 return -1;
-              return compareType (dest->next, src->next);
+              return comparePtrType(dest, src, FALSE);
             }
 
           if (DCL_TYPE (src) == DCL_TYPE (dest))
@@ -2083,7 +2102,7 @@ compareType (sym_link * dest, sym_link * src)
                 {
                   //checkFunction(src,dest);
                 }
-              return compareType (dest->next, src->next);
+              return comparePtrType(dest, src, FALSE);
             }
           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
             {
@@ -2093,7 +2112,9 @@ compareType (sym_link * dest, sym_link * src)
               (IS_GENPTR (dest) ||
                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
              ))
-            return -1;
+            {
+              return comparePtrType(dest, src, TRUE);
+            }
           if (IS_PTR (dest) && IS_ARRAY (src))
             {
               value *val=aggregateToPointer (valFromType(src));
@@ -2112,6 +2133,9 @@ compareType (sym_link * dest, sym_link * src)
         return 0;
     }
 
+  if (IS_PTR (src) && IS_VOID (dest))
+    return -1;
+
   /* if one is a specifier and the other is not */
   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
       (IS_SPEC (dest) && !IS_SPEC (src)))
@@ -2161,7 +2185,7 @@ compareType (sym_link * dest, sym_link * src)
     return -1;
 
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
-    return -1;
+    return -2;
 
   return 1;
 }
@@ -2346,7 +2370,7 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
 }
 
 /*------------------------------------------------------------------*/
-/* inCalleeSaveList - return 1 if found in callee save list          */
+/* inCalleeSaveList - return 1 if found in callee save list         */
 /*------------------------------------------------------------------*/
 static int
 calleeCmp(void *p1, void *p2)
@@ -2402,6 +2426,8 @@ aggregateToPointer (value * val)
           }
           break;
         case S_AUTO:
+          DCL_TYPE (val->type) = PTR_TYPE(SPEC_OCLS(val->etype));
+          break;
         case S_DATA:
         case S_REGISTER:
           DCL_TYPE (val->type) = POINTER;