Removed superflous code.
[deliverable/binutils-gdb.git] / gdb / stabsread.c
index e8b0844ebb9f0923e7f8355285454a52b6e8b899..c5d31e190af341c1ebd96c35dd9a61433ea6ac37 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for decoding "stabs" debugging information format.
-   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
+   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
              Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -172,24 +172,21 @@ read_cfront_member_functions PARAMS ((struct field_info *, char **,
 
 /* end new functions added for cfront support */
 
-static void 
+static void
 add_live_range PARAMS ((struct objfile *, struct symbol *, 
                        CORE_ADDR, CORE_ADDR));
 
-static int 
+static int
 resolve_live_range PARAMS ((struct objfile *, struct symbol *, char *));
 
-static int 
+static int
 process_reference PARAMS ((char **string));
 
-static CORE_ADDR 
+static CORE_ADDR
 ref_search_value PARAMS ((int refnum));
 
-static void 
-ref_init PARAMS ((void));
-
-static char * 
-get_substring PARAMS ((char ** p, int c));
+static int
+resolve_symbol_reference PARAMS ((struct objfile *, struct symbol *, char *));
 
 static const char vptr_name[] = { '_','v','p','t','r',CPLUS_MARKER,'\0' };
 static const char vb_name[] =   { '_','v','b',CPLUS_MARKER,'\0' };
@@ -203,43 +200,46 @@ static const char vb_name[] =   { '_','v','b',CPLUS_MARKER,'\0' };
 #define BELIEVE_PCC_PROMOTION 0
 #endif
 
-struct complaint invalid_cpp_abbrev_complaint =
+static struct complaint invalid_cpp_abbrev_complaint =
   {"invalid C++ abbreviation `%s'", 0, 0};
 
-struct complaint invalid_cpp_type_complaint =
+static struct complaint invalid_cpp_type_complaint =
   {"C++ abbreviated type name unknown at symtab pos %d", 0, 0};
 
-struct complaint member_fn_complaint =
+static struct complaint member_fn_complaint =
   {"member function type missing, got '%c'", 0, 0};
 
-struct complaint const_vol_complaint =
+static struct complaint const_vol_complaint =
   {"const/volatile indicator missing, got '%c'", 0, 0};
 
-struct complaint error_type_complaint =
+static struct complaint error_type_complaint =
   {"debug info mismatch between compiler and debugger", 0, 0};
 
-struct complaint invalid_member_complaint =
+static struct complaint invalid_member_complaint =
   {"invalid (minimal) member type data format at symtab pos %d.", 0, 0};
 
-struct complaint range_type_base_complaint =
+static struct complaint range_type_base_complaint =
   {"base type %d of range type is not defined", 0, 0};
 
-struct complaint reg_value_complaint =
+static struct complaint reg_value_complaint =
   {"register number %d too large (max %d) in symbol %s", 0, 0};
 
-struct complaint vtbl_notfound_complaint =
+static struct complaint vtbl_notfound_complaint =
   {"virtual function table pointer not found when defining class `%s'", 0, 0};
 
-struct complaint unrecognized_cplus_name_complaint =
+static struct complaint unrecognized_cplus_name_complaint =
   {"Unknown C++ symbol name `%s'", 0, 0};
 
-struct complaint rs6000_builtin_complaint =
+static struct complaint rs6000_builtin_complaint =
   {"Unknown builtin type %d", 0, 0};
 
-struct complaint unresolved_sym_chain_complaint =
+static struct complaint unresolved_sym_chain_complaint =
   {"%s: common block `%s' from global_sym_chain unresolved", 0, 0};
 
-struct complaint stabs_general_complaint =
+static struct complaint stabs_general_complaint =
+  {"%s", 0, 0};
+
+static struct complaint lrs_general_complaint =
   {"%s", 0, 0};
 
 /* Make a list of forward references which haven't been defined.  */
@@ -1043,24 +1043,21 @@ resolve_cfront_continuation (objfile, sym, p)
 /* End of code added to support parsing of ARM/Cfront stabs strings */
 
 
-/* This routine fixes up symbol references to point to the original
-   symbol definition.
-   The main need for this function is to add information for supporting 
-   live range splitting.
-   eg: p : "#7=", "#2=z:r(0,1)" "#2:r(0,1);l(#5,#6),l(#7,#4)" */
-int
+/* This routine fixes up symbol references/aliases to point to the original
+   symbol definition.  Returns 0 on failure, non-zero on success.  */
+
+static int
 resolve_symbol_reference (objfile, sym, p)
-  struct objfile * objfile;
-  struct symbol * sym;
-  char * p;
+  struct objfile *objfile;
+  struct symbol *sym;
+  char *p;
 {
   int refnum;
-  struct symbol * ref_sym=0;
-  struct cleanup *back_to;
-
-  back_to = make_cleanup (null_cleanup, 0);
+  struct symbol *ref_sym=0;
+  struct alias_list *alias;
 
-  if (*p != '#')       /* symbol ref id */
+  /* If this is not a symbol reference return now.  */
+  if (*p != '#')
     return 0;  
 
   /* Use "#<num>" as the name; we'll fix the name later.
@@ -1075,10 +1072,17 @@ resolve_symbol_reference (objfile, sym, p)
   /*---------------------------------------------------------*/
 
   /* This gets reference name from string.  sym may not have a name. */
+
+  /* Get the reference number associated with the reference id in the
+     gdb stab string.  From that reference number, get the main/primary
+     symbol for this alias.  */
   refnum = process_reference (&p);
   ref_sym = ref_search (refnum);
   if (!ref_sym)
-    error ("error: symbol for reference not found.\n");
+    {
+      complain (&lrs_general_complaint, "symbol for reference not found");
+      return 0;
+    }
 
   /* Parse the stab of the referencing symbol
      now that we have the referenced symbol.
@@ -1107,8 +1111,33 @@ resolve_symbol_reference (objfile, sym, p)
    /*--------------------------------------------------*/
    /* Add this symbol to the reference list.           */
    /*--------------------------------------------------*/
-   SYMBOL_ALIASES (sym) = SYMBOL_ALIASES (ref_sym);
-   SYMBOL_ALIASES (ref_sym) = sym;
+
+  alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack,
+                                              sizeof (struct alias_list));
+  if (!alias)
+    {
+      complain (&lrs_general_complaint, "Unable to allocate alias list memory");
+      return 0;
+    }
+
+  alias->next = 0;
+  alias->sym = sym;
+
+  if (!SYMBOL_ALIASES (ref_sym))
+    {
+      SYMBOL_ALIASES (ref_sym) = alias;
+    }
+  else
+    {
+      struct alias_list *temp;
+
+      /* Get to the end of the list.  */
+      for (temp = SYMBOL_ALIASES (ref_sym);
+          temp->next;
+          temp = temp->next)
+       ;
+      temp->next = alias;
+    }
 
    /* Want to fix up name so that other functions (eg. valops)
       will correctly print the name.
@@ -1117,57 +1146,30 @@ resolve_symbol_reference (objfile, sym, p)
    SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym);
 
   /* Done!  */
-
-  do_cleanups (back_to);
-  return 0;  
-}
-
-/* Get range symbol reference. eg. "#2),l(#3,#5)"   
-   postpone resolve_reference until after we're done reading symbols. */
-struct symbol *
-resolve_reference (p)
-     char *p;
-{
-    char sym_refid[32];
-    struct symbol *sym = 0;
-    char *s = p;
-    int len;
-
-    if (!s || *s != '#')
-      return 0;
-    p = strchr (s, ')');
-    if (!p || p == s)
-      return 0;
-    len = p - s + 1;
-    strncpy (sym_refid, s, len);
-    sym_refid[len] = '\0';
-    sym = lookup_symbol (sym_refid, 0, VAR_NAMESPACE, 0, 0); 
-    return sym;
+  return 1;
 }
 
 /* Structure for storing pointers to reference definitions for fast lookup 
    during "process_later". */
-#define MAX_REFS 100   /* FIXME!  Change to use heap. */
-static struct ref_map_s
+
+struct ref_map
 {
   char *stabs;
   CORE_ADDR value;
   struct symbol *sym;
-} ref_map[MAX_REFS];   
-
-/* Initialize our list of references.
-   This should be called before any symbol table is read.
-   FIXME: Will reference numbers be unique only to objects?  If so, we may 
-   need to add something to disambiguate the refids.  Or, it might be OK to 
-   leave as is, as long as we read and process an object's symbol table all 
-   at once.  */
-static int ref_count = 0;      /* Ptr to free cell in linked list. */
-static void 
-ref_init ()
-{
-  ref_count = 0;
-  memset (ref_map, 0, MAX_REFS * sizeof (struct ref_map_s));
-}
+};
+
+#define MAX_CHUNK_REFS 100
+#define REF_CHUNK_SIZE (MAX_CHUNK_REFS * sizeof (struct ref_map))
+#define REF_MAP_SIZE(ref_chunk) ((ref_chunk) * REF_CHUNK_SIZE)
+
+static struct ref_map *ref_map;        
+
+/* Ptr to free cell in chunk's linked list. */
+static int ref_count = 0;      
+
+/* Number of chunks malloced. */
+static int ref_chunk = 0;
 
 /* Create array of pointers mapping refids to symbols and stab strings.
    Add pointers to reference definition symbols and/or their values as we 
@@ -1181,17 +1183,24 @@ ref_add (refnum, sym, stabs, value)
      CORE_ADDR value;
 {
   if (ref_count == 0)
-    ref_init ();
+    ref_chunk = 0;
   if (refnum >= ref_count)
     ref_count = refnum + 1;
-  if (ref_count > MAX_REFS)
-    error ("no more free slots in chain\n");
+  if (ref_count > ref_chunk * MAX_CHUNK_REFS)
+    {
+      int new_slots = ref_count - ref_chunk * MAX_CHUNK_REFS; 
+      int new_chunks = new_slots / MAX_CHUNK_REFS + 1;
+      ref_map = (struct ref_map *)
+       xrealloc (ref_map, REF_MAP_SIZE (ref_chunk + new_chunks));
+      memset (ref_map + ref_chunk * MAX_CHUNK_REFS, 0, new_chunks * REF_CHUNK_SIZE);
+      ref_chunk += new_chunks;
+    }
   ref_map[refnum].stabs = stabs;
   ref_map[refnum].sym = sym;
   ref_map[refnum].value = value;
 }
 
-/* Return defined sym for the reference "refnum" */
+/* Return defined sym for the reference REFNUM.  */
 struct symbol *
 ref_search (refnum)
      int refnum;
