Fix gcc -Wall warnings. See ChangeLog for details.
[deliverable/binutils-gdb.git] / gdb / stabsread.c
index da4632f5679f1aea6ded7aac2482ee43d3934e8b..ac848b928fe122fafd63d9af9b32ed6ed5e0b8e5 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for decoding "stabs" debugging information format.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
+   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
              Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -16,7 +16,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Support routines for reading and decoding debugging information in
    the "stabs" format.  This format is used with many systems that use
@@ -25,11 +25,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    Avoid placing any object file format specific code in this file. */
 
 #include "defs.h"
-#include <string.h>
+#include "gdb_string.h"
 #include "bfd.h"
 #include "obstack.h"
 #include "symtab.h"
 #include "gdbtypes.h"
+#include "expression.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "aout/stab_gnu.h"     /* We always use GNU stabs, not native */
@@ -39,6 +40,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "buildsym.h"
 #include "complaints.h"
 #include "demangle.h"
+#include "language.h"
 
 #include <ctype.h>
 
@@ -73,12 +75,19 @@ struct field_info
     } *fnlist;
 };
 
+static void
+read_one_struct_field PARAMS ((struct field_info *, char **, char *,
+                              struct type *, struct objfile *));
+
+static char * 
+get_substring PARAMS ((char **, int));
+
 static struct type *
 dbx_alloc_type PARAMS ((int [2], struct objfile *));
 
 static long read_huge_number PARAMS ((char **, int, int *));
 
