* inftarg.c (child_thread_alive): New function to see if a
[deliverable/binutils-gdb.git] / gdb / stabsread.c
index befb564479e1acc23849bff804a4d1f1448b5a75..ccd7b8e28b0db7496a2bc7855e4d7b3d92706de8 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for decoding "stabs" debugging information format.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
              Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -25,6 +25,7 @@ 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 "bfd.h"
 #include "obstack.h"
 #include "symtab.h"
@@ -32,6 +33,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "symfile.h"
 #include "objfiles.h"
 #include "aout/stab_gnu.h"     /* We always use GNU stabs, not native */
+#include "libaout.h"
+#include "aout/aout64.h"
+#include "gdb-stabs.h"
 #include "buildsym.h"
 #include "complaints.h"
 #include "demangle.h"
@@ -54,7 +58,12 @@ struct field_info
   struct nextfield
     {
       struct nextfield *next;
+
+      /* This is the raw visibility from the stab.  It is not checked
+        for being one of the visibilities we recognize, so code which
+        examines this field better be able to deal.  */
       int visibility;
+
       struct field field;
     } *list;
   struct next_fnfieldlist
@@ -144,30 +153,6 @@ static const char vb_name[] =   { '_','v','b',CPLUS_MARKER,'\0' };
 #define BELIEVE_PCC_PROMOTION 0
 #endif
 
-#if 0
-/* I think this can go away, all current uses have been removed.
-   GCC emits a few crazy types which can only be distinguished by the
-   name (complex, long long on some machines), but I'd say fix GCC.  */
-
-/* During some calls to read_type (and thus to read_range_type), this
-   contains the name of the type being defined.  Range types are only
-   used in C as basic types.  We use the name to distinguish the otherwise
-   identical basic types "int" and "long" and their unsigned versions.
-   FIXME, this should disappear with better type management.  */
-
-static char *long_kludge_name;
-#endif
-
-#if 0
-struct complaint dbx_class_complaint =
-{
-  "encountered DBX-style class variable debugging information.\n\
-You seem to have compiled your program with \
-\"g++ -g0\" instead of \"g++ -g\".\n\
-Therefore GDB will not know about your class variables", 0, 0
-};
-#endif
-
 struct complaint invalid_cpp_abbrev_complaint =
   {"invalid C++ abbreviation `%s'", 0, 0};
 
