* src/ds390/gen.c (genAddrOf): fixed bug #704087
[fw/sdcc] / src / SDCCsymt.c
index b160c7f7311a11933a8c9ae27482cf1f92849722..dfec56bbd932838ee549f88e55f33f8a13fcce9d 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;
 }
@@ -347,8 +348,6 @@ pointerTypes (sym_link * ptr, sym_link * type)
      storage class of the type */
   if (IS_SPEC (type))
     {
-      DCL_PTR_CONST (ptr) = SPEC_CONST (type);
-      DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
       switch (SPEC_SCLS (type))
        {
        case S_XDATA:
@@ -364,7 +363,6 @@ pointerTypes (sym_link * ptr, sym_link * type)
          DCL_TYPE (ptr) = POINTER;
          break;
        case S_CODE:
-         DCL_PTR_CONST (ptr) = port->mem.code_ro;
          DCL_TYPE (ptr) = CPOINTER;
          break;
        case S_EEPROM:
@@ -375,9 +373,7 @@ pointerTypes (sym_link * ptr, sym_link * type)
          break;
        }
       /* the storage class of type ends here */
-      SPEC_SCLS (type) =
-       SPEC_CONST (type) =
-       SPEC_VOLATILE (type) = 0;
+      SPEC_SCLS (type) = 0;
     }
 
   /* now change all the remaining unknown pointers
@@ -422,7 +418,7 @@ addDecl (symbol * sym, int type, sym_link * p)
     }
   else
     {
-      head = tail = newLink ();
+      head = tail = newLink (DECLARATOR);
       DCL_TYPE (head) = type;
     }
 
@@ -457,22 +453,25 @@ addDecl (symbol * sym, int type, sym_link * p)
     }
 
   /* if the type is an unknown pointer and has
-     a tspec then take the storage class const & volatile
+     a tspec then take the const & volatile
      attribute from the tspec & make it those of this
      symbol */
+
   if (p &&
-      !IS_SPEC (p) &&
-      //DCL_TYPE (p) == UPOINTER &&
+      IS_DECL (p) &&
+      DCL_TYPE (p) == UPOINTER &&
       DCL_TSPEC (p))
     {
+      // only for declarators
+      wassert (IS_DECL(sym->type));
+
       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));
-      SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
-      SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (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;
     }
 
@@ -557,8 +556,6 @@ 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");
@@ -642,7 +639,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;
 }
 
 /*------------------------------------------------------------------*/
@@ -681,8 +678,7 @@ newCharLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_CHAR;
 
   return p;
@@ -696,8 +692,7 @@ newFloatLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_FLOAT;
 
   return p;
@@ -711,8 +706,7 @@ newLongLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_INT;
   SPEC_LONG (p) = 1;
 
@@ -727,8 +721,7 @@ newIntLink ()
 {
   sym_link *p;
 
-  p = newLink ();
-  p->class = SPECIFIER;
+  p = newLink (SPECIFIER);
   SPEC_NOUN (p) = V_INT;
 
   return p;
@@ -1173,7 +1166,8 @@ checkSClass (symbol * sym, int isProto)
   /* if no other storage class specified */
   if (sym->level == 0 &&
       SPEC_CONST (sym->etype) &&
-      SPEC_SCLS(sym->etype) == S_FIXED) {
+      SPEC_SCLS(sym->etype) == S_FIXED &&
+      !IS_FUNC(sym->type)) {
     SPEC_SCLS (sym->etype) = S_CODE;
   }
   
@@ -1328,11 +1322,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;
     }
@@ -1570,7 +1564,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;
        }
 
@@ -1588,23 +1582,8 @@ aggregateToPointer (value * val)
          if (SPEC_OCLS(val->etype)) {
            DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
          } else {
-#if 1
            // this happens for (external) function parameters
            DCL_TYPE (val->type) = port->unqualified_pointer;
-#else
-           if (TARGET_IS_DS390) {
-             /* The AUTO and REGISTER classes should probably
-              * also become generic pointers, but I haven't yet
-              * devised a test case for that.
-              */
-             DCL_TYPE (val->type) = port->unqualified_pointer;
-             break;
-           }
-           if (options.model==MODEL_LARGE) {
-             DCL_TYPE (val->type) = FPOINTER;
-             break;
-           }
-#endif
          }
          break;
        case S_AUTO:
@@ -1892,8 +1871,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);
 
        }
@@ -1905,8 +1886,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);
@@ -2096,12 +2079,12 @@ printTypeChain (sym_link * start, FILE * of)
              break;
            }
        }
-       /* search entry in list before "type" */
-    for (search = start; search && search->next != type;)
-       search = search->next;
-    type = search;
-    if (type)
-      fputc (' ', of);
+      /* 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");
@@ -2386,7 +2369,7 @@ _mangleFunctionName(char *in)
 /*-----------------------------------------------------------------*/
 sym_link *typeFromStr (char *s)
 {
-    sym_link *r = newLink();
+    sym_link *r = newLink(DECLARATOR);
     int usign = 0;
 
     do {
@@ -2428,10 +2411,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;
@@ -2447,10 +2429,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;
            }
@@ -2607,3 +2588,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.
+}