* src/SDCCsymt.c, src/SDCCglue.c,
[fw/sdcc] / src / SDCCsymt.c
index 1e02f3cdf913f7409b77673229d4ceaadd09b495..a27c0ec60c9f80a5486768c1f2b253fbbb6ec088 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,11 +1082,7 @@ addSymChain (symbol ** symHead)
             DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
         }
 
-      /* if already exists in the symbol table then check if
-           one of them is an extern definition;
-         if yes then then check if the type match;
-         if the types match then delete the current entry and
-           add the new entry */
+      /* if already exists in the symbol table on the same level */
       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
           csym->level == sym->level)
         {
@@ -1097,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)
                 {
@@ -1156,6 +1152,14 @@ addSymChain (symbol ** symHead)
           if (csym->ival && !sym->ival)
             sym->ival = csym->ival;
 
+          if (!csym->cdef && !sym->cdef && IS_EXTERN (sym->etype))
+            {
+              /* 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);
+            }
+
           /* delete current entry */
           deleteSym (SymbolTab, csym, csym->name);
           deleteFromSeg(csym);
@@ -1209,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
@@ -1274,16 +1280,17 @@ compStructSize (int su, structdef * sdef)
       if (!loop->etype->select.s.b_signed)
         SPEC_USIGN(loop->etype) = 1;
 
-      SPEC_BLEN (loop->etype) = loop->bitVar;
-
       if (loop->bitVar == BITVAR_PAD) {
         /* A zero length bitfield forces padding */
-        SPEC_BSTR (loop->etype) = bitOffset;
         SPEC_BLEN (loop->etype) = 0;
-        bitOffset = 8;
+        SPEC_BSTR (loop->etype) = bitOffset;
+        if (bitOffset > 0)
+          bitOffset = 8; /* padding is not needed when at bit 0 */
         loop->offset = sum;
       }
       else {
+        SPEC_BLEN (loop->etype) = loop->bitVar;
+
         if (bitOffset == 8) {
           bitOffset = 0;
           sum++;
@@ -1681,14 +1688,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 */
@@ -1865,7 +1872,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))
@@ -2040,8 +2047,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)
@@ -2067,7 +2094,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))
@@ -2076,7 +2103,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))
             {
@@ -2086,7 +2113,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));
@@ -2105,6 +2134,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)))
@@ -2154,7 +2186,7 @@ compareType (sym_link * dest, sym_link * src)
     return -1;
 
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
-    return -1;
+    return -2;
 
   return 1;
 }
@@ -2339,7 +2371,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)
@@ -2395,6 +2427,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;