@@ -201,6 +186,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: `%s' from global_sym_chain unresolved", 0, 0};
+
 struct complaint stabs_general_complaint =
   {"%s", 0, 0};
 
@@ -213,10 +201,39 @@ static int undef_types_length;
 /* Check for and handle cretinous stabs symbol name continuation!  */
 #define STABS_CONTINUE(pp)                             \
   do {                                                 \
-    if (**(pp) == '\\') *(pp) = next_symbol_text ();   \
+    if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
+      *(pp) = next_symbol_text ();     \
   } while (0)
-
 \f
+/* FIXME: These probably should be our own types (like rs6000_builtin_type
+   has its own types) rather than builtin_type_*.  */
+static struct type **os9k_type_vector[] = {
+       0,
+       &builtin_type_int,
+       &builtin_type_char,
+       &builtin_type_long,
+       &builtin_type_short,
+       &builtin_type_unsigned_char,
+       &builtin_type_unsigned_short,
+       &builtin_type_unsigned_long,
+       &builtin_type_unsigned_int,
+       &builtin_type_float,
+       &builtin_type_double,
+       &builtin_type_void,
+       &builtin_type_long_double
+};
+
+static void os9k_init_type_vector PARAMS ((struct type **));
+
+static void
+os9k_init_type_vector(tv)
+    struct type **tv;
+{
+  int i;
+  for (i=0; i<sizeof(os9k_type_vector)/sizeof(struct type **); i++)
+    tv[i] = (os9k_type_vector[i] == 0 ? 0 : *(os9k_type_vector[i]));
+}
+
 /* Look up a dbx type-number pair.  Return the address of the slot
    where the type for that number-pair is stored.
    The number-pair is in TYPENUMS.
@@ -282,6 +299,10 @@ Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
                      (type_vector_length * sizeof (struct type *)));
          memset (&type_vector[old_len], 0,
                  (type_vector_length - old_len) * sizeof (struct type *));
+
+         if (os9k_stabs)
+           /* Deal with OS9000 fundamental types.  */
+           os9k_init_type_vector (type_vector);
        }
       return (&type_vector[index]);
     }
@@ -376,9 +397,22 @@ patch_block_stabs (symbols, stabs, objfile)
        {
          name = stabs->stab[ii];
          pp = (char*) strchr (name, ':');
+         while (pp[1] == ':')
+           {
+              pp += 2;
+              pp = (char *)strchr(pp, ':');
+           }
          sym = find_symbol_in_list (symbols, name, pp-name);
          if (!sym)
            {
+             /* FIXME-maybe: it would be nice if we noticed whether
+                the variable was defined *anywhere*, not just whether
+                it is defined in this compilation unit.  But neither
+                xlc or GCC seem to need such a definition, and until
+                we do psymtabs (so that the minimal symbols from all
+                compilation units are available now), I'm not sure
+                how to get the information.  */
+
              /* On xcoff, if a global is defined and never referenced,
                 ld will remove it from the executable.  There is then
                 a N_GSYM stab for it, but no regular (C_EXT) symbol.  */
@@ -464,6 +498,10 @@ read_type_number (pp, typenums)
 
 static char *type_synonym_name;
 
+#if !defined (REG_STRUCT_HAS_ADDR)
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) 0
+#endif
+
 /* ARGSUSED */
 struct symbol *
 define_symbol (valu, string, desc, type, objfile)
@@ -494,6 +532,12 @@ define_symbol (valu, string, desc, type, objfile)
   if (p == 0)
     return 0;
 
+  while (p[1] == ':')
+    {
+       p += 2;
+       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] == ':')));
@@ -502,6 +546,19 @@ define_symbol (valu, string, desc, type, objfile)
     obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
   memset (sym, 0, sizeof (struct symbol));
 
+  switch (type & N_TYPE)
+    {
+    case N_TEXT:
+      SYMBOL_SECTION(sym) = SECT_OFF_TEXT;
+      break;
+    case N_DATA:
+      SYMBOL_SECTION(sym) = SECT_OFF_DATA;
+      break;
+    case N_BSS:
+      SYMBOL_SECTION(sym) = SECT_OFF_BSS;
+      break;
+    }
+
   if (processing_gcc_compilation)
     {
       /* GCC 2.x puts the line number in desc.  SunOS apparently puts in the
@@ -536,6 +593,12 @@ 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 */
@@ -720,23 +783,7 @@ 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));
       /* fall into process_prototype_types */
 
     process_prototype_types:
@@ -775,6 +822,7 @@ define_symbol (valu, string, desc, type, objfile)
       /* This case is faked by a conditional above,
         when there is no code letter in the dbx data.
         Dbx data never actually contains 'l'.  */
+    case 's':
     case 'l':
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_LOCAL;
@@ -806,17 +854,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;
@@ -895,7 +941,6 @@ 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
@@ -938,17 +983,34 @@ define_symbol (valu, string, desc, type, objfile)
          /* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same
             name to represent an argument passed in a register.
             GCC uses 'P' for the same case.  So if we find such a symbol pair
-            we combine it into one 'P' symbol.
+            we combine it into one 'P' symbol.  For Sun cc we need to do this
+            regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out
+            the 'p' symbol even if it never saves the argument onto the stack.
+
+            On most machines, we want to preserve both symbols, so that
+            we can still get information about what is going on with the
+            stack (VAX for computing args_printed, using stack slots instead
+            of saved registers in backtraces, etc.).
+
             Note that this code illegally combines
-              main(argc) int argc; { register int argc = 1; }
+              main(argc) struct foo argc; { register struct foo argc; }
             but this case is considered pathological and causes a warning
             from a decent compiler.  */
+
          if (local_symbols
-             && local_symbols->nsyms > 0)
+             && local_symbols->nsyms > 0
+#ifndef USE_REGISTER_NOT_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)
+#endif
+             )
            {
              struct symbol *prev_sym;
              prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
-             if (SYMBOL_CLASS (prev_sym) == LOC_ARG
+             if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG
+                  || SYMBOL_CLASS (prev_sym) == LOC_ARG)
                  && STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME(sym)))
                {
                  SYMBOL_CLASS (prev_sym) = LOC_REGPARM;
@@ -971,22 +1033,23 @@ 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;
 
     case 't':
-#if 0
-      /* See comment where long_kludge_name is declared.  */
-      /* Here we save the name of the symbol for read_range_type, which
-        ends up reading in the basic types.  In stabs, unfortunately there
-        is no distinction between "int" and "long" types except their
-        names.  Until we work out a saner type policy (eliminating most
-        builtin types and using the names specified in the files), we
-        save away the name so that far away from here in read_range_type,
-        we can examine it to decide between "int" and "long".  FIXME.  */
-      long_kludge_name = SYMBOL_NAME (sym);
-#endif
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
 
       /* For a nameless type, we don't want a create a symbol, thus we
@@ -1014,7 +1077,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
@@ -1055,6 +1124,17 @@ define_symbol (valu, string, desc, type, objfile)
                                            strlen (SYMBOL_NAME (sym)),
                                            &objfile -> symbol_obstack);
        }
+      /* 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);
+       }
 
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
 
@@ -1091,8 +1171,23 @@ 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, &local_symbols);
+      if (os9k_stabs)
+       add_symbol_to_list (sym, &global_symbols);
+      else
+       add_symbol_to_list (sym, &local_symbols);
       break;
 
     case 'v':
@@ -1104,6 +1199,20 @@ define_symbol (valu, string, desc, type, objfile)
       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_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)
@@ -1131,16 +1240,22 @@ define_symbol (valu, string, desc, type, objfile)
      If REG_STRUCT_HAS_ADDR yields non-zero we have to convert LOC_REGPARM
      to LOC_REGPARM_ADDR for structures and unions.  */
 
-#if !defined (REG_STRUCT_HAS_ADDR)
-#define REG_STRUCT_HAS_ADDR(gcc_p) 0
-#endif
-
   if (SYMBOL_CLASS (sym) == LOC_REGPARM
-      && REG_STRUCT_HAS_ADDR (processing_gcc_compilation)
-      && (   (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
+      && 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;
+
   return sym;
 }
 
@@ -1188,7 +1303,7 @@ error_type (pp)
        }
 
       /* Check for and handle cretinous dbx symbol name continuation!  */
-      if ((*pp)[-1] == '\\')
+      if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
        {
          *pp = next_symbol_text ();
        }
@@ -1222,6 +1337,9 @@ read_type (pp, objfile)
      there is no size attribute.  */
   int type_size = -1;
 
+  /* Used to distinguish string and bitstring from char-array and set. */
+  int is_string = 0;
+
   /* Read type number if present.  The type number may be omitted.
      for instance in a two-dimensional array declared with type
      "ar1;1;10;ar1;1;10;4".  */
@@ -1271,6 +1389,11 @@ read_type (pp, objfile)
                  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.  */
@@ -1304,7 +1427,7 @@ read_type (pp, objfile)
        char *type_name;
        
        {
-         char *from, *to;
+         char *from, *to, *p, *q1, *q2;
          
          /* Set the type code according to the following letter.  */
          switch ((*pp)[0])
@@ -1319,30 +1442,51 @@ read_type (pp, objfile)
              code = TYPE_CODE_ENUM;
              break;
            default:
-             return error_type (pp);
+             {
+               /* Complain and keep going, so compilers can invent new
+                  cross-reference types.  */
+               static struct complaint msg =
+                 {"Unrecognized cross-reference type `%c'", 0, 0};
+               complain (&msg, (*pp)[0]);
+               code = TYPE_CODE_STRUCT;
+               break;
+             }
            }
