2007-07-01 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / gdb / stabsread.c
index b916245c0825d9b1d6c7ef3d4c866d60efb673fb..e1550878ee137ebf53453103c3c06f121a784320 100644 (file)
@@ -1,6 +1,7 @@
 /* Support routines for decoding "stabs" debugging information format.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -17,8 +18,8 @@
 
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* Support routines for reading and decoding debugging information in
    the "stabs" format.  This format is used with many systems that use
@@ -89,11 +90,9 @@ static void
 read_one_struct_field (struct field_info *, char **, char *,
                       struct type *, struct objfile *);
 
-static char *get_substring (char **, int);
-
 static struct type *dbx_alloc_type (int[2], struct objfile *);
 
-static long read_huge_number (char **, int, int *);
+static long read_huge_number (char **, int, int *, int);
 
 static struct type *error_type (char **, struct objfile *);
 
@@ -107,7 +106,7 @@ static int read_type_number (char **, int *);
 
 static struct type *read_type (char **, struct objfile *);
 
-static struct type *read_range_type (char **, int[2], struct objfile *);
+static struct type *read_range_type (char **, int[2], int, struct objfile *);
 
 static struct type *read_sun_builtin_type (char **, int[2], struct objfile *);
 
@@ -148,7 +147,7 @@ static struct type *read_array_type (char **, struct type *,
 
 static struct field *read_args (char **, int, struct objfile *, int *, int *);
 
-static void add_undefined_type (struct type *);
+static void add_undefined_type (struct type *, int[2]);
 
 static int
 read_cpp_abbrev (struct field_info *, char **, struct type *,
@@ -158,34 +157,23 @@ static char *find_name_end (char *name);
 
 static int process_reference (char **string);
 
-static CORE_ADDR ref_search_value (int refnum);
-
 void stabsread_clear_cache (void);
 
 static const char vptr_name[] = "_vptr$";
 static const char vb_name[] = "_vb$";
 
-/* Define this as 1 if a pcc declaration of a char or short argument
-   gives the correct address.  Otherwise assume pcc gives the
-   address of the corresponding int, which is not the same on a
-   big-endian machine.  */
-
-#if !defined (BELIEVE_PCC_PROMOTION)
-#define BELIEVE_PCC_PROMOTION 0
-#endif
-
 static void
 invalid_cpp_abbrev_complaint (const char *arg1)
 {
-  complaint (&symfile_complaints, "invalid C++ abbreviation `%s'", arg1);
+  complaint (&symfile_complaints, _("invalid C++ abbreviation `%s'"), arg1);
 }
 
 static void
-reg_value_complaint (int arg1, int arg2, const char *arg3)
+reg_value_complaint (int regnum, int num_regs, const char *sym)
 {
   complaint (&symfile_complaints,
-            "register number %d too large (max %d) in symbol %s", arg1, arg2,
-            arg3);
+            _("register number %d too large (max %d) in symbol %s"),
+             regnum, num_regs - 1, sym);
 }
 
 static void
@@ -194,12 +182,6 @@ stabs_general_complaint (const char *arg1)
   complaint (&symfile_complaints, "%s", arg1);
 }
 
-static void
-lrs_general_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints, "%s", arg1);
-}
-
 /* Make a list of forward references which haven't been defined.  */
 
 static struct type **undef_types;
@@ -207,6 +189,20 @@ static int undef_types_allocated;
 static int undef_types_length;
 static struct symbol *current_symbol = NULL;
 
