[rfa/c++] cp_lookup_rtti_type, take 2

Michael Elizabeth Chastain
2003-12-01T21:40:40Z

Here is version #2 of cp_lookup_rtti_type.

Changes since version #1:

. changed name from lookup_rtti_type to cp_lookup_rtti_type.
. cp_lookup_rtti_type lives in cp-support.h/cp-support.c
instead of symtab.h/gdbtypes.c.
. tweaked one of the warning messages
. old: "RTTI symbol for class '%s' is not a typedef"
. new: "RTTI symbol for class '%s' is not a type"

It's still the same basic plan where cp_lookup_rtti_type is a chunk
of code that used to be in gnuv3_rtti_type, with more sanity checking,
and now gnuv2_rtti_type uses it too, so now gnuv2_rtti_type works.

And it still needs this follow-up work:

. The calls to lookup_rtti_type need a proper "block" parameter.
The old code needed this too; I haven't regressed anything.
I put FIXME notes in for this.

. hpacc_value_rtti_type has the same buggy code. I can't change the
code because I can't test it, but I can put in a big FIXME into it.
(I wonder if anyone still uses HP aCC with gdb).

. Nested types give a warning and don't work.
It would be nice to make them work.

. Types with virtual bases appear to work with v3, but give a warning
and don't work with v2. "don't work" probably means that they fall back
to the static type rather than the dynamic type, which probably
usually works. Again, this is also a property of the current code.

. rtti.exp needs to recognize a modified message (see below).

The PR's are:

http://sources.redhat.com/gdb/bugs/1465
http://sources.redhat.com/gdb/bugs/1377

These bugs are regressions versus gdb 6.0 so they are high priority.

Testing: I tested with gcc v2 and v3, dwarf-2 and stabs+.
Nothing got worse. gdb.cp/class2.exp has a specific test for this,
which now passes. Some tests in gdb.cp/rtti.exp changed their
kfail number so rtti.exp will need an upgrade.

Some tests in virtfunc.exp that broke after the 2003-09-11 namespace
commit started working again:

http://sources.redhat.com/gdb/bugs/1377
[regression] g++ 2.95.3, dwarf-2, hand function call: SIGSEGV

Since I'm not in symtab.h/gdbtypes.c any more, I don't think I need
approval from a symtab maintainer, just a C++ maintainer. Lart me if
I'm wrong.

Okay to commit?

Michael C

2003-12-01 Michael Chastain <mec.gnu@mindspring.com>

Partial fix for PR c++/1465.
Fix for PR c++/1377.
* cp-support.h (cp_lookup_rtti_type): New function.
* cp-support.c (cp_lookup_rtti_type): New function.
* gnu-v2-abi.c: Update copyright years.
(gnuv2_rtti_type): Call cp_lookup_rtti_type.
* gnu-v3-abi.c: Update copyright years.
(gnuv3_rtti_type): Call cp_lookup_rtti_type.

Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 cp-support.h
*** cp-support.h 25 Sep 2003 16:39:38 -0000 1.9
--- cp-support.h 1 Dec 2003 20:03:35 -0000
*************** struct symbol;
*** 34,39 ****
--- 34,40 ----
struct obstack;
struct block;
struct objfile;
+ struct type;

/* This struct is designed to store data from using directives. It
says that names from namespace INNER should be visible within
*************** extern unsigned int cp_find_first_compon
*** 60,65 ****
--- 61,69 ----
extern unsigned int cp_entire_prefix_len (const char *name);

extern struct symbol **make_symbol_overload_list (struct symbol *);
+
+ extern struct type *cp_lookup_rtti_type (const char *name,
+ struct block *block);

/* Functions/variables from cp-namespace.c. */

Index: cp-support.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 cp-support.c
*** cp-support.c 14 Sep 2003 16:32:12 -0000 1.9
--- cp-support.c 1 Dec 2003 20:03:36 -0000
***************
*** 33,38 ****
--- 33,39 ----
#include "symtab.h"
#include "block.h"
#include "complaints.h"
+ #include "gdbtypes.h"

/* Functions related to demangled name parsing. */

*************** make_symbol_overload_list (struct symbol
*** 582,587 ****
--- 583,630 ----
return (sym_return_val);
}

+ /* Lookup the rtti type for a class name. */
+
+ struct type *
+ cp_lookup_rtti_type (const char *name, struct block *block)
+ {
+ struct symbol * rtti_sym;
+ struct type * rtti_type;
+
+ rtti_sym = lookup_symbol (name, block, STRUCT_DOMAIN, NULL, NULL);
+
+ if (rtti_sym == NULL)
+ {
+ warning ("RTTI symbol not found for class '%s'", name);
+ return NULL;
+ }
+
+ if (SYMBOL_CLASS (rtti_sym) != LOC_TYPEDEF)
+ {
+ warning ("RTTI symbol for class '%s' is not a type", name);
+ return NULL;
+ }
+
+ rtti_type = SYMBOL_TYPE (rtti_sym);
+
+ switch (TYPE_CODE (rtti_type))
+ {
+ case TYPE_CODE_CLASS:
+ break;
+ case TYPE_CODE_NAMESPACE:
+ /* chastain/2003-11-26: the symbol tables often contain fake
+ symbols for namespaces with the same name as the struct.
+ This warning is an indication of a bug in the lookup order
+ or a bug in the way that the symbol tables are populated. */
+ warning ("RTTI symbol for class '%s' is a namespace", name);
+ return NULL;
+ default:
+ warning ("RTTI symbol for class '%s' has bad type", name);
+ return NULL;
+ }
+
+ return rtti_type;
+ }