-         
-         to = type_name = (char *)
-           obstack_alloc (&objfile -> type_obstack,
-                          (((char *) strchr (*pp, ':') - (*pp)) + 1));
+          
+         q1 = strchr(*pp, '<');
+         p = strchr(*pp, ':');
+         if (p == NULL)
+           return error_type (pp);
+         while (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);
+           }
+         to = type_name = 
+               (char *)obstack_alloc (&objfile->type_obstack, p - *pp + 1);
        
          /* Copy the name.  */
          from = *pp + 1;
-         while ((*to++ = *from++) != ':')
-           ;
-         *--to = '\0';
+         while (from < p) 
+           *to++ = *from++;
+         *to = '\0';
          
-         /* Set the pointer ahead of the name which we just read.  */
-         *pp = from;
+         /* Set the pointer ahead of the name which we just read, and
+            the colon.  */
+         *pp = from + 1;
        }
 
-       /* Now check to see whether the type has already been declared.  */
-       /* This is necessary at least in the case where the
-          program says something like
-            struct foo bar[5];
-          The compiler puts out a cross-reference; we better find
-          set the length of the structure correctly so we can
-          set the length of the array.  */
+       /* Now check to see whether the type has already been
+          declared.  This was written for arrays of cross-referenced
+          types before we had TYPE_CODE_TARGET_STUBBED, so I'm pretty
+          sure it is not necessary anymore.  But it might be a good
+          idea, to save a little memory.  */
+
        for (ppt = file_symbols; ppt; ppt = ppt->next)
          for (i = 0; i < ppt->nsyms; i++)
            {
@@ -1358,7 +1502,7 @@ read_type (pp, objfile)
                  return type;
                }
            }