+/* Make a list of nameless types that are undefined.
+   This happens when another type is referenced by its number
+   before this type is actually defined. For instance "t(0,1)=k(0,2)"
+   and type (0,2) is defined only later.  */
+
+struct nat
+{
+  int typenums[2];
+  struct type *type;
+};
+static struct nat *noname_undefs;
+static int noname_undefs_allocated;
+static int noname_undefs_length;
+
 /* Check for and handle cretinous stabs symbol name continuation!  */
 #define STABS_CONTINUE(pp,objfile)                             \
   do {                                                 \
@@ -238,7 +234,7 @@ dbx_lookup_type (int typenums[2])
   if (filenum < 0 || filenum >= n_this_object_header_files)
     {
       complaint (&symfile_complaints,
-                "Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
+                _("Invalid symbol data: type number (%d,%d) out of range at symtab pos %d."),
                 filenum, index, symnum);
       goto error_return;
     }
@@ -290,7 +286,7 @@ dbx_lookup_type (int typenums[2])
          struct type *temp_type;
          struct type **temp_type_p;
 
-         warning ("GDB internal error: bad real_filenum");
+         warning (_("GDB internal error: bad real_filenum"));
 
        error_return:
          temp_type = init_type (TYPE_CODE_ERROR, 0, 0, NULL, NULL);
@@ -388,14 +384,14 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs,
                 ld will remove it from the executable.  There is then
                 a N_GSYM stab for it, but no regular (C_EXT) symbol.  */
              sym = (struct symbol *)
-               obstack_alloc (&objfile->symbol_obstack,
+               obstack_alloc (&objfile->objfile_obstack,
                               sizeof (struct symbol));
 
              memset (sym, 0, sizeof (struct symbol));
              SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
              SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
              DEPRECATED_SYMBOL_NAME (sym) =
-               obsavestring (name, pp - name, &objfile->symbol_obstack);
+               obsavestring (name, pp - name, &objfile->objfile_obstack);
              pp += 2;
              if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
                {
@@ -444,17 +440,17 @@ read_type_number (char **pp, int *typenums)
   if (**pp == '(')
     {
       (*pp)++;
-      typenums[0] = read_huge_number (pp, ',', &nbits);
+      typenums[0] = read_huge_number (pp, ',', &nbits, 0);
       if (nbits != 0)
        return -1;
-      typenums[1] = read_huge_number (pp, ')', &nbits);
+      typenums[1] = read_huge_number (pp, ')', &nbits, 0);
       if (nbits != 0)
        return -1;
     }
   else
     {
       typenums[0] = 0;
-      typenums[1] = read_huge_number (pp, 0, &nbits);
+      typenums[1] = read_huge_number (pp, 0, &nbits, 0);
       if (nbits != 0)
        return -1;
     }
@@ -533,16 +529,6 @@ ref_search (int refnum)
   return ref_map[refnum].sym;
 }
 
-/* Return value for the reference REFNUM.  */
-
-static CORE_ADDR
-ref_search_value (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.  */
 
@@ -631,7 +617,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
   nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
 
   current_symbol = sym = (struct symbol *)
-    obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+    obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
   memset (sym, 0, sizeof (struct symbol));
 
   switch (type & N_TYPE)
@@ -665,7 +651,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
        {
        case 't':
          DEPRECATED_SYMBOL_NAME (sym) = obsavestring ("this", strlen ("this"),
-                                           &objfile->symbol_obstack);
+                                           &objfile->objfile_obstack);
          break;
 
        case 'v':               /* $vtbl_ptr_type */
@@ -674,7 +660,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
        case 'e':
          DEPRECATED_SYMBOL_NAME (sym) = obsavestring ("eh_throw", strlen ("eh_throw"),
-                                           &objfile->symbol_obstack);
+                                           &objfile->objfile_obstack);
          break;
 
        case '_':
@@ -688,7 +674,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 #endif
 
        default:
-         complaint (&symfile_complaints, "Unknown C++ symbol name `%s'",
+         complaint (&symfile_complaints, _("Unknown C++ symbol name `%s'"),
                     string);
          goto normal;          /* Do *something* with it */
        }
@@ -741,7 +727,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
        case 'r':
          {
            double d = atof (p);
-           char *dbl_valu;
+           gdb_byte *dbl_valu;
 
            /* FIXME-if-picky-about-floating-accuracy: Should be using
               target arithmetic to get the value.  real.c in GCC
@@ -756,8 +742,8 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
            SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile,
                                                         FT_DBL_PREC_FLOAT);
-           dbl_valu = (char *)
-             obstack_alloc (&objfile->symbol_obstack,
+           dbl_valu =
+             obstack_alloc (&objfile->objfile_obstack,
                             TYPE_LENGTH (SYMBOL_TYPE (sym)));
            store_typed_floating (dbl_valu, SYMBOL_TYPE (sym), d);
            SYMBOL_VALUE_BYTES (sym) = dbl_valu;
@@ -968,7 +954,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
 
-      if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (current_gdbarch) != BFD_ENDIAN_BIG)
        {
          /* On little-endian machines, this crud is never necessary,
             and, if the extra bytes contain garbage, is harmful.  */
@@ -976,10 +962,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
        }
 
       /* If it's gcc-compiled, if it says `short', believe it.  */
-      if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)
+      if (processing_gcc_compilation
+         || gdbarch_believe_pcc_promotion (current_gdbarch))
        break;
 
-      if (!BELIEVE_PCC_PROMOTION)
+      if (!gdbarch_believe_pcc_promotion (current_gdbarch))
        {
          /* This is the signed type which arguments get promoted to.  */
          static struct type *pcc_promotion_type;
@@ -989,69 +976,27 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
          /* Call it "int" because this is mainly C lossage.  */
          if (pcc_promotion_type == NULL)
            pcc_promotion_type =
-             init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+             init_type (TYPE_CODE_INT, 
+                        gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT,
                         0, "int", NULL);
 
          if (pcc_unsigned_promotion_type == NULL)
            pcc_unsigned_promotion_type =
-             init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+             init_type (TYPE_CODE_INT, 
+                        gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT,
                         TYPE_FLAG_UNSIGNED, "unsigned int", NULL);
 
-         if (BELIEVE_PCC_PROMOTION_TYPE)
-           {
-             /* This is defined on machines (e.g. sparc) where we
-                should believe the type of a PCC 'short' argument,
-                but shouldn't believe the address (the address is the
-                address of the corresponding int).
-
-                My guess is that this correction, as opposed to
-                changing the parameter to an 'int' (as done below,
-                for PCC on most machines), is the right thing to do
-                on all machines, but I don't want to risk breaking
-                something that already works.  On most PCC machines,
-                the sparc problem doesn't come up because the calling
-                function has to zero the top bytes (not knowing
-                whether the called function wants an int or a short),
-                so there is little practical difference between an
-                int and a short (except perhaps what happens when the
-                GDB user types "print short_arg = 0x10000;").
-
-                Hacked for SunOS 4.1 by gnu@cygnus.com.  In 4.1, the
-                compiler actually produces the correct address (we
-                don't need to fix it up).  I made this code adapt so
-                that it will offset the symbol if it was pointing at
-                an int-aligned location and not otherwise.  This way
-                you can use the same gdb for 4.0.x and 4.1 systems.
-
-                If the parameter is shorter than an int, and is
-                integral (e.g. char, short, or unsigned equivalent),
-                and is claimed to be passed on an integer boundary,
-                don't believe it!  Offset the parameter's address to
-                the tail-end of that integer.  */
-
-             if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
-                 && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
-             && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (pcc_promotion_type))
-               {
-                 SYMBOL_VALUE (sym) += TYPE_LENGTH (pcc_promotion_type)
-                   - TYPE_LENGTH (SYMBOL_TYPE (sym));
-               }
-             break;
-           }
-         else
+         /* If PCC says a parameter is a short or a char, it is
+            really an int.  */
+         if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
+             && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
            {
-             /* If PCC says a parameter is a short or a char,
-                it is really an int.  */
-             if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
-                 && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
-               {
-                 SYMBOL_TYPE (sym) =
-                   TYPE_UNSIGNED (SYMBOL_TYPE (sym))
-                   ? pcc_unsigned_promotion_type
-                   : pcc_promotion_type;
-               }
-             break;
+             SYMBOL_TYPE (sym) =
+               TYPE_UNSIGNED (SYMBOL_TYPE (sym))
+               ? pcc_unsigned_promotion_type
+               : pcc_promotion_type;
            }
+         break;
        }
 
     case 'P':
