* fixed GCC 4.4.0 mingw compilation:
[fw/sdcc] / src / SDCCsymt.c
index ab99e717b98978c45eb5bc8d5a5b49c8ce34b380..6692939f2cb1e7442958e6012b44d7726fd11d1d 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)
@@ -184,6 +184,7 @@ deleteSym (bucket ** stab, void *sym, char *sname)
 
   if (!bp)                      /* did not find it */
     return;
+
   /* if this is the first one in the chain */
   if (!bp->prev)
     {
@@ -199,11 +200,10 @@ deleteSym (bucket ** stab, void *sym, char *sname)
 
       bp->prev->next = bp->next;
     }
-
 }
 
 /*-----------------------------------------------------------------*/
-/* findSym - finds a symbol in a table           */
+/* findSym - finds a symbol in a table                             */
 /*-----------------------------------------------------------------*/
 void *
 findSym (bucket ** stab, void *sym, const char *sname)
@@ -592,7 +592,6 @@ void checkTypeSanity(sym_link *etype, char *name) {
     // short AND long
     werror (E_LONG_AND_SHORT_INVALID, noun, name);
   }
-
 }
 
 /*------------------------------------------------------------------*/
@@ -690,9 +689,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 +746,7 @@ newFloatLink ()
 }
 
 /*------------------------------------------------------------------*/
-/* newFixed16x16Link - a new Float type                                  */
+/* newFixed16x16Link - a new Float type                             */
 /*------------------------------------------------------------------*/
 sym_link *
 newFixed16x16Link ()
@@ -1007,7 +1006,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 +1031,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,23 +1081,20 @@ 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)
         {
           /* if not formal parameter and not in file scope
              then show symbol redefined error
-             else check if symbols have conpatible types */
+             else check if symbols have compatible types */
           if (!sym->_isparm && sym->level > 0)
             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 +1151,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 +1212,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,6 +1272,8 @@ compStructSize (int su, structdef * sdef)
     /* if this is a bit field  */
     if (loop->bitVar) {
 
+      SPEC_BUNNAMED (loop->etype) = loop->bitUnnamed;
+
       /* change it to a unsigned bit */
       SPEC_NOUN (loop->etype) = V_BITFIELD;
       /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
@@ -1281,16 +1281,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++;
@@ -1688,14 +1689,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 +1873,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 +2048,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 +2095,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 +2104,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 +2114,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 +2135,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 +2187,7 @@ compareType (sym_link * dest, sym_link * src)
     return -1;
 
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
-    return -1;
+    return -2;
 
   return 1;
 }
@@ -2298,7 +2324,7 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
   srcScls = SPEC_SCLS (src);
 
   /* Compensate for const to const code change in checkSClass() */
-  if (!level & port->mem.code_ro && SPEC_CONST (dest))
+  if ((!level & port->mem.code_ro) && SPEC_CONST (dest))
     {
       if (srcScls == S_CODE && destScls == S_FIXED)
         destScls = S_CODE;
@@ -2346,7 +2372,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 +2428,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;
@@ -3259,8 +3287,8 @@ symbol *__fps16x16_lteq;
 symbol *__fps16x16_gt;
 symbol *__fps16x16_gteq;
 
-/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
-symbol *__muldiv[3][3][2];
+/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */
+symbol *__muldiv[3][3][4];
 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
 sym_link *__multypes[3][2];
 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
@@ -3414,7 +3442,7 @@ initCSupport ()
   };
   const char *ssu[] =
   {
-    "s", "u"
+    "s", "su", "us", "u"
   };
   const char *srlrr[] =
   {
@@ -3484,12 +3512,12 @@ initCSupport ()
             {
               if (tofrom)
                 {
-                  SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su], sbwd[bwd]);
+                  SNPRINTF (buffer, sizeof(buffer), "__fs2%s%s", ssu[su*3], sbwd[bwd]);
                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
                 }
               else
                 {
-                  SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su], sbwd[bwd]);
+                  SNPRINTF (buffer, sizeof(buffer), "__%s%s2fs", ssu[su*3], sbwd[bwd]);
                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
                 }
             }
@@ -3504,7 +3532,7 @@ initCSupport ()
             {
               if (tofrom)
                 {
-                  SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]);
+                  SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su*3], fp16x16sbwd[bwd]);
                   if(bwd == 3) {
                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent);
                   } else
@@ -3512,7 +3540,7 @@ initCSupport ()
                 }
               else
                 {
-                  SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]);
+                  SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su*3], fp16x16sbwd[bwd]);
                   if(bwd == 3) {
                     __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent);
                   } else
@@ -3532,7 +3560,7 @@ initCSupport ()
               SNPRINTF (buffer, sizeof(buffer),
                         "_%s%s%s",
                        smuldivmod[muldivmod],
-                       ssu[su],
+                       ssu[su*3],
                        sbwd[bwd]);
               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
@@ -3544,7 +3572,34 @@ initCSupport ()
   Therefore they've been merged into mulint() and mullong().
 */
 
-  for (bwd = 0; bwd < 3; bwd++)
+  /* byte */
+  bwd = 0;
+  for (su = 0; su < 4; su++)
+    {
+      for (muldivmod = 0; muldivmod < 3; muldivmod++)
+        {
+          /* muluchar, mulschar, mulsuchar and muluschar are separate functions, because e.g. the z80
+             port is sign/zero-extending to int before calling mulint() */
+          /* div and mod : s8_t x s8_t -> s8_t should be s8_t x s8_t -> s16_t, see below */
+          if (!TARGET_IS_PIC16 || muldivmod != 1 || su != 0)
+            {
+              SNPRINTF (buffer, sizeof(buffer),
+                  "_%s%s%s",
+                  smuldivmod[muldivmod],
+                  ssu[su],
+                  sbwd[bwd]);
+              __muldiv[muldivmod][bwd][su] = funcOfType (
+                  _mangleFunctionName(buffer),
+                  __multypes[bwd][su%2],
+                  __multypes[bwd][su/2],
+                  2,
+                  options.intlong_rent);
+              FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
+            }
+        }
+    }
+
+  for (bwd = 1; bwd < 3; bwd++)
     {
       for (su = 0; su < 2; su++)
         {
@@ -3556,7 +3611,7 @@ initCSupport ()
                 SNPRINTF (buffer, sizeof(buffer),
                     "_%s%s%s",
                     smuldivmod[muldivmod],
-                    ssu[su],
+                    ssu[su*3],
                     sbwd[bwd]);
                 __muldiv[muldivmod][bwd][su] = funcOfType (
                     _mangleFunctionName(buffer),
@@ -3596,20 +3651,6 @@ initCSupport ()
 
   /* mul only */
   muldivmod = 0;
-  /* byte */
-  bwd = 0;
-  for (su = 0; su < 2; su++)
-    {
-      /* muluchar and mulschar are still separate functions, because e.g. the z80
-         port is sign/zero-extending to int before calling mulint() */
-      SNPRINTF (buffer, sizeof(buffer),
-                "_%s%s%s",
-                smuldivmod[muldivmod],
-                ssu[su],
-                sbwd[bwd]);
-      __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
-      FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
-    }
   /* signed only */
   su = 0;
   /* word and doubleword */
@@ -3635,7 +3676,7 @@ initCSupport ()
               SNPRINTF (buffer, sizeof(buffer),
                         "_%s%s%s",
                        srlrr[rlrr],
-                       ssu[su],
+                       ssu[su*3],
                        sbwd[bwd]);
               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;