@@ -1201,7 +1210,8 @@ ref_search (refnum)
   return ref_map[refnum].sym;
 }
 
-/* Return value for the reference "refnum" */
+/* Return value for the reference REFNUM.  */
+
 static CORE_ADDR
 ref_search_value (refnum)
      int refnum;
@@ -1211,9 +1221,8 @@ ref_search_value (refnum)
   return ref_map[refnum].value;
 }
    
-/* Parse reference id and advance string to the next character following
-   the string. 
-   Return the reference number. */
+/* Parse a reference id in STRING and return the resulting
+   reference number.  Move STRING beyond the reference id.  */
 
 static int 
 process_reference (string)
@@ -1225,8 +1234,10 @@ process_reference (string)
   if (**string != '#') 
     return 0;  
      
+  /* Advance beyond the initial '#'.  */
+  p = *string + 1;
+
   /* Read number as reference id. */
-  p = *string + 1;     /* Advance beyond '#' */
   while (*p && isdigit (*p))
     {
       refnum = refnum * 10 + *p - '0';
@@ -1236,9 +1247,9 @@ process_reference (string)
   return refnum;
 }
 
-/* If string defines a reference, store away a pointer to the reference 
-   definition for fast lookup when we "process_later",
-   and return the reference number. */
+/* If STRING defines a reference, store away a pointer to the reference 
+   definition for later use.  Return the reference number.  */
+
 int
 symbol_reference_defined (string)
      char **string;
