* fixed GCC 4.4.0 mingw compilation:
[fw/sdcc] / src / SDCCsymt.c
index 40e1fed661ed02d3e1d3172c0342813453db5a8c..72f323ab3437b7d0de6f0fec90d132b1d5ffc86b 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "common.h"
 #include "newalloc.h"
+#include "dbuf_string.h"
 
 #include "SDCCsymt.h"
 
@@ -39,7 +40,7 @@ void printFromToType(sym_link *from, sym_link *to) {
 
 /* noun strings */
 char *nounName(sym_link *sl) {
-  switch (SPEC_NOUN(sl)) 
+  switch (SPEC_NOUN(sl))
     {
     case V_INT: {
       if (SPEC_LONG(sl)) return "long";
@@ -69,7 +70,7 @@ bucket *enumTab[256];           /* enumerated    table  */
 /*------------------------------------------------------------------*/
 /* initSymt () - initialises symbol table related stuff             */
 /*------------------------------------------------------------------*/
-void 
+void
 initSymt ()
 {
   int i = 0;
@@ -80,7 +81,7 @@ initSymt ()
 
 }
 /*-----------------------------------------------------------------*/
-/* newBucket - allocates & returns a new bucket        */
+/* newBucket - allocates & returns a new bucket                    */
 /*-----------------------------------------------------------------*/
 bucket *
 newBucket ()
@@ -95,7 +96,7 @@ newBucket ()
 /*-----------------------------------------------------------------*/
 /* hashKey - computes the hashkey given a symbol name              */
 /*-----------------------------------------------------------------*/
-int 
+int
 hashKey (const char *s)
 {
   unsigned long key = 0;
@@ -108,7 +109,7 @@ hashKey (const char *s)
 /*-----------------------------------------------------------------*/
 /* addSym - adds a symbol to the hash Table                        */
 /*-----------------------------------------------------------------*/
-void 
+void
 addSym (bucket ** stab,
         void *sym,
         char *sname,
@@ -117,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;
@@ -140,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 */
 
@@ -162,9 +163,9 @@ addSym (bucket ** stab,
 }
 
 /*-----------------------------------------------------------------*/
-/* deleteSym - deletes a symbol from the hash Table  entry     */
+/* deleteSym - deletes a symbol from the hash Table entry          */
 /*-----------------------------------------------------------------*/
-void 
+void
 deleteSym (bucket ** stab, void *sym, char *sname)
 {
   int i = 0;
@@ -183,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)
     {
@@ -198,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)
@@ -292,11 +293,11 @@ newSymbol (char *name, int scope)
 
   sym = Safe_alloc ( sizeof (symbol));
 
-  strncpyz (sym->name, name, sizeof(sym->name));        /* copy the name */
-  sym->level = scope;           /* set the level    */
+  strncpyz (sym->name, name, sizeof(sym->name)); /* copy the name */
+  sym->level = scope;           /* set the level */
   sym->block = currBlockno;
-  sym->lineDef = mylineno;      /* set the line number */
-  sym->fileDef = currFname;
+  sym->lineDef = lexLineno;    /* set the line number */
+  sym->fileDef = lexFilename;
   return sym;
 }
 
@@ -327,7 +328,7 @@ newStruct (char *tag)
   strncpyz (s->tag, tag, sizeof(s->tag));               /* copy the tag */
   return s;
 }
-  
+
 /*------------------------------------------------------------------*/
 /* sclsFromPtr - Return the storage class a pointer points into.    */
 /*               S_FIXED is returned for generic pointers or other  */
@@ -362,7 +363,7 @@ sclsFromPtr(sym_link *ptr)
 /*------------------------------------------------------------------*/
 /* pointerTypes - do the computation for the pointer types          */
 /*------------------------------------------------------------------*/
-void 
+void
 pointerTypes (sym_link * ptr, sym_link * type)
 {
   if (IS_SPEC (ptr))
@@ -375,7 +376,7 @@ pointerTypes (sym_link * ptr, sym_link * type)
   /* could not find it */
   if (!ptr || IS_SPEC (ptr))
     return;
-  
+
   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
     pointerTypes (ptr->next, type);
     return;
@@ -435,9 +436,10 @@ pointerTypes (sym_link * ptr, sym_link * type)
 /*------------------------------------------------------------------*/
 /* addDecl - adds a declarator @ the end of a chain                 */
 /*------------------------------------------------------------------*/
-void 
+void
 addDecl (symbol * sym, int type, sym_link * p)
 {
+  static sym_link *empty = NULL;
   sym_link *head;
   sym_link *tail;
   sym_link *t;
@@ -445,6 +447,9 @@ addDecl (symbol * sym, int type, sym_link * p)
   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
 
+  if (empty == NULL)
+    empty = newLink(SPECIFIER);
+
   /* if we are passed a link then set head & tail */
   if (p)
     {
@@ -464,28 +469,28 @@ addDecl (symbol * sym, int type, sym_link * p)
       sym->type = head;
       sym->etype = tail;
     }
+  else if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
+    {
+      sym->etype = mergeSpec (sym->etype, head, sym->name);
+    }
+  else if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
+    {
+      t = sym->type;
+      while (t->next != sym->etype)
+        t = t->next;
+      t->next = head;
+      tail->next = sym->etype;
+    }
+  else if (IS_FUNC (sym->type) && IS_SPEC (sym->type->next) &&
+           !memcmp(sym->type->next, empty, sizeof(sym_link)))
+    {
+      sym->type->next = head;
+      sym->etype = tail;
+    }
   else
     {
-      if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
-        {
-          sym->etype = mergeSpec (sym->etype, head, sym->name);
-        }
-      else
-        {
-          if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
-            {
-              t = sym->type;
-              while (t->next != sym->etype)
-                t = t->next;
-              t->next = head;
-              tail->next = sym->etype;
-            }
-          else
-            {
-              sym->etype->next = head;
-              sym->etype = tail;
-            }
-        }
+      sym->etype->next = head;
+      sym->etype = tail;
     }
 
   /* if the type is an unknown pointer and has
@@ -540,19 +545,19 @@ void checkTypeSanity(sym_link *etype, char *name) {
     fprintf (stderr, "checking sanity for %s %p\n", name, etype);
   }
 
-  if ((SPEC_NOUN(etype)==V_CHAR || 
-       SPEC_NOUN(etype)==V_FLOAT || 
+  if ((SPEC_NOUN(etype)==V_CHAR ||
+       SPEC_NOUN(etype)==V_FLOAT ||
        SPEC_NOUN(etype)==V_FIXED16X16 ||
-       SPEC_NOUN(etype)==V_DOUBLE || 
+       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(etype)==V_FLOAT || 
+  if ((SPEC_NOUN(etype)==V_FLOAT ||
        SPEC_NOUN(etype)==V_FIXED16X16 ||
-       SPEC_NOUN(etype)==V_DOUBLE || 
-       SPEC_NOUN(etype)==V_VOID) && 
+       SPEC_NOUN(etype)==V_DOUBLE ||
+       SPEC_NOUN(etype)==V_VOID) &&
       (etype->select.s.b_signed || SPEC_USIGN(etype))) {
     // signed or unsigned for float double or void
     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
@@ -564,7 +569,7 @@ void checkTypeSanity(sym_link *etype, char *name) {
     SPEC_SHORT(etype) = 0;
   }
 
-  /* if no noun e.g. 
+  /* if no noun e.g.
      "const a;" or "data b;" or "signed s" or "long l"
      assume an int */
   if (!SPEC_NOUN(etype)) {
@@ -580,14 +585,13 @@ void checkTypeSanity(sym_link *etype, char *name) {
   }
 
   if (etype->select.s.b_signed && SPEC_USIGN(etype)) {
-    // signed AND unsigned 
+    // signed AND unsigned
     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
   }
   if (SPEC_SHORT(etype) && SPEC_LONG(etype)) {
     // short AND long
     werror (E_LONG_AND_SHORT_INVALID, noun, name);
   }
-
 }
 
 /*------------------------------------------------------------------*/
@@ -618,7 +622,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
       werror(E_TWO_OR_MORE_DATA_TYPES, name);
     }
   }
-  
+
   if (SPEC_SCLS(src)) {
     /* if destination has no storage class */
     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
@@ -633,7 +637,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
 
   /* copy all the specifications  */
 
-  // we really should do: 
+  // we really should do:
 #if 0
   if (SPEC_what(src)) {
     if (SPEC_what(dest)) {
@@ -650,9 +654,11 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   dest->select.s.b_signed|=src->select.s.b_signed;
   SPEC_STAT (dest) |= SPEC_STAT (src);
   SPEC_EXTR (dest) |= SPEC_EXTR (src);
+  SPEC_INLINE (dest) |= SPEC_INLINE (src);
   SPEC_CONST(dest) |= SPEC_CONST (src);
   SPEC_ABSA (dest) |= SPEC_ABSA (src);
   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
+  SPEC_RESTRICT (dest) |= SPEC_RESTRICT (src);
   SPEC_ADDR (dest) |= SPEC_ADDR (src);
   SPEC_OCLS (dest) = SPEC_OCLS (src);
   SPEC_BLEN (dest) |= SPEC_BLEN (src);
@@ -661,11 +667,11 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   SPEC_ENUM (dest) |= SPEC_ENUM (src);
   if (SPEC_ARGREG(src) && !SPEC_ARGREG(dest))
       SPEC_ARGREG(dest) = SPEC_ARGREG(src);
-  
+
   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
 
-  /* these are the only function attributes that will be set 
+  /* these are the only function attributes that will be set
      in a specifier while parsing */
   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
   FUNC_BANKED(dest) |= FUNC_BANKED(src);
@@ -678,13 +684,14 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   FUNC_ISOVERLAY(dest) |= FUNC_ISOVERLAY(src);
   FUNC_INTNO(dest) |= FUNC_INTNO(src);
   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
+  FUNC_ISINLINE (dest) |= FUNC_ISINLINE (src);
 
   return dest;
 }
 
-/*------------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
 /* genSymName - generates and returns a name used for anonymous vars */
-/*------------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
 char *
 genSymName (int level)
 {
@@ -739,7 +746,7 @@ newFloatLink ()
 }
 
 /*------------------------------------------------------------------*/
-/* newFixed16x16Link - a new Float type                                  */
+/* newFixed16x16Link - a new Float type                             */
 /*------------------------------------------------------------------*/
 sym_link *
 newFixed16x16Link ()
@@ -798,7 +805,7 @@ newBoolLink ()
 /*------------------------------------------------------------------*/
 /* getSize - returns size of a type chain in bytes                  */
 /*------------------------------------------------------------------*/
-unsigned int 
+unsigned int
 getSize (sym_link * p)
 {
   /* if nothing return 0 */
@@ -839,7 +846,7 @@ getSize (sym_link * p)
       if (DCL_ELEM(p)) {
         return DCL_ELEM (p) * getSize (p->next);
       } else {
-          //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
+          //    werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
           //    "can not tell the size of an array[]");
         return 0;
       }
@@ -900,7 +907,7 @@ checkStructFlexArray (symbol *sym, sym_link *p)
 /*------------------------------------------------------------------*/
 /* bitsForType - returns # of bits required to store this type      */
 /*------------------------------------------------------------------*/
-unsigned int 
+unsigned int
 bitsForType (sym_link * p)
 {
   /* if nothing return 0 */
@@ -999,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)
@@ -1024,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)
@@ -1051,7 +1058,7 @@ reverseLink (sym_link * type)
 /*------------------------------------------------------------------*/
 /* addSymChain - adds a symbol chain to the symboltable             */
 /*------------------------------------------------------------------*/
-void 
+void
 addSymChain (symbol ** symHead)
 {
   symbol *sym = *symHead;
@@ -1066,83 +1073,103 @@ addSymChain (symbol ** symHead)
 
       if (!sym->level && !(IS_SPEC(sym->etype) && IS_TYPEDEF(sym->etype)))
         checkDecl (sym, 0);
-      
-      /* 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      */
+      else
+        {
+          /* if this is an array without any dimension
+             then update the dimension from the initial value */
+          if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
+            DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
+        }
+
+      /* if already exists in the symbol table on the same level */
       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
-          csym->level == sym->level) {
+          csym->level == sym->level)
+        {
+          /* if not formal parameter and not in file scope
+             then show symbol redefined error
+             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 (IS_DECL(csym->type) && DCL_TYPE(csym->type)==ARRAY
+                  && IS_DECL(sym->type) && DCL_TYPE(sym->type)==ARRAY)
+                {
+                  if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
+                    DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
+                }
 
-        /* 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)
-          {
-            if (!DCL_ELEM(csym->type) && DCL_ELEM(sym->type))
-              DCL_ELEM(csym->type) = DCL_ELEM(sym->type);
-          }
+              #if 0
+              /* If only one of the definitions used the "at" keyword, copy */
+              /* the address to the other. */
+              if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
+                  && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
+                {
+                  SPEC_ABSA (sym->etype) = 1;
+                  SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
+                }
+              if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
+                  && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
+                {
+                  SPEC_ABSA (csym->etype) = 1;
+                  SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
+                }
+              #endif
 
-        #if 0
-        /* If only one of the definitions used the "at" keyword, copy */
-        /* the address to the other. */
-        if (IS_SPEC(csym->etype) && SPEC_ABSA(csym->etype)
-            && IS_SPEC(sym->etype) && !SPEC_ABSA(sym->etype))
-          {
-            SPEC_ABSA (sym->etype) = 1;
-            SPEC_ADDR (sym->etype) = SPEC_ADDR (csym->etype);
-          }
-        if (IS_SPEC(csym->etype) && !SPEC_ABSA(csym->etype)
-            && IS_SPEC(sym->etype) && SPEC_ABSA(sym->etype))
-          {
-            SPEC_ABSA (csym->etype) = 1;
-            SPEC_ADDR (csym->etype) = SPEC_ADDR (sym->etype);
-          }
-        #endif
-  
-        error = 0;        
-        if (csym->ival && sym->ival)
-          error = 1;
-        if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
-          error = 1;
-        
-        if (error) {
-          /* one definition extern ? */
-          if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
-            werror (E_EXTERN_MISMATCH, sym->name);
-          else
-            werror (E_DUPLICATE, sym->name);
-          werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
-          #if 0
-          fprintf (stderr, "from type '");
-          printTypeChain (csym->type, stderr);
-          if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
-            fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
-          fprintf (stderr, "'\nto type '");
-          printTypeChain (sym->type, stderr);
-          if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
-            fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
-          fprintf (stderr, "'\n");
-          #endif
-          continue;
+              error = 0;
+              if (csym->ival && sym->ival)
+                error = 1;
+              if (compareTypeExact (csym->type, sym->type, sym->level) != 1)
+                error = 1;
+            }
+
+          if (error)
+            {
+              /* one definition extern ? */
+              if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
+                werror (E_EXTERN_MISMATCH, sym->name);
+              else
+                werror (E_DUPLICATE, sym->name);
+              werrorfl (csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
+              #if 0
+              fprintf (stderr, "from type '");
+              printTypeChain (csym->type, stderr);
+              if (IS_SPEC (csym->etype) && SPEC_ABSA (csym->etype))
+                fprintf(stderr, " at 0x%x", SPEC_ADDR (csym->etype));
+              fprintf (stderr, "'\nto type '");
+              printTypeChain (sym->type, stderr);
+              if (IS_SPEC (sym->etype) && SPEC_ABSA (sym->etype))
+                fprintf(stderr, " at 0x%x", SPEC_ADDR (sym->etype));
+              fprintf (stderr, "'\n");
+              #endif
+              continue;
+            }
+
+          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);
+
+          symPtrPtr = symHead;
+          while (*symPtrPtr && *symPtrPtr != csym)
+            symPtrPtr = &(*symPtrPtr)->next;
+          if (*symPtrPtr == csym)
+            *symPtrPtr = csym->next;
         }
 
-        if (csym->ival && !sym->ival)
-          sym->ival = csym->ival;
-
-        /* delete current entry */
-        deleteSym (SymbolTab, csym, csym->name);
-        deleteFromSeg(csym);
-        
-        symPtrPtr = symHead;
-        while (*symPtrPtr && *symPtrPtr != csym)
-          symPtrPtr = &(*symPtrPtr)->next;
-        if (*symPtrPtr == csym)
-          *symPtrPtr = csym->next;
-          
-      }
-      
       /* add new entry */
       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
     }
@@ -1152,7 +1179,7 @@ addSymChain (symbol ** symHead)
 /*------------------------------------------------------------------*/
 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
 /*------------------------------------------------------------------*/
-int 
+int
 funcInChain (sym_link * lnk)
 {
   while (lnk)
@@ -1175,7 +1202,7 @@ structElemType (sym_link * stype, value * id)
   sym_link *petype = getSpec (stype);
 
   if (fields && id) {
-    
+
     /* look for the id */
     while (fields)
       {
@@ -1185,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
@@ -1196,7 +1225,7 @@ structElemType (sym_link * stype, value * id)
   }
 
   werror (E_NOT_MEMBER, id->name);
-    
+
   // the show must go on
   return newIntLink();
 }
@@ -1221,134 +1250,137 @@ getStructElement (structdef * sdef, symbol * sym)
 /*------------------------------------------------------------------*/
 /* compStructSize - computes the size of a structure                */
 /*------------------------------------------------------------------*/
-int 
+int
 compStructSize (int su, structdef * sdef)
 {
-    int sum = 0, usum = 0;
-    int bitOffset = 0;
-    symbol *loop;
-
-    /* for the identifiers  */
-    loop = sdef->fields;
-    while (loop) {
+  int sum = 0, usum = 0;
+  int bitOffset = 0;
+  symbol *loop;
+
+  /* for the identifiers  */
+  loop = sdef->fields;
+  while (loop) {
+
+    /* create the internal name for this variable */
+    SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
+    if (su == UNION) {
+        sum = 0;
+        bitOffset = 0;
+    }
+    SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
+
+    /* 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: */
+      /* a "plain" int bitfield is unsigned */
+      if (!loop->etype->select.s.b_signed)
+        SPEC_USIGN(loop->etype) = 1;
+
+      if (loop->bitVar == BITVAR_PAD) {
+        /* A zero length bitfield forces padding */
+        SPEC_BLEN (loop->etype) = 0;
+        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;
 
-        /* create the internal name for this variable */
-        SNPRINTF (loop->rname, sizeof(loop->rname), "_%s", loop->name);
-        if (su == UNION) {
-            sum = 0;
-            bitOffset = 0;
+        if (bitOffset == 8) {
+          bitOffset = 0;
+          sum++;
         }
-        SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
-
-        /* if this is a bit field  */
-        if (loop->bitVar) {
-
-            /* change it to a unsigned bit */
-            SPEC_NOUN (loop->etype) = V_BITFIELD;
-            /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
-            /* a "plain" int bitfield is unsigned */
-            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;
-                loop->offset = sum;
-            }
-            else {
-                if (bitOffset == 8) {
-                    bitOffset = 0;
-                    sum++;
-                }
-                /* check if this fit into the remaining   */
-                /* bits of this byte else align it to the */
-                /* next byte boundary                     */
-                if (loop->bitVar <= (8 - bitOffset)) {
-                    /* fits into current byte */
-                    loop->offset = sum;
-                    SPEC_BSTR (loop->etype) = bitOffset;
-                    bitOffset += loop->bitVar;
-                }
-                else if (!bitOffset) {
-                    /* does not fit, but is already byte aligned */
-                    loop->offset = sum;
-                    SPEC_BSTR (loop->etype) = bitOffset;
-                    bitOffset += loop->bitVar;
-                } 
-                else {
-                                       if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
-                                               /* if PIC16 && enviroment variable is set, then
-                                                * tightly pack bitfields, this means that when a
-                                                * bitfield goes beyond byte alignment, do not
-                                                * automatically start allocatint from next byte,
-                                                * but also use the available bits first */
-                                               fprintf(stderr, ": packing bitfields in structures\n");
-                                               SPEC_BSTR (loop->etype) = bitOffset;
-                                               bitOffset += loop->bitVar;
-                                               loop->offset = (su == UNION ? sum = 0 : sum);
-                                       } else {
-                                               /* does not fit; need to realign first */
-                           sum++;
-                       loop->offset = (su == UNION ? sum = 0 : sum);
-                           bitOffset = 0;
-                       SPEC_BSTR (loop->etype) = bitOffset;
-                           bitOffset += loop->bitVar;
-                       }
-                }
-                while (bitOffset>8) {
-                    bitOffset -= 8;
-                    sum++;
-                } 
-            }
+        /* check if this fit into the remaining   */
+        /* bits of this byte else align it to the */
+        /* next byte boundary                     */
+        if (loop->bitVar <= (8 - bitOffset)) {
+          /* fits into current byte */
+          loop->offset = sum;
+          SPEC_BSTR (loop->etype) = bitOffset;
+          bitOffset += loop->bitVar;
+        }
+        else if (!bitOffset) {
+          /* does not fit, but is already byte aligned */
+          loop->offset = sum;
+          SPEC_BSTR (loop->etype) = bitOffset;
+          bitOffset += loop->bitVar;
         }
         else {
-            /* This is a non-bit field. Make sure we are */
-            /* byte aligned first */
-            if (bitOffset) {
-                sum++;
-                loop->offset = (su == UNION ? sum = 0 : sum);
-                bitOffset = 0;
-            }
-            loop->offset = sum;
-            checkDecl (loop, 1);
-            sum += getSize (loop->type);
-
-            /* search for "flexibel array members" */
-            /* and do some syntax checks */
-            if (   su == STRUCT
-                && checkStructFlexArray (loop, loop->type))
-              {
-                /* found a "flexible array member" */
-                sdef->b_flexArrayMember = TRUE;
-                /* is another struct-member following? */
-                if (loop->next)
-                  werror (E_FLEXARRAY_NOTATEND);
-                /* is it the first struct-member? */
-                else if (loop == sdef->fields)
-                  werror (E_FLEXARRAY_INEMPTYSTRCT);
-              }
+          if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
+            /* if PIC16 && enviroment variable is set, then
+             * tightly pack bitfields, this means that when a
+             * bitfield goes beyond byte alignment, do not
+             * automatically start allocatint from next byte,
+             * but also use the available bits first */
+            fprintf(stderr, ": packing bitfields in structures\n");
+            SPEC_BSTR (loop->etype) = bitOffset;
+            bitOffset += loop->bitVar;
+            loop->offset = (su == UNION ? sum = 0 : sum);
+          } else {
+            /* does not fit; need to realign first */
+            sum++;
+            loop->offset = (su == UNION ? sum = 0 : sum);
+            bitOffset = 0;
+            SPEC_BSTR (loop->etype) = bitOffset;
+            bitOffset += loop->bitVar;
+          }
         }
-
-        loop = loop->next;
-
-        /* if union then size = sizeof largest field */
-        if (su == UNION) {
-            /* For UNION, round up after each field */
-            sum += ((bitOffset+7)/8);
-            usum = max (usum, sum);
+        while (bitOffset>8) {
+          bitOffset -= 8;
+          sum++;
         }
+      }
+    }
+    else {
+      /* This is a non-bit field. Make sure we are */
+      /* byte aligned first */
+      if (bitOffset) {
+        sum++;
+        loop->offset = (su == UNION ? sum = 0 : sum);
+        bitOffset = 0;
+      }
+      loop->offset = sum;
+      checkDecl (loop, 1);
+      sum += getSize (loop->type);
+
+      /* search for "flexibel array members" */
+      /* and do some syntax checks */
+      if (   su == STRUCT
+          && checkStructFlexArray (loop, loop->type))
+        {
+          /* found a "flexible array member" */
+          sdef->b_flexArrayMember = TRUE;
+          /* is another struct-member following? */
+          if (loop->next)
+            werror (E_FLEXARRAY_NOTATEND);
+          /* is it the first struct-member? */
+          else if (loop == sdef->fields)
+            werror (E_FLEXARRAY_INEMPTYSTRCT);
+        }
+    }
 
+    loop = loop->next;
+
+    /* if union then size = sizeof largest field */
+    if (su == UNION) {
+      /* For UNION, round up after each field */
+      sum += ((bitOffset+7)/8);
+      usum = max (usum, sum);
     }
-    
-    /* For STRUCT, round up after all fields processed */
-    if (su != UNION)
-        sum += ((bitOffset+7)/8);
 
-    return (su == UNION ? usum : sum);
+  }
+
+  /* For STRUCT, round up after all fields processed */
+  if (su != UNION)
+    sum += ((bitOffset+7)/8);
+
+  return (su == UNION ? usum : sum);
 }
 
 /*-------------------------------------------------------------------*/
@@ -1375,12 +1407,12 @@ promoteAnonStructs (int su, structdef * sdef)
           /* Found an anonymous struct/union. Replace it */
           /* with the fields it contains and adjust all  */
           /* the offsets */
-          
+
           base = field->offset;
           subfield = copySymbolChain (SPEC_STRUCT (field->type)->fields);
           if (!subfield)
             continue;           /* just in case it's empty */
-          
+
           *tofield = subfield;
           for (;;)
             {
@@ -1399,7 +1431,7 @@ promoteAnonStructs (int su, structdef * sdef)
                     }
                   dupfield = dupfield->next;
                 }
-              
+
               subfield->offset += base;
               if (subfield->next)
                 subfield = subfield->next;
@@ -1419,27 +1451,44 @@ promoteAnonStructs (int su, structdef * sdef)
 /*------------------------------------------------------------------*/
 /* checkSClass - check the storage class specification              */
 /*------------------------------------------------------------------*/
-static void 
+static void
 checkSClass (symbol * sym, int isProto)
 {
   sym_link *t;
-  
+
   if (getenv("DEBUG_SANITY")) {
     fprintf (stderr, "checkSClass: %s \n", sym->name);
   }
-  
-  /* type is literal can happen for enums change
-     to auto */
+
+  /* type is literal can happen for enums change to auto */
   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
     SPEC_SCLS (sym->etype) = S_AUTO;
-  
+
   /* if sfr or sbit then must also be volatile */
   if (SPEC_SCLS (sym->etype) == S_SBIT ||
       SPEC_SCLS (sym->etype) == S_SFR)
     {
       SPEC_VOLATILE (sym->etype) = 1;
     }
-  
+
+  /* make sure restrict is only used with pointers */
+  if (SPEC_RESTRICT (sym->etype))
+    {
+      werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
+      SPEC_RESTRICT (sym->etype) = 0;
+    }
+  t = sym->type;
+  while (t)
+    {
+      if (IS_DECL (t) && DCL_PTR_RESTRICT (t) && !IS_PTR (t))
+        {
+          werrorfl (sym->fileDef, sym->lineDef, E_BAD_RESTRICT);
+          DCL_PTR_RESTRICT (t) = 0;
+          break;
+        }
+      t = t->next;
+    }
+
   /* if absolute address given then it mark it as
      volatile -- except in the PIC port */
 
@@ -1450,7 +1499,7 @@ checkSClass (symbol * sym, int isProto)
 
     if (IS_ABSOLUTE (sym->etype))
       SPEC_VOLATILE (sym->etype) = 1;
-  
+
   if (TARGET_IS_MCS51 &&
       IS_ABSOLUTE (sym->etype) &&
       SPEC_SCLS (sym->etype) == S_SFR)
@@ -1553,7 +1602,7 @@ checkSClass (symbol * sym, int isProto)
 
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
-  if (sym->level &&
+  if (sym->level && !IS_STATIC(sym->etype) &&
       SPEC_ABSA (sym->etype) &&
       (options.stackAuto || reentrant))
     {
@@ -1588,6 +1637,7 @@ checkSClass (symbol * sym, int isProto)
         //!sym->level &&
         port->mem.code_ro &&
         !IS_EXTERN (sym->etype) &&
+        !SPEC_ABSA (sym->etype) &&
         !funcInChain (sym->type))
       werror (E_CODE_NO_INIT, sym->name);
   }
@@ -1609,7 +1659,7 @@ checkSClass (symbol * sym, int isProto)
            * control this allocation, but the code was originally that way, and
            * changing it for non-390 ports breaks the compiler badly.
            */
-          bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
+          bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ?
                 1 : options.useXstack;
           SPEC_SCLS (sym->etype) = (useXdata ?
                                     S_XDATA : S_FIXED);
@@ -1620,7 +1670,7 @@ checkSClass (symbol * sym, int isProto)
 /*------------------------------------------------------------------*/
 /* changePointer - change pointer to functions                      */
 /*------------------------------------------------------------------*/
-void 
+void
 changePointer (sym_link * p)
 {
 
@@ -1639,14 +1689,14 @@ changePointer (sym_link * p)
 }
 
 /*------------------------------------------------------------------*/
-/* checkDecl - does semantic validation of a declaration                   */
+/* checkDecl - does semantic validation of a declaration            */
 /*------------------------------------------------------------------*/
-int 
+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 */
@@ -1682,7 +1732,7 @@ copyLinkChain (sym_link * p)
 /* cleanUpBlock - cleansup the symbol table specified for all the   */
 /*                symbols in the given block                        */
 /*------------------------------------------------------------------*/
-void 
+void
 cleanUpBlock (bucket ** table, int block)
 {
   int i;
@@ -1705,7 +1755,7 @@ cleanUpBlock (bucket ** table, int block)
 /* cleanUpLevel - cleansup the symbol table specified for all the   */
 /*                symbols in the given level                        */
 /*------------------------------------------------------------------*/
-void 
+void
 cleanUpLevel (bucket ** table, int level)
 {
   int i;
@@ -1739,7 +1789,7 @@ computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
       SPEC_USIGN (reType) = SPEC_USIGN (etype1);
       return reType;
     }
-  
+
   if (SPEC_USIGN (etype1))
     {
       if (   IS_LITERAL (etype2)
@@ -1819,12 +1869,12 @@ computeType (sym_link * type1, sym_link * type2,
     rType = newFloatLink ();
   else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
     rType = newFloatLink ();
-            
+
   /* 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))
     {
@@ -1862,6 +1912,17 @@ computeType (sym_link * type1, sym_link * type2,
 
   switch (resultType)
     {
+      case RESULT_TYPE_IFX:
+        if (TARGET_IS_HC08)
+          break;
+        //fallthrough
+      case RESULT_TYPE_BIT:
+        if (op == ':')
+          {
+            SPEC_NOUN (reType) = V_BIT;
+            return rType;
+          }
+        break;
       case RESULT_TYPE_CHAR:
         if (IS_BITVAR (reType))
           {
@@ -1957,7 +2018,7 @@ computeType (sym_link * type1, sym_link * type2,
                 2 * 100 =  200;
 
      - ToDo: document '|', '^' and '&'
-     
+
      Homework: - why is (200 * 200 < 0) true?
                - why is { char l = 200, r = 200; (r * l > 0) } true?
   */
@@ -1966,12 +2027,12 @@ computeType (sym_link * type1, sym_link * type2,
       && (   (SPEC_USIGN (etype1)
               /* if this operand is promoted to a larger type,
                  then it will be promoted to a signed type */
-              && !(getSize (etype1) < getSize (reType))
+              && !(bitsForType (etype1) < bitsForType (reType))
               /* char require special handling */
               && !IS_CHAR (etype1))
-          || /* same for 2nd operand */  
+          || /* same for 2nd operand */
              (SPEC_USIGN (etype2)
-              && !(getSize (etype2) < getSize (reType))
+              && !(bitsForType (etype2) < bitsForType (reType))
               && !IS_CHAR (etype2))
           || /* if both are 'unsigned char' and not promoted
                 let the result be unsigned too */
@@ -1987,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)
@@ -2014,30 +2095,36 @@ 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)) {
-            if (IS_FUNC(src)) {
-              //checkFunction(src,dest);
+          if (DCL_TYPE (src) == DCL_TYPE (dest))
+            {
+              if (IS_FUNC(src))
+                {
+                  //checkFunction(src,dest);
+                }
+              return comparePtrType(dest, src, FALSE);
             }
-            return compareType (dest->next, src->next);
-          }
-          if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next)) {
-            return -1;
-          }
-          if (IS_PTR (src) && 
+          if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
+            {
+              return -1;
+            }
+          if (IS_PTR (src) &&
               (IS_GENPTR (dest) ||
                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
              ))
-            return -1;
-          if (IS_PTR (dest) && IS_ARRAY (src)) {
-            value *val=aggregateToPointer (valFromType(src));
-            int res=compareType (dest, val->type);
-            Safe_free(val->type);
-            Safe_free(val);
-            return res;
-          }
+            {
+              return comparePtrType(dest, src, TRUE);
+            }
+          if (IS_PTR (dest) && IS_ARRAY (src))
+            {
+              value *val=aggregateToPointer (valFromType(src));
+              int res=compareType (dest, val->type);
+              Safe_free(val->type);
+              Safe_free(val);
+              return res;
+            }
           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
             return compareType (dest->next, src);
           return 0;
@@ -2048,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)))
@@ -2079,7 +2169,7 @@ compareType (sym_link * dest, sym_link * src)
              instead of the next two lines, but the regression tests fail with
              them; I guess it's a problem with replaceCheaperOp  */
           getSize (dest) == getSize (src) &&
-          !(!IS_BIT (dest) && IS_BIT (src)))
+          (IS_BIT (dest) == IS_BIT (src)))
         return 1;
       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
         return -1;
@@ -2097,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;
 }
@@ -2109,7 +2199,7 @@ int
 compareTypeExact (sym_link * dest, sym_link * src, int level)
 {
   STORAGE_CLASS srcScls, destScls;
-  
+
   if (!dest && !src)
     return 1;
 
@@ -2175,7 +2265,7 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
                   /* if one them ended we have a problem */
                   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
                       (!exargs && acargs && !IS_VOID (acargs->type)))
-                    return 0;                  
+                    return 0;
                   return 1;
               }
             return compareTypeExact (dest->next, src->next, level);
@@ -2212,7 +2302,7 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
       if (SPEC_SHORT (dest) != SPEC_SHORT (src))
         return 0;
     }