@@ -1069,13 +1014,16 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       /* Parameter which is in a register.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_REGPARM;
-      SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
-      if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
+      SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
+      if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
+                                 + gdbarch_num_pseudo_regs (current_gdbarch))
        {
          reg_value_complaint (SYMBOL_VALUE (sym),
-                              NUM_REGS + NUM_PSEUDO_REGS,
+                              gdbarch_num_regs (current_gdbarch)
+                                + gdbarch_num_pseudo_regs (current_gdbarch),
                               SYMBOL_PRINT_NAME (sym));
-         SYMBOL_VALUE (sym) = SP_REGNUM;       /* Known safe, though useless */
+         SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
+         /* Known safe, though useless */
        }
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
@@ -1085,13 +1033,16 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       /* Register variable (either global or local).  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_REGISTER;
-      SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
-      if (SYMBOL_VALUE (sym) >= NUM_REGS + NUM_PSEUDO_REGS)
+      SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
+      if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
+                               + gdbarch_num_pseudo_regs (current_gdbarch))
        {
          reg_value_complaint (SYMBOL_VALUE (sym),
-                              NUM_REGS + NUM_PSEUDO_REGS,
+                              gdbarch_num_regs (current_gdbarch)
+                                + gdbarch_num_pseudo_regs (current_gdbarch),
                               SYMBOL_PRINT_NAME (sym));
-         SYMBOL_VALUE (sym) = SP_REGNUM;       /* Known safe, though useless */
+         SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
+         /* Known safe, though useless */
        }
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       if (within_function)
@@ -1118,17 +1069,15 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
          if (local_symbols
              && local_symbols->nsyms > 0
-#ifndef USE_REGISTER_NOT_ARG
              && gdbarch_stabs_argument_has_addr (current_gdbarch,
-                                                 SYMBOL_TYPE (sym))
-#endif
-           )
+                                                 SYMBOL_TYPE (sym)))
            {
              struct symbol *prev_sym;
              prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
              if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG
                   || SYMBOL_CLASS (prev_sym) == LOC_ARG)
-                 && STREQ (DEPRECATED_SYMBOL_NAME (prev_sym), DEPRECATED_SYMBOL_NAME (sym)))
+                 && strcmp (DEPRECATED_SYMBOL_NAME (prev_sym),
+                            DEPRECATED_SYMBOL_NAME (sym)) == 0)
                {
                  SYMBOL_CLASS (prev_sym) = LOC_REGPARM;
                  /* Use the type from the LOC_REGISTER; that is the type
@@ -1167,6 +1116,22 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       break;
 
     case 't':
+      /* In Ada, there is no distinction between typedef and non-typedef;
+         any type declaration implicitly has the equivalent of a typedef,
+         and thus 't' is in fact equivalent to 'Tt'. 
+
+         Therefore, for Ada units, we check the character immediately
+         before the 't', and if we do not find a 'T', then make sure to
+         create the associated symbol in the STRUCT_DOMAIN ('t' definitions
+         will be stored in the VAR_DOMAIN).  If the symbol was indeed
+         defined as 'Tt' then the STRUCT_DOMAIN symbol will be created
+         elsewhere, so we don't need to take care of that.
+         
+         This is important to do, because of forward references:
+         The cleanup of undefined types stored in undef_types only uses
+         STRUCT_DOMAIN symbols to perform the replacement.  */
+      synonym = (SYMBOL_LANGUAGE (sym) == language_ada && p[-2] != 'T');
+
       /* Typedef */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
 
@@ -1250,6 +1215,24 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
        }
 
       add_symbol_to_list (sym, &file_symbols);
+
+      if (synonym)
+        {
+          /* Create the STRUCT_DOMAIN clone.  */
+          struct symbol *struct_sym = (struct symbol *)
+            obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
+
+          *struct_sym = *sym;
+          SYMBOL_CLASS (struct_sym) = LOC_TYPEDEF;
+          SYMBOL_VALUE (struct_sym) = valu;
+          SYMBOL_DOMAIN (struct_sym) = STRUCT_DOMAIN;
+          if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+            TYPE_NAME (SYMBOL_TYPE (sym))
+              = obconcat (&objfile->objfile_obstack, "", "",
+                          DEPRECATED_SYMBOL_NAME (sym));
+          add_symbol_to_list (struct_sym, &file_symbols);
+        }
+      
       break;
 
     case 'T':
@@ -1272,21 +1255,21 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
       if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
        TYPE_TAG_NAME (SYMBOL_TYPE (sym))
-         = obconcat (&objfile->type_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym));
+         = obconcat (&objfile->objfile_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym));
       add_symbol_to_list (sym, &file_symbols);
 
       if (synonym)
        {
          /* Clone the sym and then modify it. */
          struct symbol *typedef_sym = (struct symbol *)
-         obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+         obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
          *typedef_sym = *sym;
          SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF;
          SYMBOL_VALUE (typedef_sym) = valu;
          SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
          if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
            TYPE_NAME (SYMBOL_TYPE (sym))
-             = obconcat (&objfile->type_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym));
+             = obconcat (&objfile->objfile_obstack, "", "", DEPRECATED_SYMBOL_NAME (sym));
          add_symbol_to_list (typedef_sym, &file_symbols);
        }
       break;
@@ -1325,13 +1308,16 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       /* 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 + NUM_PSEUDO_REGS)
+      SYMBOL_VALUE (sym) = gdbarch_stab_reg_to_regnum (current_gdbarch, valu);
+      if (SYMBOL_VALUE (sym) >= gdbarch_num_regs (current_gdbarch)
+                               + gdbarch_num_pseudo_regs (current_gdbarch))
        {
          reg_value_complaint (SYMBOL_VALUE (sym),
-                              NUM_REGS + NUM_PSEUDO_REGS,
+                              gdbarch_num_regs (current_gdbarch)
+                                + gdbarch_num_pseudo_regs (current_gdbarch),
                               SYMBOL_PRINT_NAME (sym));
-         SYMBOL_VALUE (sym) = SP_REGNUM;       /* Known safe, though useless */
+         SYMBOL_VALUE (sym) = gdbarch_sp_regnum (current_gdbarch);
+         /* Known safe, though useless */
        }
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
@@ -1410,7 +1396,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 static struct type *
 error_type (char **pp, struct objfile *objfile)
 {
-  complaint (&symfile_complaints, "couldn't parse type; debugger out of date?");
+  complaint (&symfile_complaints, _("couldn't parse type; debugger out of date?"));
   while (1)
     {
       /* Skip to end of symbol.  */
@@ -1467,11 +1453,21 @@ read_type (char **pp, struct objfile *objfile)
       if (read_type_number (pp, typenums) != 0)
        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
-         both cases.  */
       if (**pp != '=')
-       return dbx_alloc_type (typenums, objfile);
+        {
+          /* Type is not being defined here.  Either it already
+             exists, or this is a forward reference to it.
+             dbx_alloc_type handles both cases.  */
+          type = dbx_alloc_type (typenums, objfile);
+
+          /* If this is a forward reference, arrange to complain if it
+             doesn't get patched up by the time we're done
+             reading.  */
+          if (TYPE_CODE (type) == TYPE_CODE_UNDEF)
+            add_undefined_type (type, typenums);
+
+          return type;
+        }
 
       /* Type is being defined here.  */
       /* Skip the '='.
@@ -1521,7 +1517,7 @@ again:
                /* Complain and keep going, so compilers can invent new
                   cross-reference types.  */
                complaint (&symfile_complaints,
-                          "Unrecognized cross-reference type `%c'", (*pp)[0]);
+                          _("Unrecognized cross-reference type `%c'"), (*pp)[0]);
                code = TYPE_CODE_STRUCT;
                break;
              }