-static struct type *error_type PARAMS ((char **));
+static struct type *error_type PARAMS ((char **, struct objfile *));
 
 static void
 patch_block_stabs PARAMS ((struct pending *, struct pending_stabs *,
@@ -141,6 +150,47 @@ static int
 read_cpp_abbrev PARAMS ((struct field_info *, char **, struct type *,
                         struct objfile *));
 
+/* new functions added for cfront support */
+
+static int
+copy_cfront_struct_fields PARAMS ((struct field_info *, struct type *,
+                                   struct objfile *));
+
+static char *
+get_cfront_method_physname PARAMS ((char *));
+
+static int
+read_cfront_baseclasses PARAMS ((struct field_info *, char **, 
+                                struct type *, struct objfile *));
+
+static int
+read_cfront_static_fields PARAMS ((struct field_info *, char**,
+                                  struct type *, struct objfile *));
+static int
+read_cfront_member_functions PARAMS ((struct field_info *, char **, 
+                                     struct type *, struct objfile *));
+
+/* end new functions added for cfront support */
+
+static void 
+add_live_range PARAMS ((struct objfile *, struct symbol *, 
+                       CORE_ADDR, CORE_ADDR));
+
+static void 
+resolve_live_range PARAMS ((struct objfile *, struct symbol *, char *));
+
+static int 
+process_reference PARAMS ((char **string));
+
+static CORE_ADDR 
+ref_search_value PARAMS ((int refnum));
+
+static void 
+ref_init PARAMS ((void));
+
+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' };
 
@@ -175,7 +225,7 @@ struct complaint range_type_base_complaint =
   {"base type %d of range type is not defined", 0, 0};
 
 struct complaint reg_value_complaint =
-  {"register number too large in symbol %s", 0, 0};
+  {"register number %d too large (max %d) in symbol %s", 0, 0};
 
 struct complaint vtbl_notfound_complaint =
   {"virtual function table pointer not found when defining class `%s'", 0, 0};
@@ -186,6 +236,9 @@ struct complaint unrecognized_cplus_name_complaint =
 struct complaint rs6000_builtin_complaint =
   {"Unknown builtin type %d", 0, 0};
 
+struct complaint unresolved_sym_chain_complaint =
+  {"%s: common block `%s' from global_sym_chain unresolved", 0, 0};
+
 struct complaint stabs_general_complaint =
   {"%s", 0, 0};
 
@@ -194,12 +247,13 @@ struct complaint stabs_general_complaint =
 static struct type **undef_types;
 static int undef_types_allocated;
 static int undef_types_length;
+static struct symbol *current_symbol = NULL;
 
 /* Check for and handle cretinous stabs symbol name continuation!  */
-#define STABS_CONTINUE(pp)                             \
+#define STABS_CONTINUE(pp,objfile)                             \
   do {                                                 \
     if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
-      *(pp) = next_symbol_text ();     \
+      *(pp) = next_symbol_text (objfile);      \
   } while (0)
 \f
 /* FIXME: These probably should be our own types (like rs6000_builtin_type
@@ -285,7 +339,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
            {
              type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
              type_vector = (struct type **)
-               malloc (type_vector_length * sizeof (struct type *));
+               xmalloc (type_vector_length * sizeof (struct type *));
            }
          while (index >= type_vector_length)
            {
@@ -307,7 +361,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
     {
       real_filenum = this_object_header_files[filenum];
 
-      if (real_filenum >= n_header_files)
+      if (real_filenum >= N_HEADER_FILES (current_objfile))
        {
          struct type *temp_type;
          struct type **temp_type_p;
@@ -321,7 +375,7 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
          return temp_type_p;
        }
 
-      f = &header_files[real_filenum];
+      f = HEADER_FILES (current_objfile) + real_filenum;
 
       f_orig_length = f->length;
       if (index >= f_orig_length)
@@ -421,7 +475,7 @@ patch_block_stabs (symbols, stabs, objfile)
              SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
              SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
              SYMBOL_NAME (sym) =
-               obstack_copy0 (&objfile->symbol_obstack, name, pp - name);
+               obsavestring (name, pp - name, &objfile->symbol_obstack);
              pp += 2;
              if (*(pp-1) == 'F' || *(pp-1) == 'f')
                {
@@ -487,18 +541,745 @@ read_type_number (pp, typenums)
 }
 
 \f
-/* To handle GNU C++ typename abbreviation, we need to be able to
-   fill in a type's name as soon as space for that type is allocated.
-   `type_synonym_name' is the name of the type being allocated.
-   It is cleared as soon as it is used (lest all allocated types
-   get this name).  */
-
-static char *type_synonym_name;
-
 #if !defined (REG_STRUCT_HAS_ADDR)
 #define REG_STRUCT_HAS_ADDR(gcc_p,type) 0
 #endif
 
+#define VISIBILITY_PRIVATE     '0'     /* Stabs character for private field */
+#define VISIBILITY_PROTECTED   '1'     /* Stabs character for protected fld */
+#define VISIBILITY_PUBLIC      '2'     /* Stabs character for public field */
+#define VISIBILITY_IGNORE      '9'     /* Optimized out or zero length */
+
+#define CFRONT_VISIBILITY_PRIVATE      '2'     /* Stabs character for private field */
+#define CFRONT_VISIBILITY_PUBLIC       '1'     /* Stabs character for public field */
+
+/* This code added to support parsing of ARM/Cfront stabs strings */
+
+/* Get substring from string up to char c, advance string pointer past
+   suibstring. */
+
+static char * 
+get_substring (p, c)
+  char ** p;
+  int c;
+{
+  char *str;
+  str = *p;
+  *p = strchr (*p, c);
+  if (*p) 
+    {
+      **p = 0;
+      (*p)++;
+    }
+  else 
+    str = 0;
+  return str;
+}
+
+/* Physname gets strcat'd onto sname in order to recreate the mangled
+   name (see funtion gdb_mangle_name in gdbtypes.c).  For cfront, make
+   the physname look like that of g++ - take out the initial mangling
+   eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */
+
+static char * 
+get_cfront_method_physname (fname)
+  char *fname;
+{
+  int len = 0;
+  /* FIXME would like to make this generic for g++ too, but 
+     that is already handled in read_member_funcctions */
+  char * p = fname;
+
+  /* search ahead to find the start of the mangled suffix */
+  if (*p == '_' && *(p+1)=='_') /* compiler generated; probably a ctor/dtor */
+    p += 2;            
+  while (p && (unsigned) ((p+1) - fname) < strlen (fname) && *(p+1) != '_')
+    p = strchr (p, '_');
+  if (!(p && *p == '_' && *(p+1) == '_')) 
+    error ("Invalid mangled function name %s",fname);
+  p += 2; /* advance past '__' */
+
+  /* struct name length and name of type should come next; advance past it */
+  while (isdigit (*p))
+    {
+      len = len * 10 + (*p - '0');
+      p++;
+    }
+  p += len;
+
+  return p;
+}
+
+/* Read base classes within cfront class definition.
+   eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+             ^^^^^^^^^^^^^^^^^^
+
+       A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+             ^
+   */
+
+static int
+read_cfront_baseclasses (fip, pp, type, objfile) 
+  struct field_info *fip;
+  struct objfile *objfile;
+  char ** pp;
+  struct type *type;
+{
+  static struct complaint msg_unknown = {"\
+        Unsupported token in stabs string %s.\n",
+                 0, 0};
+  static struct complaint msg_notfound = {"\
+                  Unable to find base type for %s.\n",
+                                0, 0};
+  int bnum = 0;
+  char * p;
+  int i;
+  struct nextfield *new;
+
+  if (**pp == ';')             /* no base classes; return */
+    {
+      ++(*pp);
+      return 1;
+    }
+
+  /* first count base classes so we can allocate space before parsing */
+  for (p = *pp; p && *p && *p != ';'; p++)
+    {
+      if (*p == ' ')
+       bnum++;
+    }
+  bnum++;      /* add one more for last one */
+
+  /* now parse the base classes until we get to the start of the methods 
+     (code extracted and munged from read_baseclasses) */
+  ALLOCATE_CPLUS_STRUCT_TYPE (type);
+  TYPE_N_BASECLASSES(type) = bnum;
+
+  /* allocate space */
+  {
+    int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type));
+    char *pointer;
+
+    pointer = (char *) TYPE_ALLOC (type, num_bytes);
+    TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
+  }
+  B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
+
+  for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+    {
+      new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+      make_cleanup (free, new);
+      memset (new, 0, sizeof (struct nextfield));
+      new -> next = fip -> list;
+      fip -> list = new;
+      FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */
+
+      STABS_CONTINUE (pp, objfile);
+
+      /* virtual?  eg: v2@Bvir */
+      if (**pp=='v')
+        {
+          SET_TYPE_FIELD_VIRTUAL (type, i);
+          ++(*pp);
+       }
+
+      /* access?  eg: 2@Bvir */
+       /* Note: protected inheritance not supported in cfront */
+      switch (*(*pp)++)
+        {
+          case CFRONT_VISIBILITY_PRIVATE:
+            new -> visibility = VISIBILITY_PRIVATE;
+            break;
+          case CFRONT_VISIBILITY_PUBLIC:
+            new -> visibility = VISIBILITY_PUBLIC;
+            break;
+          default:
+            /* Bad visibility format.  Complain and treat it as
+               public.  */
+            {
+              static struct complaint msg = {
+                "Unknown visibility `%c' for baseclass", 0, 0};
+              complain (&msg, new -> visibility);
+              new -> visibility = VISIBILITY_PUBLIC;
+            }
+        }
+
+      /* "@" comes next - eg: @Bvir */
+      if (**pp!='@')
+        {
+          complain (&msg_unknown, *pp);
+          return 1;
+       }
+      ++(*pp);
+
+
+        /* Set the bit offset of the portion of the object corresponding 
+          to this baseclass.  Always zero in the absence of
+           multiple inheritance.  */
+       /* Unable to read bit position from stabs;
+          Assuming no multiple inheritance for now FIXME! */
+       /* We may have read this in the structure definition;
+          now we should fixup the members to be the actual base classes */
+        FIELD_BITPOS (new->field) = 0;
+
+       /* Get the base class name and type */
+         {
+           char * bname;               /* base class name */
+           struct symbol * bsym;       /* base class */
+           char * p1, * p2;
+           p1 = strchr (*pp,' ');
+           p2 = strchr (*pp,';');
+           if (p1<p2)
+              bname = get_substring (pp,' ');
+           else
+              bname = get_substring (pp,';');
+            if (!bname || !*bname)
+             {
+               complain (&msg_unknown, *pp);
+               return 1;
+             }
+           /* FIXME! attach base info to type */
+           bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name*/
+           if (bsym) 
+             {
+               new -> field.type = SYMBOL_TYPE(bsym);
+               new -> field.name = type_name_no_tag (new -> field.type);
+             }
+           else
+             {
+               complain (&msg_notfound, *pp);
+               return 1;
+             }
+         }
+
+      /* If more base classes to parse, loop again.
+         We ate the last ' ' or ';' in get_substring,
+         so on exit we will have skipped the trailing ';' */
+      /* if invalid, return 0; add code to detect  - FIXME! */
+    }
+  return 1;
+}
+
+/* read cfront member functions.
+   pp points to string starting with list of functions
+   eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
+       A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
+*/
+
+static int
+read_cfront_member_functions (fip, pp, type, objfile)
+     struct field_info *fip;
+     char **pp;
+     struct type *type;
+     struct objfile *objfile;
+{
+  /* This code extracted from read_member_functions 
+     so as to do the similar thing for our funcs */
+
+  int nfn_fields = 0;
+  int length = 0;
+  /* Total number of member functions defined in this class.  If the class
+     defines two `f' functions, and one `g' function, then this will have
+     the value 3.  */
+  int total_length = 0;
+  int i;
+  struct next_fnfield
+    {
+      struct next_fnfield *next;
+      struct fn_field fn_field;
+    } *sublist;
+  struct type *look_ahead_type;
+  struct next_fnfieldlist *new_fnlist;
+  struct next_fnfield *new_sublist;
+  char *main_fn_name;
+  char * fname;
+  struct symbol * ref_func = 0;
+      
+  /* Process each list until we find the end of the member functions.
+     eg: p = "__ct__1AFv foo__1AFv ;;;" */
+
+  STABS_CONTINUE (pp, objfile);                /* handle \\ */
+
+  while (**pp != ';' && (fname = get_substring (pp, ' '), fname)) 
+    {
+      int is_static = 0;
+      int sublist_count = 0;
+      char * pname;
+      if (fname[0] == '*')      /* static member */
+        {
+          is_static=1;
+          sublist_count++;
+          fname++;
+        }
+      ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /* demangled name */
+      if (!ref_func) 
+        {
+          static struct complaint msg = {"\
+               Unable to find function symbol for %s\n",
+                                0, 0};
+         complain (&msg, fname);
+         continue;
+       }
+      sublist = NULL;
+      look_ahead_type = NULL;
+      length = 0;
+          
+      new_fnlist = (struct next_fnfieldlist *)
+      xmalloc (sizeof (struct next_fnfieldlist));
+      make_cleanup (free, new_fnlist);
+      memset (new_fnlist, 0, sizeof (struct next_fnfieldlist));
+          
+      /* The following is code to work around cfront generated stabs.
+         The stabs contains full mangled name for each field.
+         We try to demangle the name and extract the field name out of it.  */
+      {
+        char *dem, *dem_p, *dem_args;
+        int dem_len;
+        dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS);
+        if (dem != NULL)
+          {
+            dem_p = strrchr (dem, ':');
+            if (dem_p != 0 && *(dem_p-1) == ':')
+              dem_p++;
+           /* get rid of args */
+            dem_args = strchr (dem_p, '(');
+           if (dem_args == NULL)
+             dem_len = strlen (dem_p);
+           else
+             dem_len = dem_args - dem_p;
+            main_fn_name =
+                   obsavestring (dem_p, dem_len, &objfile -> type_obstack);
+          }
+        else
+          {
+            main_fn_name =
+                   obsavestring (fname, strlen (fname), &objfile -> type_obstack);
+          }
+      } /* end of code for cfront work around */
+
+    new_fnlist -> fn_fieldlist.name = main_fn_name;
+      
+    /*-------------------------------------------------*/
+    /* Set up the sublists
+       Sublists are stuff like args, static, visibility, etc.
+       so in ARM, we have to set that info some other way.
+       Multiple sublists happen if overloading
+       eg: foo::26=##1;:;2A.;
+       In g++, we'd loop here thru all the sublists...  */
+
+    new_sublist =
+       (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield));
+    make_cleanup (free, new_sublist);
+    memset (new_sublist, 0, sizeof (struct next_fnfield));
+         
+    /* eat 1; from :;2A.; */
+    new_sublist -> fn_field.type = SYMBOL_TYPE(ref_func); /* normally takes a read_type */
+    /* Make this type look like a method stub for gdb */
+    TYPE_FLAGS (new_sublist -> fn_field.type) |= TYPE_FLAG_STUB;
+    TYPE_CODE (new_sublist -> fn_field.type) = TYPE_CODE_METHOD;
+
+    /* If this is just a stub, then we don't have the real name here. */
+    if (TYPE_FLAGS (new_sublist -> fn_field.type) & TYPE_FLAG_STUB)
+      {
+        if (!TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type))
+        TYPE_DOMAIN_TYPE (new_sublist -> fn_field.type) = type;
+        new_sublist -> fn_field.is_stub = 1;
+      }
+
+    /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i 
+       physname gets strcat'd in order to recreate the onto mangled name */
+    pname = get_cfront_method_physname (fname);
+    new_sublist -> fn_field.physname = savestring (pname, strlen (pname));
+      
+
+    /* Set this member function's visibility fields. 
+       Unable to distinguish access from stabs definition!
+         Assuming public for now.  FIXME!
+        (for private, set new_sublist->fn_field.is_private = 1,
+        for public, set new_sublist->fn_field.is_protected = 1) */
+       
+    /* Unable to distinguish const/volatile from stabs definition!
+       Assuming normal for now.  FIXME! */
+
+    new_sublist -> fn_field.is_const = 0;
+    new_sublist -> fn_field.is_volatile = 0;   /* volatile not implemented in cfront */
+         
+    /* Set virtual/static function info
+       How to get vtable offsets ? 
+       Assuming normal for now FIXME!! 
+       For vtables, figure out from whence this virtual function came.
+       It may belong to virtual function table of
+       one of its baseclasses.
+        set:
+          new_sublist -> fn_field.voffset = vtable offset,
+          new_sublist -> fn_field.fcontext = look_ahead_type;
+          where look_ahead_type is type of baseclass */
+    if (is_static)
+      new_sublist -> fn_field.voffset = VOFFSET_STATIC;
+    else                               /* normal member function.  */
+      new_sublist -> fn_field.voffset = 0;
+    new_sublist -> fn_field.fcontext = 0;
+
+    /* Prepare new sublist */
+    new_sublist -> next = sublist;
+    sublist = new_sublist;
+    length++;
+
+    /* In g++, we loop thu sublists - now we set from functions. */
+    new_fnlist -> fn_fieldlist.fn_fields = (struct fn_field *)
+         obstack_alloc (&objfile -> type_obstack, 
+              sizeof (struct fn_field) * length);
+    memset (new_fnlist -> fn_fieldlist.fn_fields, 0,
+           sizeof (struct fn_field) * length);
+    for (i = length; (i--, sublist); sublist = sublist -> next)
+      {
+        new_fnlist -> fn_fieldlist.fn_fields[i] = sublist -> fn_field;
+      }
+      
+    new_fnlist -> fn_fieldlist.length = length;
+    new_fnlist -> next = fip -> fnlist;
+    fip -> fnlist = new_fnlist;
+    nfn_fields++;
+    total_length += length;
+    STABS_CONTINUE (pp, objfile); /* handle \\ */
+  } /* end of loop */
+
+  if (nfn_fields)
+    {
+      /* type should already have space */
+      TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
+      TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields);
+      memset (TYPE_FN_FIELDLISTS (type), 0,
+               sizeof (struct fn_fieldlist) * nfn_fields);
+      TYPE_NFN_FIELDS (type) = nfn_fields;
+      TYPE_NFN_FIELDS_TOTAL (type) = total_length;
+    }
+
+  /* end of scope for reading member func */
+
+  /* eg: ";;" */
+
+  /* Skip trailing ';' and bump count of number of fields seen */
+  if (**pp == ';')
+    (*pp)++;
+  else
+    return 0;
+  return 1;
+}
+
+/* This routine fixes up partial cfront types that were created
+   while parsing the stabs.  The main need for this function is
+   to add information such as methods to classes.
+   Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */
+int
+resolve_cfront_continuation (objfile, sym, p)
+  struct objfile * objfile;
+  struct symbol * sym;
+  char * p;
+{
+  struct symbol * ref_sym=0;
+  char * sname;
+  /* snarfed from read_struct_type */
+  struct field_info fi;
+  struct type *type;
+  struct cleanup *back_to;
+
+  /* Need to make sure that fi isn't gunna conflict with struct 
+     in case struct already had some fnfs */
+  fi.list = NULL;
+  fi.fnlist = NULL;       
+  back_to = make_cleanup (null_cleanup, 0);
+
+  /* We only accept structs, classes and unions at the moment. 
+     Other continuation types include t (typedef), r (long dbl), ... 
+     We may want to add support for them as well; 
+     right now they are handled by duplicating the symbol information 
+     into the type information (see define_symbol) */
+  if (*p != 's'       /* structs */
+    && *p != 'c'      /* class */
+    && *p != 'u')     /* union */
+    return 0;  /* only handle C++ types */
+  p++;  
+
+  /* Get symbol typs name and validate 
+     eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */
+  sname = get_substring (&p, ';');
+  if (!sname || strcmp (sname, SYMBOL_NAME(sym)))
+    error ("Internal error: base symbol type name does not match\n");
+
+  /* Find symbol's internal gdb reference using demangled_name.
+     This is the real sym that we want; 
+     sym was a temp hack to make debugger happy */
+  ref_sym = lookup_symbol (SYMBOL_NAME(sym), 0, STRUCT_NAMESPACE, 0, 0); 
+  type = SYMBOL_TYPE(ref_sym);
+
+
+  /* Now read the baseclasses, if any, read the regular C struct or C++
+     class member fields, attach the fields to the type, read the C++
+     member functions, attach them to the type, and then read any tilde
+     field (baseclass specifier for the class holding the main vtable). */
+
+  if (!read_cfront_baseclasses (&fi, &p, type, objfile)
+      /* g++ does this next, but cfront already did this: 
+           || !read_struct_fields (&fi, &p, type, objfile) */
+      || !copy_cfront_struct_fields (&fi, type, objfile)
+      || !read_cfront_member_functions (&fi, &p, type, objfile)
+      || !read_cfront_static_fields (&fi, &p, type, objfile)
+      || !attach_fields_to_type (&fi, type, objfile)
+      || !attach_fn_fields_to_type (&fi, type)
+      /* g++ does this next, but cfront doesn't seem to have this: 
+               || !read_tilde_fields (&fi, &p, type, objfile) */
+      )
+    {
+      type = error_type (&p, objfile);
+    }
+
+  do_cleanups (back_to);
+  return 0;  
+}
+/* End of code added to support parsing of ARM/Cfront stabs strings */
+
+
+/* This routine fixes up symbol references/aliases to point to the original
+   symbol definition.  */
+
+static int
+resolve_symbol_reference (objfile, sym, p)
+  struct objfile *objfile;
+  struct symbol *sym;
+  char *p;
+{
+  int refnum;
+  struct symbol *ref_sym=0;
+  struct alias_list *alias;
+
+  /* If this is not a symbol reference return now.  */
+  if (*p != '#')
+    return 0;  
+
+  /* Use "#<num>" as the name; we'll fix the name later.
+     We stored the original symbol name as "#<id>=<name>"
+     so we can now search for "#<id>" to resolving the reference.
+     We'll fix the names later by removing the "#<id>" or "#<id>=" */
+
+  /*---------------------------------------------------------*/
+  /* Get the reference id number, and 
+     advance p past the names so we can parse the rest. 
+       eg: id=2 for p : "2=", "2=z:r(0,1)" "2:r(0,1);l(#5,#6),l(#7,#4)" */
+  /*---------------------------------------------------------*/
+
+  /* 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");
+
+
+  /* Parse the stab of the referencing symbol
+     now that we have the referenced symbol.
+     Add it as a new symbol and a link back to the referenced symbol.
+     eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
+
+
+  /* If the stab symbol table and string contain:
+         RSYM   0      5      00000000 868    #15=z:r(0,1)
+         LBRAC  0      0      00000000 899    #5=
+         SLINE  0      16     00000003 923    #6=
+     Then the same symbols can be later referenced by:
+         RSYM   0      5      00000000 927    #15:r(0,1);l(#5,#6)
+     This is used in live range splitting to:
+     1) specify that a symbol (#15) is actually just a new storage 
+        class for a symbol (#15=z) which was previously defined.
+     2) specify that the beginning and ending ranges for a symbol 
+        (#15) are the values of the beginning (#5) and ending (#6) 
+        symbols. */
+       
+   /* Read number as reference id.
+      eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
+   /* FIXME! Might I want to use SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+      in case of "l(0,0)"? */
+
+   /*--------------------------------------------------*/
+   /* Add this symbol to the reference list.           */
+   /*--------------------------------------------------*/
+
+  alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack,
+                                              sizeof (struct alias_list));
+  if (!alias)
+    error ("Unable to allocate alias list memory");
+
+  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.
+      Don't add_symbol_to_list so that lookup_symbol won't find it.
+      nope... needed for fixups. */
+   SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym);
+
+  /* Done!  */
+  return 0;  
+}
+
+#define MAX_CHUNK_REFS 100     
+#define REF_CHUNK_SIZE \
+    MAX_CHUNK_REFS * sizeof (struct ref_map_s)
+#define REF_MAP_SIZE(ref_chunk) \
+    ref_chunk * REF_CHUNK_SIZE
+
+/* Structure for storing pointers to reference definitions for fast lookup 
+   during "process_later". */
+static struct ref_map_s
+{
+  char *stabs;
+  CORE_ADDR value;
+  struct symbol *sym;
+} *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;
+
+/* Initialize our list of references.
+   This should be called before any symbol table is read.  */
+
+static void 
+ref_init ()
+{
+  ref_count = 0;
+  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 
+   find them, using their reference numbers as our index. 
+   These will be used later when we resolve references. */
+void
+ref_add (refnum, sym, stabs, value)
+     int refnum;
+     struct symbol *sym;
+     char *stabs;
+     CORE_ADDR value;
+{
+  if (ref_count == 0)
+    ref_init ();
+  if (refnum >= ref_count)
+    ref_count = refnum + 1;
+  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 = xrealloc (ref_map, REF_MAP_SIZE(ref_chunk + new_chunks));
+      if (!ref_map) 
+       error ("no more free slots in chain\n");
+      memset (ref_map + REF_MAP_SIZE(ref_chunk), 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.  */
+struct symbol *
+ref_search (refnum)
+     int refnum;
+{
+  if (refnum < 0 || refnum > ref_count)
+    return 0;
+  return ref_map[refnum].sym;
+}
+
+/* Return value for the reference REFNUM.  */
+
+static CORE_ADDR
+ref_search_value (refnum)
+     int refnum;
+{
+  if (refnum < 0 || refnum > ref_count)
+    return 0;
+  return ref_map[refnum].value;
+}
+   
+/* Parse a reference id in STRING and return the resulting
+   reference number.  Move STRING beyond the reference id.  */
+
+static int 
+process_reference (string)
+    char **string;
+{
+  char *p;
+  int refnum = 0;
+
+  if (**string != '#') 
+    return 0;  
+     
+  /* Advance beyond the initial '#'.  */
+  p = *string + 1;
+
+  /* Read number as reference id. */
+  while (*p && isdigit (*p))
+    {
+      refnum = refnum * 10 + *p - '0';
+      p++;
+    }
+  *string = p;
+  return refnum;
+}
+
+/* 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;
+{
+  char *p = *string;
+  int refnum = 0;
+
+  refnum = process_reference (&p);
+
+  /* Defining symbols end in '=' */
+  if (*p == '=') 
+    {
+      /* Symbol is being defined here. */ 
+      *string = p + 1;
+      return refnum;
+    }
+  else
+    {
+      /* Must be a reference.   Either the symbol has already been defined,
+         or this is a forward reference to it.  */
+      *string = p;
+      return -1;
+    }
+}
+
 /* ARGSUSED */
 struct symbol *
 define_symbol (valu, string, desc, type, objfile)
@@ -532,14 +1313,14 @@ define_symbol (valu, string, desc, type, objfile)
   while (p[1] == ':')
     {
        p += 2;
-       p = strchr(p, ':');
+       p = strchr (p, ':');
     }
 
   /* If a nameless stab entry, all we need is the type, not the symbol.
      e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */
   nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
 
-  sym = (struct symbol *) 
+  current_symbol = sym = (struct symbol *) 
     obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
   memset (sym, 0, sizeof (struct symbol));
 
@@ -567,7 +1348,7 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_LINE(sym) = 0;                    /* unknown */
     }
 
-  if (string[0] == CPLUS_MARKER)
+  if (is_cplus_marker (string[0]))
     {
       /* Special GNU C++ names.  */
       switch (string[1])
@@ -590,11 +1371,62 @@ define_symbol (valu, string, desc, type, objfile)
            /* This was an anonymous type that was never fixed up.  */
            goto normal;
 
+#ifdef STATIC_TRANSFORM_NAME
+         case 'X':
+           /* SunPRO (3.0 at least) static variable encoding.  */
+           goto normal;
+#endif
+
          default:
            complain (&unrecognized_cplus_name_complaint, string);
            goto normal;                /* Do *something* with it */
        }
     }
