undid the hackup of const and volatile, the problem is much bigger
[fw/sdcc] / src / SDCCsymt.c
index 7e5e40a5cc6bdd0b54ea67c63912e419249fe01a..231e4f65b1b13c1514604bd5c944578cf663b70b 100644 (file)
@@ -298,11 +298,12 @@ newSymbol (char *name, int scope)
 /* newLink - creates a new link (declarator,specifier)              */
 /*------------------------------------------------------------------*/
 sym_link *
-newLink ()
+newLink (SYM_LINK_CLASS select)
 {
   sym_link *p;
 
   p = Safe_alloc ( sizeof (sym_link));
+  p->class=select;
 
   return p;
 }
@@ -372,7 +373,7 @@ pointerTypes (sym_link * ptr, sym_link * type)
          break;
        }
       /* the storage class of type ends here */
-      SPEC_SCLS (type) =
+      SPEC_SCLS (type) = 
        SPEC_CONST (type) =
        SPEC_VOLATILE (type) = 0;
     }
@@ -419,7 +420,7 @@ addDecl (symbol * sym, int type, sym_link * p)
     }
   else
     {
-      head = tail = newLink ();
+      head = tail = newLink (DECLARATOR);
       DCL_TYPE (head) = type;
     }
 
@@ -468,10 +469,10 @@ addDecl (symbol * sym, int type, sym_link * p)
 
       if (!IS_SPEC (sym->etype))
        {
-         sym->etype = sym->etype->next = newLink ();
-         sym->etype->class = SPECIFIER;
+         sym->etype = sym->etype->next = newLink (SPECIFIER);
        }
-      
+
+      SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
       DCL_PTR_CONST (sym->type) = SPEC_CONST (DCL_TSPEC (p));
       DCL_PTR_VOLATILE (sym->type) = SPEC_VOLATILE (DCL_TSPEC (p));
       DCL_TSPEC (p) = NULL;
@@ -558,17 +559,8 @@ void checkTypeSanity(sym_link *etype, char *name) {
 sym_link *
 mergeSpec (sym_link * dest, sym_link * src, char *name)
 {
-  sym_link *symlink=dest;
-
   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
-#if 0
-    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
-    exit (1);
-#else
     werror (E_SYNTAX_ERROR, yytext);
-    // the show must go on
-    return newIntLink();
-#endif
   }
 
   if (SPEC_NOUN(src)) {
@@ -597,17 +589,6 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
 
   /* copy all the specifications  */
 
-  // we really should do: 
-#if 0
-  if (SPEC_what(src)) {
-    if (SPEC_what(dest)) {
-      werror(W_DUPLICATE_SPEC, "what");
-    }
-    SPEC_what(dst)|=SPEC_what(src);
-  }
-#endif
-  // but there are more important thing right now
-
   SPEC_LONG (dest) |= SPEC_LONG (src);
   dest->select.s._short|=src->select.s._short;
   SPEC_USIGN (dest) |= SPEC_USIGN (src);
@@ -643,7 +624,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   FUNC_INTNO(dest) |= FUNC_INTNO(src);
   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
 
-  return symlink;
+  return dest;
 }
 
 /*------------------------------------------------------------------*/
@@ -682,8 +663,7 @@ newCharLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_CHAR;
 
   return p;
@@ -697,8 +677,7 @@ newFloatLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_FLOAT;
 
   return p;
@@ -712,8 +691,7 @@ newLongLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_INT;
   SPEC_LONG (p) = 1;
 
@@ -728,8 +706,7 @@ newIntLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_INT;
 
   return p;
@@ -1178,13 +1155,17 @@ checkSClass (symbol * sym, int isProto)
       !IS_FUNC(sym->type)) {
     SPEC_SCLS (sym->etype) = S_CODE;
   }
-  
+
   /* global variable in code space is a constant */
   if (sym->level == 0 &&
       SPEC_SCLS (sym->etype) == S_CODE &&
-      port->mem.code_ro)
-    SPEC_CONST (sym->etype) = 1;
-  
+      port->mem.code_ro) {
+    if (IS_SPEC(sym->type)) {
+      SPEC_CONST (sym->type) = 1;
+    } else {
+      DCL_PTR_CONST (sym->type) = 1;
+    }
+  }
 
   /* if bit variable then no storage class can be */
   /* specified since bit is already a storage */
@@ -1330,11 +1311,11 @@ copyLinkChain (sym_link * p)
   sym_link *head, *curr, *loop;
 
   curr = p;
-  head = loop = (curr ? newLink () : (void *) NULL);
+  head = loop = (curr ? newLink (p->class) : (void *) NULL);
   while (curr)
     {
       memcpy (loop, curr, sizeof (sym_link));  /* copy it */
-      loop->next = (curr->next ? newLink () : (void *) NULL);
+      loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
       loop = loop->next;
       curr = curr->next;
     }
@@ -1572,7 +1553,7 @@ aggregateToPointer (value * val)
          sym_link *p = val->type;
 
          werror (W_STRUCT_AS_ARG, val->name);
-         val->type = newLink ();
+         val->type = newLink (DECLARATOR);
          val->type->next = p;
        }
 
@@ -1879,8 +1860,10 @@ processFuncArgs (symbol * func)
          val->sym->etype = getSpec (val->sym->type);
          val->sym->_isparm = 1;
          strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname));
-         SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
-           SPEC_STAT (func->etype);
+         if (IS_SPEC(func->etype)) {
+           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
+             SPEC_STAT (func->etype);
+         }
          addSymChain (val->sym);
 
        }
