Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [RFA] Fix gdb/277 by separating types
@ 2002-05-12 20:10 Michael Elizabeth Chastain
  2002-05-12 20:16 ` Daniel Jacobowitz
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Elizabeth Chastain @ 2002-05-12 20:10 UTC (permalink / raw)
  To: drow; +Cc: gdb-patches

I do build an object directory from scratch (just to avoid these
kinds of problems).

BTW I am using gcc 2.95.3, I don't know where you got 2.95.2 from.

I bet the difference in our machines is somewhere in libc.
I am using stock red hat linux 7.2 glibc, glibc 2.2.4-13.

It's reproducing on my machine.  Here's a shorter recipe:

  ./gdb gdb.base/break
  (gdb) break main
  (gdb) run
  (gdb) maint print symbols symbols_output

Have a look at the end of symbols_output in the tarball.
Mine is reproducibly crapping out in file 'init.c' here:

   typedef void (*__gconv_end_fct)();
   typedef int (*__gconv_fct)();
   struct __gconv_info {
       size_t __nsteps;
       struct __gconv_step *__steps;
       struct __gconv_step_data __data[0];
   };

   typedef int (*__gconv_init_fct)();
   struct __gconv_step {

When I do maint-print-symbols with gdb 5.2, it runs fine,
and gives me this output for __gconv_step:

   typedef int (*__gconv_init_fct)(struct __gconv_step *);
   struct __gconv_step {
       struct __gconv_loaded_object *__shlib_handle;
       const char *__modname;
       int __counter;
       char *__from_name;
       char *__to_name;
       int (*__fct)(struct __gconv_step *, struct __gconv_step_data *, const unsigned char **, const unsigned char *, unsigned char **, size_t *, int, int);
       int (*__init_fct)(struct __gconv_step *);
       void (*__end_fct)(struct __gconv_step *);
       int __min_needed_from;
       int __max_needed_from;
       int __min_needed_to;
       int __max_needed_to;
       int __stateful;
       void *__data;
   };

In the stack trace, I'm seeing it crap out on c_print_type of
__shlib_handle.  __gconv_loaded_object is a forward reference,
but it is not defined in this symtab: it is defined in a different
symtab.

Michael C


^ permalink raw reply	[flat|nested] 9+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types
@ 2002-05-12 20:13 Michael Elizabeth Chastain
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Elizabeth Chastain @ 2002-05-12 20:13 UTC (permalink / raw)
  To: drow; +Cc: gdb-patches

One more clue: I build all my gcc's, including gcc 2.95.3,
with --disable-shared.  I doubt that is relevant because
main-print-symbols is dying while dumping glibc symbols,
not libgcc.a symbols.

Michael C


^ permalink raw reply	[flat|nested] 9+ messages in thread
* Re: [RFA] Fix gdb/277 by separating types
@ 2002-05-12 19:19 Michael Elizabeth Chastain
  2002-05-12 19:38 ` Daniel Jacobowitz
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Elizabeth Chastain @ 2002-05-12 19:19 UTC (permalink / raw)
  To: drow, gdb-patches

Mr. Test-Bed choked on this pair of patches.  He died early in the
first configuration tested, in gdb.base/maint.exp.

There's a tarball at

  ftp://ftp.shout.net/pub/users/mec/gdb/20020510-drow-test.tar.gz

That includes gdb.log, the gdb executable, and the core file in it.

Michael C