+  else if (string[0] == '#')
+    {
+      /* Special GNU C extension for referencing symbols.  */
+      char *s;
+      int refnum, nlen;
+
+      /* 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;
+      refnum = symbol_reference_defined (&s);
+      if (refnum >= 0)
+         ref_add (refnum, sym, string, SYMBOL_VALUE (sym));
+      else
+       resolve_symbol_reference (objfile, sym, string);
+
+      /* S..P contains the name of the symbol.  We need to store
+        the correct name into SYMBOL_NAME.  */
+      nlen = p - s;
+      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
     {
     normal:
@@ -654,7 +1486,7 @@ define_symbol (valu, string, desc, type, objfile)
       if (*p != '=')
        {
          SYMBOL_CLASS (sym) = LOC_CONST;
-         SYMBOL_TYPE (sym) = error_type (&p);
+         SYMBOL_TYPE (sym) = error_type (&p, objfile);
          SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
          add_symbol_to_list (sym, &file_symbols);
          return sym;
@@ -728,7 +1560,7 @@ define_symbol (valu, string, desc, type, objfile)
 
            if (*p != ',')
              {
-               SYMBOL_TYPE (sym) = error_type (&p);
+               SYMBOL_TYPE (sym) = error_type (&p, objfile);
                break;
              }
            ++p;
@@ -745,7 +1577,7 @@ define_symbol (valu, string, desc, type, objfile)
        default:
          {
            SYMBOL_CLASS (sym) = LOC_CONST;
-           SYMBOL_TYPE (sym) = error_type (&p);
+           SYMBOL_TYPE (sym) = error_type (&p, objfile);
          }
        }
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
@@ -774,23 +1606,12 @@ define_symbol (valu, string, desc, type, objfile)
         We need to convert this to the function-returning-type-X type
         in GDB.  E.g. "int" is converted to "function returning int".  */
       if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC)
-       {
-#if 0
-         /* This code doesn't work -- it needs to realloc and can't.  */
-         /* Attempt to set up to record a function prototype... */
-         struct type *new = alloc_type (objfile);
-
-         /* Generate a template for the type of this function.  The 
-            types of the arguments will be added as we read the symbol 
-            table. */
-         *new = *lookup_function_type (SYMBOL_TYPE(sym));
-         SYMBOL_TYPE(sym) = new;
-         TYPE_OBJFILE (new) = objfile;
-         in_function_type = new;
-#else
-         SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
-#endif
-       }
+       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:
@@ -798,10 +1619,15 @@ define_symbol (valu, string, desc, type, objfile)
         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);
-      }
+      if (*p == ';')
+       {
+         TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+
+         while (*p == ';') {
+           p++;
+           read_type (&p, objfile);
+         }
+       }
       break;
 
     case 'F':
@@ -818,11 +1644,18 @@ define_symbol (valu, string, desc, type, objfile)
         corresponding linker definition to find the value.
         These definitions appear at the end of the namelist.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      i = hashname (SYMBOL_NAME (sym));
-      SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
-      global_sym_chain[i] = sym;
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      /* Don't add symbol references to global_sym_chain.
+        Symbol references don't have valid names and wont't match up with
+        minimal symbols when the global_sym_chain is relocated.
+        We'll fixup symbol references when we fixup the defining symbol.  */
+      if (SYMBOL_NAME (sym) && SYMBOL_NAME (sym)[0] != '#')
+       {
+          i = hashname (SYMBOL_NAME (sym));
+          SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i];
+          global_sym_chain[i] = sym;
+       }
       add_symbol_to_list (sym, &global_symbols);
       break;
 
@@ -861,17 +1694,15 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type);
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-#if 0
-      /* This doesn't work yet.  */
-      add_param_to_type (&in_function_type, sym);
-#endif
       add_symbol_to_list (sym, &local_symbols);
 
-#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
-      /* On little-endian machines, this crud is never necessary, and,
-        if the extra bytes contain garbage, is harmful.  */
-      break;
-#else /* Big endian.  */
+      if (TARGET_BYTE_ORDER != BIG_ENDIAN)
+       {
+         /* On little-endian machines, this crud is never necessary,
+            and, if the extra bytes contain garbage, is harmful.  */
+         break;
+       }
+
       /* If it's gcc-compiled, if it says `short', believe it.  */
       if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)
        break;
@@ -950,15 +1781,14 @@ define_symbol (valu, string, desc, type, objfile)
 #endif /* no BELIEVE_PCC_PROMOTION_TYPE.  */
       }
 #endif /* !BELIEVE_PCC_PROMOTION.  */
-#endif /* Big endian.  */
 
     case 'P':
-      /* acc seems to use P to delare the prototypes of functions that
+      /* acc seems to use P to declare the prototypes of functions that
          are referenced by this file.  gdb is not prepared to deal
          with this extra information.  FIXME, it ought to.  */
       if (type == N_FUN)
        {
-         read_type (&p, objfile);
+         SYMBOL_TYPE (sym) = read_type (&p, objfile);
          goto process_prototype_types;
        }
       /*FALLTHROUGH*/