/* Don't allow just "maintenance cplus". */

Index: gnu-v2-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v2-abi.c,v
retrieving revision 1.13
diff -c -3 -p -r1.13 gnu-v2-abi.c
*** gnu-v2-abi.c 16 Sep 2003 18:56:35 -0000 1.13
--- gnu-v2-abi.c 1 Dec 2003 20:03:37 -0000
***************
*** 1,6 ****
/* Abstraction of GNU v2 abi.

! Copyright 2001, 2003 Free Software Foundation, Inc.

Contributed by Daniel Berlin <dberlin@redhat.com>

--- 1,6 ----
/* Abstraction of GNU v2 abi.

! Copyright 2001, 2002, 2003 Free Software Foundation, Inc.

Contributed by Daniel Berlin <dberlin@redhat.com>

***************
*** 30,35 ****
--- 30,36 ----
#include "value.h"
#include "demangle.h"
#include "cp-abi.h"
+ #include "cp-support.h"

#include <ctype.h>

*************** gnuv2_value_rtti_type (struct value *v,
*** 259,267 ****
*(strchr(demangled_name,' '))=0;

/* Lookup the type for the name */
! rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
!
! if (rtti_type==NULL)
return NULL;

if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1)
--- 260,268 ----
*(strchr(demangled_name,' '))=0;

/* Lookup the type for the name */
! /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */
! rtti_type = cp_lookup_rtti_type (demangled_name, NULL);
! if (rtti_type == NULL)
return NULL;

if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1)
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 gnu-v3-abi.c
*** gnu-v3-abi.c 22 Aug 2003 20:45:55 -0000 1.19
--- gnu-v3-abi.c 1 Dec 2003 20:03:37 -0000
***************
*** 1,7 ****
/* Abstraction of GNU v3 abi.
Contributed by Jim Blandy <jimb@redhat.com>

! Copyright 2001, 2002 Free Software Foundation, Inc.

This file is part of GDB.

--- 1,7 ----
/* Abstraction of GNU v3 abi.
Contributed by Jim Blandy <jimb@redhat.com>

! Copyright 2001, 2002, 2003 Free Software Foundation, Inc.

This file is part of GDB.

***************
*** 23,28 ****
--- 23,29 ----
#include "defs.h"
#include "value.h"
#include "cp-abi.h"
+ #include "cp-support.h"
#include "demangle.h"
#include "gdb_assert.h"
#include "gdb_string.h"
*************** gnuv3_rtti_type (struct value *value,
*** 196,202 ****
struct minimal_symbol *vtable_symbol;
const char *vtable_symbol_name;
const char *class_name;
- struct symbol *class_symbol;
struct type *run_time_type;
struct type *base_type;
LONGEST offset_to_top;
--- 197,202 ----
*************** gnuv3_rtti_type (struct value *value,
*** 255,280 ****
class_name = vtable_symbol_name + 11;

/* Try to look up the class name as a type name. */
! class_symbol = lookup_symbol (class_name, 0, STRUCT_DOMAIN, 0, 0);
! if (! class_symbol)
! {
! warning ("can't find class named `%s', as given by C++ RTTI", class_name);
! return NULL;
! }
!
! /* Make sure the type symbol is sane. (An earlier version of this
! code would find constructor functions, who have the same name as
! the class.) */
! if (SYMBOL_CLASS (class_symbol) != LOC_TYPEDEF
! || TYPE_CODE (SYMBOL_TYPE (class_symbol)) != TYPE_CODE_CLASS)
! {
! warning ("C++ RTTI gives a class name of `%s', but that isn't a type name",
! class_name);
! return NULL;
! }
!
! /* This is the object's run-time type! */
! run_time_type = SYMBOL_TYPE (class_symbol);

/* Get the offset from VALUE to the top of the complete object.
NOTE: this is the reverse of the meaning of *TOP_P. */
--- 255,264 ----
class_name = vtable_symbol_name + 11;

/* Try to look up the class name as a type name. */
! /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */
! run_time_type = cp_lookup_rtti_type (class_name, NULL);
! if (run_time_type == NULL)
! return NULL;

/* Get the offset from VALUE to the top of the complete object.
NOTE: this is the reverse of the meaning of *TOP_P. */