@@ -1548,7 +1544,7 @@ again:
                return error_type (pp, objfile);
            }
          to = type_name =
-           (char *) obstack_alloc (&objfile->type_obstack, p - *pp + 1);
+           (char *) obstack_alloc (&objfile->objfile_obstack, p - *pp + 1);
 
          /* Copy the name.  */
          from = *pp + 1;
@@ -1561,11 +1557,9 @@ again:
          *pp = from + 1;
        }
 
-       /* 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.  */
+        /* If this type has already been declared, then reuse the same
+           type, rather than allocating a new one.  This saves some
+           memory.  */
 
        for (ppt = file_symbols; ppt; ppt = ppt->next)
          for (i = 0; i < ppt->nsyms; i++)
@@ -1575,10 +1569,12 @@ again:
              if (SYMBOL_CLASS (sym) == LOC_TYPEDEF
                  && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
                  && (TYPE_CODE (SYMBOL_TYPE (sym)) == code)
-                 && STREQ (DEPRECATED_SYMBOL_NAME (sym), type_name))
+                 && strcmp (DEPRECATED_SYMBOL_NAME (sym), type_name) == 0)
                {
-                 obstack_free (&objfile->type_obstack, type_name);
+                 obstack_free (&objfile->objfile_obstack, type_name);
                  type = SYMBOL_TYPE (sym);
+                 if (typenums[0] != -1)
+                   *dbx_lookup_type (typenums) = type;
                  return type;
                }
            }
@@ -1594,7 +1590,7 @@ again:
        INIT_CPLUS_SPECIFIC (type);
        TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
 
-       add_undefined_type (type);
+       add_undefined_type (type, typenums);
        return type;
       }
 
@@ -1727,7 +1723,7 @@ again:
         else
           {
            complaint (&symfile_complaints,
-                      "Prototyped function type didn't end arguments with `#':\n%s",
+                      _("Prototyped function type didn't end arguments with `#':\n%s"),
                       type_start);
           }
 
@@ -1786,7 +1782,7 @@ again:
 
          memtype = read_type (pp, objfile);
          type = dbx_alloc_type (typenums, objfile);
-         smash_to_member_type (type, domain, memtype);
+         smash_to_memberptr_type (type, domain, memtype);
        }
       else
        /* type attribute */
@@ -1838,7 +1834,7 @@ again:
          return_type = read_type (pp, objfile);
          if (*(*pp)++ != ';')
            complaint (&symfile_complaints,
-                      "invalid (minimal) member type data format at symtab pos %d.",
+                      _("invalid (minimal) member type data format at symtab pos %d."),
                       symnum);
          type = allocate_stub_method (return_type);
          if (typenums[0] != -1)
@@ -1859,6 +1855,8 @@ again:
 
          return_type = read_type (pp, objfile);
          args = read_args (pp, ';', objfile, &nargs, &varargs);
+         if (args == NULL)
+           return error_type (pp, objfile);
          type = dbx_alloc_type (typenums, objfile);
          smash_to_method_type (type, domain, return_type, args,
                                nargs, varargs);
@@ -1866,7 +1864,7 @@ again:
       break;
 
     case 'r':                  /* Range type */
-      type = read_range_type (pp, typenums, objfile);
+      type = read_range_type (pp, typenums, type_size, objfile);
       if (typenums[0] != -1)
        *dbx_lookup_type (typenums) = type;
       break;
@@ -1941,7 +1939,7 @@ again:
 
   if (type == 0)
     {
-      warning ("GDB internal error, type is NULL in stabsread.c\n");
+      warning (_("GDB internal error, type is NULL in stabsread.c."));
       return error_type (pp, objfile);
     }
 
@@ -1966,7 +1964,7 @@ rs6000_builtin_type (int typenum)
 
   if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED)
     {
-      complaint (&symfile_complaints, "Unknown builtin type %d", typenum);
+      complaint (&symfile_complaints, _("Unknown builtin type %d"), typenum);
       return builtin_type_error;
     }
   if (negative_types[-typenum] != NULL)
@@ -2131,7 +2129,7 @@ update_method_name_from_physname (char **old_name, char *physname)
   if (method_name == NULL)
     {
       complaint (&symfile_complaints,
-                "Method has bad physname %s\n", physname);
+                _("Method has bad physname %s\n"), physname);
       return;
     }
 
@@ -2329,7 +2327,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type,
              break;
            default:
              complaint (&symfile_complaints,
-                        "const/volatile indicator missing, got '%c'", **pp);
+                        _("const/volatile indicator missing, got '%c'"), **pp);
              break;
            }
 
@@ -2346,7 +2344,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type,
                   the sign bit out, and usable as a valid index into
                   the array.  Remove the sign bit here.  */
                new_sublist->fn_field.voffset =
-                 (0x7fffffff & read_huge_number (pp, ';', &nbits)) + 2;
+                 (0x7fffffff & read_huge_number (pp, ';', &nbits, 0)) + 2;
                if (nbits != 0)
                  return 0;
 
@@ -2412,7 +2410,7 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type,
            default:
              /* error */
              complaint (&symfile_complaints,
-                        "member function type missing, got '%c'", (*pp)[-1]);
+                        _("member function type missing, got '%c'"), (*pp)[-1]);
              /* Fall through into normal member function.  */
 
            case '.':