@@ -970,7 +1800,8 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
       if (SYMBOL_VALUE (sym) >= NUM_REGS)
        {
-         complain (&reg_value_complaint, SYMBOL_SOURCE_NAME (sym));
+         complain (&reg_value_complaint, SYMBOL_VALUE (sym), NUM_REGS,
+                   SYMBOL_SOURCE_NAME (sym));
          SYMBOL_VALUE (sym) = SP_REGNUM;  /* Known safe, though useless */
        }
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
@@ -984,7 +1815,8 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
       if (SYMBOL_VALUE (sym) >= NUM_REGS)
        {
-         complain (&reg_value_complaint, SYMBOL_SOURCE_NAME (sym));
+         complain (&reg_value_complaint, SYMBOL_VALUE (sym), NUM_REGS,
+                   SYMBOL_SOURCE_NAME (sym));
          SYMBOL_VALUE (sym) = SP_REGNUM;  /* Known safe, though useless */
        }
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
@@ -1013,7 +1845,9 @@ define_symbol (valu, string, desc, type, objfile)
              && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
                                      SYMBOL_TYPE (sym))
              && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
-                 || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)
+                 || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION
+                 || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_SET
+                 || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_BITSTRING)
 #endif
              )
            {
@@ -1043,6 +1877,18 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
+#ifdef STATIC_TRANSFORM_NAME
+      if (SYMBOL_NAME (sym)[0] == '$')
+      {
+       struct minimal_symbol *msym;
+       msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+       if (msym != NULL)
+         {
+           SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym));
+           SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
+         }
+      }
+#endif
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       add_symbol_to_list (sym, &file_symbols);
       break;
@@ -1075,7 +1921,13 @@ define_symbol (valu, string, desc, type, objfile)
 
       if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL)
        {
-         if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+         /* gcc-2.6 or later (when using -fvtable-thunks)
+            emits a unique named type for a vtable entry.
+            Some gdb code depends on that specific name. */
+         extern const char vtbl_ptr_name[];
+
+         if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+              && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name))
              || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
            {
              /* If we are giving a name to a type such as "pointer to
@@ -1110,23 +1962,13 @@ define_symbol (valu, string, desc, type, objfile)
       synonym = *p == 't';
 
       if (synonym)
-       {
-         p++;
-         type_synonym_name = obsavestring (SYMBOL_NAME (sym),
-                                           strlen (SYMBOL_NAME (sym)),
-                                           &objfile -> symbol_obstack);
-       }
+       p++;
       /* The semantics of C++ state that "struct foo { ... }" also defines 
         a typedef for "foo".  Unfortunately, cfront never makes the typedef
         when translating C++ into C.  We make the typedef here so that
         "ptype foo" works as expected for cfront translated code.  */
       else if (current_subfile->language == language_cplus)
-       {
-         synonym = 1;
-         type_synonym_name = obsavestring (SYMBOL_NAME (sym),
-                                           strlen (SYMBOL_NAME (sym)),
-                                           &objfile -> symbol_obstack);
-       }
+       synonym = 1;
 
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
 
@@ -1163,6 +2005,18 @@ define_symbol (valu, string, desc, type, objfile)
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
+#ifdef STATIC_TRANSFORM_NAME
+      if (SYMBOL_NAME (sym)[0] == '$')
+      {
+       struct minimal_symbol *msym;
+       msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+       if (msym != NULL)
+         {
+           SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym));
+           SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
+         }
+      }
+#endif
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       if (os9k_stabs)
        add_symbol_to_list (sym, &global_symbols);
@@ -1170,59 +2024,206 @@ define_symbol (valu, string, desc, type, objfile)
        add_symbol_to_list (sym, &local_symbols);
       break;
 
-    case 'v':
-      /* Reference parameter */
-      SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_REF_ARG;
-      SYMBOL_VALUE (sym) = valu;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      add_symbol_to_list (sym, &local_symbols);
-      break;
+    case 'v':
+      /* Reference parameter */
+      SYMBOL_TYPE (sym) = read_type (&p, objfile);
+      SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      SYMBOL_VALUE (sym) = valu;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      add_symbol_to_list (sym, &local_symbols);
+      break;
+
+    case 'a':
+      /* Reference parameter which is in a register.  */
+      SYMBOL_TYPE (sym) = read_type (&p, objfile);
+      SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+      SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
+      if (SYMBOL_VALUE (sym) >= NUM_REGS)
+       {
+         complain (&reg_value_complaint, SYMBOL_VALUE (sym), NUM_REGS,
+                   SYMBOL_SOURCE_NAME (sym));
+         SYMBOL_VALUE (sym) = SP_REGNUM;  /* Known safe, though useless */
+       }
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      add_symbol_to_list (sym, &local_symbols);
+      break;
+
+    case 'X':
+      /* This is used by Sun FORTRAN for "function result value".
+        Sun claims ("dbx and dbxtool interfaces", 2nd ed)
+        that Pascal uses it too, but when I tried it Pascal used
+        "x:3" (local symbol) instead.  */
+      SYMBOL_TYPE (sym) = read_type (&p, objfile);
+      SYMBOL_CLASS (sym) = LOC_LOCAL;
+      SYMBOL_VALUE (sym) = valu;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      add_symbol_to_list (sym, &local_symbols);
+      break;
+
+    /* New code added to support cfront stabs strings.
+       Note: case 'P' already handled above */
+    case 'Z':
+      /* Cfront type continuation coming up!
+        Find the original definition and add to it.
+        We'll have to do this for the typedef too,
+        since we cloned the symbol to define a type in read_type.
+        Stabs info examples:
+                __1C :Ztl 
+                foo__1CFv :ZtF (first def foo__1CFv:F(0,3);(0,24))
+                C:ZsC;;__ct__1CFv func1__1CFv func2__1CFv ... ;;;
+                where C is the name of the class.
+        Unfortunately, we can't lookup the original symbol yet 'cuz 
+        we haven't finished reading all the symbols.
+        Instead, we save it for processing later */
+      process_later (sym, p, resolve_cfront_continuation);
+      SYMBOL_TYPE (sym) = error_type (&p, objfile); /* FIXME! change later */ 
+      SYMBOL_CLASS (sym) = LOC_CONST; 
+      SYMBOL_VALUE (sym) = 0; 
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      /* Don't add to list - we'll delete it later when 
+         we add the continuation to the real sym */
+      return sym;
+      /* End of new code added to support cfront stabs strings */
+
+    default:
+      SYMBOL_TYPE (sym) = error_type (&p, objfile);
+      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_VALUE (sym) = 0;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      add_symbol_to_list (sym, &file_symbols);
+      break;
+    }
+
+  /* When passing structures to a function, some systems sometimes pass
+     the address in a register, not the structure itself. */
+
+  if (REG_STRUCT_HAS_ADDR (processing_gcc_compilation, SYMBOL_TYPE (sym))
+      && (SYMBOL_CLASS (sym) == LOC_REGPARM || SYMBOL_CLASS (sym) == LOC_ARG))
+    {
+      struct type *symbol_type = check_typedef (SYMBOL_TYPE (sym));
+
+      if ((TYPE_CODE (symbol_type) == TYPE_CODE_STRUCT)
+         || (TYPE_CODE (symbol_type) == TYPE_CODE_UNION)
+         || (TYPE_CODE (symbol_type) == TYPE_CODE_BITSTRING)
+         || (TYPE_CODE (symbol_type) == TYPE_CODE_SET))
+       {
+         /* If REG_STRUCT_HAS_ADDR yields non-zero we have to convert
+            LOC_REGPARM to LOC_REGPARM_ADDR for structures and unions. */
+         if (SYMBOL_CLASS (sym) == LOC_REGPARM)
+           SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+         /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th
+            and subsequent arguments on the sparc, for example).  */
+         else if (SYMBOL_CLASS (sym) == LOC_ARG)
+           SYMBOL_CLASS (sym) = LOC_REF_ARG;
+       }
+    }
+
+  /* Is there more to parse?  For example LRS/alias information?  */
+  while (*p && *p == ';')
+    {
+      p++;
+      if (*p && *p == 'l')
+        {
+          /* GNU extensions for live range splitting may be appended to 
+             the end of the stab string.  eg. "l(#1,#2);l(#3,#5)" */
+
+         /* Resolve the live range and add it to SYM's live range list.  */
+         resolve_live_range (objfile, sym, p);
+
+         /* Find end of live range info. */
+         p = strchr (p, ')');
+          if (!*p || *p != ')')
+            error ("Internal error: live range format not recognized.\n");
+          p++;
+       }
+    }
+  return sym;
+}
+
+/* Add the live range found in P to the symbol SYM in objfile OBJFILE.  */
+
+static void 
+resolve_live_range (objfile, sym, p)
+  struct objfile * objfile;
+  struct symbol *sym;
+  char *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");
+  p++;
+
+  if (!*p || *p != '(')
+    error ("Internal error: live range string.\n");
+  p++;
+       
+  /* 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");
+
+  if (!*p || *p != ',')
+    error ("Internal error: live range string.\n");
+  p++;
+
+  /* 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");
+
+  if (!*p || *p != ')')
+    error ("Internal error: live range string.\n");
 
-    case 'X':
-      /* This is used by Sun FORTRAN for "function result value".
-        Sun claims ("dbx and dbxtool interfaces", 2nd ed)
-        that Pascal uses it too, but when I tried it Pascal used
-        "x:3" (local symbol) instead.  */
-      SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_LOCAL;
-      SYMBOL_VALUE (sym) = valu;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      add_symbol_to_list (sym, &local_symbols);
-      break;
+  /* Now that we know the bounds of the range, add it to the
+     symbol.  */
+  add_live_range (objfile, sym, start, end);
+}
 
-    default:
-      SYMBOL_TYPE (sym) = error_type (&p);
-      SYMBOL_CLASS (sym) = LOC_CONST;
-      SYMBOL_VALUE (sym) = 0;
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-      add_symbol_to_list (sym, &file_symbols);
-      break;
-    }
+/* Add a new live range defined by START and END to the symbol SYM
+   in objfile OBJFILE.  */
 
-  /* When passing structures to a function, some systems sometimes pass
-     the address in a register, not the structure itself. 
-
-     If REG_STRUCT_HAS_ADDR yields non-zero we have to convert LOC_REGPARM
-     to LOC_REGPARM_ADDR for structures and unions.  */
-
-  if (SYMBOL_CLASS (sym) == LOC_REGPARM
-      && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
-                             SYMBOL_TYPE (sym))
-      && ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
-         || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
-    SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
-
-  /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th and
-     subsequent arguments on the sparc, for example).  */
-  if (SYMBOL_CLASS (sym) == LOC_ARG
-      && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
-                             SYMBOL_TYPE (sym))
-      && ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
-         || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
-    SYMBOL_CLASS (sym) = LOC_REF_ARG;
+static void
+add_live_range (objfile, sym, start, end)
+  struct objfile *objfile;
+  struct symbol *sym;
+  CORE_ADDR start, end;
+{
+  struct range_list *r, *rs;
 
-  return sym;
+  if (start >= end)
+    error ("Internal error: end of live range follows start.\n");
+
+  /* Alloc new live range structure. */
+  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_RANGES (sym))
+    {
+      SYMBOL_RANGES (sym) = r;
+    }
+  else
+    {
+      /* Get the last range for the symbol. */
+      for (rs = SYMBOL_RANGES (sym); rs->next; rs = rs->next)
+       ;
+      rs->next = r;
+    }
 }
 
 \f
@@ -1233,7 +2234,7 @@ define_symbol (valu, string, desc, type, objfile)
    Thus code like this:
 
    if (*(*pp)++ != ';')
-     return error_type (pp);
+     return error_type (pp, objfile);
 
    is wrong because if *pp starts out pointing at '\0' (typically as the
    result of an earlier error), it will be incremented to point to the
@@ -1241,13 +2242,13 @@ define_symbol (valu, string, desc, type, objfile)
    if you run off the end of the string table.  Instead use
 
    if (**pp != ';')