-       
+
        /* Didn't find the type to which this refers, so we must
           be dealing with a forward reference.  Allocate a type
           structure for it, and keep track of it so we can
@@ -1387,41 +1531,49 @@ read_type (pp, objfile)
     case '9':
     case '(':
 
-      (*pp)--;
-      if (read_type_number (pp, xtypenums) != 0)
-       return error_type (pp);
-
-      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, 0, 0, NULL, objfile);
-      else
-       {
-         struct type *xtype = *dbx_lookup_type (xtypenums);
-
-         /* This can happen if we had '-' followed by a garbage character,
-            for example.  */
-         if (xtype == NULL)
-           return error_type (pp);
+      {
+       char *pp_saved;
 
-         /* 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).  */
+       (*pp)--;
+       pp_saved = *pp;
 
-         type = alloc_type (objfile);
-         memcpy (type, xtype, sizeof (struct type));
+       /* Peek ahead at the number to detect void.  */
+       if (read_type_number (pp, xtypenums) != 0)
+         return error_type (pp);
 
-         /* 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_NAME (type) = NULL;
-         TYPE_TAG_NAME (type) = NULL;
-       }
-      if (typenums[0] != -1)
-       *dbx_lookup_type (typenums) = type;
-      break;
+       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
+         {
+           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_NAME (type) = NULL;
+           TYPE_TAG_NAME (type) = NULL;
+         }
+       if (typenums[0] != -1)
+         *dbx_lookup_type (typenums) = type;
+       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
@@ -1441,16 +1593,40 @@ read_type (pp, objfile)
       break;
 
     case 'f':                          /* Function returning another type */
+      if (os9k_stabs && **pp == '(')
+       {
+         /* Function prototype; parse it.
+            We must conditionalize this on os9k_stabs because otherwise
+            it could be confused with a Sun-style (1,3) typenumber
+            (I think).  */
+         struct type *t;
+         ++*pp;
+         while (**pp != ')')
+            {
+              t = read_type(pp, objfile);
+              if (**pp == ',') ++*pp;
+            }
+       }
       type1 = read_type (pp, objfile);
       type = make_function_type (type1, dbx_lookup_type (typenums));
       break;
 
-    case 'k':                          /* Const qualifier on some type (Sun) */
+    case 'k':                     /* Const qualifier on some type (Sun) */
+    case 'c':                     /* Const qualifier on some type (OS9000) */
+      /* 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);
       type = read_type (pp, objfile);
       /* FIXME! For now, we ignore const and volatile qualifiers.  */
       break;
 
-    case 'B':                          /* Volatile qual on some type (Sun) */
+    case 'B':                       /* Volatile qual on some type (Sun) */
+    case 'i':                       /* Volatile qual on some type (OS9000) */
+      /* 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);
       type = read_type (pp, objfile);
       /* FIXME! For now, we ignore const and volatile qualifiers.  */
       break;
@@ -1511,10 +1687,17 @@ read_type (pp, objfile)
        *dbx_lookup_type (typenums) = type;
       break;
 
-    case 'b':                          /* Sun ACC builtin int type */
-      type = read_sun_builtin_type (pp, typenums, objfile);
-      if (typenums[0] != -1)
-       *dbx_lookup_type (typenums) = type;
+    case 'b':
+      if (os9k_stabs)
+       /* Const and volatile qualified type.  */
+       type = read_type (pp, objfile);
+      else
+       {
+         /* Sun ACC builtin int type */
+         type = read_sun_builtin_type (pp, typenums, objfile);
+         if (typenums[0] != -1)
+           *dbx_lookup_type (typenums) = type;
+       }
       break;
 
     case 'R':                          /* Sun ACC builtin float type */
@@ -1557,6 +1740,17 @@ read_type (pp, objfile)
       
       type = dbx_alloc_type (typenums, objfile);
       type = read_array_type (pp, type, objfile);
+      if (is_string)
+       TYPE_CODE (type) = TYPE_CODE_STRING;
+      break;
+
+    case 'S':
+      type1 = read_type (pp, objfile);
+      type = create_set_type ((struct type*) NULL, type1);
+      if (is_string)
+       TYPE_CODE (type) = TYPE_CODE_BITSTRING;
+      if (typenums[0] != -1)
+       *dbx_lookup_type (typenums) = type;
       break;
 
     default:
@@ -1573,7 +1767,7 @@ read_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;
 }
@@ -1586,7 +1780,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;
@@ -1649,7 +1843,7 @@ rs6000_builtin_type (typenum)
                           "unsigned long", NULL);
       break;
     case 11:
-      rettype = init_type (TYPE_CODE_VOID, 0, 0, "void", NULL);
+      rettype = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
       break;
     case 12:
       /* IEEE single precision (32 bit).  */
@@ -1720,6 +1914,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;
@@ -1730,6 +1938,7 @@ rs6000_builtin_type (typenum)
 #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:
@@ -2138,36 +2347,19 @@ read_one_struct_field (fip, pp, p, type, objfile)
   fip -> list -> field.name =
     obsavestring (*pp, p - *pp, &objfile -> type_obstack);
   *pp = p + 1;