===

  # gdb.log excerpt
  # target=native, host=i686-pc-linux-gnu%rh-7.2,
  # gdb=HEAD%20020510 + drow-1 + drow-2, gcc=2.95.3, gdb=-gdwarf-2

  (gdb) PASS: gdb.base/maint.exp: maint print symbols w/o args
  maint print symbols symbols_output^M
  /berman/fsf/_today_/source/gdb/HEAD/src/gdb/gdbtypes.c:508: gdb-internal-error:
  make_cv_type: Assertion `TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)' failed.^M
  An internal GDB error was detected.  This may make further^M
  debugging unreliable.  Quit this debugging session? (y or n) FAIL: gdb.base/maint.exp: (timeout) maint print symbols
  maint print type argc^M
  Please answer y or n.^M
  An internal GDB error was detected.  This may make further^M
  debugging unreliable.  Quit this debugging session? (y or n) FAIL: gdb.base/maint.exp: (timeout) maint print type
  maint info sections^M
  Please answer y or n.^M
  An internal GDB error was detected.  This may make further^M
  debugging unreliable.  Quit this debugging session? (y or n)

===

  Script started on Sun May 12 22:10:19 2002
  [mec@berman test]$ /usr/bin/gdb ./gdb core
  GNU gdb Red Hat Linux 7.x (5.0rh-15) (MI_OUT)
  Copyright 2001 Free Software Foundation, Inc.
  GDB is free software, covered by the GNU General Public License, and you are
  welcome to change it and/or distribute copies of it under certain conditions.
  Type "show copying" to see the conditions.
  There is absolutely no warranty for GDB.  Type "show warranty" for details.
  This GDB was configured as "i386-redhat-linux"...
  Core was generated by `gdb -nw -nx'.
  Program terminated with signal 6, Aborted.
  Reading symbols from /usr/lib/libncurses.so.5...done.
  Loaded symbols for /usr/lib/libncurses.so.5
  Reading symbols from /lib/i686/libm.so.6...done.
  Loaded symbols for /lib/i686/libm.so.6
  Reading symbols from /lib/libdl.so.2...done.
  Loaded symbols for /lib/libdl.so.2
  Reading symbols from /lib/i686/libc.so.6...done.
  Loaded symbols for /lib/i686/libc.so.6
  Reading symbols from /lib/ld-linux.so.2...done.
  Loaded symbols for /lib/ld-linux.so.2
  Reading symbols from /lib/libthread_db.so.1...done.
  Loaded symbols for /lib/libthread_db.so.1
  #0  0x400c2a01 in __kill () from /lib/i686/libc.so.6
  (gdb) set height 0
  (gdb) bt
  #0  0x400c2a01 in __kill () from /lib/i686/libc.so.6
  #1  0x400c27da in raise (sig=6) at ../sysdeps/posix/raise.c:27
  #2  0x400c3f82 in abort () at ../sysdeps/generic/abort.c:88
  #3  0x080e014d in internal_verror (
      file=0x81cfb40 "/berman/fsf/_today_/source/gdb/HEAD/src/gdb/gdbtypes.c", 
      line=508, fmt=0x81cfb1f "%s%sAssertion `%s' failed.", ap=0xbfffec7c)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/utils.c:726
  #4  0x080e017b in internal_error ()
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/utils.c:749
  #5  0x080ace76 in make_cv_type ()
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/gdbtypes.c:517
  #6  0x080ae075 in check_typedef (type=0x85a2250)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/gdbtypes.c:1294
  #7  0x080d6513 in c_type_print_base (type=0x85a2250, stream=0x925da20, show=0, 
      level=7) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/c-typeprint.c:684
  #8  0x080d6545 in c_type_print_base (type=0x85a229c, stream=0x925da20, show=0, 
      level=7) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/c-typeprint.c:695
  #9  0x080d57ef in c_print_type (type=0x85a229c, 
      varstring=0x85a2228 "__shlib_handle", stream=0x925da20, show=0, level=7)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/c-typeprint.c:74
  #10 0x080d6876 in c_type_print_base (type=0x85a21dc, stream=0x925da20, show=1, 
      level=3) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/c-typeprint.c:895
  #11 0x080d57ef in c_print_type (type=0x85a21dc, varstring=0x81c0033 "", 
      stream=0x925da20, show=1, level=3)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/c-typeprint.c:74
  #12 0x08093052 in print_symbol (args=0xbffff090)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/symmisc.c:574
  #13 0x080dd81f in do_catch_errors (uiout=0x8263d48, data=0xbffff060)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:492
  #14 0x080dd761 in catcher (func=0x80dd810 <do_catch_errors>, 
      func_uiout=0x8263d48, func_args=0xbffff060, func_val=0xbffff058, 
      func_caught=0xbffff05c, errstring=0x81bfdd7 "Error printing symbol:\n", 
      mask=6) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:424
  #15 0x080dd866 in catch_errors (func=0x8092c60 <print_symbol>, 
      func_args=0xbffff090, errstring=0x81bfdd7 "Error printing symbol:\n", 
      mask=6) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:504
  #16 0x08092a99 in dump_symtab (objfile=0x8282da8, symtab=0x85a4544, 
      outfile=0x925da20)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/symmisc.c:483
  #17 0x08092c24 in maintenance_print_symbols (args=0x824461c "symbols_output", 
      from_tty=1) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/symmisc.c:540
  #18 0x0813ece4 in do_cfunc (c=0x825a198, args=0x824461c "symbols_output", 
      from_tty=1)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/cli/cli-decode.c:52
  #19 0x080ddb93 in execute_command (p=0x8244629 "t", from_tty=1)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:711
  #20 0x080a20ad in command_handler (command=0x8244608 "")
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-top.c:504
  #21 0x080a2573 in command_line_handler (
      rl=0x925d830 "maint print symbols symbols_output")
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-top.c:797
  #22 0x0819c486 in rl_callback_read_char ()
      at /berman/fsf/_today_/source/gdb/HEAD/src/readline/callback.c:114
  #23 0x080a1a3b in rl_callback_read_char_wrapper (client_data=0x0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-top.c:168
  #24 0x080a1f9f in stdin_event_handler (error=0, client_data=0x0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-top.c:418
  #25 0x080f2117 in handle_file_event (event_file_desc=0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-loop.c:714
  #26 0x080f1b8e in process_event ()
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-loop.c:335
  #27 0x080f1bdb in gdb_do_one_event (data=0x0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-loop.c:372
  #28 0x080dd81f in do_catch_errors (uiout=0x8263d48, data=0xbffff380)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:492
  #29 0x080dd761 in catcher (func=0x80dd810 <do_catch_errors>, 
      func_uiout=0x8263d48, func_args=0xbffff380, func_val=0xbffff378, 
      func_caught=0xbffff37c, errstring=0x81e6680 "", mask=6)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:424
  #30 0x080dd866 in catch_errors (func=0x80f1bb0 <gdb_do_one_event>, 
      func_args=0x0, errstring=0x81e6680 "", mask=6)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:504
  #31 0x080f1c13 in start_event_loop ()
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/event-loop.c:396
  #32 0x08072ff1 in captured_command_loop (data=0x0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/main.c:94
  #33 0x080dd81f in do_catch_errors (uiout=0x8263d48, data=0xbffff4f0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:492
  #34 0x080dd761 in catcher (func=0x80dd810 <do_catch_errors>, 
      func_uiout=0x8263d48, func_args=0xbffff4f0, func_val=0xbffff4e8, 
      func_caught=0xbffff4ec, errstring=0x81b5e4d "", mask=6)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:424
  #35 0x080dd866 in catch_errors (func=0x8072fe0 <captured_command_loop>, 
      func_args=0x0, errstring=0x81b5e4d "", mask=6)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:504
  #36 0x080735c3 in captured_main (data=0xbffff7b0)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/main.c:723
  #37 0x080dd81f in do_catch_errors (uiout=0x8225d80, data=0xbffff790)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:492
  #38 0x080dd761 in catcher (func=0x80dd810 <do_catch_errors>, 
      func_uiout=0x8225d80, func_args=0xbffff790, func_val=0xbffff788, 
      func_caught=0xbffff78c, errstring=0x81b5e4d "", mask=6)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:424
  #39 0x080dd866 in catch_errors (func=0x8073030 <captured_main>, 
      func_args=0xbffff7b0, errstring=0x81b5e4d "", mask=6)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/top.c:504
  #40 0x08073ada in main (argc=3, argv=0xbffff824)
      at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/main.c:734
  #41 0x400b0507 in __libc_start_main (main=0x8073ab0 <main>, argc=3, 
      ubp_av=0xbffff824, init=0x80723d0 <_init>, fini=0x81b5d10 <_fini>, 
      rtld_fini=0x4000dc14 <_dl_fini>, stack_end=0xbffff81c)
      at ../sysdeps/generic/libc-start.c:129
  (gdb) quit
  [mec@berman test]$ exit
  Script done on Sun May 12 22:11:54 2002


