dos cvs had problem with .lnk file
[fw/sdcc] / src / SDCCsymt.c
index a6052bf9831d0d29b6b059104b75b4afa01d8a64..f9bc69a0f94bdd95193ac72ab8248acc3606b745 100644 (file)
@@ -318,9 +318,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 +436,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))
@@ -524,31 +528,34 @@ void checkTypeSanity(sym_link *etype, char *name) {
 /*------------------------------------------------------------------*/
 /* mergeSpec - merges two specifiers and returns the new one        */
 /*------------------------------------------------------------------*/
-#define LAST_MINUTE_2_3_0_FIX
 sym_link *
 mergeSpec (sym_link * dest, sym_link * src, char *name)
 {
 
-#ifdef LAST_MINUTE_2_3_0_FIX
   sym_link *symlink;
 
   if (!IS_SPEC(dest)) {
-    // This should not happen
-    fprintf (stderr, "*** internal error: can't merge declarators\n");
+    // 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 (!IS_SPEC(dest)) {
+    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);
@@ -614,11 +621,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
 
-#ifdef LAST_MINUTE_2_3_0_FIX
   return symlink;
-#else
-  return dest;
-#endif
 }
 
 /*------------------------------------------------------------------*/
@@ -943,56 +946,37 @@ addSymChain (symbol * symHead)
 {
   symbol *sym = symHead;
   symbol *csym = NULL;
-  int bothSymbolsExtern;
-
 
   for (; sym != NULL; sym = sym->next)
     {
       changePointer(sym);
+      checkTypeSanity(sym->etype, sym->name);
 
       /* 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      */
       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
-         csym->level == sym->level)
-       {
-
-         /* one definition extern ? */
-         if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype))
-           {
-             bothSymbolsExtern=
-               IS_EXTERN (csym->etype) && IS_EXTERN (sym->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);
-
-             /* this isn't really needed, but alla */
-             sym->etype->select.s._extern=bothSymbolsExtern;
-
-             /* 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);
     }
 }
@@ -1111,7 +1095,7 @@ compStructSize (int su, structdef * sdef)
            }
        }
        else {
-           checkDecl (loop);
+           checkDecl (loop, 1);
            sum += getSize (loop->type);
        }
 
@@ -1143,7 +1127,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);
@@ -1211,23 +1195,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 ||
@@ -1243,7 +1210,6 @@ checkSClass (symbol * sym)
       }
     }
   }
-#endif
   
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
@@ -1271,15 +1237,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 */
@@ -1329,10 +1297,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
@@ -1482,14 +1450,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;
@@ -1696,10 +1663,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;