@@ -2532,11 +2530,11 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type,
              make_cleanup (xfree, destr_fnlist);
              memset (destr_fnlist, 0, sizeof (struct next_fnfieldlist));
              destr_fnlist->fn_fieldlist.name
-               = obconcat (&objfile->type_obstack, "", "~",
+               = obconcat (&objfile->objfile_obstack, "", "~",
                            new_fnlist->fn_fieldlist.name);
 
              destr_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
-               obstack_alloc (&objfile->type_obstack,
+               obstack_alloc (&objfile->objfile_obstack,
                               sizeof (struct fn_field) * has_destructor);
              memset (destr_fnlist->fn_fieldlist.fn_fields, 0,
                  sizeof (struct fn_field) * has_destructor);
@@ -2582,7 +2580,8 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type,
            }
          else if (has_destructor && new_fnlist->fn_fieldlist.name[0] != '~')
            {
-             new_fnlist->fn_fieldlist.name = concat ("~", main_fn_name, NULL);
+             new_fnlist->fn_fieldlist.name =
+               concat ("~", main_fn_name, (char *)NULL);
              xfree (main_fn_name);
            }
          else if (!has_stub)
@@ -2597,11 +2596,11 @@ read_member_functions (struct field_info *fip, char **pp, struct type *type,
              if (ret)
                new_fnlist->fn_fieldlist.name
                  = obsavestring (dem_opname, strlen (dem_opname),
-                                 &objfile->type_obstack);
+                                 &objfile->objfile_obstack);
            }
 
          new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
-           obstack_alloc (&objfile->type_obstack,
+           obstack_alloc (&objfile->objfile_obstack,
                           sizeof (struct fn_field) * length);
          memset (new_fnlist->fn_fieldlist.fn_fields, 0,
                  sizeof (struct fn_field) * length);
@@ -2670,7 +2669,7 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type,
                  name = "";
          }
          fip->list->field.name =
-           obconcat (&objfile->type_obstack, vptr_name, name, "");
+           obconcat (&objfile->objfile_obstack, vptr_name, name, "");
          break;
 
        case 'b':               /* $vb -- a virtual bsomethingorother */
@@ -2678,18 +2677,18 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type,
          if (name == NULL)
            {
              complaint (&symfile_complaints,
-                        "C++ abbreviated type name unknown at symtab pos %d",
+                        _("C++ abbreviated type name unknown at symtab pos %d"),
                         symnum);
              name = "FOO";
            }
          fip->list->field.name =
-           obconcat (&objfile->type_obstack, vb_name, name, "");
+           obconcat (&objfile->objfile_obstack, vb_name, name, "");
          break;
 
        default:
          invalid_cpp_abbrev_complaint (*pp);
          fip->list->field.name =
-           obconcat (&objfile->type_obstack,
+           obconcat (&objfile->objfile_obstack,
                      "INVALID_CPLUSPLUS_ABBREV", "", "");
          break;
        }
@@ -2711,7 +2710,8 @@ read_cpp_abbrev (struct field_info *fip, char **pp, struct type *type,
 
       {
        int nbits;
-       FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits);
+       FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits,
+                                                            0);
        if (nbits != 0)
          return 0;
       }
@@ -2735,7 +2735,7 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p,
                       struct type *type, struct objfile *objfile)
 {
   fip->list->field.name =
-    obsavestring (*pp, p - *pp, &objfile->type_obstack);
+    obsavestring (*pp, p - *pp, &objfile->objfile_obstack);
   *pp = p + 1;
 
   /* This means we have a visibility for a field coming. */
@@ -2784,13 +2784,13 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p,
 
   {
     int nbits;
-    FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits);
+    FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits, 0);
     if (nbits != 0)
       {
        stabs_general_complaint ("bad structure-type format");
        return;
       }
-    FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits);
+    FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits, 0);
     if (nbits != 0)
       {
        stabs_general_complaint ("bad structure-type format");
@@ -2805,7 +2805,7 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p,
          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
+         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.
@@ -2837,7 +2837,8 @@ read_one_struct_field (struct field_info *fip, char **pp, char *p,
       if ((FIELD_BITSIZE (fip->list->field)
           == TARGET_CHAR_BIT * TYPE_LENGTH (field_type)
           || (TYPE_CODE (field_type) == TYPE_CODE_ENUM
-              && FIELD_BITSIZE (fip->list->field) == TARGET_INT_BIT)
+              && FIELD_BITSIZE (fip->list->field)
+                 == gdbarch_int_bit (current_gdbarch))
          )
          &&
          FIELD_BITPOS (fip->list->field) % 8 == 0)
@@ -2986,7 +2987,7 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type,
   ALLOCATE_CPLUS_STRUCT_TYPE (type);
   {
     int nbits;
-    TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits);
+    TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits, 0);
     if (nbits != 0)
       return 0;
   }
@@ -3030,7 +3031,7 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type,
          /* Unknown character.  Complain and treat it as non-virtual.  */
          {
            complaint (&symfile_complaints,
-                      "Unknown virtual character `%c' for baseclass", **pp);
+                      _("Unknown virtual character `%c' for baseclass"), **pp);
          }
        }
       ++(*pp);
@@ -3047,7 +3048,7 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type,
             public.  */
          {
            complaint (&symfile_complaints,
-                      "Unknown visibility `%c' for baseclass",
+                      _("Unknown visibility `%c' for baseclass"),
                       new->visibility);
            new->visibility = VISIBILITY_PUBLIC;
          }
@@ -3060,7 +3061,7 @@ read_baseclasses (struct field_info *fip, char **pp, struct type *type,
           corresponding to this baseclass.  Always zero in the absence of
           multiple inheritance.  */
 
-       FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits);
+       FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits, 0);
        if (nbits != 0)
          return 0;
       }
@@ -3155,7 +3156,7 @@ read_tilde_fields (struct field_info *fip, char **pp, struct type *type,
                }
              /* Virtual function table field not found.  */
              complaint (&symfile_complaints,
-                        "virtual function table pointer not found when defining class `%s'",
+                        _("virtual function table pointer not found when defining class `%s'"),
                         TYPE_NAME (type));
              return 0;
            }