-  
+
   if (IS_STRUCT (dest))
     {
       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
@@ -2229,12 +2319,12 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
     return 0;
   if (SPEC_ABSA (dest) && SPEC_ADDR (dest) != SPEC_ADDR (src))
     return 0;
-      
+
   destScls = SPEC_SCLS (dest);
   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;
@@ -2242,12 +2332,12 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
         srcScls = S_CODE;
     }
 
-  /* compensate for allocGlobal() */  
+  /* compensate for allocGlobal() */
   if ((srcScls == S_FIXED || srcScls == S_AUTO)
       && port->mem.default_globl_map == xdata
       && !level)
     srcScls = S_XDATA;
-  
+
   if (level>0 && !SPEC_STAT (dest))
     {
       /* Compensate for hack-o-matic in checkSClass() */
@@ -2277,12 +2367,12 @@ compareTypeExact (sym_link * dest, sym_link * src, int level)
       #endif
       return 0;
     }
-  
+
   return 1;
 }
 
 /*------------------------------------------------------------------*/
-/* 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)
@@ -2299,8 +2389,8 @@ inCalleeSaveList(char *s)
 }
 
 /*-----------------------------------------------------------------*/
-/* aggregateToPointer:  change an agggregate type function      */
-/*         argument to a pointer to that type.     */
+/* aggregateToPointer:     change an aggregate type function       */
+/*                         argument to a pointer to that type.     */
 /*-----------------------------------------------------------------*/
 value *
 aggregateToPointer (value * val)
