This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Beginnings of g++ RTTI support


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
      {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]