@@ -1892,8 +1875,10 @@ processFuncArgs (symbol * func)
          val->sym->_isparm = 1;
          SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
            (options.model != MODEL_SMALL ? xdata : data);
-         SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
-           SPEC_STAT (func->etype);
+         if (IS_SPEC(func->etype)) {
+           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
+             SPEC_STAT (func->etype);
+         }
        }
       if (!isinSet(operKeyReset, val->sym)) {
        addSet (&operKeyReset, val->sym);
@@ -1937,6 +1922,7 @@ printTypeChain (sym_link * start, FILE * of)
 {
   int nlr = 0;
   sym_link * type, * search;
+  STORAGE_CLASS scls;
 
   if (!of)
     {
@@ -1949,16 +1935,44 @@ printTypeChain (sym_link * start, FILE * of)
     return;
   }
 
-  /* print the chain as it is written in the source: */
-  /* start with the last entry                       */
+  /* Print the chain as it is written in the source: */
+  /* start with the last entry.                      */
+  /* However, the storage class at the end of the    */
+  /* chain reall applies to the first in the chain!  */
+
   for (type = start; type && type->next; type = type->next)
     ;
+  scls=SPEC_SCLS(type);
   while (type)
     {
+      if (type==start) {
+       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;
+         default: break;
+         }
+      }
+
       if (IS_DECL (type))
        {
-         if (DCL_PTR_VOLATILE (type)) {
-           fprintf (of, "volatile ");
+         if (!IS_FUNC(type)) {
+           if (DCL_PTR_VOLATILE (type)) {
+             fprintf (of, "volatile-");
+           }
+           if (DCL_PTR_CONST (type)) {
+             fprintf (of, "const-");
+           }
          }
          switch (DCL_TYPE (type))
            {
@@ -1968,45 +1982,28 @@ printTypeChain (sym_link * start, FILE * of)
                       (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
              break;
            case GPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "generic * ");
+             fprintf (of, "generic* ");
              break;
            case CPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "code * ");
+             fprintf (of, "code* ");
              break;
            case FPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "xdata * ");
+             fprintf (of, "xdata* ");
              break;
            case EEPPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "eeprom * ");
+             fprintf (of, "eeprom* ");
              break;
-
            case POINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "near *");
+             fprintf (of, "near* ");
              break;
            case IPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "idata * ");
+             fprintf (of, "idata* ");
              break;
            case PPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "pdata * ");
+             fprintf (of, "pdata* ");
              break;
            case UPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "unkown * ");
+             fprintf (of, "unkown* ");
              break;
            case ARRAY:
              if (DCL_ELEM(type)) {
@@ -2019,34 +2016,17 @@ printTypeChain (sym_link * start, FILE * of)
        }
       else
        {
-         switch (SPEC_SCLS(type)) 
-           {
-           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;
-           default: break;
-           }
-
          if (SPEC_VOLATILE (type))
-           fprintf (of, "volatile ");
-         if (SPEC_USIGN (type))
-           fprintf (of, "unsigned ");
+           fprintf (of, "volatile-");
          if (SPEC_CONST (type))
-           fprintf (of, "const ");
+           fprintf (of, "const-");
+         if (SPEC_USIGN (type))
+           fprintf (of, "unsigned-");
          switch (SPEC_NOUN (type))
            {
            case V_INT:
              if (IS_LONG (type))
-               fprintf (of, "long ");
+               fprintf (of, "long-");
              fprintf (of, "int");
              break;
 
@@ -2373,7 +2353,7 @@ _mangleFunctionName(char *in)
 /*-----------------------------------------------------------------*/
 sym_link *typeFromStr (char *s)
 {
-    sym_link *r = newLink();
+    sym_link *r = newLink(DECLARATOR);
     int usign = 0;
 
     do {
@@ -2415,10 +2395,9 @@ sym_link *typeFromStr (char *s)
        case 'd':
        case 'F':
            assert(*(s+1)=='*');
-           nr = newLink();
+           nr = newLink(DECLARATOR);
            nr->next = r;
            r = nr;
-           r->class = DECLARATOR ;
            switch (*s) {
            case 'g':
                DCL_TYPE(r) = GPOINTER;
@@ -2434,10 +2413,9 @@ sym_link *typeFromStr (char *s)
                break;
            case 'F':
                DCL_TYPE(r) = FUNCTION;
-               nr = newLink();
+               nr = newLink(DECLARATOR);
                nr->next = r;
                r = nr;
-               r->class = DECLARATOR ;
                DCL_TYPE(r) = CPOINTER;
                break;
            }
@@ -2594,3 +2572,23 @@ void initBuiltIns()
        FUNC_ISREENT(sym->type) = 0;    /* can never be reentrant */
     }
 }
+
+sym_link *validateLink(sym_link        *l, 
+                       const char      *macro,
+                       const char      *args,
+                       const char      select,
+                       const char      *file, 
+                       unsigned        line)
+{    
+  if (l && l->class==select)
+    {
+       return l;
+    }
+    fprintf(stderr, 
+           "Internal error: validateLink failed in %s(%s) @ %s:%u:"
+           " expected %s, got %s\n",
+           macro, args, file, line, 
+           DECLSPEC2TXT(select), l ? DECLSPEC2TXT(l->class) : "null-link");
+    exit(-1);
+    return l; // never reached, makes compiler happy.
+}