@@ -1252,7 +1263,6 @@ symbol_reference_defined (string)
   if (*p == '=') 
     {
       /* Symbol is being defined here. */ 
-
       *string = p + 1;
       return refnum;
     }
@@ -1260,9 +1270,8 @@ symbol_reference_defined (string)
     {
       /* Must be a reference.   Either the symbol has already been defined,
          or this is a forward reference to it.  */
-
       *string = p;
-      return 0;        /* Not defined here */
+      return -1;
     }
 }
 
@@ -1374,37 +1383,44 @@ define_symbol (valu, string, desc, type, objfile)
       char *s;
       int refnum, nlen;
 
-      /* Initialize symbol references and determine if this is 
-         a definition.  If symbol reference is being defined, go 
-         ahead and add it.  Otherwise, just return sym. */
+      /* If STRING defines a new reference id, then add it to the
+        reference map.  Else it must be referring to a previously
+        defined symbol, so add it to the alias list of the previously
+        defined symbol.  */
       s = string;
-      if (refnum = symbol_reference_defined (&s), refnum)
-        ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
+      refnum = symbol_reference_defined (&s);
+      if (refnum >= 0)
+         ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
       else
-        process_later (sym, string, resolve_symbol_reference);
+       if (!resolve_symbol_reference (objfile, sym, string))
+         return NULL;
 