-  
+
   /* This means we have a visibility for a field coming. */
   if (**pp == '/')
     {
       (*pp)++;
       fip -> list -> visibility = *(*pp)++;
-      switch (fip -> list -> visibility)
-       {
-         case VISIBILITY_PRIVATE:
-         case VISIBILITY_PROTECTED:
-           break;
-         
-         case VISIBILITY_PUBLIC:
-           /* Nothing to do */
-           break;
-         
-         default:
-           /* Unknown visibility specifier. */
-           complain (&stabs_general_complaint,
-                     "unknown visibility specifier");
-           return;
-           break;
-       }
     }
   else
     {
       /* normal dbx-style format, no explicit visibility */
       fip -> list -> visibility = VISIBILITY_PUBLIC;
     }
-  
+
   fip -> list -> field.type = read_type (pp, objfile);
   if (**pp == ':')
     {
@@ -2217,41 +2409,33 @@ read_one_struct_field (fip, pp, p, type, objfile)
        return;
       }
   }
-#if 0
-  /* FIXME-tiemann: Can't the compiler put out something which
-     lets us distinguish these? (or maybe just not put out anything
-     for the field).  What is the story here?  What does the compiler
-     really do?  Also, patch gdb.texinfo for this case; I document
-     it as a possible problem there.  Search for "DBX-style".  */
-  
-  /* This is wrong because this is identical to the symbols
-     produced for GCC 0-size arrays.  For example:
-     typedef union {
-     int num;
-     char str[0];
-     } foo;
-     The code which dumped core in such circumstances should be
-     fixed not to dump core.  */
-  
-  /* g++ -g0 can put out bitpos & bitsize zero for a static
-     field.  This does not give us any way of getting its
-     class, so we can't know its name.  But we can just
-     ignore the field so we don't dump core and other nasty
-     stuff.  */
+
   if (fip -> list -> field.bitpos == 0 && fip -> list -> field.bitsize == 0)
     {
-      complain (&dbx_class_complaint);
+      /* 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
+        this case is to use VISIBILITY_IGNORE, but that is a recent
+        invention.  (2) It is a 0-size array.  For example
+        union { int num; char str[0]; } foo.  Printing "<no value>" for
+        str in "p foo" is OK, since foo.str (and thus foo.str[3])
+        will continue to work, and a 0-size array as a whole doesn't
+        have any contents to print.
+
+        I suspect this probably could also happen with gcc -gstabs (not
+        -gstabs+) for static fields, and perhaps other C++ extensions.
+        Hopefully few people use -gstabs with gdb, since it is intended
+        for dbx compatibility.  */
+
       /* Ignore this field.  */
-      fip -> list = fip -> list -> next;
+      fip -> list-> visibility = VISIBILITY_IGNORE;
     }
   else