@@ -3265,7 +3266,7 @@ attach_fields_to_type (struct field_info *fip, struct type *type,
        default:
          /* Unknown visibility.  Complain and treat it as public.  */
          {
-           complaint (&symfile_complaints, "Unknown visibility `%c' for field",
+           complaint (&symfile_complaints, _("Unknown visibility `%c' for field"),
                       fip->list->visibility);
          }
          break;
@@ -3307,7 +3308,7 @@ complain_about_struct_wipeout (struct type *type)
     }
 
   complaint (&symfile_complaints,
-            "struct/union type gets multiply defined: %s%s", kind, name);
+            _("struct/union type gets multiply defined: %s%s"), kind, name);
 }
 
 
@@ -3365,7 +3366,7 @@ read_struct_type (char **pp, struct type *type, enum type_code type_code,
 
   {
     int nbits;
-    TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits);
+    TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits, 0);
     if (nbits != 0)
       return error_type (pp, objfile);
   }
@@ -3423,7 +3424,7 @@ read_array_type (char **pp, struct type *type,
       (*pp)++;
       adjustable = 1;
     }
-  lower = read_huge_number (pp, ';', &nbits);
+  lower = read_huge_number (pp, ';', &nbits, 0);
 
   if (nbits != 0)
     return error_type (pp, objfile);
@@ -3433,7 +3434,7 @@ read_array_type (char **pp, struct type *type,
       (*pp)++;
       adjustable = 1;
     }
-  upper = read_huge_number (pp, ';', &nbits);
+  upper = read_huge_number (pp, ';', &nbits, 0);
   if (nbits != 0)
     return error_type (pp, objfile);
 
@@ -3505,14 +3506,14 @@ read_enum_type (char **pp, struct type *type,
       p = *pp;
       while (*p != ':')
        p++;
-      name = obsavestring (*pp, p - *pp, &objfile->symbol_obstack);
+      name = obsavestring (*pp, p - *pp, &objfile->objfile_obstack);
       *pp = p + 1;
-      n = read_huge_number (pp, ',', &nbits);
+      n = read_huge_number (pp, ',', &nbits, 0);
       if (nbits != 0)
        return error_type (pp, objfile);
 
       sym = (struct symbol *)
-       obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+       obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
       memset (sym, 0, sizeof (struct symbol));
       DEPRECATED_SYMBOL_NAME (sym) = name;
       SYMBOL_LANGUAGE (sym) = current_subfile->language;
@@ -3530,7 +3531,7 @@ read_enum_type (char **pp, struct type *type,
 
   /* Now fill in the fields of the type-structure.  */
 
-  TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT;
+  TYPE_LENGTH (type) = gdbarch_int_bit (current_gdbarch) / HOST_CHAR_BIT;
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
   if (unsigned_enum)
@@ -3619,17 +3620,17 @@ read_sun_builtin_type (char **pp, int typenums[2], struct objfile *objfile)
      by this type, except that unsigned short is 4 instead of 2.
      Since this information is redundant with the third number,
      we will ignore it.  */
-  read_huge_number (pp, ';', &nbits);
+  read_huge_number (pp, ';', &nbits, 0);
   if (nbits != 0)
     return error_type (pp, objfile);
 
   /* The second number is always 0, so ignore it too. */
-  read_huge_number (pp, ';', &nbits);
+  read_huge_number (pp, ';', &nbits, 0);
   if (nbits != 0)
     return error_type (pp, objfile);
 
   /* The third number is the number of bits for this type. */
-  type_bits = read_huge_number (pp, 0, &nbits);
+  type_bits = read_huge_number (pp, 0, &nbits, 0);
   if (nbits != 0)
     return error_type (pp, objfile);
   /* The type *should* end with a semicolon.  If it are embedded
@@ -3662,12 +3663,12 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile)
 
   /* The first number has more details about the type, for example
      FN_COMPLEX.  */
-  details = read_huge_number (pp, ';', &nbits);
+  details = read_huge_number (pp, ';', &nbits, 0);
   if (nbits != 0)
     return error_type (pp, objfile);
 
   /* The second number is the number of bytes occupied by this type */
-  nbytes = read_huge_number (pp, ';', &nbits);
+  nbytes = read_huge_number (pp, ';', &nbits, 0);
   if (nbits != 0)
     return error_type (pp, objfile);
 
@@ -3690,22 +3691,30 @@ read_sun_floating_type (char **pp, int typenums[2], struct objfile *objfile)
    and that character is skipped if it does match.
    If END is zero, *PP is left pointing to that character.
 
+   If TWOS_COMPLEMENT_BITS is set to a strictly positive value and if
+   the number is represented in an octal representation, assume that
+   it is represented in a 2's complement representation with a size of
+   TWOS_COMPLEMENT_BITS.
+
    If the number fits in a long, set *BITS to 0 and return the value.
    If not, set *BITS to be the number of bits in the number and return 0.
 
    If encounter garbage, set *BITS to -1 and return 0.  */
 
 static long
-read_huge_number (char **pp, int end, int *bits)
+read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
 {
   char *p = *pp;
   int sign = 1;
+  int sign_bit;
   long n = 0;
+  long sn = 0;
   int radix = 10;
   char overflow = 0;
   int nbits = 0;
   int c;
   long upper_limit;
+  int twos_complement_representation = radix == 8 && twos_complement_bits > 0;
 
   if (*p == '-')
     {
@@ -3726,12 +3735,36 @@ read_huge_number (char **pp, int end, int *bits)
   while ((c = *p++) >= '0' && c < ('0' + radix))
     {
       if (n <= upper_limit)
-       {
-         n *= radix;
-         n += c - '0';         /* FIXME this overflows anyway */
-       }
+        {
+          if (twos_complement_representation)
+            {
+              /* Octal, signed, twos complement representation. In this case,
+                 sn is the signed value, n is the corresponding absolute
+                 value. signed_bit is the position of the sign bit in the
+                 first three bits.  */
+              if (sn == 0)
+                {
+                  sign_bit = (twos_complement_bits % 3 + 2) % 3;
+                  sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit));
+                }
+              else
+                {
+                  sn *= radix;
+                  sn += c - '0';
+                }
+
+              if (sn < 0)
+                n = -sn;
+            }
+          else
+            {
+              /* unsigned representation */
+              n *= radix;
+              n += c - '0';            /* FIXME this overflows anyway */
+            }
+        }
       else
-       overflow = 1;
+        overflow = 1;
 
       /* This depends on large values being output in octal, which is
          what GCC does. */
@@ -3788,14 +3821,18 @@ read_huge_number (char **pp, int end, int *bits)
     {
       if (bits)
        *bits = 0;
-      return n * sign;
+      if (twos_complement_representation)
+        return sn;
+      else
+        return n * sign;
     }
   /* It's *BITS which has the interesting information.  */
   return 0;
 }
 
 static struct type *
-read_range_type (char **pp, int typenums[2], struct objfile *objfile)
+read_range_type (char **pp, int typenums[2], int type_size,
+                 struct objfile *objfile)
 {
   char *orig_pp = *pp;
   int rangenums[2];
@@ -3824,8 +3861,8 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile)
 
   /* The remaining two operands are usually lower and upper bounds
      of the range.  But in some special cases they mean something else.  */
-  n2 = read_huge_number (pp, ';', &n2bits);
-  n3 = read_huge_number (pp, ';', &n3bits);
+  n2 = read_huge_number (pp, ';', &n2bits, type_size);
+  n3 = read_huge_number (pp, ';', &n3bits, type_size);
 
   if (n2bits == -1 || n3bits == -1)
     return error_type (pp, objfile);
@@ -3841,8 +3878,19 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile)
       /* Number of bits in the type.  */
       int nbits = 0;
 
+      /* If a type size attribute has been specified, the bounds of
+         the range should fit in this size. If the lower bounds needs
+         more bits than the upper bound, then the type is signed.  */
+      if (n2bits <= type_size && n3bits <= type_size)
+        {
+          if (n2bits == type_size && n2bits > n3bits)
+            got_signed = 1;
+          else
+            got_unsigned = 1;
+          nbits = type_size;
+        }
       /* Range from 0 to <large number> is an unsigned large integral type.  */
-      if ((n2bits == 0 && n2 == 0) && n3bits != 0)
+      else if ((n2bits == 0 && n2 == 0) && n3bits != 0)
        {
          got_unsigned = 1;
          nbits = n3bits;
@@ -3908,7 +3956,8 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile)
       /* It is unsigned int or unsigned long.  */
       /* GCC 2.3.3 uses this for long long too, but that is just a GDB 3.5
          compatibility hack.  */
-      return init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+      return init_type (TYPE_CODE_INT, 
+                       gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT,
                        TYPE_FLAG_UNSIGNED, NULL, objfile);
     }
 