-     return error_type (pp);
+     return error_type (pp, objfile);
    ++*pp;
 
    or
 
    if (**pp != ';')
-     foo = error_type (pp);
+     foo = error_type (pp, objfile);
    else
      ++*pp;
 
@@ -1256,8 +2257,9 @@ define_symbol (valu, string, desc, type, objfile)
    debugger will be able to read the new symbol tables.  */
 
 static struct type *
-error_type (pp)
+error_type (pp, objfile)
      char **pp;
+     struct objfile *objfile;
 {
   complain (&error_type_complaint);
   while (1)
@@ -1271,7 +2273,7 @@ error_type (pp)
       /* Check for and handle cretinous dbx symbol name continuation!  */
       if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
        {
-         *pp = next_symbol_text ();
+         *pp = next_symbol_text (objfile);
        }
       else
        {
@@ -1296,7 +2298,6 @@ read_type (pp, objfile)
   register struct type *type = 0;
   struct type *type1;
   int typenums[2];
-  int xtypenums[2];
   char type_descriptor;
 
   /* Size in bits of type if specified by a type attribute, or -1 if
@@ -1314,7 +2315,7 @@ read_type (pp, objfile)
       || **pp == '-')
     {
       if (read_type_number (pp, typenums) != 0)
-       return error_type (pp);
+       return error_type (pp, objfile);
       
       /* Type is not being defined here.  Either it already exists,
         or this is a forward reference to it.  dbx_alloc_type handles
@@ -1323,52 +2324,9 @@ read_type (pp, objfile)
        return dbx_alloc_type (typenums, objfile);
 
       /* Type is being defined here.  */
-      /* Skip the '='.  */
-      ++(*pp);
-
-      while (**pp == '@')
-       {
-         char *p = *pp + 1;
-         /* It might be a type attribute or a member type.  */
-         if (isdigit (*p) || *p ==  '(' || *p == '-')
-           /* Member type.  */
-           break;
-         else
-           {
-             /* Type attributes.  */
-             char *attr = p;
-
-             /* Skip to the semicolon.  */
-             while (*p != ';' && *p != '\0')
-               ++p;
-             *pp = p;
-             if (*p == '\0')
-               return error_type (pp);
-             else
-               /* Skip the semicolon.  */
-               ++*pp;
-
-             switch (*attr)
-               {
-               case 's':
-                 type_size = atoi (attr + 1);
-                 if (type_size <= 0)
-                   type_size = -1;
-                 break;
-
-               case 'S':
-                 is_string = 1;
-                 break;
-
-               default:
-                 /* Ignore unrecognized type attributes, so future compilers
-                    can invent new ones.  */
-                 break;
-               }
-           }
-       }
-      /* Skip the type descriptor, we get it below with (*pp)[-1].  */
-      ++(*pp);
+      /* Skip the '='.
+        Also skip the type descriptor - we get it below with (*pp)[-1].  */
+      (*pp)+=2;
     }
   else
     {
@@ -1378,6 +2336,7 @@ read_type (pp, objfile)
       (*pp)++;
     }
 
+ again:
   type_descriptor = (*pp)[-1];
   switch (type_descriptor)
     {
@@ -1419,19 +2378,25 @@ read_type (pp, objfile)
              }
            }
           
-         q1 = strchr(*pp, '<');
-         p = strchr(*pp, ':');
+         q1 = strchr (*pp, '<');
+         p = strchr (*pp, ':');
          if (p == NULL)
-           return error_type (pp);
-         while (q1 && p > q1 && p[1] == ':')
+           return error_type (pp, objfile);
+         if (q1 && p > q1 && p[1] == ':')
            {
-              q2 = strchr(q1, '>');
-              if (!q2 || q2 < p)
-                break;
-              p += 2;
-              p = strchr(p, ':');
-              if (p == NULL)
-                return error_type (pp);
+             int nesting_level = 0;
+             for (q2 = q1; *q2; q2++)
+               {
+                 if (*q2 == '<')
+                   nesting_level++;
+                 else if (*q2 == '>')
+                   nesting_level--;
+                 else if (*q2 == ':' && nesting_level == 0)
+                   break;
+               }
+             p = q2;
+             if (*p != ':')
+               return error_type (pp, objfile);
            }
          to = type_name = 
                (char *)obstack_alloc (&objfile->type_obstack, p - *pp + 1);
@@ -1496,50 +2461,35 @@ read_type (pp, objfile)
     case '8':
     case '9':
     case '(':
+      (*pp)--;
 
-      {
-       char *pp_saved;
-
-       (*pp)--;
-       pp_saved = *pp;
-
-       /* Peek ahead at the number to detect void.  */
-       if (read_type_number (pp, xtypenums) != 0)
-         return error_type (pp);
+      /* We deal with something like t(1,2)=(3,4)=... which
+        the Lucid compiler and recent gcc versions (post 2.7.3) use. */
 
-       if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
-         /* It's being defined as itself.  That means it is "void".  */
-         type = init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
-       else
+      /* Allocate and enter the typedef type first.
+        This handles recursive types. */
+      type = dbx_alloc_type (typenums, objfile);
+      TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
+      { struct type *xtype = read_type (pp, objfile);
+       if (type == xtype)
+         {
+           /* It's being defined as itself.  That means it is "void".  */
+           TYPE_CODE (type) = TYPE_CODE_VOID;
+           TYPE_LENGTH (type) = 1;
+         }
+       else if (type_size >= 0 || is_string)
          {
-           struct type *xtype;
-
-           /* Go back to the number and have read_type get it.  This means
-              that we can deal with something like t(1,2)=(3,4)=... which
-              the Lucid compiler uses.  */
-           *pp = pp_saved;
-           xtype = read_type (pp, objfile);
-
-           /* The type is being defined to another type.  So we copy the type.
-              This loses if we copy a C++ class and so we lose track of how
-              the names are mangled (but g++ doesn't output stabs like this
-              now anyway).  */
-
-           type = alloc_type (objfile);
-           memcpy (type, xtype, sizeof (struct type));
-
-           /* The idea behind clearing the names is that the only purpose
-              for defining a type to another type is so that the name of
-              one can be different.  So we probably don't need to worry much
-              about the case where the compiler doesn't give a name to the
-              new type.  */
+           *type = *xtype;
            TYPE_NAME (type) = NULL;
            TYPE_TAG_NAME (type) = NULL;
          }
-       if (typenums[0] != -1)
-         *dbx_lookup_type (typenums) = type;
-       break;
+       else
+         {
+           TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
+           TYPE_TARGET_TYPE (type) = xtype;
+         }
       }
+      break;
 
     /* In the following types, we must be sure to overwrite any existing
        type that the typenums refer to, rather than allocating a new one
@@ -1569,7 +2519,7 @@ read_type (pp, objfile)
          ++*pp;
          while (**pp != ')')
             {
-              t = read_type(pp, objfile);
+              t = read_type (pp, objfile);
               if (**pp == ',') ++*pp;
             }
        }
@@ -1582,7 +2532,7 @@ read_type (pp, objfile)
       /* Because 'c' means other things to AIX and 'k' is perfectly good,
         only accept 'c' in the os9k_stabs case.  */
       if (type_descriptor == 'c' && !os9k_stabs)
-       return error_type (pp);
+       return error_type (pp, objfile);
       type = read_type (pp, objfile);
       /* FIXME! For now, we ignore const and volatile qualifiers.  */
       break;
@@ -1592,26 +2542,59 @@ read_type (pp, objfile)
       /* Because 'i' means other things to AIX and 'B' is perfectly good,
         only accept 'i' in the os9k_stabs case.  */
       if (type_descriptor == 'i' && !os9k_stabs)
-       return error_type (pp);
+       return error_type (pp, objfile);
       type = read_type (pp, objfile);
       /* FIXME! For now, we ignore const and volatile qualifiers.  */
       break;
 
-/* FIXME -- we should be doing smash_to_XXX types here.  */
-    case '@':                          /* Member (class & variable) type */
-      {
-       struct type *domain = read_type (pp, objfile);
-       struct type *memtype;
+    case '@':
+      if (isdigit (**pp) || **pp ==  '(' || **pp == '-')
+       { /* Member (class & variable) type */
+         /* FIXME -- we should be doing smash_to_XXX types here.  */
 
-       if (**pp != ',')
-         /* Invalid member type data format.  */
-         return error_type (pp);
-       ++*pp;
+         struct type *domain = read_type (pp, objfile);
+         struct type *memtype;
 
-       memtype = read_type (pp, objfile);
-       type = dbx_alloc_type (typenums, objfile);
-       smash_to_member_type (type, domain, memtype);
-      }
+         if (**pp != ',')
+           /* Invalid member type data format.  */
+           return error_type (pp, objfile);
+         ++*pp;
+
+         memtype = read_type (pp, objfile);
+         type = dbx_alloc_type (typenums, objfile);
+         smash_to_member_type (type, domain, memtype);
+       }
+      else /* type attribute */
+       {
+         char *attr = *pp;
+         /* Skip to the semicolon.  */
+         while (**pp != ';' && **pp != '\0')
+           ++(*pp);
+         if (**pp == '\0')
+           return error_type (pp, objfile);
+         else
+           ++*pp;  /* Skip the semicolon.  */
+
+         switch (*attr)
+           {
+           case 's':
+             type_size = atoi (attr + 1);
+             if (type_size <= 0)
+               type_size = -1;
+             break;
+
+           case 'S':
+             is_string = 1;
+             break;
+
+           default:
+             /* Ignore unrecognized type attributes, so future compilers
+                can invent new ones.  */
+             break;
+           }
+         ++*pp;
+         goto again;
+       }
       break;
 
     case '#':                          /* Method (class & fn) type */
@@ -1636,7 +2619,7 @@ read_type (pp, objfile)
 
          if (**pp != ',')
            /* Invalid member type data format.  */
-           return error_type (pp);
+           return error_type (pp, objfile);
          else
            ++(*pp);
 
@@ -1682,11 +2665,6 @@ read_type (pp, objfile)
     case 's':                          /* Struct type */
     case 'u':                          /* Union type */
       type = dbx_alloc_type (typenums, objfile);
-      if (!TYPE_NAME (type))
-       {
-         TYPE_NAME (type) = type_synonym_name;
-       }
-      type_synonym_name = NULL;
       switch (type_descriptor)
        {
          case 's':
@@ -1701,7 +2679,7 @@ read_type (pp, objfile)
 
     case 'a':                          /* Array type */
       if (**pp != 'r')
-       return error_type (pp);
+       return error_type (pp, objfile);
       ++*pp;
       
       type = dbx_alloc_type (typenums, objfile);
@@ -1722,18 +2700,18 @@ read_type (pp, objfile)
     default:
       --*pp;                   /* Go back to the symbol in error */
                                /* Particularly important if it was \0! */
-      return error_type (pp);
+      return error_type (pp, objfile);
     }
 
   if (type == 0)
     {
       warning ("GDB internal error, type is NULL in stabsread.c\n");
-      return error_type (pp);
+      return error_type (pp, objfile);
     }
 
   /* Size specified in a type attribute overrides any other size.  */
   if (type_size != -1)
-    TYPE_LENGTH (type) = type_size / TARGET_CHAR_BIT;
+    TYPE_LENGTH (type) = (type_size + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
 
   return type;
 }
@@ -1746,7 +2724,7 @@ rs6000_builtin_type (typenum)
      int typenum;
 {
   /* We recognize types numbered from -NUMBER_RECOGNIZED to -1.  */
-#define NUMBER_RECOGNIZED 30
+#define NUMBER_RECOGNIZED 34
   /* This includes an empty slot for type number -0.  */
   static struct type *negative_types[NUMBER_RECOGNIZED + 1];
   struct type *rettype = NULL;
@@ -1829,7 +2807,8 @@ rs6000_builtin_type (typenum)
       rettype = init_type (TYPE_CODE_INT, 4, 0, "integer", NULL);
       break;
     case 16:
-      rettype = init_type (TYPE_CODE_BOOL, 4, 0, "boolean", NULL);
+      rettype = init_type (TYPE_CODE_BOOL, 4, TYPE_FLAG_UNSIGNED,
+                          "boolean", NULL);
       break;
     case 17:
       rettype = init_type (TYPE_CODE_FLT, 4, 0, "short real", NULL);
@@ -1880,6 +2859,20 @@ rs6000_builtin_type (typenum)
     case 30:
       rettype = init_type (TYPE_CODE_CHAR, 2, 0, "wchar", NULL);
       break;
+    case 31:
+      rettype = init_type (TYPE_CODE_INT, 8, 0, "long long", NULL);
+      break;
+    case 32:
+      rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED,
+                          "unsigned long long", NULL);
+      break;
+    case 33:
+      rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED,
+                          "logical*8", NULL);
+      break;
+    case 34:
+      rettype = init_type (TYPE_CODE_INT, 8, 0, "integer*8", NULL);
+      break;
     }
   negative_types[-typenum] = rettype;
   return rettype;
@@ -1887,11 +2880,6 @@ rs6000_builtin_type (typenum)
 \f
 /* This page contains subroutines of read_type.  */
 
-#define VISIBILITY_PRIVATE     '0'     /* Stabs character for private field */
-#define VISIBILITY_PROTECTED   '1'     /* Stabs character for protected fld */
-#define VISIBILITY_PUBLIC      '2'     /* Stabs character for public field */
-#define VISIBILITY_IGNORE      '9'     /* Optimized out or zero length */
-
 /* Read member function stabs info for C++ classes.  The form of each member
    function data is:
 
@@ -1959,7 +2947,7 @@ read_member_functions (fip, pp, type, objfile)
       make_cleanup (free, new_fnlist);
       memset (new_fnlist, 0, sizeof (struct next_fnfieldlist));
       
-      if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == CPLUS_MARKER)
+      if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && is_cplus_marker ((*pp)[2]))
        {
          /* This is a completely wierd case.  In order to stuff in the
             names that might contain colons (the usual name delimiter),
@@ -1976,7 +2964,7 @@ read_member_functions (fip, pp, type, objfile)
          /* Skip past '::'.  */
          *pp = p + 2;
 
-         STABS_CONTINUE (pp);
+         STABS_CONTINUE (pp, objfile);
          p = *pp;
          while (*p != '.')
            {
@@ -2005,7 +2993,7 @@ read_member_functions (fip, pp, type, objfile)
          if (look_ahead_type == NULL)
            {
              /* Normal case. */
-             STABS_CONTINUE (pp);
+             STABS_CONTINUE (pp, objfile);
              
              new_sublist -> fn_field.type = read_type (pp, objfile);
              if (**pp != ':')
@@ -2050,7 +3038,7 @@ read_member_functions (fip, pp, type, objfile)
                break;
            }
          
-         STABS_CONTINUE (pp);
+         STABS_CONTINUE (pp, objfile);
          switch (**pp)
            {
              case 'A': /* Normal functions. */
@@ -2099,7 +3087,7 @@ read_member_functions (fip, pp, type, objfile)
                if (nbits != 0)
                  return 0;
              
-               STABS_CONTINUE (pp);
+               STABS_CONTINUE (pp, objfile);
                if (**pp == ';' || **pp == '\0')
                  {
                    /* Must be g++ version 1.  */
@@ -2156,7 +3144,7 @@ read_member_functions (fip, pp, type, objfile)
          new_sublist -> next = sublist;
          sublist = new_sublist;
          length++;
-         STABS_CONTINUE (pp);
+         STABS_CONTINUE (pp, objfile);
        }
       while (**pp != ';' && **pp != '\0');
       
@@ -2177,7 +3165,7 @@ read_member_functions (fip, pp, type, objfile)
       fip -> fnlist = new_fnlist;
       nfn_fields++;
       total_length += length;
-      STABS_CONTINUE (pp);
+      STABS_CONTINUE (pp, objfile);
     }
 
   if (nfn_fields)
@@ -2269,12 +3257,12 @@ read_cpp_abbrev (fip, pp, type, objfile)
 
       {
        int nbits;
-       fip->list->field.bitpos = read_huge_number (pp, ';', &nbits);
+       FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits);
        if (nbits != 0)
          return 0;
       }
       /* This field is unpacked.  */
-      fip->list->field.bitsize = 0;
+      FIELD_BITSIZE (fip->list->field) = 0;
       fip->list->visibility = VISIBILITY_PRIVATE;
     }
   else
@@ -2296,7 +3284,36 @@ read_one_struct_field (fip, pp, p, type, objfile)
      struct type *type;
      struct objfile *objfile;
 {
-  fip -> list -> field.name =
+  /* The following is code to work around cfront generated stabs.
+     The stabs contains full mangled name for each field.
+     We try to demangle the name and extract the field name out of it.
+  */
+  if (ARM_DEMANGLING && current_subfile->language == language_cplus)
+    {
+      char save_p;
+      char *dem, *dem_p;
+      save_p = *p;
+      *p = '\0';
+      dem = cplus_demangle (*pp, DMGL_ANSI | DMGL_PARAMS);
+      if (dem != NULL)
+        {
+          dem_p = strrchr (dem, ':');
+          if (dem_p != 0 && *(dem_p-1)==':')
+            dem_p++;
+          FIELD_NAME (fip->list->field) =
+            obsavestring (dem_p, strlen (dem_p), &objfile -> type_obstack);
+        }
+      else
+        {
+          FIELD_NAME (fip->list->field) =
+            obsavestring (*pp, p - *pp, &objfile -> type_obstack);
+        }
+      *p = save_p;
+    }
+  /* end of code for cfront work around */
+
+  else
+    fip -> list -> field.name =
     obsavestring (*pp, p - *pp, &objfile -> type_obstack);
   *pp = p + 1;
 
@@ -2323,17 +3340,14 @@ read_one_struct_field (fip, pp, p, type, objfile)
          fip -> list -> field.bitpos = (long)-2; /* nested type */
          p = ++(*pp);
        }
-      else
+      else ...;
 #endif
-       {
-         /* Static class member.  */
-         fip -> list -> field.bitpos = (long) -1;
-       }
       while (*p != ';') 
        {
          p++;
        }
-      fip -> list -> field.bitsize = (long) savestring (*pp, p - *pp);
+      /* Static class member.  */
+      SET_FIELD_PHYSNAME (fip->list->field, savestring (*pp, p - *pp));
       *pp = p + 1;
       return;
     }
@@ -2348,13 +3362,13 @@ read_one_struct_field (fip, pp, p, type, objfile)
 
   {
     int nbits;
-    fip -> list -> field.bitpos = read_huge_number (pp, ',', &nbits);
+    FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits);
     if (nbits != 0)
       {
        complain (&stabs_general_complaint, "bad structure-type format");
        return;
       }
-    fip -> list -> field.bitsize = read_huge_number (pp, ';', &nbits);
+    FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits);
     if (nbits != 0)
       {
        complain (&stabs_general_complaint, "bad structure-type format");
@@ -2362,7 +3376,8 @@ read_one_struct_field (fip, pp, p, type, objfile)
       }
   }
 
-  if (fip -> list -> field.bitpos == 0 && fip -> list -> field.bitsize == 0)
+  if (FIELD_BITPOS (fip->list->field) == 0
+      && FIELD_BITSIZE (fip->list->field) == 0)
     {
       /* This can happen in two cases: (1) at least for gcc 2.4.5 or so,
         it is a field which has been optimized out.  The correct stab for
@@ -2388,22 +3403,21 @@ 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 (fip -> list -> field.type) != TYPE_CODE_INT
-         && TYPE_CODE (fip -> list -> field.type) != TYPE_CODE_ENUM)
+      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)
        {
-         fip -> list -> field.bitsize = 0;
+         FIELD_BITSIZE (fip->list->field) = 0;
        }
-      if ((fip -> list -> field.bitsize 
-          == TARGET_CHAR_BIT * TYPE_LENGTH (fip -> list -> field.type)
-          || (TYPE_CODE (fip -> list -> field.type) == TYPE_CODE_ENUM
-              && (fip -> list -> field.bitsize
-                  == TARGET_INT_BIT)
-              )
+      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
+              && FIELD_BITSIZE (fip->list->field) == TARGET_INT_BIT )
           )
          &&
-         fip -> list -> field.bitpos % 8 == 0)
+         FIELD_BITPOS (fip->list->field) % 8 == 0)
        {
-         fip -> list -> field.bitsize = 0;
+         FIELD_BITSIZE (fip->list->field) = 0;
        }
     }
 }
@@ -2449,7 +3463,8 @@ read_struct_fields (fip, pp, type, objfile)
 
   while (**pp != ';')
     {
-      STABS_CONTINUE (pp);
+      if (os9k_stabs && **pp == ',') break;
+      STABS_CONTINUE (pp, objfile);
       /* Get space to record the next field's data.  */
       new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
       make_cleanup (free, new);
@@ -2463,12 +3478,9 @@ read_struct_fields (fip, pp, type, objfile)
       /* If is starts with CPLUS_MARKER it is a special abbreviation,
         unless the CPLUS_MARKER is followed by an underscore, in
         which case it is just the name of an anonymous type, which we
-        should handle like any other type name.  We accept either '$'
-        or '.', because a field name can never contain one of these
-        characters except as a CPLUS_MARKER (we probably should be
-        doing that in most parts of GDB).  */
+        should handle like any other type name.  */
 
-      if ((*p == '$' || *p == '.') && p[1] != '_')
+      if (is_cplus_marker (p[0]) && p[1] != '_')
        {
          if (!read_cpp_abbrev (fip, pp, type, objfile))
            return 0;
@@ -2579,9 +3591,9 @@ read_baseclasses (fip, pp, type, objfile)
       memset (new, 0, sizeof (struct nextfield));
       new -> next = fip -> list;
       fip -> list = new;
-      new -> field.bitsize = 0;        /* this should be an unpacked field! */
+      FIELD_BITSIZE (new->field) = 0;  /* this should be an unpacked field! */
 
-      STABS_CONTINUE (pp);
+      STABS_CONTINUE (pp, objfile);
       switch (**pp)
        {
          case '0':
@@ -2625,7 +3637,7 @@ read_baseclasses (fip, pp, type, objfile)
           corresponding to this baseclass.  Always zero in the absence of
           multiple inheritance.  */
 
-       new -> field.bitpos = read_huge_number (pp, ',', &nbits);
+       FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits);
        if (nbits != 0)
          return 0;
       }
@@ -2663,7 +3675,7 @@ read_tilde_fields (fip, pp, type, objfile)
 {
   register char *p;
 
-  STABS_CONTINUE (pp);
+  STABS_CONTINUE (pp, objfile);
 
   /* If we are positioned at a ';', then skip it. */
   if (**pp == ';')
@@ -2743,17 +3755,6 @@ attach_fn_fields_to_type (fip, type)
 {
   register int n;
 
-  for (n = 0; n < TYPE_N_BASECLASSES (type); n++)
-    {
-      if (TYPE_CODE (TYPE_BASECLASS (type, n)) == TYPE_CODE_UNDEF)
-       {
-         /* @@ Memory leak on objfile -> type_obstack?  */
-         return 0;
-       }
-      TYPE_NFN_FIELDS_TOTAL (type) +=
-       TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, n));
-    }
-
   for (n = TYPE_NFN_FIELDS (type);
        fip -> fnlist != NULL;
        fip -> fnlist = fip -> fnlist -> next)
@@ -2764,6 +3765,143 @@ attach_fn_fields_to_type (fip, type)
   return 1;
 }
 
