diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b61514e5305..da73f777b0c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2003-12-04 Michael Chastain + + 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. + 2003-12-04 J. Brobecker * stabsread.c (read_type): Save a reference to types that are defined diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 9e6d44b119c..9b447fcadf3 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -33,6 +33,7 @@ #include "symtab.h" #include "block.h" #include "complaints.h" +#include "gdbtypes.h" /* Functions related to demangled name parsing. */ @@ -582,6 +583,48 @@ make_symbol_overload_list (struct symbol *fsym) 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". */ diff --git a/gdb/cp-support.h b/gdb/cp-support.h index d8cb5252d55..c08efe1539c 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -34,6 +34,7 @@ struct symbol; 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 @@ -61,6 +62,9 @@ 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. */ extern unsigned char processing_has_namespace_info; diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c index 2234d3bf8ef..8cb2a7e4494 100644 --- a/gdb/gnu-v2-abi.c +++ b/gdb/gnu-v2-abi.c @@ -1,6 +1,6 @@ /* Abstraction of GNU v2 abi. - Copyright 2001, 2003 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Daniel Berlin @@ -30,6 +30,7 @@ #include "value.h" #include "demangle.h" #include "cp-abi.h" +#include "cp-support.h" #include @@ -259,9 +260,9 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) *(strchr(demangled_name,' '))=0; /* Lookup the type for the name */ - rtti_type=lookup_typename(demangled_name, (struct block *)0,1); - - if (rtti_type==NULL) + /* 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) diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index b18e644796e..0fbdd6eefbf 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -1,7 +1,7 @@ /* Abstraction of GNU v3 abi. Contributed by Jim Blandy - Copyright 2001, 2002 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -23,6 +23,7 @@ #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" @@ -196,7 +197,6 @@ gnuv3_rtti_type (struct value *value, 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; @@ -255,26 +255,10 @@ gnuv3_rtti_type (struct value *value, 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); + /* 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. */