^ permalink raw reply	[flat|nested] 9+ messages in thread
* [RFA] Fix gdb/277 by separating types
@ 2002-05-12 17:53 Daniel Jacobowitz
  2002-05-12 22:22 ` Eli Zaretskii
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2002-05-12 17:53 UTC (permalink / raw)
  To: gdb-patches

This patch requires my previous cleanup patch.  It fixes a test in
gdb.c++/method.exp for GCC 3.x/stabs+, and closes gdb/277.

Basically, I divide the type structure into two elements.  One marks our
position on the ring of related types - I removed the separate AS and CV
rings, which could never have worked quite right.  With them, a '@code const
int' and a 'const @code int' would be different types.  Everything left in
the new TYPE_CORE_TYPE should be shared among all qualified versions of this
type, and also can be safely copied a la replace_type.  replace_type is
still gross, but no longer runs much risk of being unsafe.

As a consequence of doing this properly, the grossness in finish_cv_type is
no longer necessary, so I deleted all traces of it.

No regressions on i386-linux, fixes the testcase mentioned above.  OK to
commit?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2002-05-12  Daniel Jacobowitz  <drow@mvista.com>

	Fix PR gdb/277.
	* gdbtypes.h: Update accessor macros to use TYPE_CORE_TYPE.
	(TYPE_CONST, TYPE_VOLATILE, TYPE_CODE_SPACE, TYPE_DATA_SPACE): Use
	TYPE_INSTANCE_FLAGS.
	(struct type_core): New.
	(struct type): Move most members to struct type_core.  Change
	cv_type and as_type to new type_chain member.  Add instance_flags.
	(TYPE_CORE_TYPE, TYPE_CHAIN, TYPE_INSTANCE_FLAGS): New macros.
	(TYPE_CV_TYPE, TYPE_AS_TYPE): Remove.
	(finish_cv_type): Remove prototype.
	* gdbtypes.c (alloc_type): Update comment.  Allocate TYPE_CORE_TYPE.
	Set TYPE_CHAIN.
	(alloc_type_instance): New function.
	(smash_type): New function.
	(make_pointer_type, make_reference_type, make_function_type)
	(smash_to_member_type, smash_to_method_type): Call smash_type.
	(make_qualified_type): New function.
	(make_type_with_address_space): Call make_qualified_type.
	(make_cv_type): Likewise.
	(finish_cv_type): Remove unnecessary function.
	(replace_type): Update comment.  Copy TYPE_CORE_TYPE.
	(recursive_dump_type): Dump TYPE_CHAIN and TYPE_INSTANCE_FLAGS;
	remove TYPE_CV_TYPE and TYPE_AS_TYPE.
	* c-typeprint.c (c_type_print_modifier): Use TYPE_INSTANCE_FLAGS.
	* dwarf2read.c (read_structure_scope): Don't call finish_cv_type.
	* hpread.c (hpread_read_struct_type): Likewise.
	* stabsread.c (read_struct_type): Likewise.

diff -x *.orig -pur gdb.inter/c-typeprint.c gdb.real/c-typeprint.c
--- gdb.inter/c-typeprint.c	Sun May 12 20:34:14 2002
+++ gdb.real/c-typeprint.c	Sun May 12 02:58:37 2002
@@ -316,7 +316,7 @@ c_type_print_modifier (struct type *type
       did_print_modifier = 1;
     }
 
-  address_space_id = address_space_int_to_name (TYPE_FLAGS (type));
+  address_space_id = address_space_int_to_name (TYPE_INSTANCE_FLAGS (type));
   if (address_space_id)
     {
       if (did_print_modifier || need_pre_space)
diff -x *.orig -pur gdb.inter/dwarf2read.c gdb.real/dwarf2read.c
--- gdb.inter/dwarf2read.c	Sun May 12 20:25:57 2002
+++ gdb.real/dwarf2read.c	Sun May 12 19:35:06 2002
@@ -2486,8 +2486,6 @@ read_structure_scope (struct die_info *d
       /* No children, must be stub. */
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
-
-  finish_cv_type (die->type);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
diff -x *.orig -pur gdb.inter/gdbtypes.c gdb.real/gdbtypes.c
--- gdb.inter/gdbtypes.c	Sun May 12 20:34:14 2002
+++ gdb.real/gdbtypes.c	Sun May 12 20:04:07 2002
@@ -135,7 +135,8 @@ static void virtual_base_list_aux (struc
 
 /* Alloc a new type structure and fill it with some defaults.  If
    OBJFILE is non-NULL, then allocate the space for the type structure
-   in that objfile's type_obstack. */
+   in that objfile's type_obstack.  Otherwise allocate the new type structure
+   by xmalloc () (for permanent types).  */
 
 struct type *
 alloc_type (struct objfile *objfile)
@@ -147,26 +148,74 @@ alloc_type (struct objfile *objfile)
   if (objfile == NULL)
     {
       type = (struct type *) xmalloc (sizeof (struct type));
+      memset ((char *) (type), 0, sizeof (struct type));
+      TYPE_CORE_TYPE (type) = xmalloc (sizeof (struct type_core));
     }
   else
     {
       type = (struct type *) obstack_alloc (&objfile->type_obstack,
 					    sizeof (struct type));
+      memset ((char *) (type), 0, sizeof (struct type));
+      TYPE_CORE_TYPE (type)
+	= (struct type_core *) obstack_alloc (&objfile->type_obstack,
+					      sizeof (struct type_core));
       OBJSTAT (objfile, n_types++);
     }
-  memset ((char *) type, 0, sizeof (struct type));
+  memset ((char *) TYPE_CORE_TYPE (type), 0, sizeof (struct type_core));
 
   /* Initialize the fields that might not be zero. */
 
   TYPE_CODE (type) = TYPE_CODE_UNDEF;
   TYPE_OBJFILE (type) = objfile;
   TYPE_VPTR_FIELDNO (type) = -1;
-  TYPE_CV_TYPE (type) = type;	/* chain back to itself */
-  TYPE_AS_TYPE (type) = type;	/* ditto */
+  TYPE_CHAIN (type) = type;	/* Chain back to itself.  */
 
   return (type);
 }
 
+/* Alloc a new type instance structure, fill it with some defaults,
+   and point it at OLDTYPE.  Allocate the new type instance from the
+   same place as OLDTYPE.  */
+
+static struct type *
+alloc_type_instance (struct type *oldtype)
+{
+  struct type *type;
+
+  /* Allocate the structure.  */
+
+  if (TYPE_OBJFILE (oldtype) == NULL)
+    {
+      type = (struct type *) xmalloc (sizeof (struct type));
+      memset ((char *) (type), 0, sizeof (struct type));
+    }
+  else
+    {
+      type = (struct type *)
+	obstack_alloc (&TYPE_OBJFILE (oldtype)->type_obstack,
+		       sizeof (struct type));
+      memset ((char *) (type), 0, sizeof (struct type));
+    }
+  TYPE_CORE_TYPE (type) = TYPE_CORE_TYPE (oldtype);
+
+  TYPE_CHAIN (type) = type;	/* Chain back to itself for now.  */
+
+  return (type);
+}
+
+/* Clear all remnants of the previous type at TYPE, in preparation for
+   replacing it with something else.  */
+static void
+smash_type (struct type *type)
+{
+  memset ((char *) TYPE_CORE_TYPE (type), 0, sizeof (struct type_core));
+
+  /* For now, delete the rings.  */
+  TYPE_CHAIN (type) = type;
+
+  /* For now, leave the pointer/reference types alone.  */
+}
+
 /* Lookup a pointer to a type TYPE.  TYPEPTR, if nonzero, points
    to a pointer to memory where the pointer type should be stored.
    If *TYPEPTR is zero, update it to point to the pointer type we return.
@@ -202,7 +251,7 @@ make_pointer_type (struct type *type, st
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
-      memset ((char *) ntype, 0, sizeof (struct type));
+      smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
     }
 
@@ -269,7 +318,7 @@ make_reference_type (struct type *type, 
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
-      memset ((char *) ntype, 0, sizeof (struct type));
+      smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
     }
 
@@ -318,7 +367,7 @@ make_function_type (struct type *type, s
     {
       ntype = *typeptr;
       objfile = TYPE_OBJFILE (ntype);
-      memset ((char *) ntype, 0, sizeof (struct type));
+      smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
     }
 
@@ -368,45 +417,63 @@ address_space_int_to_name (int space_fla
     return NULL;
 }
 
-/* Make an address-space-delimited variant of a type -- a type that
-   is identical to the one supplied except that it has an address
-   space attribute attached to it (such as "code" or "data").
-
-   This is for Harvard architectures. */
+/* Create a new type with instance flags NEW_FLAGS, based on TYPE.
+   If STORAGE is non-NULL, create the new type instance there.  */
 
 struct type *
-make_type_with_address_space (struct type *type, int space_flag)
+make_qualified_type (struct type *type, int new_flags,
+		     struct type *storage)
 {
   struct type *ntype;
 
   ntype = type;
   do {
-    if ((ntype->flags & space_flag) != 0)
+    if (TYPE_INSTANCE_FLAGS (ntype) == new_flags)
       return ntype;
-    ntype = TYPE_AS_TYPE (ntype);
+    ntype = TYPE_CHAIN (ntype);
   } while (ntype != type);
 
-  /* Create a new, duplicate type. */
-  ntype = alloc_type (TYPE_OBJFILE (type));
-  /* Copy original type. */
-  memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+  /* Create a new type instance.  */
+  if (storage == NULL)
+    ntype = alloc_type_instance (type);
+  else
+    {
+      ntype = storage;
+      TYPE_CORE_TYPE (ntype) = TYPE_CORE_TYPE (type);
+      TYPE_CHAIN (ntype) = ntype;
+    }
 
   /* Pointers or references to the original type are not relevant to
-     the new type; but if the original type is a pointer, the new type
-     points to the same thing (so TYPE_TARGET_TYPE remains unchanged). */
+     the new type.  */
   TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
   TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;
-  TYPE_CV_TYPE (ntype) = ntype;
 
-  /* Chain the new address-space-specific type to the old type. */
-  ntype->as_type = type->as_type;
-  type->as_type = ntype;
+  /* Chain the new qualified type to the old type.  */
+  TYPE_CHAIN (ntype) = TYPE_CHAIN (type);
+  TYPE_CHAIN (type) = ntype;
+
+  /* Now set the instance flags and return the new type.  */
+  TYPE_INSTANCE_FLAGS (ntype) = new_flags;
 
-  /* Now set the address-space flag, and return the new type. */
-  ntype->flags |= space_flag;
   return ntype;
 }
 
+/* Make an address-space-delimited variant of a type -- a type that
+   is identical to the one supplied except that it has an address
+   space attribute attached to it (such as "code" or "data").
+
+   This is for Harvard architectures. */
+
+struct type *
+make_type_with_address_space (struct type *type, int space_flag)
+{
+  struct type *ntype;
+  int new_flags = ((TYPE_INSTANCE_FLAGS (type)
+		    & ~(TYPE_FLAG_CODE_SPACE | TYPE_FLAG_DATA_SPACE))
+		   | space_flag);
+
+  return make_qualified_type (type, new_flags, NULL);
+}
 
 /* Make a "c-v" variant of a type -- a type that is identical to the
    one supplied except that it may have const or volatile attributes
@@ -425,142 +492,49 @@ make_cv_type (int cnst, int voltl, struc
   register struct type *tmp_type = type;	/* tmp type */
   struct objfile *objfile;
 
-  ntype = TYPE_CV_TYPE (type);
-
-  while (ntype != type)
-    {
-      if ((TYPE_CONST (ntype) == cnst) &&
-	  (TYPE_VOLATILE (ntype) == voltl))
-	{
-	  if (typeptr == 0)
-	    return ntype;
-	  else if (*typeptr == 0)
-	    {
-	      *typeptr = ntype;	/* Tracking alloc, and we have new type.  */
-	      return ntype;
-	    }
-	}
-      tmp_type = ntype;
-      ntype = TYPE_CV_TYPE (ntype);
-    }
-
-  if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
-    {
-      ntype = alloc_type (TYPE_OBJFILE (type));
-      if (typeptr)
-	*typeptr = ntype;
-    }
-  else
-    /* We have storage, but need to reset it.  */
-    {
-      ntype = *typeptr;
-      objfile = TYPE_OBJFILE (ntype);
-      /* memset ((char *) ntype, 0, sizeof (struct type)); */
-      TYPE_OBJFILE (ntype) = objfile;
-    }
+  int new_flags = (TYPE_INSTANCE_FLAGS (type)
+		   & ~(TYPE_FLAG_CONST | TYPE_FLAG_VOLATILE));
 
-  /* Copy original type */
-  memcpy ((char *) ntype, (char *) type, sizeof (struct type));
-  /* But zero out fields that shouldn't be copied */
-  TYPE_POINTER_TYPE (ntype) = (struct type *) 0;	/* Need new pointer kind */
-  TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;	/* Need new referene kind */
-  TYPE_AS_TYPE (ntype) = ntype;		/* Need new address-space kind. */
-  /* Note: TYPE_TARGET_TYPE can be left as is */
-
-  /* Set flags appropriately */
   if (cnst)
-    TYPE_FLAGS (ntype) |= TYPE_FLAG_CONST;
-  else
-    TYPE_FLAGS (ntype) &= ~TYPE_FLAG_CONST;
+    new_flags |= TYPE_FLAG_CONST;
 
   if (voltl)
-    TYPE_FLAGS (ntype) |= TYPE_FLAG_VOLATILE;
-  else
-    TYPE_FLAGS (ntype) &= ~TYPE_FLAG_VOLATILE;
-
-  /* Fix the chain of cv variants */
-  TYPE_CV_TYPE (ntype) = type;
-  TYPE_CV_TYPE (tmp_type) = ntype;
-
-  return ntype;
-}
-
-/* When reading in a class type, we may have created references to
-   cv-qualified versions of the type (in method arguments, for
-   instance).  Update everything on the cv ring from the primary
-   type TYPE.
-
-   The only reason we do not need to do the same thing for address
-   spaces is that type readers do not create address space qualified
-   types.  */
-void
-finish_cv_type (struct type *type)
-{
-  struct type *ntype, *cv_type, *ptr_type, *ref_type;
-  int cv_flags;
-
-  gdb_assert (!TYPE_CONST (type) && !TYPE_VOLATILE (type));
+    new_flags |= TYPE_FLAG_VOLATILE;
 
-  ntype = type;
-  while ((ntype = TYPE_CV_TYPE (ntype)) != type)
+  if (typeptr && *typeptr != NULL)
     {
-      /* Save cv_flags.  */
-      cv_flags = TYPE_FLAGS (ntype) & (TYPE_FLAG_VOLATILE | TYPE_FLAG_CONST);
-
-      /* If any reference or pointer types were created, save them too.  */
-      ptr_type = TYPE_POINTER_TYPE (ntype);
-      ref_type = TYPE_REFERENCE_TYPE (ntype);
-
-      /* Don't disturb the CV chain.  */
-      cv_type = TYPE_CV_TYPE (ntype);
-
-      /* Verify that we haven't added any address-space qualified types,
-	 for the future.  */
-      gdb_assert (ntype == TYPE_AS_TYPE (ntype));
-
-      /* Copy original type */
-      memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+      /* Objfile is per-core-type.  This const-qualified type had best
+	 belong to the same objfile as the type it is qualifying...  */
+      gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type));
+    }
+  
+  ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL);
 
-      /* Restore everything.  */
-      TYPE_POINTER_TYPE (ntype) = ptr_type;
-      TYPE_REFERENCE_TYPE (ntype) = ref_type;
-      TYPE_CV_TYPE (ntype) = cv_type;
-      TYPE_FLAGS (ntype) = TYPE_FLAGS (ntype) | cv_flags;
+  if (typeptr != NULL)
+    *typeptr = ntype;
 
-      TYPE_AS_TYPE (ntype) = ntype;
-    }
+  return ntype;
 }
 
-/* Replace the contents of ntype with the type *type.
+/* Replace the contents of ntype with the type *type.  This changes the
+   contents, rather than the pointer for TYPE_CORE_TYPE (ntype); thus
+   the changes are propogated to all types in the TYPE_CHAIN.
 
    In order to build recursive types, it's inevitable that we'll need
    to update types in place --- but this sort of indiscriminate
    smashing is ugly, and needs to be replaced with something more
-   controlled.  For example, Daniel Jacobowitz has suggested moving
-   the fields common to a set of c/v variants into their own object,
-   which the variants would share.
-
-   This function does not handle the replacement type being
-   cv-qualified; it could be easily fixed to, but it would be better
-   to just change the whole approach.  */
+   controlled.  TYPE_CORE_TYPE is a step in this direction; it's not
+   clear if more steps are needed.  */
 void
 replace_type (struct type *ntype, struct type *type)
 {
   struct type *cv_chain, *as_chain, *ptr, *ref;
 
-  cv_chain = TYPE_CV_TYPE (ntype);
-  as_chain = TYPE_AS_TYPE (ntype);
-  ptr = TYPE_POINTER_TYPE (ntype);
-  ref = TYPE_REFERENCE_TYPE (ntype);
-
-  *ntype = *type;
-
-  TYPE_POINTER_TYPE (ntype) = ptr;
-  TYPE_REFERENCE_TYPE (ntype) = ref;
-  TYPE_CV_TYPE (ntype) = cv_chain;
-  TYPE_AS_TYPE (ntype) = as_chain;
+  *TYPE_CORE_TYPE (ntype) = *TYPE_CORE_TYPE (type);
 
-  finish_cv_type (ntype);
+  /* Assert that the two types have equivalent instance qualifiers.
+     This should be true for at least all of our debug readers.  */
+  gdb_assert (TYPE_INSTANCE_FLAGS (ntype) == TYPE_INSTANCE_FLAGS (type));
 }
 
 /* Implement direct support for MEMBER_TYPE in GNU C++.
@@ -879,7 +853,7 @@ smash_to_member_type (struct type *type,
 
   objfile = TYPE_OBJFILE (type);
 
-  memset ((char *) type, 0, sizeof (struct type));
+  smash_type (type);
   TYPE_OBJFILE (type) = objfile;
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
@@ -902,7 +876,7 @@ smash_to_method_type (struct type *type,
 
   objfile = TYPE_OBJFILE (type);
 
-  memset ((char *) type, 0, sizeof (struct type));
+  smash_type (type);
   TYPE_OBJFILE (type) = objfile;
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
@@ -3011,13 +2985,11 @@ recursive_dump_type (struct type *type, 
   printfi_filtered (spaces, "reference_type ");
   gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
   printf_filtered ("\n");
-  printfi_filtered (spaces, "cv_type ");
-  gdb_print_host_address (TYPE_CV_TYPE (type), gdb_stdout);
-  printf_filtered ("\n");
-  printfi_filtered (spaces, "as_type ");
-  gdb_print_host_address (TYPE_AS_TYPE (type), gdb_stdout);
+  printfi_filtered (spaces, "type_chain ");
+  gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout);
   printf_filtered ("\n");
   printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
+  printfi_filtered (spaces, "instance_flags 0x%x", TYPE_INSTANCE_FLAGS (type));
   if (TYPE_UNSIGNED (type))
     {
       puts_filtered (" TYPE_FLAG_UNSIGNED");
diff -x *.orig -pur gdb.inter/gdbtypes.h gdb.real/gdbtypes.h
--- gdb.inter/gdbtypes.h	Sun May 12 20:34:14 2002
+++ gdb.real/gdbtypes.h	Sun May 12 19:34:42 2002
@@ -187,14 +187,14 @@ enum type_code
  */
 
 #define TYPE_FLAG_CONST		(1 << 5)
-#define TYPE_CONST(t)		(TYPE_FLAGS (t) & TYPE_FLAG_CONST)
+#define TYPE_CONST(t)		(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CONST)
 
 /* Volatile type.  If this is set, the corresponding type has a
  * volatile modifier.
  */
 
 #define TYPE_FLAG_VOLATILE	(1 << 6)
-#define TYPE_VOLATILE(t)	(TYPE_FLAGS (t) & TYPE_FLAG_VOLATILE)
+#define TYPE_VOLATILE(t)	(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_VOLATILE)
 
 
 /* This is a function type which appears to have a prototype.  We need this
@@ -235,10 +235,10 @@ enum type_code
    is instruction space, and for data objects is data memory.  */
 
 #define TYPE_FLAG_CODE_SPACE	(1 << 9)
-#define TYPE_CODE_SPACE(t)	(TYPE_FLAGS (t) & TYPE_FLAG_CODE_SPACE)
+#define TYPE_CODE_SPACE(t)	(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_CODE_SPACE)
 
 #define TYPE_FLAG_DATA_SPACE	(1 << 10)
-#define TYPE_DATA_SPACE(t)	(TYPE_FLAGS (t) & TYPE_FLAG_DATA_SPACE)
+#define TYPE_DATA_SPACE(t)	(TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_DATA_SPACE)
 
 /* FIXME: Kludge to mark a varargs function type for C++ member
    function argument processing.  Currently only used in dwarf2read.c,
@@ -254,238 +254,240 @@ enum type_code
 #define TYPE_FLAG_VECTOR	(1 << 12)
 #define TYPE_VECTOR(t)		(TYPE_FLAGS (t) & TYPE_FLAG_VECTOR)
 
+struct type_core
+{
+  /* Code for kind of type */
+
+  enum type_code code;
+
+  /* Name of this type, or NULL if none.
+
+     This is used for printing only, except by poorly designed C++ code.
+     For looking up a name, look for a symbol in the VAR_NAMESPACE.  */
+
+  char *name;
+
+  /* Tag name for this type, or NULL if none.  This means that the
+     name of the type consists of a keyword followed by the tag name.
+     Which keyword is determined by the type code ("struct" for
+     TYPE_CODE_STRUCT, etc.).  As far as I know C/C++ are the only languages
+     with this feature.
+
+     This is used for printing only, except by poorly designed C++ code.
+     For looking up a name, look for a symbol in the STRUCT_NAMESPACE.
+     One more legitimate use is that if TYPE_FLAG_STUB is set, this is
+     the name to use to look for definitions in other files.  */
+
+  char *tag_name;
+
+  /* Length of storage for a value of this type.  This is what
+     sizeof(type) would return; use it for address arithmetic,
+     memory reads and writes, etc.  This size includes padding.  For
+     example, an i386 extended-precision floating point value really
+     only occupies ten bytes, but most ABI's declare its size to be
+     12 bytes, to preserve alignment.  A `struct type' representing
+     such a floating-point type would have a `length' value of 12,
+     even though the last two bytes are unused.
+
+     There's a bit of a host/target mess here, if you're concerned
+     about machines whose bytes aren't eight bits long, or who don't
+     have byte-addressed memory.  Various places pass this to memcpy
+     and such, meaning it must be in units of host bytes.  Various
+     other places expect they can calculate addresses by adding it
+     and such, meaning it must be in units of target bytes.  For
+     some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8
+     and TARGET_CHAR_BIT will be (say) 32, this is a problem.
+
+     One fix would be to make this field in bits (requiring that it
+     always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) ---
+     the other choice would be to make it consistently in units of
+     HOST_CHAR_BIT.  However, this would still fail to address
+     machines based on a ternary or decimal representation.  */
+  
+  unsigned length;
 
-struct type
-  {
-
-    /* Code for kind of type */
-
-    enum type_code code;
-
-    /* Name of this type, or NULL if none.
-
-       This is used for printing only, except by poorly designed C++ code.
-       For looking up a name, look for a symbol in the VAR_NAMESPACE.  */
-
-    char *name;
-
-    /* Tag name for this type, or NULL if none.  This means that the
-       name of the type consists of a keyword followed by the tag name.
-       Which keyword is determined by the type code ("struct" for
-       TYPE_CODE_STRUCT, etc.).  As far as I know C/C++ are the only languages
-       with this feature.
-
-       This is used for printing only, except by poorly designed C++ code.
-       For looking up a name, look for a symbol in the STRUCT_NAMESPACE.
-       One more legitimate use is that if TYPE_FLAG_STUB is set, this is
-       the name to use to look for definitions in other files.  */
-
-    char *tag_name;
-
-    /* Length of storage for a value of this type.  This is what
-       sizeof(type) would return; use it for address arithmetic,
-       memory reads and writes, etc.  This size includes padding.  For
-       example, an i386 extended-precision floating point value really
-       only occupies ten bytes, but most ABI's declare its size to be
-       12 bytes, to preserve alignment.  A `struct type' representing
-       such a floating-point type would have a `length' value of 12,
-       even though the last two bytes are unused.
-
-       There's a bit of a host/target mess here, if you're concerned
-       about machines whose bytes aren't eight bits long, or who don't
-       have byte-addressed memory.  Various places pass this to memcpy
-       and such, meaning it must be in units of host bytes.  Various
-       other places expect they can calculate addresses by adding it
-       and such, meaning it must be in units of target bytes.  For
-       some DSP targets, in which HOST_CHAR_BIT will (presumably) be 8
-       and TARGET_CHAR_BIT will be (say) 32, this is a problem.
-
-       One fix would be to make this field in bits (requiring that it
-       always be a multiple of HOST_CHAR_BIT and TARGET_CHAR_BIT) ---
-       the other choice would be to make it consistently in units of
-       HOST_CHAR_BIT.  However, this would still fail to address
-       machines based on a ternary or decimal representation.  */
-    unsigned length;
-
-    /* FIXME, these should probably be restricted to a Fortran-specific
-       field in some fashion.  */
+  /* FIXME, these should probably be restricted to a Fortran-specific
+     field in some fashion.  */
 #define BOUND_CANNOT_BE_DETERMINED   5
 #define BOUND_BY_REF_ON_STACK        4
 #define BOUND_BY_VALUE_ON_STACK      3
 #define BOUND_BY_REF_IN_REG          2
 #define BOUND_BY_VALUE_IN_REG        1
 #define BOUND_SIMPLE                 0
-    int upper_bound_type;
-    int lower_bound_type;
-
-    /* Every type is now associated with a particular objfile, and the
-       type is allocated on the type_obstack for that objfile.  One problem
-       however, is that there are times when gdb allocates new types while
-       it is not in the process of reading symbols from a particular objfile.
-       Fortunately, these happen when the type being created is a derived
-       type of an existing type, such as in lookup_pointer_type().  So
-       we can just allocate the new type using the same objfile as the
-       existing type, but to do this we need a backpointer to the objfile
-       from the existing type.  Yes this is somewhat ugly, but without
-       major overhaul of the internal type system, it can't be avoided
-       for now. */
-
-    struct objfile *objfile;
-
-    /* For a pointer type, describes the type of object pointed to.
-       For an array type, describes the type of the elements.
-       For a function or method type, describes the type of the return value.
-       For a range type, describes the type of the full range.
-       For a complex type, describes the type of each coordinate.
-       Unused otherwise.  */
-
-    struct type *target_type;
-
-    /* Type that is a pointer to this type.
-       NULL if no such pointer-to type is known yet.
-       The debugger may add the address of such a type
-       if it has to construct one later.  */
-
-    struct type *pointer_type;
-
-    /* C++: also need a reference type.  */
-
-    struct type *reference_type;
-
-    /* C-v variant chain. This points to a type that
-       differs from this one only in a const or volatile
-       attribute (or both). The various c-v variants
-       are chained together in a ring. */
-    struct type *cv_type;
-
-    /* Address-space delimited variant chain.  This points to a type
-       that differs from this one only in an address-space qualifier
-       attribute.  The otherwise-identical address-space delimited 
-       types are chained together in a ring. */
-    struct type *as_type;
-
-    /* Flags about this type.  */
-
-    int flags;
-
-    /* Number of fields described for this type */
-
-    short nfields;
-
-    /* For structure and union types, a description of each field.
-       For set and pascal array types, there is one "field",
-       whose type is the domain type of the set or array.
-       For range types, there are two "fields",
-       the minimum and maximum values (both inclusive).
-       For enum types, each possible value is described by one "field".
-       For a function type, a "field" for each parameter type.
-       For C++ classes, there is one field for each base class (if it is
-       a derived class) plus one field for each class data member.  Member
-       functions are recorded elsewhere.
-
-       Using a pointer to a separate array of fields
-       allows all types to have the same size, which is useful
-       because we can allocate the space for a type before
-       we know what to put in it.  */
-
-    struct field
-      {
-	union field_location
-	  {
-	    /* Position of this field, counting in bits from start of
-	       containing structure.
-	       For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
-	       For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
-	       For a range bound or enum value, this is the value itself. */
-
-	    int bitpos;
-
-	    /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr
-	       is the location (in the target) of the static field.
-	       Otherwise, physname is the mangled label of the static field. */
-
-	    CORE_ADDR physaddr;
-	    char *physname;
+  int upper_bound_type;
+  int lower_bound_type;
 
-	    /* For a function type, this is 1 if the argument is marked
-	       artificial.  Artificial arguments should not be shown to the
-	       user.  */
-	    int artificial;
-	  }
-	loc;
+  /* Every type is now associated with a particular objfile, and the
+     type is allocated on the type_obstack for that objfile.  One problem
+     however, is that there are times when gdb allocates new types while
+     it is not in the process of reading symbols from a particular objfile.
+     Fortunately, these happen when the type being created is a derived
+     type of an existing type, such as in lookup_pointer_type().  So
+     we can just allocate the new type using the same objfile as the
+     existing type, but to do this we need a backpointer to the objfile
+     from the existing type.  Yes this is somewhat ugly, but without
+     major overhaul of the internal type system, it can't be avoided
+     for now. */
+
+  struct objfile *objfile;
+
+  /* For a pointer type, describes the type of object pointed to.
+     For an array type, describes the type of the elements.
+     For a function or method type, describes the type of the return value.
+     For a range type, describes the type of the full range.
+     For a complex type, describes the type of each coordinate.
+     Unused otherwise.  */
+
+  struct type *target_type;
+
+  /* Flags about this type.  */
+
+  int flags;
+
+  /* Number of fields described for this type */
+
+  short nfields;
+
+  /* For structure and union types, a description of each field.
+     For set and pascal array types, there is one "field",
+     whose type is the domain type of the set or array.
+     For range types, there are two "fields",
+     the minimum and maximum values (both inclusive).
+     For enum types, each possible value is described by one "field".
+     For a function type, a "field" for each parameter type.
+     For C++ classes, there is one field for each base class (if it is
+     a derived class) plus one field for each class data member.  Member
+     functions are recorded elsewhere.
+
+     Using a pointer to a separate array of fields
+     allows all types to have the same size, which is useful
+     because we can allocate the space for a type before
+     we know what to put in it.  */
 
-	/* Size of this field, in bits, or zero if not packed.
-	   For an unpacked field, the field's type's length
-	   says how many bytes the field occupies.
-	   A value of -1 or -2 indicates a static field;  -1 means the location
-	   is specified by the label loc.physname;  -2 means that loc.physaddr
-	   specifies the actual address. */
-
-	int bitsize;
-
-	/* In a struct or union type, type of this field.
-	   In a function type, type of this argument.
-	   In an array type, the domain-type of the array.  */
-
-	struct type *type;
-
-	/* Name of field, value or argument.
-	   NULL for range bounds and array domains.  */
-
-	char *name;
-
-      }
-     *fields;
-
-    /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
-       is the base class which defined the virtual function table pointer.  
+  struct field
+  {
+    union field_location
+    {
+      /* Position of this field, counting in bits from start of
+	 containing structure.
+	 For BITS_BIG_ENDIAN=1 targets, it is the bit offset to the MSB.
+	 For BITS_BIG_ENDIAN=0 targets, it is the bit offset to the LSB.
+	 For a range bound or enum value, this is the value itself. */
+
+      int bitpos;
+
+      /* For a static field, if TYPE_FIELD_STATIC_HAS_ADDR then physaddr
+	 is the location (in the target) of the static field.
+	 Otherwise, physname is the mangled label of the static field. */
+
+      CORE_ADDR physaddr;
+      char *physname;
+
+      /* For a function type, this is 1 if the argument is marked
+	 artificial.  Artificial arguments should not be shown to the
+	 user.  */
+      int artificial;
+    }
+    loc;
+
+    /* Size of this field, in bits, or zero if not packed.
+       For an unpacked field, the field's type's length
+       says how many bytes the field occupies.
+       A value of -1 or -2 indicates a static field;  -1 means the location
+       is specified by the label loc.physname;  -2 means that loc.physaddr
+       specifies the actual address. */
+
+    int bitsize;
+
+    /* In a struct or union type, type of this field.
+       In a function type, type of this argument.
+       In an array type, the domain-type of the array.  */
 
-       For types that are pointer to member types (TYPE_CODE_MEMBER),
-       VPTR_BASETYPE is the type that this pointer is a member of.
+    struct type *type;
 
-       For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate
-       type that contains the method.
+    /* Name of field, value or argument.
+       NULL for range bounds and array domains.  */
 
-       Unused otherwise.  */
+    char *name;
 
-    struct type *vptr_basetype;
+  } *fields;
 
-    /* Field number of the virtual function table pointer in
-       VPTR_BASETYPE.  If -1, we were unable to find the virtual
-       function table pointer in initial symbol reading, and
-       fill_in_vptr_fieldno should be called to find it if possible.
+  /* For types with virtual functions (TYPE_CODE_STRUCT), VPTR_BASETYPE
+     is the base class which defined the virtual function table pointer.  
 
-       Unused if this type does not have virtual functions.  */
+     For types that are pointer to member types (TYPE_CODE_MEMBER),
+     VPTR_BASETYPE is the type that this pointer is a member of.
 
-    int vptr_fieldno;
+     For method types (TYPE_CODE_METHOD), VPTR_BASETYPE is the aggregate
+     type that contains the method.
 
-    /* Slot to point to additional language-specific fields of this type.  */
+     Unused otherwise.  */
 
-    union type_specific
-      {
+  struct type *vptr_basetype;
 
-	/* ARG_TYPES is for TYPE_CODE_METHOD.
-	   Contains the type of each argument, ending with a void type
-	   after the last argument for normal member functions or a NULL
-	   pointer after the last argument for functions with variable
-	   arguments.  */
+  /* Field number of the virtual function table pointer in
+     VPTR_BASETYPE.  If -1, we were unable to find the virtual
+     function table pointer in initial symbol reading, and
+     fill_in_vptr_fieldno should be called to find it if possible.
 
-	struct type **arg_types;
+     Unused if this type does not have virtual functions.  */
 
-	/* CPLUS_STUFF is for TYPE_CODE_STRUCT.  It is initialized to point to
-	   cplus_struct_default, a default static instance of a struct
-	   cplus_struct_type. */
+  int vptr_fieldno;
 
-	struct cplus_struct_type *cplus_stuff;
+  /* Slot to point to additional language-specific fields of this type.  */
 
-	/* FLOATFORMAT is for TYPE_CODE_FLT.  It is a pointer to the
-           floatformat object that describes the floating-point value
-           that resides within the type.  */
+  union type_specific
+  {
+    /* ARG_TYPES is for TYPE_CODE_METHOD.
+       Contains the type of each argument, ending with a void type
+       after the last argument for normal member functions or a NULL
+       pointer after the last argument for functions with variable
+       arguments.  */
+
+    struct type **arg_types;
+
+    /* CPLUS_STUFF is for TYPE_CODE_STRUCT.  It is initialized to point to
+       cplus_struct_default, a default static instance of a struct
+       cplus_struct_type. */
+
+    struct cplus_struct_type *cplus_stuff;
+
+    /* FLOATFORMAT is for TYPE_CODE_FLT.  It is a pointer to the
+       floatformat object that describes the floating-point value
+       that resides within the type.  */
+
+    const struct floatformat *floatformat;
+  } type_specific;
+};
 
-	const struct floatformat *floatformat;
-      }
-    type_specific;
-  };
+/* A ``struct type'' describes a particular instance of a type, with
+   some particular qualification.  */
+struct type
+{
+  /* Type that is a pointer to this type.
+     NULL if no such pointer-to type is known yet.
+     The debugger may add the address of such a type
+     if it has to construct one later.  */
+
+  struct type *pointer_type;
+
+  /* C++: also need a reference type.  */
+
+  struct type *reference_type;
+
+  /* Variant chain.  This points to a type that differs from this one only
+     in qualifiers.  Currently, the possible qualifiers are const, volatile,
+     code-space, and data-space.  The variants are linked in a circular
+     ring and share CORE_TYPE.  */
+  struct type *chain;
+
+  /* Flags specific to this instance of the type, indicating where
+     on the ring we are.  */
+  int instance_flags;
+
+  /* Core type, shared by a group of qualified types.  */
+  struct type_core *core_type;
+};
 
 #define	NULL_TYPE ((struct type *) 0)
 
@@ -738,25 +740,26 @@ extern void allocate_cplus_struct_type (
 #define HAVE_CPLUS_STRUCT(type) \
   (TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default)
 
-#define TYPE_NAME(thistype) (thistype)->name
-#define TYPE_TAG_NAME(type) ((type)->tag_name)
-#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type
+#define TYPE_INSTANCE_FLAGS(thistype) (thistype)->instance_flags
+#define TYPE_CORE_TYPE(thistype) (thistype)->core_type
+#define TYPE_NAME(thistype) TYPE_CORE_TYPE(thistype)->name
+#define TYPE_TAG_NAME(type) TYPE_CORE_TYPE(type)->tag_name
+#define TYPE_TARGET_TYPE(thistype) TYPE_CORE_TYPE(thistype)->target_type
 #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
 #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
-#define TYPE_CV_TYPE(thistype) (thistype)->cv_type
-#define TYPE_AS_TYPE(thistype) (thistype)->as_type
+#define TYPE_CHAIN(thistype) (thistype)->chain
 /* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
    But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
    so you only have to call check_typedef once.  Since allocate_value
    calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe.  */
-#define TYPE_LENGTH(thistype) (thistype)->length
-#define TYPE_OBJFILE(thistype) (thistype)->objfile
-#define TYPE_FLAGS(thistype) (thistype)->flags
+#define TYPE_LENGTH(thistype) TYPE_CORE_TYPE(thistype)->length
+#define TYPE_OBJFILE(thistype) TYPE_CORE_TYPE(thistype)->objfile
+#define TYPE_FLAGS(thistype) TYPE_CORE_TYPE(thistype)->flags
 /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
    type, you need to do TYPE_CODE (check_type (this_type)). */
-#define TYPE_CODE(thistype) (thistype)->code
-#define TYPE_NFIELDS(thistype) (thistype)->nfields
-#define TYPE_FIELDS(thistype) (thistype)->fields
+#define TYPE_CODE(thistype) TYPE_CORE_TYPE(thistype)->code
+#define TYPE_NFIELDS(thistype) TYPE_CORE_TYPE(thistype)->nfields
+#define TYPE_FIELDS(thistype) TYPE_CORE_TYPE(thistype)->fields
 #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args
 #define TYPE_INSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->instantiations
 
@@ -766,8 +769,10 @@ extern void allocate_cplus_struct_type (
 
 /* Moto-specific stuff for FORTRAN arrays */
 
-#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) (thistype)->upper_bound_type
-#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) (thistype)->lower_bound_type
+#define TYPE_ARRAY_UPPER_BOUND_TYPE(thistype) \
+	TYPE_CORE_TYPE(thistype)->upper_bound_type
+#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) \
+	TYPE_CORE_TYPE(thistype)->lower_bound_type
 
 #define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
    (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),1))
@@ -777,22 +782,22 @@ extern void allocate_cplus_struct_type (
 
 /* C++ */
 
-#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype
-#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype
-#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno
+#define TYPE_VPTR_BASETYPE(thistype) TYPE_CORE_TYPE(thistype)->vptr_basetype
+#define TYPE_DOMAIN_TYPE(thistype) TYPE_CORE_TYPE(thistype)->vptr_basetype
+#define TYPE_VPTR_FIELDNO(thistype) TYPE_CORE_TYPE(thistype)->vptr_fieldno
 #define TYPE_FN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fields
 #define TYPE_NFN_FIELDS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields
 #define TYPE_NFN_FIELDS_TOTAL(thistype) TYPE_CPLUS_SPECIFIC(thistype)->nfn_fields_total
 #define TYPE_NTEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ntemplate_args
 #define TYPE_NINSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ninstantiations
 #define TYPE_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type
-#define	TYPE_TYPE_SPECIFIC(thistype) (thistype)->type_specific
-#define TYPE_ARG_TYPES(thistype) (thistype)->type_specific.arg_types
-#define TYPE_CPLUS_SPECIFIC(thistype) (thistype)->type_specific.cplus_stuff
-#define TYPE_FLOATFORMAT(thistype) (thistype)->type_specific.floatformat
-#define TYPE_BASECLASS(thistype,index) (thistype)->fields[index].type
+#define	TYPE_TYPE_SPECIFIC(thistype) TYPE_CORE_TYPE(thistype)->type_specific
+#define TYPE_ARG_TYPES(thistype) TYPE_CORE_TYPE(thistype)->type_specific.arg_types
+#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_CORE_TYPE(thistype)->type_specific.cplus_stuff
+#define TYPE_FLOATFORMAT(thistype) TYPE_CORE_TYPE(thistype)->type_specific.floatformat
+#define TYPE_BASECLASS(thistype,index) TYPE_CORE_TYPE(thistype)->fields[index].type
 #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
-#define TYPE_BASECLASS_NAME(thistype,index) (thistype)->fields[index].name
+#define TYPE_BASECLASS_NAME(thistype,index) TYPE_CORE_TYPE(thistype)->fields[index].name
 #define TYPE_BASECLASS_BITPOS(thistype,index) TYPE_FIELD_BITPOS(thistype,index)
 #define BASETYPE_VIA_PUBLIC(thistype, index) \
   ((!TYPE_FIELD_PRIVATE(thistype, index)) && (!TYPE_FIELD_PROTECTED(thistype, index)))
@@ -812,7 +817,7 @@ extern void allocate_cplus_struct_type (
   ((thisfld).bitsize = -1, FIELD_PHYSNAME(thisfld) = (name))
 #define SET_FIELD_PHYSADDR(thisfld, name) \
   ((thisfld).bitsize = -2, FIELD_PHYSADDR(thisfld) = (name))
-#define TYPE_FIELD(thistype, n) (thistype)->fields[n]
+#define TYPE_FIELD(thistype, n) TYPE_CORE_TYPE(thistype)->fields[n]
 #define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n))
 #define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n))
 #define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS(TYPE_FIELD(thistype,n))
@@ -851,8 +856,8 @@ extern void allocate_cplus_struct_type (
   (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits == NULL ? 0 \
     : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)))
 
-#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitsize < 0)
-#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) ((thistype)->fields[n].bitsize == -2)
+#define TYPE_FIELD_STATIC(thistype, n) (TYPE_CORE_TYPE (thistype)->fields[n].bitsize < 0)
+#define TYPE_FIELD_STATIC_HAS_ADDR(thistype, n) (TYPE_CORE_TYPE (thistype)->fields[n].bitsize == -2)
 #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_PHYSNAME(TYPE_FIELD(thistype, n))
 #define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_PHYSADDR(TYPE_FIELD(thistype, n))
 
@@ -1076,8 +1081,6 @@ extern struct type *lookup_reference_typ
 extern struct type *make_reference_type (struct type *, struct type **);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
-
-extern void finish_cv_type (struct type *);
 
 extern void replace_type (struct type *, struct type *);
 
diff -x *.orig -pur gdb.inter/hpread.c gdb.real/hpread.c
--- gdb.inter/hpread.c	Sun May 12 20:34:14 2002
+++ gdb.real/hpread.c	Sun May 12 20:01:55 2002
@@ -4403,9 +4403,6 @@ hpread_read_struct_type (dnttpointer hp_
   /* Clear the global saying what template we are in the middle of processing */
   current_template = NULL;
 
-  /* Fix up any cv-qualified versions of this type.  */
-  finish_cv_type (type);
-
   return type;
 }
 
diff -x *.orig -pur gdb.inter/stabsread.c gdb.real/stabsread.c
--- gdb.inter/stabsread.c	Sun May 12 20:25:57 2002
+++ gdb.real/stabsread.c	Sun May 12 19:34:50 2002
@@ -4302,8 +4302,6 @@ read_struct_type (char **pp, struct type
       type = error_type (pp, objfile);
     }
 
-  /* Fix up any cv-qualified versions of this type.  */
-  finish_cv_type (type);
   do_cleanups (back_to);
   return (type);
 }


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2002-05-13 13:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-12 20:10 [RFA] Fix gdb/277 by separating types Michael Elizabeth Chastain
2002-05-12 20:16 ` Daniel Jacobowitz
  -- strict thread matches above, loose matches on Subject: below --
2002-05-12 20:13 Michael Elizabeth Chastain
2002-05-12 19:19 Michael Elizabeth Chastain
2002-05-12 19:38 ` Daniel Jacobowitz
2002-05-12 17:53 Daniel Jacobowitz
2002-05-12 22:22 ` Eli Zaretskii
2002-05-13  6:30   ` Andrew Cagney
2002-05-13  6:41   ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox