sequence of specifiers in pintTypeChain() corrected
[fw/sdcc] / src / SDCCsymt.c
index 9ff910f0c10790d4279b79d872100bab8d166377..fe7223a8323d0a97efbbd23a34ab14a3ef3c8db8 100644 (file)
@@ -217,13 +217,12 @@ findSymWithLevel (bucket ** stab, symbol * sym)
    **/
   while (bp)
     {
-
       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
        {
          /* if this is parameter then nothing else need to be checked */
          if (((symbol *) (bp->sym))->_isparm)
            return (bp->sym);
-         /* if levels match then block numbers hsould also match */
+         /* if levels match then block numbers should also match */
          if (bp->level && bp->level == sym->level && bp->block == sym->block)
            return (bp->sym);
          /* if levels don't match then we are okay */
@@ -318,9 +317,13 @@ pointerTypes (sym_link * ptr, sym_link * type)
     ptr = ptr->next;
 
   /* could not find it */
-  if (!ptr || IS_SPEC (ptr) ||
-      DCL_TYPE (ptr) != UPOINTER)
+  if (!ptr || IS_SPEC (ptr))
+    return;
+  
+  if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
+    pointerTypes (ptr->next, type);
     return;
+  }
 
   /* change the pointer type depending on the
      storage class of the type */
@@ -432,13 +435,13 @@ addDecl (symbol * sym, int type, sym_link * p)
        }
     }
 
-  /* if the type is a unknown pointer and has
+  /* if the type is an unknown pointer and has
      a tspec then take the storage class const & volatile
      attribute from the tspec & make it those of this
      symbol */
   if (p &&
       !IS_SPEC (p) &&
-      DCL_TYPE (p) == UPOINTER &&
+      //DCL_TYPE (p) == UPOINTER &&
       DCL_TSPEC (p))
     {
       if (!IS_SPEC (sym->etype))
@@ -528,6 +531,33 @@ sym_link *
 mergeSpec (sym_link * dest, sym_link * src, char *name)
 {
 
+  sym_link *symlink=dest;
+
+#if 0
+  if (!IS_SPEC(dest)) {
+    // This can happen for pointers, find the end type
+    while (dest && !IS_SPEC(dest))
+      dest=dest->next;
+  }
+  if (!IS_SPEC(src)) {
+    // here we have a declarator as source, reverse them
+    symlink=src;
+    src=dest;
+    dest=symlink;
+    while (dest && !IS_SPEC(dest)) {
+      // and find the specifier
+      dest=dest->next;
+    }
+  } else {
+    symlink=dest;
+  }
+#endif
+
+  if (!IS_SPEC(dest) || !IS_SPEC(src)) {
+    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
+    exit (1);
+  }
+
   if (getenv("DEBUG_mergeSpec")) {
     fprintf (stderr, "mergeSpec: \"%s\"\n", name);
   }
@@ -592,7 +622,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
 
-  return dest;
+  return symlink;
 }
 
 /*------------------------------------------------------------------*/
@@ -918,48 +948,36 @@ addSymChain (symbol * symHead)
   symbol *sym = symHead;
   symbol *csym = NULL;
 
-
   for (; sym != NULL; sym = sym->next)
     {
       changePointer(sym);
+      checkTypeSanity(sym->etype, sym->name);
 
       /* if already exists in the symbol table then check if
-         the previous was an extern definition if yes then
+         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 ((csym = findSymWithLevel (SymbolTab, sym)) &&
-         csym->level == sym->level)
-       {
-
-         /* previous definition extern ? */
-         if (IS_EXTERN (csym->etype))
-           {
-             /* do types match ? */
-             if (compareType (csym->type, sym->type) != 1)
-               /* no then error */
-               werror (E_DUPLICATE, csym->name);
-
-             /* delete current entry */
-             deleteSym (SymbolTab, csym, csym->name);
-             /* add new entry */
-             addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
-           }
-         else                  /* not extern */
-           werror (E_DUPLICATE, sym->name);
+         csym->level == sym->level) {
+       
+       /* one definition extern ? */
+       if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
+         /* do types match ? */
+         if (compareType (csym->type, sym->type) != 1) {
+           /* no then error */
+           werror (E_EXTERN_MISMATCH, csym->name);
+           continue;
+         }
+         /* delete current entry */
+         deleteSym (SymbolTab, csym, csym->name);
+       } else {
+         /* not extern */
+         werror (E_DUPLICATE, sym->name);
          continue;
        }
+      }
 
-      /* check if previously defined */
-      if (csym && csym->level == sym->level)
-       {
-         /* if the previous one was declared as extern */
-         /* then check the type with the current one         */
-         if (IS_EXTERN (csym->etype))
-           {
-             if (compareType (csym->type, sym->type) <= 0)
-               werror (W_EXTERN_MISMATCH, csym->name);
-           }
-       }
+      /* add new entry */
       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
     }
 }
@@ -1078,7 +1096,7 @@ compStructSize (int su, structdef * sdef)
            }
        }
        else {
-           checkDecl (loop);
+           checkDecl (loop, 1);
            sum += getSize (loop->type);
        }
 
@@ -1110,7 +1128,7 @@ compStructSize (int su, structdef * sdef)
 /* checkSClass - check the storage class specification              */
 /*------------------------------------------------------------------*/
 static void 
-checkSClass (symbol * sym)
+checkSClass (symbol * sym, int isProto)
 {
   if (getenv("DEBUG_SANITY")) {
     fprintf (stderr, "checkSClass: %s \n", sym->name);
@@ -1178,23 +1196,6 @@ checkSClass (symbol * sym)
       sym->ival = NULL;
     }
 
-#if 0
-  /* if this is an automatic symbol then */
-  /* storage class will be ignored and   */
-  /* symbol will be allocated on stack/  */
-  /* data depending on flag             */
-  if (sym->level &&
-      (options.stackAuto || reentrant) &&
-      (SPEC_SCLS (sym->etype) != S_AUTO &&
-       SPEC_SCLS (sym->etype) != S_FIXED &&
-       SPEC_SCLS (sym->etype) != S_REGISTER &&
-       SPEC_SCLS (sym->etype) != S_STACK &&
-       SPEC_SCLS (sym->etype) != S_XSTACK))
-    {
-      werror (E_AUTO_ASSUMED, sym->name);
-      SPEC_SCLS (sym->etype) = S_AUTO;
-    }
-#else
   /* if this is an atomatic symbol */
   if (sym->level && (options.stackAuto || reentrant)) {
     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
@@ -1210,7 +1211,6 @@ checkSClass (symbol * sym)
       }
     }
   }
-#endif
   
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
@@ -1238,15 +1238,17 @@ checkSClass (symbol * sym)
       SPEC_BSTR (sym->etype) = 0;
     }
 
-  /* variables declared in CODE space must have */
-  /* initializers if not an extern */
-  if (SPEC_SCLS (sym->etype) == S_CODE &&
-      sym->ival == NULL &&
-      !sym->level &&
-      port->mem.code_ro &&
-      !IS_EXTERN (sym->etype) &&
-      !funcInChain (sym->type))
-    werror (E_CODE_NO_INIT, sym->name);
+  if (!isProto) {
+    /* variables declared in CODE space must have */
+    /* initializers if not an extern */
+    if (SPEC_SCLS (sym->etype) == S_CODE &&
+       sym->ival == NULL &&
+       //!sym->level &&
+       port->mem.code_ro &&
+       !IS_EXTERN (sym->etype) &&
+       !funcInChain (sym->type))
+      werror (E_CODE_NO_INIT, sym->name);
+  }
 
   /* if parameter or local variable then change */
   /* the storage class to reflect where the var will go */
@@ -1296,10 +1298,10 @@ changePointer (symbol * sym)
 /* checkDecl - does semantic validation of a declaration                   */
 /*------------------------------------------------------------------*/
 int 
-checkDecl (symbol * sym)
+checkDecl (symbol * sym, int isProto)
 {
 
-  checkSClass (sym);           /* check the storage class      */
+  checkSClass (sym, isProto);          /* check the storage class      */
   changePointer (sym);         /* change pointers if required */
 
   /* if this is an array without any dimension
@@ -1427,9 +1429,9 @@ computeType (sym_link * type1, sym_link * type2)
   return rType;
 }
 
-/*------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match                 */
-/*------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+/* compareType - will do type check return 1 if match, -1 if castable */
+/*--------------------------------------------------------------------*/
 int 
 compareType (sym_link * dest, sym_link * src)
 {
@@ -1449,14 +1451,13 @@ compareType (sym_link * dest, sym_link * src)
        {
          if (DCL_TYPE (src) == DCL_TYPE (dest))
            return compareType (dest->next, src->next);
-         else if (IS_PTR (src) && IS_PTR (dest))
+         if (IS_PTR (src) && IS_PTR (dest))
            return -1;
-         else if (IS_PTR (dest) && IS_ARRAY (src))
+         if (IS_PTR (dest) && IS_ARRAY (src))
            return -1;
-         else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
+         if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
            return -1 * compareType (dest->next, src);
-         else
-           return 0;
+         return 0;
        }
       else if (IS_PTR (dest) && IS_INTEGRAL (src))
        return -1;
@@ -1508,7 +1509,7 @@ compareType (sym_link * dest, sym_link * src)
     return -1;
 
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
-    return -2;
+    return -1;
 
   return 1;
 }
@@ -1663,10 +1664,10 @@ checkFunction (symbol * sym)
   if (compareType (csym->type, sym->type) <= 0)
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
-      werror (E_CONTINUE, "previous definition type ");
+      werror (W_CONTINUE, "previous definition type ");
       printTypeChain (csym->type, stderr);
       fprintf (stderr, "\n");
-      werror (E_CONTINUE, "current definition type ");
+      werror (W_CONTINUE, "current definition type ");
       printTypeChain (sym->type, stderr);
       fprintf (stderr, "\n");
       return 0;
@@ -1870,10 +1871,11 @@ void PT(sym_link *type)
 /*-----------------------------------------------------------------*/
 /* printTypeChain - prints the type chain in human readable form   */
 /*-----------------------------------------------------------------*/
-void 
-printTypeChain (sym_link * type, FILE * of)
+void
+printTypeChain (sym_link * start, FILE * of)
 {
   int nlr = 0;
+  sym_link * type, * search;
 
   if (!of)
     {
@@ -1881,61 +1883,65 @@ printTypeChain (sym_link * type, FILE * of)
       nlr = 1;
     }
 
+  /* print the chain as it is written in the source: */
+  /* start with the last entry                       */
+  for (type = start; type && type->next; type = type->next)
+    ;
   while (type)
     {
       if (IS_DECL (type))
        {
-         if (DCL_PTR_VOLATILE(type)) {
+         if (DCL_PTR_VOLATILE (type)) {
            fprintf (of, "volatile ");
          }
          switch (DCL_TYPE (type))
            {
            case FUNCTION:
-             fprintf (of, "function ");
+             fprintf (of, "function");
              break;
            case GPOINTER:
-             fprintf (of, "_generic * ");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "generic *");
              break;
            case CPOINTER:
-             fprintf (of, "_code * ");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "code *");
              break;
            case FPOINTER:
-             fprintf (of, "_far * ");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "far *");
              break;
            case EEPPOINTER:
-             fprintf (of, "_eeprom * ");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "eeprom * ");
              break;
 
            case POINTER:
-             fprintf (of, "_near * ");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "near *");
              break;
            case IPOINTER:
-             fprintf (of, "_idata *");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "idata *");
              break;
            case PPOINTER:
-             fprintf (of, "_pdata *");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "pdata *");
              break;
            case UPOINTER:
-             fprintf (of, " _unkown *");
              if (DCL_PTR_CONST (type))
                fprintf (of, "const ");
+             fprintf (of, "unkown *");
              break;
            case ARRAY:
-             fprintf (of, "array of ");
+             fprintf (of, "array of");
              break;
            }
        }
@@ -1953,19 +1959,19 @@ printTypeChain (sym_link * type, FILE * of)
            case V_INT:
              if (IS_LONG (type))
                fprintf (of, "long ");
-             fprintf (of, "int ");
+             fprintf (of, "int");
              break;
 
            case V_CHAR:
-             fprintf (of, "char ");
+             fprintf (of, "char");
              break;
 
            case V_VOID:
-             fprintf (of, "void ");
+             fprintf (of, "void");
              break;
 
            case V_FLOAT:
-             fprintf (of, "float ");
+             fprintf (of, "float");
              break;
 
            case V_STRUCT:
@@ -1973,7 +1979,7 @@ printTypeChain (sym_link * type, FILE * of)
              break;
 
            case V_SBIT:
-             fprintf (of, "sbit ");
+             fprintf (of, "sbit");
              break;
 
            case V_BIT:
@@ -1981,15 +1987,20 @@ printTypeChain (sym_link * type, FILE * of)
              break;
 
            case V_DOUBLE:
-             fprintf (of, "double ");
+             fprintf (of, "double");
              break;
 
            default:
-             fprintf (of, "unknown type ");
+             fprintf (of, "unknown type");
              break;
            }
        }
-      type = type->next;
+       /* search entry in list before "type" */
+    for (search = start; search && search->next != type;)
+       search = search->next;
+    type = search;
+    if (type)
+      fputc (' ', of);
     }
   if (nlr)
     fprintf (of, "\n");
@@ -1998,7 +2009,7 @@ printTypeChain (sym_link * type, FILE * of)
 /*-----------------------------------------------------------------*/
 /* cdbTypeInfo - print the type information for debugger           */
 /*-----------------------------------------------------------------*/
-void 
+void
 cdbTypeInfo (sym_link * type, FILE * of)
 {
   fprintf (of, "{%d}", getSize (type));
@@ -2235,22 +2246,21 @@ symbol *__muldiv[3][3][2];
 sym_link *__multypes[3][2];
 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
 symbol *__conv[2][3][2];
+/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
+symbol *__rlrr[2][3][2];
 
 sym_link *floatType;
 
-static void 
-_makeRegParam (symbol * sym)
+static char *
+_mangleFunctionName(char *in)
 {
-  value *val;
-
-  val = sym->args;             /* loop thru all the arguments   */
-
-  /* reset regparm for the port */
-  (*port->reset_regparms) ();
-  while (val)
+  if (port->getMangledFunctionName) 
     {
-      SPEC_REGPARM (val->etype) = 1;
-      val = val->next;
+      return port->getMangledFunctionName(in);
+    }
+  else
+    {
+      return in;
     }
 }
 
@@ -2272,8 +2282,17 @@ initCSupport ()
   {
     "s", "u"
   };
+  const char *srlrr[] =
+  {
+    "rl", "rr"
+  };
+
+  int bwd, su, muldivmod, tofrom, rlrr;
 
-  int bwd, su, muldivmod, tofrom;
+  if (getenv("SDCC_NO_C_SUPPORT")) {
+    /* for debugging only */
+    return;
+  }
 
   floatType = newFloatLink ();
 
@@ -2319,12 +2338,12 @@ initCSupport ()
              if (tofrom)
                {
                  sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
-                 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
+                 __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
                }
              else
                {
                  sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
-                 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
+                 __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
                }
            }
        }
@@ -2340,10 +2359,24 @@ initCSupport ()
                       smuldivmod[muldivmod],
                       ssu[su],
                       sbwd[bwd]);
-              __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+              __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
              SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
-             if (bwd < port->muldiv.force_reg_param_below)
-               _makeRegParam (__muldiv[muldivmod][bwd][su]);
+           }
+       }
+    }
+
+  for (rlrr = 0; rlrr < 2; rlrr++)
+    {
+      for (bwd = 0; bwd < 3; bwd++)
+       {
+         for (su = 0; su < 2; su++)
+           {
+             sprintf (buffer, "_%s%s%s",
+                      srlrr[rlrr],
+                      ssu[su],
+                      sbwd[bwd]);
+              __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
+             SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1;
            }
        }
     }