-      /* s is after refid... advance string there
-         so that the symbol name will not include the refid. */
+      /* S..P contains the name of the symbol.  We need to store
+        the correct name into SYMBOL_NAME.  */
       nlen = p - s;
-      if (nlen > 0)
-        {
-          SYMBOL_NAME (sym) = (char *)
-           obstack_alloc (&objfile -> symbol_obstack, nlen);
-          strncpy (SYMBOL_NAME (sym), s, nlen);
-          SYMBOL_NAME (sym)[nlen] = '\0';
-          SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
-        }
-      else
-        /* FIXME! Want SYMBOL_NAME (sym) = 0;
-          Get error if leave name 0.  So give it something. */
-        {
-          nlen = p - string;
-          SYMBOL_NAME (sym)    = (char *)
-           obstack_alloc (&objfile -> symbol_obstack, nlen);
-          strncpy (SYMBOL_NAME (sym), string, nlen);
-          SYMBOL_NAME (sym)[nlen] = '\0';
-          SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
-        }
+      if (refnum >= 0)
+       {
+         if (nlen > 0)
+           {
+             SYMBOL_NAME (sym) = (char *)
+               obstack_alloc (&objfile -> symbol_obstack, nlen);
+             strncpy (SYMBOL_NAME (sym), s, nlen);
+             SYMBOL_NAME (sym)[nlen] = '\0';
+             SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+           }
+         else
+           /* FIXME! Want SYMBOL_NAME (sym) = 0;
+              Get error if leave name 0.  So give it something. */
+           {
+             nlen = p - string;
+             SYMBOL_NAME (sym) = (char *)
+               obstack_alloc (&objfile -> symbol_obstack, nlen);
+             strncpy (SYMBOL_NAME (sym), string, nlen);
+             SYMBOL_NAME (sym)[nlen] = '\0';
+             SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+           }
+       }
+      /* Advance STRING beyond the reference id.  */
       string = s;
     }
   else
@@ -1587,17 +1603,56 @@ define_symbol (valu, string, desc, type, objfile)
         in GDB.  E.g. "int" is converted to "function returning int".  */
       if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC)
        SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+
+      /* All functions in C++ have prototypes.  */
+      if (SYMBOL_LANGUAGE (sym) == language_cplus)
+       TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+
       /* fall into process_prototype_types */
 
     process_prototype_types:
-      /* Sun acc puts declared types of arguments here.  We don't care
-        about their actual types (FIXME -- we should remember the whole
-        function prototype), but the list may define some new types
-        that we have to remember, so we must scan it now.  */
-      while (*p == ';') {
-       p++;
-       read_type (&p, objfile);
-      }
+      /* Sun acc puts declared types of arguments here.  */
+      if (*p == ';')
+       {
+         struct type *ftype = SYMBOL_TYPE (sym);
+         int nsemi = 0;
+         int nparams = 0;
+         char *p1 = p;
+
+         /* Obtain a worst case guess for the number of arguments
+            by counting the semicolons.  */
+         while (*p1)
+           {
+             if (*p1++ == ';')
+               nsemi++;
+           }
+
+         /* Allocate parameter information fields and fill them in. */
+         TYPE_FIELDS (ftype) = (struct field *)
+           TYPE_ALLOC (ftype, nsemi * sizeof (struct field));
+         while (*p++ == ';')
+           {
+             struct type *ptype;
+
+             /* A type number of zero indicates the start of varargs.
+                FIXME: GDB currently ignores vararg functions.  */
+             if (p[0] == '0' && p[1] == '\0')
+               break;
+             ptype = read_type (&p, objfile);
+
+             /* The Sun compilers mark integer arguments, which should
+                be promoted to the width of the calling conventions, with
+                a type which references itself. This type is turned into
+                a TYPE_CODE_VOID type by read_type, and we have to turn
+                it back into builtin_type_int here.
+                FIXME: Do we need a new builtin_type_promoted_int_arg ?  */
+             if (TYPE_CODE (ptype) == TYPE_CODE_VOID)
+               ptype = builtin_type_int;
+             TYPE_FIELD_TYPE (ftype, nparams++) = ptype;
+           }
+         TYPE_NFIELDS (ftype) = nparams;
+         TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+       }
       break;
 
     case 'F':
@@ -1848,7 +1903,7 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
 #ifdef STATIC_TRANSFORM_NAME
-      if (SYMBOL_NAME (sym)[0] == '$')
+      if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
       {
        struct minimal_symbol *msym;
        msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
@@ -1976,7 +2031,7 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
 #ifdef STATIC_TRANSFORM_NAME
-      if (SYMBOL_NAME (sym)[0] == '$')
+      if (IS_STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym)))
       {
        struct minimal_symbol *msym;
        msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
@@ -2088,8 +2143,8 @@ define_symbol (valu, string, desc, type, objfile)
        }
     }
 
-  /* Is there more to parse?  eg. ";l(#1,#2);l(#3,#5)" */
-  while (*p && (*p == ';' || *p == ','))
+  /* Is there more to parse?  For example LRS/alias information?  */
+  while (*p && *p == ';')
     {
       p++;
       if (*p && *p == 'l')
@@ -2097,120 +2152,131 @@ define_symbol (valu, string, desc, type, objfile)
           /* GNU extensions for live range splitting may be appended to 
              the end of the stab string.  eg. "l(#1,#2);l(#3,#5)" */
 
-          /* Fix up ranges later. */
-          process_later (sym, p, resolve_live_range);
+         /* Resolve the live range and add it to SYM's live range list.  */
+         if (!resolve_live_range (objfile, sym, p))
+           return NULL;
 
          /* Find end of live range info. */
          p = strchr (p, ')');
           if (!*p || *p != ')')
-            error ("Internal error: live range format not recognized.\n");
+           {
+             complain (&lrs_general_complaint, "live range format not recognized");
+             return NULL;
+           }
           p++;
        }
     }
   return sym;
 }
 
+/* Add the live range found in P to the symbol SYM in objfile OBJFILE.  Returns
+   non-zero on success, zero otherwise.  */
 
-/* Add live range information to symbol. (eg. p is l(#1,#2)...) */
-static int 
+static int
 resolve_live_range (objfile, sym, p)