-#endif /* 0 */
     {
       /* Detect an unpacked field and mark it as such.
         dbx gives a bit size for all fields.
         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)
        {
@@ -2287,11 +2471,12 @@ read_one_struct_field (fip, pp, p, type, objfile)
        '/0'    (VISIBILITY_PRIVATE)
        '/1'    (VISIBILITY_PROTECTED)
        '/2'    (VISIBILITY_PUBLIC)
+       '/9'    (VISIBILITY_IGNORE)
 
    or nothing, for C style fields with public visibility.
 
    Returns 1 for success, 0 for failure.  */
-       
+
 static int
 read_struct_fields (fip, pp, type, objfile)
      struct field_info *fip;
@@ -2312,6 +2497,7 @@ read_struct_fields (fip, pp, type, objfile)
 
   while (**pp != ';')
     {
+      if (os9k_stabs && **pp == ',') break;
       STABS_CONTINUE (pp);
       /* Get space to record the next field's data.  */
       new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
@@ -2322,11 +2508,16 @@ read_struct_fields (fip, pp, type, objfile)
 
       /* Get the field name.  */
       p = *pp;
-      /* 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.  */
-      if (*p == CPLUS_MARKER && p[1] != '_')
+
+      /* 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).  */
+
+      if ((*p == '$' || *p == '.') && p[1] != '_')
        {
          if (!read_cpp_abbrev (fip, pp, type, objfile))
            return 0;
@@ -2352,7 +2543,7 @@ read_struct_fields (fip, pp, type, objfile)
        }
       read_one_struct_field (fip, pp, p, type, objfile);
     }
-  if (p[1] == ':')
+  if (p[0] == ':' && p[1] == ':')
     {
       /* chill the list of fields: the last entry (at the head) is a
         partially constructed entry which we now scrub. */
@@ -2440,7 +2631,7 @@ read_baseclasses (fip, pp, type, objfile)
       new -> field.bitsize = 0;        /* this should be an unpacked field! */
 
       STABS_CONTINUE (pp);
-      switch (*(*pp)++)
+      switch (**pp)
        {
          case '0':
            /* Nothing to do. */
@@ -2449,9 +2640,14 @@ read_baseclasses (fip, pp, type, objfile)
            SET_TYPE_FIELD_VIRTUAL (type, i);
            break;
          default:
-           /* Bad visibility format.  */
-           return 0;
+           /* Unknown character.  Complain and treat it as non-virtual.  */
+           {
+             static struct complaint msg = {
+               "Unknown virtual character `%c' for baseclass", 0, 0};
+             complain (&msg, **pp);
+           }
        }
+      ++(*pp);
 
       new -> visibility = *(*pp)++;
       switch (new -> visibility)
@@ -2461,8 +2657,14 @@ read_baseclasses (fip, pp, type, objfile)
          case VISIBILITY_PUBLIC:
            break;
          default:
-           /* Bad visibility format.  */
-           return 0;
+           /* 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;
+           }
        }
 
       {
@@ -2590,17 +2792,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)
@@ -2659,6 +2850,10 @@ attach_fields_to_type (fip, type, objfile)
       TYPE_FIELD_PROTECTED_BITS (type) =
        (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
       B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
+
+      TYPE_FIELD_IGNORE_BITS (type) =
+       (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
+      B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
     }
 
   /* Copy the saved-up fields into the field vector.  Start from the head
@@ -2678,11 +2873,20 @@ attach_fields_to_type (fip, type, objfile)
            SET_TYPE_FIELD_PROTECTED (type, nfields);
            break;
 
+         case VISIBILITY_IGNORE:
+           SET_TYPE_FIELD_IGNORE (type, nfields);
+           break;
+
          case VISIBILITY_PUBLIC:
            break;
 
          default:
-           /* Should warn about this unknown visibility? */
+           /* Unknown visibility.  Complain and treat it as public.  */
+           {
+             static struct complaint msg = {
+               "Unknown visibility `%c' for field", 0, 0};
+             complain (&msg, fip -> list -> visibility);
+           }
            break;
        }
       fip -> list = fip -> list -> next;
@@ -2767,28 +2971,33 @@ read_array_type (pp, type, objfile)
   int nbits;
 
   /* Format of an array type:
-     "ar<index type>;lower;upper;<array_contents_type>".  Put code in
-     to handle this.
+     "ar<index type>;lower;upper;<array_contents_type>".
+     OS9000: "arlower,upper;<array_contents_type>".
 
      Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
      for these, produce a type like float[][].  */
 
-  index_type = read_type (pp, objfile);
-  if (**pp != ';')
-    /* Improper format of array type decl.  */
-    return error_type (pp);
-  ++*pp;
+  if (os9k_stabs)
+    index_type = builtin_type_int;
+  else
+    {
+      index_type = read_type (pp, objfile);
+      if (**pp != ';')
+       /* Improper format of array type decl.  */
+       return error_type (pp);
+      ++*pp;
+    }
 
-  if (!(**pp >= '0' && **pp <= '9'))
+  if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
     {
       (*pp)++;
       adjustable = 1;
     }
-  lower = read_huge_number (pp, ';', &nbits);
+  lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits);
   if (nbits != 0)
     return error_type (pp);
 
-  if (!(**pp >= '0' && **pp <= '9'))
+  if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
     {
       (*pp)++;
       adjustable = 1;
@@ -2812,8 +3021,9 @@ read_array_type (pp, type, objfile)
   /* 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.  */
 
-  if (TYPE_LENGTH (element_type) == 0 && !adjustable)
+  if ((TYPE_FLAGS (element_type) & TYPE_FLAG_STUB) && !adjustable)
     {
+      TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
       add_undefined_type (type);
     }
 
@@ -2839,6 +3049,7 @@ read_enum_type (pp, type, objfile)
   struct pending **symlist;
   struct pending *osyms, *syms;
   int o_nsyms;
+  int nbits;
 
 #if 0
   /* FIXME!  The stabs produced by Sun CC merrily define things that ought
@@ -2852,12 +3063,21 @@ read_enum_type (pp, type, objfile)
   osyms = *symlist;
   o_nsyms = osyms ? osyms->nsyms : 0;
 
+  if (os9k_stabs)
+    {
+      /* Size.  Perhaps this does not have to be conditionalized on
+        os9k_stabs (assuming the name of an enum constant can't start
+        with a digit).  */
+      read_huge_number (pp, 0, &nbits);
+      if (nbits != 0)
+       return error_type (pp);
+    }
+
   /* Read the value-names and their values.
      The input syntax is NAME:VALUE,NAME:VALUE, and so on.
      A semicolon or comma instead of a NAME means the end.  */
   while (**pp && **pp != ';' && **pp != ',')
     {
-      int nbits;
       STABS_CONTINUE (pp);
       p = *pp;
       while (*p != ':') p++;
@@ -2884,7 +3104,7 @@ read_enum_type (pp, type, objfile)
 
   /* Now fill in the fields of the type-structure.  */
 
-  TYPE_LENGTH (type) = sizeof (int);
+  TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT;
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
   TYPE_NFIELDS (type) = nsyms;
@@ -2900,12 +3120,11 @@ 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->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;
@@ -2918,17 +3137,6 @@ read_enum_type (pp, type, objfile)
        break;
     }
 
