This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Beginnings of g++ RTTI support
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: Beginnings of g++ RTTI support
- From: dan at cgsoftware dot com (Daniel Berlin+list.gdb-patches)
- Date: 23 Mar 2000 21:04:05 -0500
- Reply-To: dan at cgsoftware dot com
I won't be committing this patch, or any of it's successors, until
after the 5.0 branch is cut, because i think it's going to be too
complex to get right before then.
On that note, feel free to play around with it.
I know it doesn't work perfectly, but it does work.
Make sure you use "set print object on", or you don't get derived
object printing.
I already have some ideas for changes that *must* be done, and know
what doesn't work but feel free to mention anything to me privately,
and i'll happily tell you if it's supposed to work yet.
I'm taking a time out to try to get g++ exception support going
target-independently.
--Dan
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.6
diff -c -3 -p -r1.6 valops.c
*** valops.c 2000/03/13 10:01:23 1.6
--- valops.c 2000/03/24 01:57:53
*************** value_rtti_type (v, full, top, using_enc
*** 3241,3247 ****
/* RTTI works only or class objects */
if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
return NULL;
!
/* If neither the declared type nor the enclosing type of the
* value structure has a HP ANSI C++ style virtual table,
* we can't do anything. */
--- 3241,3248 ----
/* RTTI works only or class objects */
if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
return NULL;
! if (TYPE_HAS_VTABLE(known_type))
! {
/* If neither the declared type nor the enclosing type of the
* value structure has a HP ANSI C++ style virtual table,
* we can't do anything. */
*************** value_rtti_type (v, full, top, using_enc
*** 3258,3264 ****
if (using_enclosing && using_enc)
*using_enc = 1;
-
/* First get the virtual table address */
coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v))
+ VALUE_OFFSET (v)
--- 3259,3264 ----
*************** value_rtti_type (v, full, top, using_enc
*** 3299,3309 ****
if (!rtti_type)
error ("Could not find run-time type: invalid type name %s in typeinfo??", rtti_type_name);
CHECK_TYPEDEF (rtti_type);
!
! #if 0 /* debugging */
printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), TYPE_TAG_NAME (rtti_type), full ? *full : -1);
#endif
-
/* Check whether we have the entire object */
if (full /* Non-null pointer passed */
--- 3299,3307 ----
if (!rtti_type)
error ("Could not find run-time type: invalid type name %s in typeinfo??", rtti_type_name);
CHECK_TYPEDEF (rtti_type);
! #if 0
printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), TYPE_TAG_NAME (rtti_type), full ? *full : -1);
#endif
/* Check whether we have the entire object */
if (full /* Non-null pointer passed */
*************** value_rtti_type (v, full, top, using_enc
*** 3321,3328 ****
TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
*full = 1;
!
! return rtti_type;
}
/* Given a pointer value V, find the real (RTTI) type
--- 3319,3372 ----
TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
*full = 1;
! }
! else
! {
! int i=0;
! CORE_ADDR vtbl;
! struct minimal_symbol *minsym;
! struct symbol *sym;
! char *demangled_name;
! struct type *btype;
! /* If the type has no vptr fieldno, try to get it filled in */
! if (TYPE_VPTR_FIELDNO(known_type) < 0)
! fill_in_vptr_fieldno(known_type);
!
! /* If we still can't find one, give up */
! if (TYPE_VPTR_FIELDNO(known_type) < 0)
! return NULL;
!
! btype = TYPE_VPTR_BASETYPE (known_type);
! CHECK_TYPEDEF (btype);
! if (btype != known_type)
! v = value_cast (btype, v);
! /* We can't use value_ind here, because it would want to use RTTI.
! * Besides, we don't care about the type, just the actual pointer */
! vtbl=(value_as_pointer(value_field(v,TYPE_VPTR_FIELDNO(known_type))));
!
! /* Try to find a symbol that is the vtable */
! minsym=lookup_minimal_symbol_by_pc(vtbl);
! if (minsym==NULL || (demangled_name=SYMBOL_NAME(minsym))==NULL || !VTBL_PREFIX_P(demangled_name))
! {
! return NULL;
! }
! /* Skip the _vt$ part */
! demangled_name += 3;
! /* Skip the numbers */
! while (!isalpha(*demangled_name))
! demangled_name++;
! /* Lookup the type for the name */
! rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
! *full=1;
! if (TYPE_N_BASECLASSES(rtti_type) > 1)
! {
! *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
! if (*top >0)
! if (TYPE_LENGTH(rtti_type) != TYPE_LENGTH(known_type))
! *full=0;
! }
! }
! return rtti_type;
}
/* Given a pointer value V, find the real (RTTI) type
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 values.c
*** values.c 2000/03/21 01:27:34 1.2
--- values.c 2000/03/24 01:57:55
*************** value_headof (in_arg, btype, dtype)
*** 1124,1133 ****
arg = in_arg;
if (btype != dtype)
arg = value_cast (lookup_pointer_type (btype), arg);
vtbl = value_ind (value_field (value_ind (arg), TYPE_VPTR_FIELDNO (btype)));
/* Check that VTBL looks like it points to a virtual function table. */
! msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl));
if (msymbol == NULL
|| (demangled_name = SYMBOL_NAME (msymbol)) == NULL
|| !VTBL_PREFIX_P (demangled_name))
--- 1124,1144 ----
arg = in_arg;
if (btype != dtype)
arg = value_cast (lookup_pointer_type (btype), arg);
+ if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_REF)
+ {
+ /*
+ * Copy the value, but change the type from (T&) to (T*).
+ * We keep the same location information, which is efficient,
+ * and allows &(&X) to get the location containing the reference.
+ */
+ arg = value_copy (arg);
+ VALUE_TYPE (arg) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg)));
+ }
+
vtbl = value_ind (value_field (value_ind (arg), TYPE_VPTR_FIELDNO (btype)));
/* Check that VTBL looks like it points to a virtual function table. */
! msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS(vtbl));
if (msymbol == NULL
|| (demangled_name = SYMBOL_NAME (msymbol)) == NULL
|| !VTBL_PREFIX_P (demangled_name))
*************** value_headof (in_arg, btype, dtype)
*** 1141,1149 ****
VALUE_TYPE (in_arg) = error_type;
return in_arg;
}
!
/* Now search through the virtual function table. */
! entry = value_ind (vtbl);
nelems = longest_to_int (value_as_long (value_field (entry, 2)));
for (i = 1; i <= nelems; i++)
{
--- 1152,1163 ----
VALUE_TYPE (in_arg) = error_type;
return in_arg;
}
! /* djb - 2000-3-23
! This code plain doesn't work anymore.
! */
! #if 0
/* Now search through the virtual function table. */
! entry = value_ind(vtbl);
nelems = longest_to_int (value_as_long (value_field (entry, 2)));
for (i = 1; i <= nelems; i++)
{
*************** value_headof (in_arg, btype, dtype)
*** 1161,1166 ****
--- 1175,1182 ----
best_entry = entry;
}
}
+ #endif
+
/* Move the pointer according to BEST_ENTRY's offset, and figure
out what type we should return as the new pointer. */
if (best_entry == 0)
*************** value_headof (in_arg, btype, dtype)
*** 1169,1175 ****
* But we leave it in for future use, when we will hopefully
* have optimizes the vtable to use thunks instead of offsets. */
/* Use the name of vtable itself to extract a base type. */
! demangled_name += 4; /* Skip _vt$ prefix. */
}
else
{
--- 1185,1193 ----
* But we leave it in for future use, when we will hopefully
* have optimizes the vtable to use thunks instead of offsets. */
/* Use the name of vtable itself to extract a base type. */
! demangled_name += 3; /* Skip _vt$ prefix. */
! while (!isalpha(*demangled_name))
! demangled_name++;
}
else
{