-  struct objfile * objfile;
-  struct symbol *sym;
-  char *p;
+     struct objfile *objfile;
+     struct symbol *sym;
+     char *p;
 {
-  char *s=p;
   int refnum;
   CORE_ADDR start, end;
-  
+
+  /* Sanity check the beginning of the stabs string.  */
   if (!*p || *p != 'l')
-    error ("Internal error: live range string.\n");
+    {
+      complain (&lrs_general_complaint, "live range string 1");
+      return 0;
+    }
   p++;
 
   if (!*p || *p != '(')
-    error ("Internal error: live range string.\n");
+    {
+      complain (&lrs_general_complaint, "live range string 2");
+      return 0;
+    }
   p++;
        
-  /* Get starting value of range symbol reference. eg. "#1,#2),l(#3,#5)"
-     and advance p past the refid. */
+  /* Get starting value of range and advance P past the reference id.
+
+     ?!? In theory, the process_reference should never fail, but we should
+     catch that case just in case the compiler scrogged the stabs.  */
   refnum = process_reference (&p);
   start = ref_search_value (refnum);
   if (!start)
-    error ("Internal error: live range symbol not found.\n");
+    {
+      complain (&lrs_general_complaint, "Live range symbol not found 1");
+      return 0;
+    }
 
   if (!*p || *p != ',')
-    error ("Internal error: live range string.\n");
+    {
+      complain (&lrs_general_complaint, "live range string 3");
+      return 0;
+    }
   p++;
 
-  /* Get ending value of range symbol reference. eg. "#2),l(#3,#5)" */
+  /* Get ending value of range and advance P past the reference id.
+
+     ?!? In theory, the process_reference should never fail, but we should
+     catch that case just in case the compiler scrogged the stabs.  */
   refnum = process_reference (&p);
   end = ref_search_value (refnum);
   if (!end)
-    error ("Internal error: live range symbol not found.\n");
+    {
+      complain (&lrs_general_complaint, "Live range symbol not found 2");
+      return 0;
+    }
 
+  if (!*p || *p != ')')
+    {
+      complain (&lrs_general_complaint, "live range string 4");
+      return 0;
+    }
+
+  /* Now that we know the bounds of the range, add it to the
+     symbol.  */
   add_live_range (objfile, sym, start, end);
 
-  if (!*p || *p != ')')
-    error ("Internal error: live range string.\n");
-  p++;
-  return 0; 
+  return 1;
 }
 
+/* Add a new live range defined by START and END to the symbol SYM
+   in objfile OBJFILE.  */
+
 static void
 add_live_range (objfile, sym, start, end)
-  struct objfile *objfile;
-  struct symbol *sym;
-  CORE_ADDR start, end;
+     struct objfile *objfile;
+     struct symbol *sym;
+     CORE_ADDR start, end;
 {
-  struct live_range *r, *rs;
+  struct range_list *r, *rs;
 
   if (start >= end)
-    error ("Internal error: end of live range follows start.\n");
+    {
+      complain (&lrs_general_complaint, "end of live range follows start");
+      return;
+    }
 
   /* Alloc new live range structure. */
-  r = (struct live_range *)
-               obstack_alloc (&objfile->type_obstack, 
-                               sizeof (struct live_range));
+  r = (struct range_list *)
+    obstack_alloc (&objfile->type_obstack, 
+                  sizeof (struct range_list));
   r->start = start;
   r->end = end;
   r->next = 0;
 
   /* Append this range to the symbol's range list. */
-  if (!SYMBOL_RANGE (sym))
-    {
-      SYMBOL_RANGE (sym) = r;
-    }
+  if (!SYMBOL_RANGES (sym))
+    SYMBOL_RANGES (sym) = r;
   else
     {
       /* Get the last range for the symbol. */
-      for (rs = SYMBOL_RANGE (sym); rs->next; rs = rs->next)
+      for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next)
        ;
       rs->next = r;
     }
 }
 
-/* Given addr, Search thu alias list to find the one active. */
-struct symbol *
-ref_search_val (sym, addr)
-  struct symbol *sym;
-  CORE_ADDR addr;
-{
-  struct live_range *r;
-
-  while (sym)
-    {
-      if (!SYMBOL_RANGE (sym))
-        return sym;
-      for (r = SYMBOL_RANGE (sym); r; r = r->next)
-       {
-         if (r->start <= addr
-                   && r->end > addr)
-           return sym;
-       }
-      sym = SYMBOL_ALIASES (sym);
-    }
-  return 0;
-}
-
 \f
 /* Skip rest of this symbol and return an error type.
 
@@ -2826,11 +2892,11 @@ rs6000_builtin_type (typenum)
       break;
     case 25:
       /* Complex type consisting of two IEEE single precision values.  */