@@ -2338,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;
@@ -2354,7 +2446,7 @@ aggregateToPointer (value * val)
         default:
           DCL_TYPE (val->type) = port->unqualified_pointer;
         }
-      
+
       /* is there is a symbol associated then */
       /* change the type of the symbol as well */
       if (val->sym)
@@ -2368,7 +2460,7 @@ aggregateToPointer (value * val)
 /*------------------------------------------------------------------*/
 /* checkFunction - does all kinds of check on a function            */
 /*------------------------------------------------------------------*/
-int 
+int
 checkFunction (symbol * sym, symbol *csym)
 {
   value *exargs, *acargs;
@@ -2384,7 +2476,14 @@ checkFunction (symbol * sym, symbol *csym)
       werror(E_SYNTAX_ERROR, sym->name);
       return 0;
     }
-    
+
+  /* move inline specifier from return type to function attributes */
+  if (IS_INLINE (sym->etype))
+    {
+      SPEC_INLINE (sym->etype) = 0;
+      FUNC_ISINLINE (sym->type) = 1;
+    }
+
   /* make sure the type is complete and sane */
   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
 
@@ -2422,11 +2521,10 @@ checkFunction (symbol * sym, symbol *csym)
       werror (E_SHADOWREGS_NO_ISR, sym->name);
     }
 