+/* read cfront class static data.
+   pp points to string starting with the list of static data
+   eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
+                                                                  ^^^^^^^^
+
+       A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
+                                                                              ^
+   */
+
+static int
+read_cfront_static_fields (fip, pp, type, objfile)
+     struct field_info *fip;
+     char **pp;
+     struct type *type;
+     struct objfile *objfile;
+{
+  struct nextfield * new;
+  struct type *stype;
+  char * sname;
+  struct symbol * ref_static=0;
+      
+  if (**pp==';')               /* no static data; return */
+    {
+      ++(*pp);
+      return 1;
+    }
+
+  /* Process each field in the list until we find the terminating ";" */
+
+  /* eg: p = "as__1A ;;;" */
+  STABS_CONTINUE (pp, objfile);                /* handle \\ */
+  while (**pp!=';' && (sname = get_substring (pp, ' '), sname)) 
+    {
+      ref_static = lookup_symbol (sname, 0, VAR_NAMESPACE, 0, 0); /*demangled_name*/
+      if (!ref_static) 
+        {
+          static struct complaint msg = {"\
+               Unable to find symbol for static data field %s\n",
+                                0, 0};
+         complain (&msg, sname);
+         continue;
+       }
+      stype = SYMBOL_TYPE(ref_static);
+
+      /* allocate a new fip */
+      new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+      make_cleanup (free, new);
+      memset (new, 0, sizeof (struct nextfield));
+      new -> next = fip -> list;
+      fip -> list = new;
+
+      /* set visibility */
+      /* FIXME! no way to tell visibility from stabs??? */
+      new -> visibility = VISIBILITY_PUBLIC;
+
+      /* set field info into fip */
+      fip -> list -> field.type = stype; 
+
+      /* set bitpos & bitsize */
+      SET_FIELD_PHYSNAME (fip->list->field, savestring (sname, strlen (sname)));
+
+      /* set name field */
+      /* The following is code to work around cfront generated stabs.
+         The stabs contains full mangled name for each field.
+         We try to demangle the name and extract the field name out of it.
+      */
+      if (ARM_DEMANGLING)
+        {
+          char *dem, *dem_p;
+          dem = cplus_demangle (sname, DMGL_ANSI | DMGL_PARAMS);
+          if (dem != NULL)
+            {
+              dem_p = strrchr (dem, ':');
+              if (dem_p != 0 && *(dem_p-1)==':')
+                dem_p++;
+              fip->list->field.name =
+                obsavestring (dem_p, strlen (dem_p), &objfile -> type_obstack);
+            }
+          else
+            {
+              fip->list->field.name =
+                obsavestring (sname, strlen (sname), &objfile -> type_obstack); 
+           }
+        } /* end of code for cfront work around */ 
+    } /* loop again for next static field */
+  return 1;
+}
+
+/* Copy structure fields to fip so attach_fields_to_type will work.
+   type has already been created with the initial instance data fields.
+   Now we want to be able to add the other members to the class,
+   so we want to add them back to the fip and reattach them again
+   once we have collected all the class members. */
+
+static int
+copy_cfront_struct_fields (fip, type, objfile)
+     struct field_info *fip;
+     struct type *type;
+     struct objfile *objfile;
+{
+  int nfields = TYPE_NFIELDS(type);
+  int i;
+  struct nextfield * new;
+
+  /* Copy the fields into the list of fips and reset the types 
+     to remove the old fields */
+
+  for (i=0; i<nfields; i++)
+    {
+      /* allocate a new fip */
+      new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+      make_cleanup (free, new);
+      memset (new, 0, sizeof (struct nextfield));
+      new -> next = fip -> list;
+      fip -> list = new;
+
+      /* copy field info into fip */
+      new -> field = TYPE_FIELD (type, i);
+      /* set visibility */
+      if (TYPE_FIELD_PROTECTED (type, i))
+       new -> visibility = VISIBILITY_PROTECTED;
+      else if (TYPE_FIELD_PRIVATE (type, i))
+        new -> visibility = VISIBILITY_PRIVATE;
+      else
+        new -> visibility = VISIBILITY_PUBLIC;
+    }
+  /* Now delete the fields from the type since we will be 
+     allocing new space once we get the rest of the fields 
+     in attach_fields_to_type.
+     The pointer TYPE_FIELDS(type) is left dangling but should 
+     be freed later by objstack_free */
+  TYPE_FIELDS (type)=0;
+  TYPE_NFIELDS (type) = 0;
+
+  return 1;
+}
+
 /* Create the vector of fields, and record how big it is.
    We need this info to record proper virtual function table information
    for this class's virtual functions.  */
@@ -2893,7 +4031,7 @@ read_struct_type (pp, type, objfile)
     int nbits;
     TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits);
     if (nbits != 0)
-      return error_type (pp);
+      return error_type (pp, objfile);
   }
 
   /* Now read the baseclasses, if any, read the regular C struct or C++
@@ -2908,8 +4046,7 @@ read_struct_type (pp, type, objfile)
       || !attach_fn_fields_to_type (&fi, type)
       || !read_tilde_fields (&fi, pp, type, objfile))
     {
-      do_cleanups (back_to);
-      return (error_type (pp));
+      type = error_type (pp, objfile);
     }
 
   do_cleanups (back_to);
@@ -2946,7 +4083,7 @@ read_array_type (pp, type, objfile)
       index_type = read_type (pp, objfile);
       if (**pp != ';')
        /* Improper format of array type decl.  */
-       return error_type (pp);
+       return error_type (pp, objfile);
       ++*pp;
     }
 
@@ -2957,7 +4094,7 @@ read_array_type (pp, type, objfile)
     }
   lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
 
   if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
     {
@@ -2966,7 +4103,7 @@ read_array_type (pp, type, objfile)
     }
   upper = read_huge_number (pp, ';', &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
   
   element_type = read_type (pp, objfile);
 
@@ -2980,19 +4117,6 @@ read_array_type (pp, type, objfile)
     create_range_type ((struct type *) NULL, index_type, lower, upper);
   type = create_array_type (type, element_type, range_type);
 
-  /* If we have an array whose element type is not yet known, but whose
-     bounds *are* known, record it to be adjusted at the end of the file.  */
-  /* FIXME: Why check for zero length rather than TYPE_FLAG_STUB?  I think
-     the two have the same effect except that the latter is cleaner and the
-     former would be wrong for types which really are zero-length (if we
-     have any).  */
-
-  if (TYPE_LENGTH (element_type) == 0 && !adjustable)
-    {
-      TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
-      add_undefined_type (type);
-    }
-
   return type;
 }
 
@@ -3016,6 +4140,7 @@ read_enum_type (pp, type, objfile)
   struct pending *osyms, *syms;
   int o_nsyms;
   int nbits;
+  int unsigned_enum = 1;
 
 #if 0
   /* FIXME!  The stabs produced by Sun CC merrily define things that ought
@@ -3036,7 +4161,19 @@ read_enum_type (pp, type, objfile)
         with a digit).  */
       read_huge_number (pp, 0, &nbits);
       if (nbits != 0)
-       return error_type (pp);
+       return error_type (pp, objfile);
+    }
+
+  /* The aix4 compiler emits an extra field before the enum members;
+     my guess is it's a type of some sort.  Just ignore it.  */
+  if (**pp == '-')
+    {
+      /* Skip over the type.  */
+      while (**pp != ':')
+        (*pp)++;
+
+      /* Skip over the colon.  */
+      (*pp)++;
     }
 
   /* Read the value-names and their values.
@@ -3044,14 +4181,14 @@ read_enum_type (pp, type, objfile)
      A semicolon or comma instead of a NAME means the end.  */
   while (**pp && **pp != ';' && **pp != ',')
     {
-      STABS_CONTINUE (pp);
+      STABS_CONTINUE (pp, objfile);
       p = *pp;
       while (*p != ':') p++;
       name = obsavestring (*pp, p - *pp, &objfile -> symbol_obstack);
       *pp = p + 1;
       n = read_huge_number (pp, ',', &nbits);
       if (nbits != 0)
-       return error_type (pp);
+       return error_type (pp, objfile);
 
       sym = (struct symbol *)
        obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
@@ -3061,6 +4198,8 @@ read_enum_type (pp, type, objfile)
       SYMBOL_CLASS (sym) = LOC_CONST;
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       SYMBOL_VALUE (sym) = n;
+      if (n < 0)
+       unsigned_enum = 0;
       add_symbol_to_list (sym, symlist);
       nsyms++;
     }
@@ -3073,6 +4212,8 @@ read_enum_type (pp, type, objfile)
   TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT;
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
+  if (unsigned_enum)
+    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
   TYPE_NFIELDS (type) = nsyms;
   TYPE_FIELDS (type) = (struct field *)
     TYPE_ALLOC (type, sizeof (struct field) * nsyms);
@@ -3086,17 +4227,15 @@ read_enum_type (pp, type, objfile)
      that in something like "enum {FOO, LAST_THING=FOO}" we print
      FOO, not LAST_THING.  */
 
-  for (syms = *symlist, n = 0; syms; syms = syms->next)
+  for (syms = *symlist, n = nsyms - 1; syms; syms = syms->next)
     {
-      int j = 0;
-      if (syms == osyms)
-       j = o_nsyms;
-      for (; j < syms->nsyms; j++,n++)
+      int last = syms == osyms ? o_nsyms : 0;
+      int j = syms->nsyms;
+      for (; --j >= last; --n)
        {
          struct symbol *xsym = syms->symbol[j];
          SYMBOL_TYPE (xsym) = type;
          TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
-         TYPE_FIELD_VALUE (type, n) = 0;
          TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
          TYPE_FIELD_BITSIZE (type, n) = 0;
        }
@@ -3138,7 +4277,7 @@ read_sun_builtin_type (pp, typenums, objfile)
        signed_type = 0;
        break;
       default:
-       return error_type (pp);
+       return error_type (pp, objfile);
     }
   (*pp)++;
 