-#if 0
-  /* This screws up perfectly good C programs with enums.  FIXME.  */
-  /* Is this Modula-2's BOOLEAN type?  Flag it as such if so. */
-  if(TYPE_NFIELDS(type) == 2 &&
-     ((STREQ(TYPE_FIELD_NAME(type,0),"TRUE") &&
-       STREQ(TYPE_FIELD_NAME(type,1),"FALSE")) ||
-      (STREQ(TYPE_FIELD_NAME(type,1),"TRUE") &&
-       STREQ(TYPE_FIELD_NAME(type,0),"FALSE"))))
-     TYPE_CODE(type) = TYPE_CODE_BOOL;
-#endif
-
   return type;
 }
 
@@ -2992,56 +3200,24 @@ read_sun_builtin_type (pp, typenums, objfile)
   type_bits = read_huge_number (pp, 0, &nbits);
   if (nbits != 0)
     return error_type (pp);
+  /* 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
+     can deal with the omitted semicolon (but we don't have to like
+     it).  Don't bother to complain(), Sun's compiler omits the semicolon
+     for "void".  */
+  if (**pp == ';')
+    ++(*pp);
 
-#if 0
-  /* FIXME.  Here we should just be able to make a type of the right
-     number of bits and signedness.  FIXME.  */
-
-  if (type_bits == TARGET_LONG_LONG_BIT)
-    return (lookup_fundamental_type (objfile,
-                signed_type? FT_LONG_LONG: FT_UNSIGNED_LONG_LONG));
-  
-  if (type_bits == TARGET_INT_BIT)
-    {
-      /* FIXME -- the only way to distinguish `int' from `long'
-        is to look at its name!  */
-      if (signed_type)
-       {
-         if (long_kludge_name && long_kludge_name[0] == 'l' /* long */)
-           return lookup_fundamental_type (objfile, FT_LONG);
-         else
-           return lookup_fundamental_type (objfile, FT_INTEGER);
-       }
-      else
-       {
-         if (long_kludge_name
-             && ((long_kludge_name[0] == 'u' /* unsigned */ &&
-                  long_kludge_name[9] == 'l' /* long */)
-                 || (long_kludge_name[0] == 'l' /* long unsigned */)))
-           return lookup_fundamental_type (objfile, FT_UNSIGNED_LONG);
-         else
-           return lookup_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
-       }
-    }
-    
-  if (type_bits == TARGET_SHORT_BIT)
-    return (lookup_fundamental_type (objfile,
-                signed_type? FT_SHORT: FT_UNSIGNED_SHORT));
-  
-  if (type_bits == TARGET_CHAR_BIT)
-    return (lookup_fundamental_type (objfile,
-                signed_type? FT_CHAR: FT_UNSIGNED_CHAR));
-  
   if (type_bits == 0)
-    return lookup_fundamental_type (objfile, FT_VOID);
-  
-  return error_type (pp);
-#else
-  return init_type (type_bits == 0 ? TYPE_CODE_VOID : TYPE_CODE_INT,
-                   type_bits / TARGET_CHAR_BIT,
-                   signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
-                   objfile);
-#endif
+    return init_type (TYPE_CODE_VOID, 1,
+                     signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
+                     objfile);
+  else
+    return init_type (TYPE_CODE_INT,
+                     type_bits / TARGET_CHAR_BIT,
+                     signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
+                     objfile);
 }
 
 static struct type *
@@ -3115,7 +3291,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)
@@ -3193,22 +3373,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);
   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)++;
@@ -3220,7 +3405,10 @@ read_range_type (pp, typenums, objfile)
 
   if (n2bits == -1 || n3bits == -1)
     return error_type (pp);