-
-  for (argCnt=1, acargs = FUNC_ARGS(sym->type); 
-       acargs; 
+  for (argCnt=1, acargs = FUNC_ARGS(sym->type);
+       acargs;
        acargs=acargs->next, argCnt++) {
-    if (!acargs->sym) { 
+    if (!acargs->sym) {
       // this can happen for reentrant functions
       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
       // the show must go on: synthesize a name and symbol
@@ -2437,13 +2535,16 @@ checkFunction (symbol * sym, symbol *csym)
       acargs->sym->etype = getSpec (acargs->sym->type);
       acargs->sym->_isparm = 1;
       strncpyz (acargs->sym->rname, acargs->name, sizeof(acargs->sym->rname));
-    } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) { 
+    } else if (strcmp(acargs->sym->name, acargs->sym->rname)==0) {
       // synthesized name
       werror(E_PARAM_NAME_OMITTED, sym->name, argCnt);
     }
   }
   argCnt--;
 
+  /*JCF: Mark the register bank as used*/
+  RegBankUsed[FUNC_REGBANK (sym->type)] = 1;
+
   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
     return 1;                   /* not defined nothing more to check  */
 
@@ -2500,7 +2601,7 @@ checkFunction (symbol * sym, symbol *csym)
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs");
     }
-  
+
 
   /* compare expected args with actual args */
   exargs = FUNC_ARGS(csym->type);