@@ -3156,17 +4295,17 @@ read_sun_builtin_type (pp, typenums, objfile)
      we will ignore it.  */
   read_huge_number (pp, ';', &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
 
   /* The second number is always 0, so ignore it too. */
   read_huge_number (pp, ';', &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
 
   /* The third number is the number of bits for this type. */
   type_bits = read_huge_number (pp, 0, &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
   /* The type *should* end with a semicolon.  If it are embedded
      in a larger type the semicolon may be the only way to know where
      the type ends.  If this type is at the end of the stabstring we
@@ -3201,12 +4340,12 @@ read_sun_floating_type (pp, typenums, objfile)
      FN_COMPLEX.  */
   details = read_huge_number (pp, ';', &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
 
   /* The second number is the number of bytes occupied by this type */
   nbytes = read_huge_number (pp, ';', &nbits);
   if (nbits != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
 
   if (details == NF_COMPLEX || details == NF_COMPLEX16
       || details == NF_COMPLEX32)
@@ -3258,7 +4397,11 @@ read_huge_number (pp, end, bits)
       p++;
     }
 
-  upper_limit = LONG_MAX / radix;
+  if (os9k_stabs)
+    upper_limit = ULONG_MAX / radix;
+  else
+    upper_limit = LONG_MAX / radix;
+
   while ((c = *p++) >= '0' && c < ('0' + radix))
     {
       if (n <= upper_limit)
@@ -3336,22 +4479,27 @@ read_range_type (pp, typenums, objfile)
      int typenums[2];
      struct objfile *objfile;
 {
+  char *orig_pp = *pp;
   int rangenums[2];
   long n2, n3;
   int n2bits, n3bits;
   int self_subrange;
   struct type *result_type;
-  struct type *index_type;
+  struct type *index_type = NULL;
 
   /* First comes a type we are a subrange of.
      In C it is usually 0, 1 or the type being defined.  */
-  /* FIXME: according to stabs.texinfo and AIX doc, this can be a type-id
-     not just a type number.  */
   if (read_type_number (pp, rangenums) != 0)
-    return error_type (pp);
+    return error_type (pp, objfile);
   self_subrange = (rangenums[0] == typenums[0] &&
                   rangenums[1] == typenums[1]);
 
+  if (**pp == '=')
+    {
+      *pp = orig_pp;
+      index_type = read_type (pp, objfile);
+    }
+
   /* A semicolon should now follow; skip it.  */
   if (**pp == ';')
     (*pp)++;
@@ -3362,8 +4510,11 @@ read_range_type (pp, typenums, objfile)
   n3 = read_huge_number (pp, ';', &n3bits);
 
   if (n2bits == -1 || n3bits == -1)
-    return error_type (pp);
-  
+    return error_type (pp, objfile);
+
+  if (index_type)
+    goto handle_true_range;
+
   /* If limits are huge, must be large integral type.  */
   if (n2bits != 0 || n3bits != 0)
     {
@@ -3397,14 +4548,14 @@ read_range_type (pp, typenums, objfile)
                            objfile);
        }
       else
-       return error_type (pp);
+       return error_type (pp, objfile);
     }
 
   /* A type defined as a subrange of itself, with bounds both 0, is void.  */
   if (self_subrange && n2 == 0 && n3 == 0)
     return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
 
-  /* If n3 is zero and n2 is not, we want a floating type,
+  /* 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,
@@ -3436,6 +4587,10 @@ read_range_type (pp, typenums, objfile)
   else if (self_subrange && n2 == 0 && n3 == 127)
     return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile);
 
+  else if (current_symbol && SYMBOL_LANGUAGE (current_symbol) == language_chill
+          && !self_subrange)
+    goto handle_true_range;
+
   /* We used to do this only for subrange of self or subrange of int.  */
   else if (n2 == 0)
     {
@@ -3471,14 +4626,12 @@ read_range_type (pp, typenums, objfile)
 
   /* We have a real range type on our hands.  Allocate space and
      return a real pointer.  */
+ handle_true_range:
 
-  /* At this point I don't have the faintest idea how to deal with
-     a self_subrange type; I'm going to assume that this is used
-     as an idiom, and that all of them are special cases.  So . . .  */
   if (self_subrange)
-    return error_type (pp);
-
-  index_type = *dbx_lookup_type (rangenums);
+    index_type = builtin_type_int;
+  else
+    index_type = *dbx_lookup_type (rangenums);
   if (index_type == NULL)
     {
       /* Does this actually ever happen?  Is that why we are worrying
@@ -3518,7 +4671,7 @@ read_args (pp, end, objfile)
        /* Invalid argument list: no ','.  */
        return (struct type **)-1;
       (*pp)++;
-      STABS_CONTINUE (pp);
+      STABS_CONTINUE (pp, objfile);
       types[n++] = read_type (pp, objfile);
     }
   (*pp)++;                     /* get past `end' (the ':' character) */
@@ -3604,6 +4757,7 @@ common_block_end (objfile)
   sym = (struct symbol *) 
     obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
   memset (sym, 0, sizeof (struct symbol));
+  /* Note: common_block_name already saved on symbol_obstack */
   SYMBOL_NAME (sym) = common_block_name;
   SYMBOL_CLASS (sym) = LOC_BLOCK;
 
@@ -3700,7 +4854,7 @@ cleanup_undefined_types ()
          case TYPE_CODE_ENUM:
          {
            /* Check if it has been defined since.  Need to do this here
-              as well as in check_stub_type to deal with the (legitimate in
+              as well as in check_typedef to deal with the (legitimate in
               C though not C++) case of several types with the same name
               in different source files.  */
            if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB)
@@ -3737,45 +4891,7 @@ cleanup_undefined_types ()
          }
          break;
 
-       case TYPE_CODE_ARRAY:
-         {
-           /* This is a kludge which is here for historical reasons
-              because I suspect that check_stub_type does not get
-              called everywhere it needs to be called for arrays.  Even
-              with this kludge, those places are broken for the case
-              where the stub type is defined in another compilation
-              unit, but this kludge at least deals with it for the case
-              in which it is the same compilation unit.
-
-              Don't try to do this by calling check_stub_type; it might
-              cause symbols to be read in lookup_symbol, and the symbol
-              reader is not reentrant.  */
-
-           struct type *range_type;
-           int lower, upper;
-
-           if (TYPE_LENGTH (*type) != 0)               /* Better be unknown */
-             goto badtype;
-           if (TYPE_NFIELDS (*type) != 1)
-             goto badtype;
-           range_type = TYPE_FIELD_TYPE (*type, 0);
-           if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
-             goto badtype;
-
-           /* Now recompute the length of the array type, based on its
-              number of elements and the target type's length.  */
-           lower = TYPE_FIELD_BITPOS (range_type, 0);
-           upper = TYPE_FIELD_BITPOS (range_type, 1);
-           TYPE_LENGTH (*type) = (upper - lower + 1)
-             * TYPE_LENGTH (TYPE_TARGET_TYPE (*type));
-
-           /* If the target type is not a stub, we could be clearing
-              TYPE_FLAG_TARGET_STUB for *type.  */
-         }
-         break;
-
        default:
-       badtype:
          {
            static struct complaint msg = {"\
 GDB internal error.  cleanup_undefined_types with bad type %d.", 0, 0};
@@ -3798,69 +4914,153 @@ scan_file_globals (objfile)
 {
   int hash;
   struct minimal_symbol *msymbol;
-  struct symbol *sym, *prev;
+  struct symbol *sym, *prev, *rsym;
+  struct objfile *resolve_objfile;
+
+  /* SVR4 based linkers copy referenced global symbols from shared
+     libraries to the main executable.
+     If we are scanning the symbols for a shared library, try to resolve
+     them from the minimal symbols of the main executable first.  */
 
-  if (objfile->msymbols == 0)          /* Beware the null file.  */
-    return;
+  if (symfile_objfile && objfile != symfile_objfile)
+    resolve_objfile = symfile_objfile;
+  else
+    resolve_objfile = objfile;
 
-  for (msymbol = objfile -> msymbols; SYMBOL_NAME (msymbol) != NULL; msymbol++)
+  while (1)
     {
-      QUIT;
+      /* Avoid expensive loop through all minimal symbols if there are
+        no unresolved symbols.  */
+      for (hash = 0; hash < HASHSIZE; hash++)
+       {
+         if (global_sym_chain[hash])
+           break;
+       }
+      if (hash >= HASHSIZE)
+       return;
+
+      for (msymbol = resolve_objfile -> msymbols;
+          msymbol && SYMBOL_NAME (msymbol) != NULL;
+          msymbol++)
+       {
+         QUIT;
 
-      prev = NULL;
+         /* Skip static symbols.  */
+         switch (MSYMBOL_TYPE (msymbol))
+           {
+           case mst_file_text:
+           case mst_file_data:
+           case mst_file_bss:
+             continue;
+           default:
+             break;
+           }
 
-      /* Get the hash index and check all the symbols
-        under that hash index. */
+         prev = NULL;
 
-      hash = hashname (SYMBOL_NAME (msymbol));
+         /* Get the hash index and check all the symbols
+            under that hash index. */
 
-      for (sym = global_sym_chain[hash]; sym;)
-       {
-         if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
-             STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
+         hash = hashname (SYMBOL_NAME (msymbol));
+
+         for (sym = global_sym_chain[hash]; sym;)
            {
-             /* Splice this symbol out of the hash chain and
-                assign the value we have to it. */
-             if (prev)
-               {
-                 SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
-               }
-             else
+             if (SYMBOL_NAME (msymbol)[0] == SYMBOL_NAME (sym)[0] &&
+                 STREQ(SYMBOL_NAME (msymbol) + 1, SYMBOL_NAME (sym) + 1))
                {
-                 global_sym_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
-               }
-             
-             /* Check to see whether we need to fix up a common block.  */
-             /* Note: this code might be executed several times for
-                the same symbol if there are multiple references.  */
 
-             if (SYMBOL_CLASS (sym) == LOC_BLOCK)
-               {
-                 fix_common_block (sym, SYMBOL_VALUE_ADDRESS (msymbol));
-               }
-             else
-               {
-                 SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol);
-               }
+                 struct alias_list *aliases;
 
-             SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol);
-             
-             if (prev)
-               {
-                 sym = SYMBOL_VALUE_CHAIN (prev);
+                 /* Splice this symbol out of the hash chain and
+                    assign the value we have to it. */
+                 if (prev)
+                   {
+                     SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym);
+                   }
+                 else
+                   {
+                     global_sym_chain[hash] = SYMBOL_VALUE_CHAIN (sym);
+                   }
+                 
+                 /* Check to see whether we need to fix up a common block.  */
+                 /* Note: this code might be executed several times for
+                    the same symbol if there are multiple references.  */
+
+                 /* If symbol has aliases, do minimal symbol fixups for each.
+                    These live aliases/references weren't added to 
+                    global_sym_chain hash but may also need to be fixed up. */
+                 /* 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 */
+                 rsym = sym;
+                 aliases = SYMBOL_ALIASES (sym);
+                 while (rsym)
+                   {
+                     if (SYMBOL_CLASS (rsym) == LOC_BLOCK)
+                       {
+                         fix_common_block (rsym,
+                                           SYMBOL_VALUE_ADDRESS (msymbol));
+                       }
+                     else
+                       {
+                         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)
+                   {
+                     sym = SYMBOL_VALUE_CHAIN (prev);
+                   }
+                 else
+                   {
+                     sym = global_sym_chain[hash];
+                   }
                }
              else
                {
-                 sym = global_sym_chain[hash];
+                 prev = sym;
+                 sym = SYMBOL_VALUE_CHAIN (sym);
                }
            }
+       }
+      if (resolve_objfile == objfile)
+       break;
+      resolve_objfile = objfile;
+    }
+
+  /* Change the storage class of any remaining unresolved globals to
+     LOC_UNRESOLVED and remove them from the chain.  */
+  for (hash = 0; hash < HASHSIZE; hash++)
+    {
+      sym = global_sym_chain[hash];
+      while (sym)
+       {
+         prev = sym;
+         sym = SYMBOL_VALUE_CHAIN (sym);
+
+         /* Change the symbol address from the misleading chain value
+            to address zero.  */
+         SYMBOL_VALUE_ADDRESS (prev) = 0;
+
+         /* Complain about unresolved common block symbols.  */
+         if (SYMBOL_CLASS (prev) == LOC_STATIC)
+           SYMBOL_CLASS (prev) = LOC_UNRESOLVED;
          else
-           {
-             prev = sym;
-             sym = SYMBOL_VALUE_CHAIN (sym);
-           }
+           complain (&unresolved_sym_chain_complaint,
+                     objfile -> name, SYMBOL_NAME (prev));
        }
     }
+  memset (global_sym_chain, 0, sizeof (global_sym_chain));
 }
 
 /* Initialize anything that needs initializing when starting to read
This page took 0.056853 seconds and 4 git commands to generate.