-  
+
+  if (index_type)
+    goto handle_true_range;
+
   /* If limits are huge, must be large integral type.  */
   if (n2bits != 0 || n3bits != 0)
     {
@@ -3259,7 +3447,7 @@ read_range_type (pp, typenums, 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, 0, 0, NULL, objfile);
+    return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
 
   /* If n3 is zero and n2 is not, we want a floating type,
      and n2 is the width in bytes.
@@ -3328,6 +3516,7 @@ 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
@@ -3483,7 +3672,7 @@ common_block_end (objfile)
     for (j = common_block_i; j < common_block->nsyms; j++)
       add_symbol_to_list (common_block->symbol[j], &new);
 
-  SYMBOL_NAMESPACE (sym) = (enum namespace)((long) new);
+  SYMBOL_TYPE (sym) = (struct type *) new;
 
   /* Should we be putting local_symbols back to what it was?
      Does it matter?  */
@@ -3503,7 +3692,7 @@ fix_common_block (sym, valu)
     struct symbol *sym;
     int valu;
 {
-  struct pending *next = (struct pending *) SYMBOL_NAMESPACE (sym);
+  struct pending *next = (struct pending *) SYMBOL_TYPE (sym);
   for ( ; next; next = next->next)
     {
       register int j;
@@ -3556,7 +3745,10 @@ cleanup_undefined_types ()
          case TYPE_CODE_UNION:
          case TYPE_CODE_ENUM:
          {
-           /* Check if it has been defined since.  */
+           /* 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
+              C though not C++) case of several types with the same name
+              in different source files.  */
            if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB)
              {
                struct pending *ppt;
@@ -3591,8 +3783,20 @@ cleanup_undefined_types ()
          }
          break;
 
-         case TYPE_CODE_ARRAY:
+       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;
 
@@ -3610,6 +3814,9 @@ cleanup_undefined_types ()
            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;
 
@@ -3623,28 +3830,53 @@ GDB internal error.  cleanup_undefined_types with bad type %d.", 0, 0};
          break;
        }
     }
+
   undef_types_length = 0;
 }
 
 /* Scan through all of the global symbols defined in the object file,
    assigning values to the debugging symbols that need to be assigned
-   to.  Get these symbols from the minimal symbol table.  */
+   to.  Get these symbols from the minimal symbol table.
+   Return 1 if there might still be unresolved debugging symbols, else 0.  */
 
-void
-scan_file_globals (objfile)
+static int scan_file_globals_1 PARAMS ((struct objfile *));
+
+static int
+scan_file_globals_1 (objfile)
      struct objfile *objfile;
 {
   int hash;
   struct minimal_symbol *msymbol;
   struct symbol *sym, *prev;
 
+  /* 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 0;
+
   if (objfile->msymbols == 0)          /* Beware the null file.  */
-    return;
+    return 1;
 
   for (msymbol = objfile -> msymbols; SYMBOL_NAME (msymbol) != NULL; msymbol++)
     {
       QUIT;
 
+      /* Skip static symbols.  */
+      switch (MSYMBOL_TYPE (msymbol))
+       {
+       case mst_file_text:
+       case mst_file_data:
+       case mst_file_bss:
+         continue;
+       default:
+         break;
+       }
+
       prev = NULL;
 
       /* Get the hash index and check all the symbols
@@ -3680,6 +3912,8 @@ scan_file_globals (objfile)
                {
                  SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol);
                }
+
+             SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol);
              
              if (prev)
                {
@@ -3697,6 +3931,42 @@ scan_file_globals (objfile)
            }
        }
     }
+  return 1;
+}
+
+/* Assign values to global debugging symbols.
+   Search the passed objfile first, then try the runtime common symbols.
+   Complain about any remaining unresolved symbols and remove them
+   from the chain.  */
+
+void
+scan_file_globals (objfile)
+     struct objfile *objfile;
+{
+  int hash;
+  struct symbol *sym, *prev;
+
+  if (scan_file_globals_1 (objfile) == 0)
+    return;
+  if (rt_common_objfile && scan_file_globals_1 (rt_common_objfile) == 0)
+    return;
+
+  for (hash = 0; hash < HASHSIZE; hash++)
+    {
+      sym = global_sym_chain[hash];
+      while (sym)
+       {
+         complain (&unresolved_sym_chain_complaint,
+                   objfile->name, SYMBOL_NAME (sym));
+
+         /* Change the symbol address from the misleading chain value
+            to address zero.  */
+         prev = sym;
+         sym = SYMBOL_VALUE_CHAIN (sym);
+         SYMBOL_VALUE_ADDRESS (prev) = 0;
+       }
+    }
+  memset (global_sym_chain, 0, sizeof (global_sym_chain));
 }
 
 /* Initialize anything that needs initializing when starting to read
@@ -3732,6 +4002,8 @@ void start_stabs ()
 
   /* FIXME: If common_block_name is not already NULL, we should complain().  */
   common_block_name = NULL;
+
+  os9k_stabs = 0;
 }
 
 /* Call after end_symtab() */
This page took 0.039237 seconds and 4 git commands to generate.