-      rettype = init_type (TYPE_CODE_ERROR, 8, 0, "complex", NULL);
+      rettype = init_type (TYPE_CODE_COMPLEX, 8, 0, "complex", NULL);
       break;
     case 26:
       /* Complex type consisting of two IEEE double precision values.  */
-      rettype = init_type (TYPE_CODE_ERROR, 16, 0, "double complex", NULL);
+      rettype = init_type (TYPE_CODE_COMPLEX, 16, 0, "double complex", NULL);
       break;
     case 27:
       rettype = init_type (TYPE_CODE_INT, 1, 0, "integer*1", NULL);
@@ -3388,15 +3454,18 @@ read_one_struct_field (fip, pp, p, type, objfile)
         Note that forward refs cannot be packed,
         and treat enums as if they had the width of ints.  */
 
-      if (TYPE_CODE (FIELD_TYPE (fip->list->field)) != TYPE_CODE_INT
-         && TYPE_CODE (FIELD_TYPE (fip->list->field)) != TYPE_CODE_BOOL
-         && TYPE_CODE (FIELD_TYPE (fip->list->field)) != TYPE_CODE_ENUM)
+      struct type *field_type = check_typedef (FIELD_TYPE (fip->list->field));
+
+      if (TYPE_CODE (field_type) != TYPE_CODE_INT
+         && TYPE_CODE (field_type) != TYPE_CODE_RANGE
+         && TYPE_CODE (field_type) != TYPE_CODE_BOOL
+         && TYPE_CODE (field_type) != TYPE_CODE_ENUM)
        {
          FIELD_BITSIZE (fip->list->field) = 0;
        }
       if ((FIELD_BITSIZE (fip->list->field) 
-          == TARGET_CHAR_BIT * TYPE_LENGTH (FIELD_TYPE (fip->list->field))
-          || (TYPE_CODE (FIELD_TYPE (fip->list->field)) == TYPE_CODE_ENUM
+          == TARGET_CHAR_BIT * TYPE_LENGTH (field_type)
+          || (TYPE_CODE (field_type) == TYPE_CODE_ENUM
               && FIELD_BITSIZE (fip->list->field) == TARGET_INT_BIT )
           )
          &&
@@ -4234,8 +4303,9 @@ read_enum_type (pp, type, objfile)
 /* Sun's ACC uses a somewhat saner method for specifying the builtin
    typedefs in every file (for int, long, etc):
 
-       type = b <signed> <width>; <offset>; <nbits>
-       signed = u or s.  Possible c in addition to u or s (for char?).
+       type = b <signed> <width> <format type>; <offset>; <nbits>
+       signed = u or s.
+       optional format type = c or b for char or boolean.
        offset = offset from high order bit to start bit of type.
        width is # bytes in object of this type, nbits is # bits in type.
 
@@ -4252,6 +4322,7 @@ read_sun_builtin_type (pp, typenums, objfile)
   int type_bits;
   int nbits;
   int signed_type;
+  enum type_code code = TYPE_CODE_INT;
 
   switch (**pp)
     {
@@ -4269,10 +4340,16 @@ read_sun_builtin_type (pp, typenums, objfile)
   /* For some odd reason, all forms of char put a c here.  This is strange
      because no other type has this honor.  We can safely ignore this because
      we actually determine 'char'acterness by the number of bits specified in
-     the descriptor.  */
+     the descriptor.
+     Boolean forms, e.g Fortran logical*X, put a b here.  */
 
   if (**pp == 'c')
     (*pp)++;
+  else if (**pp == 'b')
+    {
+      code = TYPE_CODE_BOOL;
+      (*pp)++;
+    }
 
   /* The first number appears to be the number of bytes occupied
      by this type, except that unsigned short is 4 instead of 2.
@@ -4305,7 +4382,7 @@ read_sun_builtin_type (pp, typenums, objfile)
                      signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
                      objfile);
   else
-    return init_type (TYPE_CODE_INT,
+    return init_type (code,
                      type_bits / TARGET_CHAR_BIT,
                      signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
                      objfile);
@@ -4336,7 +4413,7 @@ read_sun_floating_type (pp, typenums, objfile)
       || details == NF_COMPLEX32)
     /* This is a type we can't handle, but we do know the size.
        We also will be able to give it a name.  */
-    return init_type (TYPE_CODE_ERROR, nbytes, 0, NULL, objfile);
+    return init_type (TYPE_CODE_COMPLEX, nbytes, 0, NULL, objfile);
 
   return init_type (TYPE_CODE_FLT, nbytes, 0, NULL, objfile);
 }
@@ -4540,20 +4617,28 @@ read_range_type (pp, typenums, objfile)
   if (self_subrange && n2 == 0 && n3 == 0)
     return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
 
-  /* If n3 is zero and n2 is positive, we want a floating type,
-     and n2 is the width in bytes.
+  /* If n3 is zero and n2 is positive, we want a floating type, and n2
+     is the width in bytes.
 
-     Fortran programs appear to use this for complex types also,
-     and they give no way to distinguish between double and single-complex!
+     Fortran programs appear to use this for complex types also.  To
+     distinguish between floats and complex, g77 (and others?)  seem
+     to use self-subranges for the complexes, and subranges of int for
+     the floats.
 
-     GDB does not have complex types.
-
-     Just return the complex as a float of that size.  It won't work right
-     for the complex values, but at least it makes the file loadable.  */
+     Also note that for complexes, g77 sets n2 to the size of one of
+     the member floats, not the whole complex beast.  My guess is that
+     this was to work well with pre-COMPLEX versions of gdb. */
 
   if (n3 == 0 && n2 > 0)
     {
-      return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+      if (self_subrange)
+       {
+         return init_type (TYPE_CODE_COMPLEX, 2 * n2, 0, NULL, objfile);
+       }
+      else
+       {
+         return init_type (TYPE_CODE_FLT, n2, 0, NULL, objfile);
+       }
     }
 
   /* If the upper bound is -1, it must really be an unsigned int.  */
@@ -4953,6 +5038,9 @@ scan_file_globals (objfile)
              if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
                  STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
                {
+
+                 struct alias_list *aliases;
+
                  /* Splice this symbol out of the hash chain and
                     assign the value we have to it. */
                  if (prev)
@@ -4974,19 +5062,30 @@ scan_file_globals (objfile)
                  /* FIXME: Maybe should have added aliases to the global chain,                     resolved symbol name, then treated aliases as normal 
                     symbols?  Still, we wouldn't want to add_to_list. */
                  /* Now do the same for each alias of this symbol */
-                 for (rsym = sym; rsym; rsym = SYMBOL_ALIASES (rsym))
+                 rsym = sym;
+                 aliases = SYMBOL_ALIASES (sym);
+                 while (rsym)
                    {
                      if (SYMBOL_CLASS (rsym) == LOC_BLOCK)
-                       {
-                         fix_common_block (rsym, SYMBOL_VALUE_ADDRESS (msymbol));
-                       }
+                       {
+                         fix_common_block (rsym,
+                                           SYMBOL_VALUE_ADDRESS (msymbol));
+                       }
                      else
-                       {
-                         SYMBOL_VALUE_ADDRESS (rsym)
+                       {
+                         SYMBOL_VALUE_ADDRESS (rsym)
                            = SYMBOL_VALUE_ADDRESS (msymbol);
-                       }
+                       }
                      SYMBOL_SECTION (rsym) = SYMBOL_SECTION (msymbol);
+                     if (aliases)
+                       {
+                         rsym = aliases->sym;
+                         aliases = aliases->next;
+                       }
+                     else
+                       rsym = NULL;
                    }
+
                  
                  if (prev)
                    {
This page took 0.035763 seconds and 4 git commands to generate.