@@ -2583,7 +2684,7 @@ void cdbStructBlock (int block)
 /*-----------------------------------------------------------------*/
 /* processFuncPtrArgs - does some processing with args of func ptrs*/
 /*-----------------------------------------------------------------*/
-void 
+void
 processFuncPtrArgs (sym_link * funcType)
 {
   value *val = FUNC_ARGS(funcType);
@@ -2599,7 +2700,7 @@ processFuncPtrArgs (sym_link * funcType)
 /*-----------------------------------------------------------------*/
 /* processFuncArgs - does some processing with function args       */
 /*-----------------------------------------------------------------*/
-void 
+void
 processFuncArgs (symbol * func)
 {
   value *val;
@@ -2641,10 +2742,10 @@ processFuncArgs (symbol * func)
     {
       int argreg = 0;
       char buffer[SDCC_NAME_MAX+1];
-      
+
       SNPRINTF (buffer, sizeof(buffer), "%s parameter %d", func->name, pNum);
       checkTypeSanity (val->etype, buffer);
-      
+
       /* mark it as a register parameter if
          the function does not have VA_ARG
          and as port dictates */
@@ -2689,7 +2790,7 @@ processFuncArgs (symbol * func)
       /* synthesize a variable name */
       if (!val->sym)
         {
-          SNPRINTF (val->name, sizeof(val->name), 
+          SNPRINTF (val->name, sizeof(val->name),
                     "_%s_PARM_%d", func->name, pNum++);
           val->sym = newSymbol (val->name, 1);
           if (SPEC_SCLS(val->etype) == S_BIT)
@@ -2721,7 +2822,7 @@ processFuncArgs (symbol * func)
           else
             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
               port->mem.default_local_map;
-          
+
           #if 0
           /* ?? static functions shouldn't imply static parameters - EEP */
           if (IS_SPEC(func->etype)) {
@@ -2743,7 +2844,7 @@ processFuncArgs (symbol * func)
 /*-----------------------------------------------------------------*/
 /* isSymbolEqual - compares two symbols return 1 if they match     */
 /*-----------------------------------------------------------------*/
-int 
+int
 isSymbolEqual (symbol * dest, symbol * src)
 {
   /* if pointers match then equal */
@@ -2772,10 +2873,8 @@ void PT(sym_link *type)
 void
 printTypeChain (sym_link * start, FILE * of)
 {
+  struct dbuf_s dbuf;
   int nlr = 0;
-  value *args;
-  sym_link * type, * search;
-  STORAGE_CLASS scls;
 
   if (!of)
     {
@@ -2783,8 +2882,23 @@ printTypeChain (sym_link * start, FILE * of)
       nlr = 1;
     }
 
+  dbuf_init (&dbuf, 1024);
+  dbuf_printTypeChain (start, &dbuf);
+  dbuf_write_and_destroy (&dbuf, of);
+
+  if (nlr)
+    putc ('\n', of);
+}
+
+void
+dbuf_printTypeChain (sym_link * start, struct dbuf_s *dbuf)
+{
+  value *args;
+  sym_link * type, * search;
+  STORAGE_CLASS scls;
+
   if (start==NULL) {
-    fprintf (of, "void");
+    dbuf_append_str (dbuf, "void");
     return;
   }
 
@@ -2802,20 +2916,20 @@ printTypeChain (sym_link * start, FILE * of)
   while (type)
     {
       if (type==start) {
-        switch (scls) 
+        switch (scls)
           {
-          case S_DATA: fprintf (of, "data-"); break;
-          case S_XDATA: fprintf (of, "xdata-"); break;
-          case S_SFR: fprintf (of, "sfr-"); break;
-          case S_SBIT: fprintf (of, "sbit-"); break;
-          case S_CODE: fprintf (of, "code-"); break;
-          case S_IDATA: fprintf (of, "idata-"); break;
-          case S_PDATA: fprintf (of, "pdata-"); break;
-          case S_LITERAL: fprintf (of, "literal-"); break;
-          case S_STACK: fprintf (of, "stack-"); break;
-          case S_XSTACK: fprintf (of, "xstack-"); break;
-          case S_BIT: fprintf (of, "bit-"); break;
-          case S_EEPROM: fprintf (of, "eeprom-"); break;
+          case S_DATA: dbuf_append_str (dbuf, "data-"); break;
+          case S_XDATA: dbuf_append_str (dbuf, "xdata-"); break;
+          case S_SFR: dbuf_append_str (dbuf, "sfr-"); break;
+          case S_SBIT: dbuf_append_str (dbuf, "sbit-"); break;
+          case S_CODE: dbuf_append_str (dbuf, "code-"); break;
+          case S_IDATA: dbuf_append_str (dbuf, "idata-"); break;
+          case S_PDATA: dbuf_append_str (dbuf, "pdata-"); break;
+          case S_LITERAL: dbuf_append_str (dbuf, "literal-"); break;
+          case S_STACK: dbuf_append_str (dbuf, "stack-"); break;
+          case S_XSTACK: dbuf_append_str (dbuf, "xstack-"); break;
+          case S_BIT: dbuf_append_str (dbuf, "bit-"); break;
+          case S_EEPROM: dbuf_append_str (dbuf, "eeprom-"); break;
           default: break;
           }
       }
@@ -2824,57 +2938,60 @@ printTypeChain (sym_link * start, FILE * of)
         {
           if (!IS_FUNC(type)) {
             if (DCL_PTR_VOLATILE (type)) {
-              fprintf (of, "volatile-");
+              dbuf_append_str (dbuf, "volatile-");
             }
             if (DCL_PTR_CONST (type)) {
-              fprintf (of, "const-");
+              dbuf_append_str (dbuf, "const-");
+            }
+            if (DCL_PTR_RESTRICT (type)) {
+              dbuf_append_str (dbuf, "restrict-");
             }
           }
           switch (DCL_TYPE (type))
             {
             case FUNCTION:
-              fprintf (of, "function %s %s", 
+              dbuf_printf (dbuf, "function %s %s",
                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
-              fprintf (of, "( ");
-              for (args = FUNC_ARGS(type); 
-                   args; 
+              dbuf_append_str (dbuf, "( ");
+              for (args = FUNC_ARGS(type);
+                   args;
                    args=args->next) {
-                printTypeChain(args->type, of);
+                dbuf_printTypeChain(args->type, dbuf);
                 if (args->next)
-                  fprintf(of, ", ");
+                  dbuf_append_str (dbuf, ", ");
               }
-              fprintf (of, ") ");
+              dbuf_append_str (dbuf, ") ");
               break;
             case GPOINTER:
-              fprintf (of, "generic* ");
+              dbuf_append_str (dbuf, "generic* ");
               break;
             case CPOINTER:
-              fprintf (of, "code* ");
+              dbuf_append_str (dbuf, "code* ");
               break;
             case FPOINTER:
-              fprintf (of, "xdata* ");
+              dbuf_append_str (dbuf, "xdata* ");
               break;
             case EEPPOINTER:
-              fprintf (of, "eeprom* ");
+              dbuf_append_str (dbuf, "eeprom* ");
               break;
             case POINTER:
-              fprintf (of, "near* ");
+              dbuf_append_str (dbuf, "near* ");
               break;
             case IPOINTER:
-              fprintf (of, "idata* ");
+              dbuf_append_str (dbuf, "idata* ");
               break;
             case PPOINTER:
-              fprintf (of, "pdata* ");
+              dbuf_append_str (dbuf, "pdata* ");
               break;
             case UPOINTER:
-              fprintf (of, "unknown* ");
+              dbuf_append_str (dbuf, "unknown* ");
               break;
             case ARRAY:
               if (DCL_ELEM(type)) {
-                fprintf (of, "[%d] ", DCL_ELEM(type));
+                dbuf_printf (dbuf, "[%d] ", DCL_ELEM(type));
               } else {
-                fprintf (of, "[] ");
+                dbuf_append_str (dbuf, "[] ");
               }
               break;
             }
@@ -2882,57 +2999,57 @@ printTypeChain (sym_link * start, FILE * of)
       else
         {
           if (SPEC_VOLATILE (type))
-            fprintf (of, "volatile-");
+            dbuf_append_str (dbuf, "volatile-");
           if (SPEC_CONST (type))
-            fprintf (of, "const-");
+            dbuf_append_str (dbuf, "const-");
           if (SPEC_USIGN (type))
-            fprintf (of, "unsigned-");
+            dbuf_append_str (dbuf, "unsigned-");
           switch (SPEC_NOUN (type))
             {
             case V_INT:
               if (IS_LONG (type))
-                fprintf (of, "long-");
-              fprintf (of, "int");
+                dbuf_append_str (dbuf, "long-");
+              dbuf_append_str (dbuf, "int");
               break;
 
             case V_CHAR:
-              fprintf (of, "char");
+              dbuf_append_str (dbuf, "char");
               break;
 
             case V_VOID:
-              fprintf (of, "void");
+              dbuf_append_str (dbuf, "void");
               break;
 
             case V_FLOAT:
-              fprintf (of, "float");
+              dbuf_append_str (dbuf, "float");
               break;
 
             case V_FIXED16X16:
-              fprintf (of, "fixed16x16");
+              dbuf_append_str (dbuf, "fixed16x16");
               break;
 
             case V_STRUCT:
-              fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
+              dbuf_printf (dbuf, "struct %s", SPEC_STRUCT (type)->tag);
               break;
 
             case V_SBIT:
-              fprintf (of, "sbit");
+              dbuf_append_str (dbuf, "sbit");
               break;
 
             case V_BIT:
-              fprintf (of, "bit");
+              dbuf_append_str (dbuf, "bit");
               break;
 
             case V_BITFIELD:
-              fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
+              dbuf_printf (dbuf, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
               break;
 
             case V_DOUBLE:
-              fprintf (of, "double");
+              dbuf_append_str (dbuf, "double");
               break;
 
             default:
-              fprintf (of, "unknown type");
+              dbuf_append_str (dbuf, "unknown type");
               break;
             }
         }
@@ -2941,10 +3058,8 @@ printTypeChain (sym_link * start, FILE * of)
         search = search->next;
       type = search;
       if (type)
-        fputc (' ', of);
+          dbuf_append_char(dbuf, ' ');
     }
-  if (nlr)
-    fprintf (of, "\n");
 }
 
 /*--------------------------------------------------------------------*/
@@ -2970,7 +3085,7 @@ printTypeChainRaw (sym_link * start, FILE * of)
   }
 
   type = start;
-  
+
   while (type)
     {
       if (IS_DECL (type))
@@ -2982,16 +3097,22 @@ printTypeChainRaw (sym_link * start, FILE * of)
             if (DCL_PTR_CONST (type)) {
               fprintf (of, "const-");
             }
+            if (DCL_PTR_RESTRICT (type)) {
+              fprintf (of, "restrict-");
+            }
           }
           switch (DCL_TYPE (type))
             {
             case FUNCTION:
-              fprintf (of, "function %s %s", 
+              if (IFFUNC_ISINLINE(type)) {
+                fprintf (of, "inline-");
+              }
+              fprintf (of, "function %s %s",
                        (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
                        (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
               fprintf (of, "( ");
-              for (args = FUNC_ARGS(type); 
-                   args; 
+              for (args = FUNC_ARGS(type);
+                   args;
                    args=args->next) {
                 printTypeChain(args->type, of);
                 if (args->next)
@@ -3040,7 +3161,7 @@ printTypeChainRaw (sym_link * start, FILE * of)
         }
       else if (IS_SPEC (type))
         {
-        switch (SPEC_SCLS (type)) 
+        switch (SPEC_SCLS (type))
           {
           case S_DATA: fprintf (of, "data-"); break;
           case S_XDATA: fprintf (of, "xdata-"); break;
@@ -3126,7 +3247,7 @@ printTypeChainRaw (sym_link * start, FILE * of)
 /* powof2 - returns power of two for the number if number is pow 2 */
 /*-----------------------------------------------------------------*/
 int
-powof2 (TYPE_UDWORD num)
+powof2 (TYPE_TARGET_ULONG num)
 {
   int nshifts = 0;
   int n1s = 0;
@@ -3166,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 */
@@ -3207,8 +3328,8 @@ _mangleFunctionName(char *in)
 /* pointer modifiers -  'g' - generic                              */
 /*                      'x' - xdata                                */
 /*                      'p' - code                                 */
-/*                      'd' - data                                 */                     
-/*                      'F' - function                             */                     
+/*                      'd' - data                                 */
+/*                      'F' - function                             */
 /* examples : "ig*" - generic int *                                */
 /*            "cx*" - char xdata *                                 */
 /*            "ui" -  unsigned int                                 */
@@ -3221,7 +3342,7 @@ sym_link *typeFromStr (char *s)
     do {
         sym_link *nr;
         switch (*s) {
-        case 'u' : 
+        case 'u' :
             usign = 1;
             s++;
             continue ;
@@ -3288,7 +3409,7 @@ sym_link *typeFromStr (char *s)
             s++;
             break;
         default:
-            werror(E_INTERNAL_ERROR, __FILE__, __LINE__, 
+            werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
                    "typeFromStr: unknown type");
             break;
         }
@@ -3304,7 +3425,7 @@ sym_link *typeFromStr (char *s)
 /*-----------------------------------------------------------------*/
 /* initCSupport - create functions for C support routines          */
 /*-----------------------------------------------------------------*/
-void 
+void
 initCSupport ()
 {
   const char *smuldivmod[] =
@@ -3321,7 +3442,7 @@ initCSupport ()
   };
   const char *ssu[] =
   {
-    "s", "u"
+    "s", "su", "us", "u"
   };
   const char *srlrr[] =
   {
@@ -3391,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);
                 }
             }
@@ -3411,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
@@ -3419,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
@@ -3439,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;
@@ -3451,39 +3572,85 @@ 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 (su = 0; su < 2; su++)
+      for (muldivmod = 0; muldivmod < 3; muldivmod++)
         {
-          for (muldivmod = 1; 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)
             {
-              /* div and mod */
               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);
+                  "_%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;
             }
         }
     }
-  /* mul only */
-  muldivmod = 0;
-  /* byte */
-  bwd = 0;
-  for (su = 0; su < 2; su++)
+
+  for (bwd = 1; bwd < 3; bwd++)
     {
-      /* muluchar and mulschar are still separate functions, because e.g. the z80
-         port is sign/zero-extending to int before calling mulint() */
+      for (su = 0; su < 2; su++)
+        {
+          for (muldivmod = 1; muldivmod < 3; muldivmod++)
+            {
+              /* 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 || bwd != 0 || su != 0)
+              {
+                SNPRINTF (buffer, sizeof(buffer),
+                    "_%s%s%s",
+                    smuldivmod[muldivmod],
+                    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;
+              }
+            }
+        }
+    }
+
+  if (TARGET_IS_PIC16)
+  {
+    /* PIC16 port wants __divschar/__modschar to return an int, so that both
+     * 100 / -4 = -25 and -128 / -1 = 128 can be handled correctly
+     * (first one would have to be sign extended, second one must not be).
+     * Similarly, modschar should be handled, but the iCode introduces cast
+     * here and forces '% : s8 x s8 -> s8' ... */
+    su = 0; bwd = 0;
+    for (muldivmod = 1; muldivmod < 2; muldivmod++) {
       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);
+          "_%s%s%s",
+          smuldivmod[muldivmod],
+          ssu[su],
+          sbwd[bwd]);
+      __muldiv[muldivmod][bwd][su] = funcOfType (
+          _mangleFunctionName(buffer),
+          __multypes[1][su],
+          __multypes[bwd][su],
+          2,
+          options.intlong_rent);
       FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
     }
+  }
+
+  /* mul only */
+  muldivmod = 0;
   /* signed only */
   su = 0;
   /* word and doubleword */
@@ -3509,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;
@@ -3536,23 +3703,23 @@ void initBuiltIns()
     }
 }
 
-sym_link *validateLink(sym_link         *l, 
+sym_link *validateLink(sym_link         *l,
                         const char      *macro,
                         const char      *args,
                         const char      select,
-                        const char      *file, 
+                        const char      *file,
                         unsigned        line)
-{    
+{
   if (l && l->class==select)
     {
         return l;
     }
-    fprintf(stderr, 
+    fprintf(stderr,
             "Internal error: validateLink failed in %s(%s) @ %s:%u:"
             " expected %s, got %s\n",
-            macro, args, file, line, 
+            macro, args, file, line,
             DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
-    exit(-1);
+    exit(EXIT_FAILURE);
     return l; // never reached, makes compiler happy.
 }
 
@@ -3572,13 +3739,13 @@ newEnumType (symbol *enumlist)
       SPEC_NOUN (type) = V_INT;
       return type;
     }
-      
+
   /* Determine the range of the enumerated values */
   sym = enumlist;
-  min = max = (int) floatFromVal (valFromType (sym->type));
+  min = max = (int) ulFromVal (valFromType (sym->type));
   for (sym = sym->next; sym; sym = sym->next)
     {
-      v = (int) floatFromVal (valFromType (sym->type));
+      v = (int) ulFromVal (valFromType (sym->type));
       if (v<min)
         min = v;
       if (v>max)
@@ -3612,6 +3779,6 @@ newEnumType (symbol *enumlist)
       if (min>=0)
         SPEC_USIGN (type) = 1;
     }
-  
-  return type;    
+
+  return type;
 }