@@ -3950,7 +3999,8 @@ read_range_type (char **pp, int typenums[2], struct objfile *objfile)
      of self_subrange.  */
   else if (n3 == 0 && n2 < 0
           && (self_subrange
-              || n2 == -TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT))
+              || n2 == -gdbarch_long_long_bit
+                         (current_gdbarch) / TARGET_CHAR_BIT))
     return init_type (TYPE_CODE_INT, -n2, 0, NULL, objfile);
   else if (n2 == -n3 - 1)
     {
@@ -3978,10 +4028,11 @@ handle_true_range:
       static struct type *range_type_index;
 
       complaint (&symfile_complaints,
-                "base type %d of range type is not defined", rangenums[1]);
+                _("base type %d of range type is not defined"), rangenums[1]);
       if (range_type_index == NULL)
        range_type_index =
-         init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
+         init_type (TYPE_CODE_INT, 
+                    gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT,
                     0, "range type index type", NULL);
       index_type = range_type_index;
     }
@@ -3991,8 +4042,8 @@ handle_true_range:
 }
 
 /* Read in an argument list.  This is a list of types, separated by commas
-   and terminated with END.  Return the list of types read in, or (struct type
-   **)-1 if there is an error.  */
+   and terminated with END.  Return the list of types read in, or NULL
+   if there is an error.  */
 
 static struct field *
 read_args (char **pp, int end, struct objfile *objfile, int *nargsp,
@@ -4007,7 +4058,7 @@ read_args (char **pp, int end, struct objfile *objfile, int *nargsp,
     {
       if (**pp != ',')
        /* Invalid argument list: no ','.  */
-       return (struct field *) -1;
+       return NULL;
       (*pp)++;
       STABS_CONTINUE (pp, objfile);
       types[n++] = read_type (pp, objfile);
@@ -4055,12 +4106,12 @@ common_block_start (char *name, struct objfile *objfile)
   if (common_block_name != NULL)
     {
       complaint (&symfile_complaints,
-                "Invalid symbol data: common block within common block");
+                _("Invalid symbol data: common block within common block"));
     }
   common_block = local_symbols;
   common_block_i = local_symbols ? local_symbols->nsyms : 0;
   common_block_name = obsavestring (name, strlen (name),
-                                   &objfile->symbol_obstack);
+                                   &objfile->objfile_obstack);
 }
 
 /* Process a N_ECOMM symbol.  */
@@ -4081,14 +4132,14 @@ common_block_end (struct objfile *objfile)
 
   if (common_block_name == NULL)
     {
-      complaint (&symfile_complaints, "ECOMM symbol unmatched by BCOMM");
+      complaint (&symfile_complaints, _("ECOMM symbol unmatched by BCOMM"));
       return;
     }
 
   sym = (struct symbol *)
-    obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+    obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
   memset (sym, 0, sizeof (struct symbol));
-  /* Note: common_block_name already saved on symbol_obstack */
+  /* Note: common_block_name already saved on objfile_obstack */
   DEPRECATED_SYMBOL_NAME (sym) = common_block_name;
   SYMBOL_CLASS (sym) = LOC_BLOCK;
 
@@ -4140,13 +4191,33 @@ fix_common_block (struct symbol *sym, int valu)
 \f
 
 
-/* What about types defined as forward references inside of a small lexical
-   scope?  */
-/* Add a type to the list of undefined types to be checked through
-   once this file has been read in.  */
+/* Add {TYPE, TYPENUMS} to the NONAME_UNDEFS vector.
+   See add_undefined_type for more details.  */
 
 static void
-add_undefined_type (struct type *type)
+add_undefined_type_noname (struct type *type, int typenums[2])
+{
+  struct nat nat;
+
+  nat.typenums[0] = typenums [0];
+  nat.typenums[1] = typenums [1];
+  nat.type = type;
+
+  if (noname_undefs_length == noname_undefs_allocated)
+    {
+      noname_undefs_allocated *= 2;
+      noname_undefs = (struct nat *)
+       xrealloc ((char *) noname_undefs,
+                 noname_undefs_allocated * sizeof (struct nat));
+    }
+  noname_undefs[noname_undefs_length++] = nat;
+}
+
+/* Add TYPE to the UNDEF_TYPES vector.
+   See add_undefined_type for more details.  */
+
+static void
+add_undefined_type_1 (struct type *type)
 {
   if (undef_types_length == undef_types_allocated)
     {
@@ -4158,6 +4229,48 @@ add_undefined_type (struct type *type)
   undef_types[undef_types_length++] = type;
 }
 
+/* What about types defined as forward references inside of a small lexical
+   scope?  */
+/* Add a type to the list of undefined types to be checked through
+   once this file has been read in.
+   
+   In practice, we actually maintain two such lists: The first list
+   (UNDEF_TYPES) is used for types whose name has been provided, and
+   concerns forward references (eg 'xs' or 'xu' forward references);
+   the second list (NONAME_UNDEFS) is used for types whose name is
+   unknown at creation time, because they were referenced through
+   their type number before the actual type was declared.
+   This function actually adds the given type to the proper list.  */
+
+static void
+add_undefined_type (struct type *type, int typenums[2])
+{
+  if (TYPE_TAG_NAME (type) == NULL)
+    add_undefined_type_noname (type, typenums);
+  else
+    add_undefined_type_1 (type);
+}
+
+/* Try to fix all undefined types pushed on the UNDEF_TYPES vector.  */
+
+void
+cleanup_undefined_types_noname (void)
+{
+  int i;
+
+  for (i = 0; i < noname_undefs_length; i++)
+    {
+      struct nat nat = noname_undefs[i];
+      struct type **type;
+
+      type = dbx_lookup_type (nat.typenums);
+      if (nat.type != *type && TYPE_CODE (*type) != TYPE_CODE_UNDEF)
+        replace_type (nat.type, *type);
+    }
+
+  noname_undefs_length = 0;
+}
+
 /* Go through each undefined type, see if it's still undefined, and fix it
    up if possible.  We have two kinds of undefined types:
 
@@ -4167,8 +4280,9 @@ add_undefined_type (struct type *type)
    TYPE_CODE_STRUCT, TYPE_CODE_UNION:  Structure whose fields were not
    yet defined at the time a pointer to it was made.
    Fix:  Do a full lookup on the struct/union tag.  */
+
 void
-cleanup_undefined_types (void)
+cleanup_undefined_types_1 (void)
 {
   struct type **type;
 
@@ -4194,7 +4308,7 @@ cleanup_undefined_types (void)
 
                if (typename == NULL)
                  {
-                   complaint (&symfile_complaints, "need a type name");
+                   complaint (&symfile_complaints, _("need a type name"));
                    break;
                  }
                for (ppt = file_symbols; ppt; ppt = ppt->next)
@@ -4207,7 +4321,7 @@ cleanup_undefined_types (void)
                            && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
                            && (TYPE_CODE (SYMBOL_TYPE (sym)) ==
                                TYPE_CODE (*type))
-                           && STREQ (DEPRECATED_SYMBOL_NAME (sym), typename))
+                           && strcmp (DEPRECATED_SYMBOL_NAME (sym), typename) == 0)
                           replace_type (*type, SYMBOL_TYPE (sym));
                      }
                  }
@@ -4218,7 +4332,8 @@ cleanup_undefined_types (void)
        default:
          {
            complaint (&symfile_complaints,
-                      "GDB internal error.  cleanup_undefined_types with bad type %d.",
+                      _("forward-referenced types left unresolved, "
+                       "type code %d."),
                       TYPE_CODE (*type));
          }
          break;
@@ -4228,6 +4343,16 @@ cleanup_undefined_types (void)
   undef_types_length = 0;
 }
 
+/* Try to fix all the undefined types we ecountered while processing
+   this unit.  */
+
+void
+cleanup_undefined_types (void)
+{
+  cleanup_undefined_types_1 ();
+  cleanup_undefined_types_noname ();
+}
+
 /* 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.  */
@@ -4289,7 +4414,7 @@ scan_file_globals (struct objfile *objfile)
          for (sym = global_sym_chain[hash]; sym;)
            {
              if (DEPRECATED_SYMBOL_NAME (msymbol)[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
-                 STREQ (DEPRECATED_SYMBOL_NAME (msymbol) + 1, DEPRECATED_SYMBOL_NAME (sym) + 1))
+                 strcmp (DEPRECATED_SYMBOL_NAME (msymbol) + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
                {
                  /* Splice this symbol out of the hash chain and
                     assign the value we have to it. */
@@ -4360,7 +4485,7 @@ scan_file_globals (struct objfile *objfile)
            SYMBOL_CLASS (prev) = LOC_UNRESOLVED;
          else
            complaint (&symfile_complaints,
-                      "%s: common block `%s' from global_sym_chain unresolved",
+                      _("%s: common block `%s' from global_sym_chain unresolved"),
                       objfile->name, DEPRECATED_SYMBOL_NAME (prev));
        }
     }
@@ -4439,12 +4564,12 @@ find_name_end (char *name)
       /* Must be an ObjC method symbol.  */
       if (s[1] != '[')
        {
-         error ("invalid symbol name \"%s\"", name);
+         error (_("invalid symbol name \"%s\""), name);
        }
       s = strchr (s, ']');
       if (s == NULL)
        {
-         error ("invalid symbol name \"%s\"", name);
+         error (_("invalid symbol name \"%s\""), name);
        }
       return strchr (s, ':');
     }
@@ -4463,4 +4588,9 @@ _initialize_stabsread (void)
   undef_types_length = 0;
   undef_types = (struct type **)
     xmalloc (undef_types_allocated * sizeof (struct type *));
+
+  noname_undefs_allocated = 20;
+  noname_undefs_length = 0;
+  noname_undefs = (struct nat *)
+    xmalloc (noname_undefs_allocated * sizeof (struct nat));
 }
This page took 0.045322 seconds and 4 git commands to generate.