Removed a large number of changes inserted by Per Bothner

for C++ support.  These will go back in when they've been
examined.
This commit is contained in:
John Gilmore 1992-09-10 00:07:06 +00:00
parent 5148923360
commit 2640f7e138
10 changed files with 103 additions and 351 deletions

View File

@ -1,3 +1,9 @@
Wed Sep 9 16:50:22 1992 John Gilmore (gnu@cygnus.com)
Removed a large number of changes inserted by Per Bothner
for C++ support. These will go back in when they've been
examined.
Tue Sep 8 21:05:18 1992 Stu Grossman (grossman at cygnus.com) Tue Sep 8 21:05:18 1992 Stu Grossman (grossman at cygnus.com)
* serial.h: Fix prototye for serial_raw(). * serial.h: Fix prototye for serial_raw().
@ -38,93 +44,16 @@ Fri Sep 4 18:53:57 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
Fri Sep 4 00:34:30 1992 Per Bothner (bothner@rtl.cygnus.com) Fri Sep 4 00:34:30 1992 Per Bothner (bothner@rtl.cygnus.com)
A bunch of changes mostly to improve debugging of C++ programs.
Specifically, nested types are supported, and the calling
of inferiors methods is improved.
* expression.h, c-exp.y: STRUCTOP_PTR and STRUCTOP_STRUCT
expression types now take an extra parameter that is used
for an (optional) type qualifier, as in: EXP.TYPE::NAME.
If there is no qualifier (as in EXP.NAME), the TYPE is NULL.
(Before, there was a cute but not-quote-valid re-write to
EXP.*(&TYPE::NAME .)
* parse.c (length_of_subexp, prefixify_subexp), expprint.c
(print_subexp), eval.c (evaluate_subexp): Handle the extra
operand of STRUCTOP_STRUCT and STRUCTOP_PTR.
* value.h: New macros METHOD_PTR_IS_VIRTUAL,
METHOD_PTR_FROM_VOFFSET, METHOD_PTR_TO_VOFFSET to partially
hide the implementation details of pointer-to-method objects.
How to tell if the pointer points to a virtual method is
still very dependent on the particular compiler, but this
should make it easier to find the places to change.
* eval.c (evaluate_subexp [case OP_FUNCALL]), valprint.c
(val_print [case TYPE_CODE_PTR]): Use the new METHOD_PTR_*
macros, instead of a hard-wired-in code that incorrectly
assumed a no-longerused representation of pointer-to-method
values. And otherwise fix the relevant bit-rotted code.
* valprint.c (type_print_base [case TYPE_CODE_STRUCT]):
If there are both fields and methods, put a space between.
* gdbtypes.h: New macro TYPE_FIELD_NESTED.
* symtab.C, syntab.h: New function find_nested_type()
searches a class recursively for a nested type.
* c-exp.y: Support nested type syntax: TYPE1::TYPE2.
This required some nasty interactions between the lexer
and the parser (surprise, surprise), using the current_type
global variable (see comment above its declaration),
and the new function find_nested_type().
* expprint.c (print_subexp), valprint.c (val_print_fields,
type_print_base [case TYPE_CODE_STRUCT]): Support nested types.
* stabsread.c (read_struct_type): Recognize types fields
nested in classes.
* gdbtypes.c, symtab.h: New functions check_struct,
check_union, and check_enum (factored out from lookup_struct,
lookup_union, lookup_enum).
* c-exp.y: Support 'enum Foo::Bar' syntax as just the same
as 'Foo::Bar' followed by a call to check_enum. Similarly
for struct and union.
* stabsread.c (read_struct_type): Fix bug in handling of
GNU C++ anonymous type (indicated by CPLUS_MARKER followed
by '_'). (It used to prematurely exit the loop reading in
the fields, so it would think it should start reading
methods while still in the fields. This could crash gdb
given a gcc that can emit nested type information.)
* valops.c (search_struct_method): Pass 'this' value by
reference instead of by value. This provides a more
consistent interface through a recursive search where the
"bottom" functions may need to adjust offsets (due to multiple
inheritance).
* valops.c, value.h, values.c: Pass extra parameters to
value_fn_field and value_virtual_fn_field so we can
correctly adjust offset for multiple inheritance.
* eval.c (evaluate_subexp [case OP_FUNCALL]): Simplify
virtual function calls by using value_virtual_fn_field().
* values.c: New function baseclass_offset, derived from
baseclass_addr (which perhaps can be made obsolete?).
It returns an offset rather than an address. This is a
cleaner interface since it doesn't mess around allocating
new values.
* valops.c (search_struct_method): Use baseclass_offset
rather than baseclass_addr.
* symfile.h: Declaration of set_demangling_style() moved * symfile.h: Declaration of set_demangling_style() moved
here from demangle.h (which is now in ../include). here from demangle.h (which is now in ../include).
* i386-xdep.c: Update comment. * i386-xdep.c: Update comment.
* utils.c (strcmp_iw): Add a hack to allow "FOO(ARGS)" to
match "FOO". This allows 'break Foo' to work when Foo is
a mangled C++ function. (See comment before function.)
Thu Sep 3 13:44:46 1992 K. Richard Pixley (rich@sendai.cygnus.com) Thu Sep 3 13:44:46 1992 K. Richard Pixley (rich@sendai.cygnus.com)
* symtab.c (completion_list_add_symbol): restructured to optimize * symtab.c (completion_list_add_symbol): restructured to optimize
for time. First clip names that cannot match. Then clip any for time. First clip names that cannot match. Then clip any
names we've already considered. Drop a redundant strncpy. Drop names we've already considered. Drop a redundant strncpy. Drop
a redundant malloc and associated free for demangled names. a redundant malloc and associated free for demangled names.
Thu Sep 3 09:17:05 1992 Stu Grossman (grossman at cygnus.com) Thu Sep 3 09:17:05 1992 Stu Grossman (grossman at cygnus.com)

View File

@ -42,14 +42,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "symfile.h" #include "symfile.h"
#include "objfiles.h" #include "objfiles.h"
/* If current_type is non-NULL, it is a signal to the lexer that we have
just parsed: 'TYPE ::' and so if an identifier is seen, the lexer must
search for it in TYPE. This lex-time search is needed to parse
C++ nested types, as in: 'TYPE :: NESTED_TYPE', since this must
parse as a type, not a (non-type) identifier. */
static struct type *current_type = NULL;
/* These MUST be included in any grammar file!!!! Please choose unique names! /* These MUST be included in any grammar file!!!! Please choose unique names!
Note that this are a combined list of variables that can be produced Note that this are a combined list of variables that can be produced
by any one of bison, byacc, or yacc. */ by any one of bison, byacc, or yacc. */
@ -128,7 +120,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
%} %}
%type <voidval> exp exp1 type_exp start variable qualified_name %type <voidval> exp exp1 type_exp start variable qualified_name
%type <tval> type typebase typebase_coloncolon qualified_type %type <tval> type typebase
%type <tvec> nonempty_typelist %type <tvec> nonempty_typelist
/* %type <bval> block */ /* %type <bval> block */
@ -152,7 +144,6 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
%token <sval> STRING %token <sval> STRING
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */ %token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
%token <tsym> TYPENAME %token <tsym> TYPENAME
%token <tval> NESTED_TYPE
%type <sval> name %type <sval> name
%type <ssym> name_not_typename %type <ssym> name_not_typename
%type <tsym> typename %type <tsym> typename
@ -274,16 +265,16 @@ exp : SIZEOF exp %prec UNARY
exp : exp ARROW name exp : exp ARROW name
{ write_exp_elt_opcode (STRUCTOP_PTR); { write_exp_elt_opcode (STRUCTOP_PTR);
write_exp_elt_type (NULL);
write_exp_string ($3); write_exp_string ($3);
write_exp_elt_opcode (STRUCTOP_PTR); } write_exp_elt_opcode (STRUCTOP_PTR); }
; ;
exp : exp ARROW typebase_coloncolon name exp : exp ARROW qualified_name
{ write_exp_elt_opcode (STRUCTOP_PTR); { /* exp->type::name becomes exp->*(&type::name) */
write_exp_elt_type ($3); /* Note: this doesn't work if name is a
write_exp_string ($4); static member! FIXME */
write_exp_elt_opcode (STRUCTOP_PTR); } write_exp_elt_opcode (UNOP_ADDR);
write_exp_elt_opcode (STRUCTOP_MPTR); }
; ;
exp : exp ARROW '*' exp exp : exp ARROW '*' exp
{ write_exp_elt_opcode (STRUCTOP_MPTR); } { write_exp_elt_opcode (STRUCTOP_MPTR); }
@ -291,16 +282,16 @@ exp : exp ARROW '*' exp
exp : exp '.' name exp : exp '.' name
{ write_exp_elt_opcode (STRUCTOP_STRUCT); { write_exp_elt_opcode (STRUCTOP_STRUCT);
write_exp_elt_type (NULL);
write_exp_string ($3); write_exp_string ($3);
write_exp_elt_opcode (STRUCTOP_STRUCT); } write_exp_elt_opcode (STRUCTOP_STRUCT); }
; ;
exp : exp '.' typebase_coloncolon name exp : exp '.' qualified_name
{ write_exp_elt_opcode (STRUCTOP_STRUCT); { /* exp.type::name becomes exp.*(&type::name) */
write_exp_elt_type ($3); /* Note: this doesn't work if name is a
write_exp_string ($4); static member! FIXME */
write_exp_elt_opcode (STRUCTOP_STRUCT); } write_exp_elt_opcode (UNOP_ADDR);
write_exp_elt_opcode (STRUCTOP_MEMBER); }
; ;
exp : exp '.' '*' exp exp : exp '.' '*' exp
@ -585,9 +576,7 @@ variable: block COLONCOLON name
write_exp_elt_opcode (OP_VAR_VALUE); } write_exp_elt_opcode (OP_VAR_VALUE); }
; ;
typebase_coloncolon : typebase COLONCOLON { current_type = $1; $$ = $1; } qualified_name: typebase COLONCOLON name
qualified_name: typebase_coloncolon name
{ {
struct type *type = $1; struct type *type = $1;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT if (TYPE_CODE (type) != TYPE_CODE_STRUCT
@ -597,11 +586,10 @@ qualified_name: typebase_coloncolon name
write_exp_elt_opcode (OP_SCOPE); write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type); write_exp_elt_type (type);
write_exp_string ($2); write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE); write_exp_elt_opcode (OP_SCOPE);
current_type = NULL;
} }
| typebase_coloncolon '~' name | typebase COLONCOLON '~' name
{ {
struct type *type = $1; struct type *type = $1;
struct stoken tmp_token; struct stoken tmp_token;
@ -610,20 +598,19 @@ qualified_name: typebase_coloncolon name
error ("`%s' is not defined as an aggregate type.", error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type)); TYPE_NAME (type));
if (strcmp (type_name_no_tag (type), $3.ptr)) if (strcmp (type_name_no_tag (type), $4.ptr))
error ("invalid destructor `%s::~%s'", error ("invalid destructor `%s::~%s'",
type_name_no_tag (type), $3.ptr); type_name_no_tag (type), $4.ptr);
tmp_token.ptr = (char*) alloca ($3.length + 2); tmp_token.ptr = (char*) alloca ($4.length + 2);
tmp_token.length = $3.length + 1; tmp_token.length = $4.length + 1;
tmp_token.ptr[0] = '~'; tmp_token.ptr[0] = '~';
memcpy (tmp_token.ptr+1, $3.ptr, $3.length); memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
tmp_token.ptr[tmp_token.length] = 0; tmp_token.ptr[tmp_token.length] = 0;
write_exp_elt_opcode (OP_SCOPE); write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type); write_exp_elt_type (type);
write_exp_string (tmp_token); write_exp_string (tmp_token);
write_exp_elt_opcode (OP_SCOPE); write_exp_elt_opcode (OP_SCOPE);
current_type = NULL;
} }
; ;
@ -835,15 +822,9 @@ func_mod: '(' ')'
{ free ((PTR)$2); $$ = 0; } { free ((PTR)$2); $$ = 0; }
; ;
qualified_type: typebase_coloncolon NESTED_TYPE
{ $$ = $2; current_type = NULL; }
;
type : ptype type : ptype
| qualified_type | typebase COLONCOLON '*'
| typebase_coloncolon '*' { $$ = lookup_member_type (builtin_type_int, $1); }
{ $$ = lookup_member_type (builtin_type_int, $1);
current_type = NULL; }
| type '(' typebase COLONCOLON '*' ')' | type '(' typebase COLONCOLON '*' ')'
{ $$ = lookup_member_type ($1, $3); } { $$ = lookup_member_type ($1, $3); }
| type '(' typebase COLONCOLON '*' ')' '(' ')' | type '(' typebase COLONCOLON '*' ')' '(' ')'
@ -895,10 +876,6 @@ typebase
| ENUM name | ENUM name
{ $$ = lookup_enum (copy_name ($2), { $$ = lookup_enum (copy_name ($2),
expression_context_block); } expression_context_block); }
| STRUCT qualified_type { $$ = check_struct ($2); }
| CLASS qualified_type { $$ = check_struct ($2); }
| UNION qualified_type { $$ = check_union ($2); }
| ENUM qualified_type { $$ = check_enum ($2); }
| UNSIGNED typename | UNSIGNED typename
{ $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); } { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
| UNSIGNED | UNSIGNED
@ -1442,17 +1419,6 @@ yylex ()
return VARIABLE; return VARIABLE;
} }
if (current_type)
{
struct type *t =
find_nested_type (current_type, copy_name (yylval.sval));
if (t)
{
yylval.tval = t;
return NESTED_TYPE;
}
}
/* Use token-type BLOCKNAME for symbols that happen to be defined as /* Use token-type BLOCKNAME for symbols that happen to be defined as
functions or symtabs. If this is not so, then ... functions or symtabs. If this is not so, then ...
Use token-type TYPENAME for symbols that happen to be defined Use token-type TYPENAME for symbols that happen to be defined

View File

@ -513,15 +513,6 @@ lookup_signed_typename (name)
return lookup_typename (name, (struct block *) NULL, 0); return lookup_typename (name, (struct block *) NULL, 0);
} }
struct type *
check_struct (type)
struct type *type;
{
if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
error ("This context has %s, not a struct or class.", TYPE_NAME (type));
return type;
}
/* Lookup a structure type named "struct NAME", /* Lookup a structure type named "struct NAME",
visible in lexical block BLOCK. */ visible in lexical block BLOCK. */
@ -539,16 +530,11 @@ lookup_struct (name, block)
{ {
error ("No struct type named %s.", name); error ("No struct type named %s.", name);
} }
return check_struct (SYMBOL_TYPE (sym)); if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
} {
error ("This context has class, union or enum %s, not a struct.", name);
struct type * }
check_union (type) return (SYMBOL_TYPE (sym));
struct type *type;
{
if (TYPE_CODE (type) != TYPE_CODE_UNION)
error ("This context has %s, not a union.", TYPE_NAME (type));
return type;
} }
/* Lookup a union type named "union NAME", /* Lookup a union type named "union NAME",
@ -568,16 +554,11 @@ lookup_union (name, block)
{ {
error ("No union type named %s.", name); error ("No union type named %s.", name);
} }
return check_union (SYMBOL_TYPE (sym)); if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
} {
error ("This context has class, struct or enum %s, not a union.", name);
struct type * }
check_enum (type) return (SYMBOL_TYPE (sym));
struct type *type;
{
if (TYPE_CODE (type) != TYPE_CODE_ENUM)
error ("This context has %s, not an enum.", TYPE_NAME (type));
return type;
} }
/* Lookup an enum type named "enum NAME", /* Lookup an enum type named "enum NAME",
@ -596,7 +577,11 @@ lookup_enum (name, block)
{ {
error ("No enum type named %s.", name); error ("No enum type named %s.", name);
} }
return check_enum (SYMBOL_TYPE (sym)); if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
{
error ("This context has class, struct or union %s, not an enum.", name);
}
return (SYMBOL_TYPE (sym));
} }
/* Lookup a template type named "template NAME<TYPE>", /* Lookup a template type named "template NAME<TYPE>",

View File

@ -435,7 +435,6 @@ allocate_cplus_struct_type PARAMS ((struct type *));
B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)) B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1) #define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1)
#define TYPE_FIELD_NESTED(thistype, n) ((thistype)->fields[n].bitpos == -2)
#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize) #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize)
#define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists #define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists

View File

@ -275,9 +275,6 @@ length_of_subexp (expr, endpos)
switch (i) switch (i)
{ {
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
/* C++ */ /* C++ */
case OP_SCOPE: case OP_SCOPE:
oplen = 4 + ((expr->elts[endpos - 2].longconst oplen = 4 + ((expr->elts[endpos - 2].longconst
@ -329,6 +326,9 @@ length_of_subexp (expr, endpos)
args = 1; args = 1;
break; break;
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
case OP_M2_STRING: case OP_M2_STRING:
case OP_STRING: case OP_STRING:
oplen = 3 + ((expr->elts[endpos - 2].longconst oplen = 3 + ((expr->elts[endpos - 2].longconst
@ -393,9 +393,6 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
opcode = inexpr->elts[inend - 1].opcode; opcode = inexpr->elts[inend - 1].opcode;
switch (opcode) switch (opcode)
{ {
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
/* C++ */ /* C++ */
case OP_SCOPE: case OP_SCOPE:
oplen = 4 + ((inexpr->elts[inend - 2].longconst oplen = 4 + ((inexpr->elts[inend - 2].longconst
@ -446,6 +443,9 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
args=1; args=1;
break; break;
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
args = 1;
case OP_M2_STRING: case OP_M2_STRING:
case OP_STRING: case OP_STRING:
oplen = 3 + ((inexpr->elts[inend - 2].longconst oplen = 3 + ((inexpr->elts[inend - 2].longconst

View File

@ -1158,8 +1158,7 @@ read_type (pp, objfile)
case '#': /* Method (class & fn) type */ case '#': /* Method (class & fn) type */
if ((*pp)[0] == '#') if ((*pp)[0] == '#')
{ {
/* This "minimized" format bogus, because it doesn't yield /* We'll get the parameter types from the name. */
enough information. I've changed gcc to not emit it. --Per */
struct type *return_type; struct type *return_type;
*pp += 1; *pp += 1;
@ -1418,10 +1417,8 @@ read_struct_type (pp, type, objfile)
p = *pp; p = *pp;
if (*p == CPLUS_MARKER) if (*p == CPLUS_MARKER)
{ {
if (*p == '_') /* GNU C++ anonymous type. */
;
/* Special GNU C++ name. */ /* Special GNU C++ name. */
else if (*++p == 'v') if (*++p == 'v')
{ {
const char *prefix; const char *prefix;
char *name = 0; char *name = 0;
@ -1460,12 +1457,15 @@ read_struct_type (pp, type, objfile)
list->field.bitsize = 0; list->field.bitsize = 0;
list->visibility = 0; /* private */ list->visibility = 0; /* private */
non_public_fields++; non_public_fields++;
nfields++;
continue;
} }
/* GNU C++ anonymous type. */
else if (*p == '_')
break;
else else
complain (&invalid_cpp_abbrev_complaint, *pp); complain (&invalid_cpp_abbrev_complaint, *pp);
nfields++;
continue;
} }
while (*p != ':') p++; while (*p != ':') p++;
@ -1508,26 +1508,21 @@ read_struct_type (pp, type, objfile)
if (**pp == ':') if (**pp == ':')
{ {
p = ++(*pp); p = ++(*pp);
#if 0
/* Possible future hook for nested types. */
if (**pp == '!') if (**pp == '!')
{ /* C++ nested type -as in FOO::BAR */ {
list->field.bitpos = (long)(-2); /* nested type */ list->field.bitpos = (long)-2; /* nested type */
p = ++(*pp); p = ++(*pp);
if (TYPE_NAME (list->field.type) == NULL && **pp == '\'')
{
for (p = ++(*pp); *p != '\''; ) p++;
TYPE_NAME (list->field.type) = savestring (*pp, p - *pp);
}
while (*p != ';') p++;
list->field.bitsize = 0;
*pp = p + 1;
} }
else else
#endif
{ /* Static class member. */ { /* Static class member. */
list->field.bitpos = (long)(-1); list->field.bitpos = (long)-1;
while (*p != ';') p++;
list->field.bitsize = (long) savestring (*pp, p - *pp);
*pp = p + 1;
} }
while (*p != ';') p++;
list->field.bitsize = (long) savestring (*pp, p - *pp);
*pp = p + 1;
nfields++; nfields++;
continue; continue;
} }

View File

@ -1269,31 +1269,6 @@ find_pc_line_pc_range (pc, startptr, endptr)
return sal.symtab != 0; return sal.symtab != 0;
} }
struct type *
find_nested_type (type, name)
struct type *type;
char *name;
{
int i;
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name && !strcmp (t_field_name, name))
if (TYPE_FIELD_NESTED (type, i))
{
return TYPE_FIELD_TYPE (type, i);
}
}
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
struct type * t = find_nested_type (TYPE_BASECLASS (type, i), name);
if (t)
return t;
}
return NULL;
}
/* If P is of the form "operator[ \t]+..." where `...' is /* If P is of the form "operator[ \t]+..." where `...' is
some legitimate operator text, return a pointer to the some legitimate operator text, return a pointer to the
beginning of the substring of the operator text. beginning of the substring of the operator text.

View File

@ -43,7 +43,7 @@ static value
search_struct_field PARAMS ((char *, value, int, struct type *, int)); search_struct_field PARAMS ((char *, value, int, struct type *, int));
static value static value
search_struct_method PARAMS ((char *, value *, value *, int, int *, search_struct_method PARAMS ((char *, value, value *, int, int *,
struct type *)); struct type *));
static int static int
@ -1038,7 +1038,6 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
if (BASETYPE_VIA_VIRTUAL (type, i)) if (BASETYPE_VIA_VIRTUAL (type, i))
{ {
value v2; value v2;
/* Fix to use baseclass_offset instead. FIXME */
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset, baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
&v2, (int *)NULL); &v2, (int *)NULL);
if (v2 == 0) if (v2 == 0)
@ -1066,9 +1065,9 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
If found, return value, else return NULL. */ If found, return value, else return NULL. */
static value static value
search_struct_method (name, arg1p, args, offset, static_memfuncp, type) search_struct_method (name, arg1, args, offset, static_memfuncp, type)
char *name; char *name;
register value *arg1p, *args; register value arg1, *args;
int offset, *static_memfuncp; int offset, *static_memfuncp;
register struct type *type; register struct type *type;
{ {
@ -1093,10 +1092,10 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
TYPE_FN_FIELD_ARGS (f, j), args)) TYPE_FN_FIELD_ARGS (f, j), args))
{ {
if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
return (value)value_virtual_fn_field (arg1p, f, j, type, offset); return (value)value_virtual_fn_field (arg1, f, j, type);
if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp) if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
*static_memfuncp = 1; *static_memfuncp = 1;
return (value)value_fn_field (arg1p, f, j, type, offset); return (value)value_fn_field (f, j);
} }
j--; j--;
} }
@ -1105,27 +1104,25 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{ {
value v; value v, v2;
int base_offset; int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i)) if (BASETYPE_VIA_VIRTUAL (type, i))
{ {
base_offset = baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
baseclass_offset (type, i, *arg1p, offset); &v2, (int *)NULL);
if (base_offset == -1) if (v2 == 0)
error ("virtual baseclass botch"); error ("virtual baseclass botch");
base_offset = 0;
} }
else else
{ {
v2 = arg1;
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8; base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
} }
v = search_struct_method (name, arg1p, args, base_offset + offset, v = search_struct_method (name, v2, args, base_offset,
static_memfuncp, TYPE_BASECLASS (type, i)); static_memfuncp, TYPE_BASECLASS (type, i));
if (v) if (v) return v;
{
/* *arg1p = arg1_tmp;*/
return v;
}
} }
return NULL; return NULL;
} }
@ -1196,7 +1193,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
if (destructor_name_p (name, t)) if (destructor_name_p (name, t))
error ("Cannot get value of destructor"); error ("Cannot get value of destructor");
v = search_struct_method (name, argp, args, 0, static_memfuncp, t); v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
if (v == 0) if (v == 0)
{ {
@ -1213,9 +1210,8 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
if (!args[1]) if (!args[1])
{ {
/* destructors are a special case. */ /* destructors are a special case. */
return (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0), return (value)value_fn_field (TYPE_FN_FIELDLIST1 (t, 0),
TYPE_FN_FIELDLIST_LENGTH (t, 0), TYPE_FN_FIELDLIST_LENGTH (t, 0));
0, 0);
} }
else else
{ {
@ -1223,7 +1219,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
} }
} }
else else
v = search_struct_method (name, argp, args, 0, static_memfuncp, t); v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
if (v == 0) if (v == 0)
{ {
@ -1418,7 +1414,7 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
(lookup_reference_type (lookup_reference_type
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
domain)), domain)),
METHOD_PTR_FROM_VOFFSET((LONGEST) TYPE_FN_FIELD_VOFFSET (f, j))); (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
} }
else else
{ {

View File

@ -510,7 +510,7 @@ val_print_fields (type, valaddr, stream, format, recurse, pretty, dont_print)
for (i = n_baseclasses; i < len; i++) for (i = n_baseclasses; i < len; i++)
{ {
/* Check if static field */ /* Check if static field */
if (TYPE_FIELD_STATIC (type, i) || TYPE_FIELD_NESTED (type, i)) if (TYPE_FIELD_STATIC (type, i))
continue; continue;
if (fields_seen) if (fields_seen)
fprintf_filtered (stream, ", "); fprintf_filtered (stream, ", ");
@ -628,7 +628,6 @@ cplus_val_print (type, valaddr, stream, format, recurse, pretty, dont_print)
obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i)); obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i));
} }
/* Fix to use baseclass_offset instead. FIXME */
baddr = baseclass_addr (type, i, valaddr, 0, &err); baddr = baseclass_addr (type, i, valaddr, 0, &err);
if (err == 0 && baddr == 0) if (err == 0 && baddr == 0)
error ("could not find virtual baseclass `%s'\n", error ("could not find virtual baseclass `%s'\n",
@ -868,9 +867,8 @@ val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
addr = unpack_pointer (lookup_pointer_type (builtin_type_void), addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr); valaddr);
if (METHOD_PTR_IS_VIRTUAL(addr)) if (addr < 128) /* FIXME! What is this 128? */
{ {
int offset = METHOD_PTR_TO_VOFFSET(addr);
len = TYPE_NFN_FIELDS (domain); len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
@ -880,9 +878,9 @@ val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
for (j = 0; j < len2; j++) for (j = 0; j < len2; j++)
{ {
QUIT; QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) if (TYPE_FN_FIELD_VOFFSET (f, j) == addr)
{ {
kind = "virtual "; kind = "virtual";
goto common; goto common;
} }
} }
@ -1847,14 +1845,10 @@ type_print_base (type, stream, show, level)
{ {
fprintf_filtered (stream, "static "); fprintf_filtered (stream, "static ");
} }
if (TYPE_FIELD_NESTED (type, i))
{
fprintf_filtered (stream, "typedef ");
}
type_print_1 (TYPE_FIELD_TYPE (type, i), type_print_1 (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i), TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4); stream, show - 1, level + 4);
if (!TYPE_FIELD_STATIC (type, i) && !TYPE_FIELD_NESTED (type, i) if (!TYPE_FIELD_STATIC (type, i)
&& TYPE_FIELD_PACKED (type, i)) && TYPE_FIELD_PACKED (type, i))
{ {
/* It is a bitfield. This code does not attempt /* It is a bitfield. This code does not attempt
@ -1868,13 +1862,8 @@ type_print_base (type, stream, show, level)
fprintf_filtered (stream, ";\n"); fprintf_filtered (stream, ";\n");
} }
/* If there are both fields and methods, put a space between. */
len = TYPE_NFN_FIELDS (type);
if (len && section_type != s_none)
fprintf_filtered (stream, "\n");
/* C++: print out the methods */ /* C++: print out the methods */
len = TYPE_NFN_FIELDS (type);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);

View File

@ -903,15 +903,12 @@ value_field (arg1, fieldno)
J is an index into F which provides the desired method. */ J is an index into F which provides the desired method. */
value value
value_fn_field (arg1p, f, j, type, offset) value_fn_field (f, j)
value *arg1p;
struct fn_field *f; struct fn_field *f;
int j; int j;
struct type *type;
int offset;
{ {
register value v; register value v;
register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); register struct type *type = TYPE_FN_FIELD_TYPE (f, j);
struct symbol *sym; struct symbol *sym;
sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
@ -919,40 +916,27 @@ value_fn_field (arg1p, f, j, type, offset)
if (! sym) error ("Internal error: could not find physical method named %s", if (! sym) error ("Internal error: could not find physical method named %s",
TYPE_FN_FIELD_PHYSNAME (f, j)); TYPE_FN_FIELD_PHYSNAME (f, j));
v = allocate_value (ftype); v = allocate_value (type);
VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
VALUE_TYPE (v) = ftype; VALUE_TYPE (v) = type;
if (arg1p)
{
if (type != VALUE_TYPE (*arg1p))
*arg1p = value_ind (value_cast (lookup_pointer_type (type),
value_addr (*arg1p)));
/* Move the `this' pointer according to the offset. */
VALUE_OFFSET (*arg1p) += offset;
}
return v; return v;
} }
/* Return a virtual function as a value. /* Return a virtual function as a value.
ARG1 is the object which provides the virtual function ARG1 is the object which provides the virtual function
table pointer. *ARG1P is side-effected in calling this function. table pointer. ARG1 is side-effected in calling this function.
F is the list of member functions which contains the desired virtual F is the list of member functions which contains the desired virtual
function. function.
J is an index into F which provides the desired virtual function. J is an index into F which provides the desired virtual function.
TYPE is the type in which F is located. */ TYPE is the type in which F is located. */
value value
value_virtual_fn_field (arg1p, f, j, type, offset) value_virtual_fn_field (arg1, f, j, type)
value *arg1p; value arg1;
struct fn_field *f; struct fn_field *f;
int j; int j;
struct type *type; struct type *type;
int offset;
{ {
value arg1 = *arg1p;
/* First, get the virtual function table pointer. That comes /* First, get the virtual function table pointer. That comes
with a strange type, so cast it to type `pointer to long' (which with a strange type, so cast it to type `pointer to long' (which
should serve just fine as a function type). Then, index into should serve just fine as a function type). Then, index into
@ -984,9 +968,7 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
/* The virtual function table is now an array of structures /* The virtual function table is now an array of structures
which have the form { int16 offset, delta; void *pfn; }. */ which have the form { int16 offset, delta; void *pfn; }. */
vtbl = value_ind (value_primitive_field (arg1, 0, vtbl = value_ind (value_field (arg1, TYPE_VPTR_FIELDNO (context)));
TYPE_VPTR_FIELDNO (context),
TYPE_VPTR_BASETYPE (context)));
/* Index into the virtual function table. This is hard-coded because /* Index into the virtual function table. This is hard-coded because
looking up a field is not cheap, and it may be important to save looking up a field is not cheap, and it may be important to save
@ -995,7 +977,7 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
entry = value_subscript (vtbl, vi); entry = value_subscript (vtbl, vi);
/* Move the `this' pointer according to the virtual function table. */ /* Move the `this' pointer according to the virtual function table. */
VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)) + offset; VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
if (! VALUE_LAZY (arg1)) if (! VALUE_LAZY (arg1))
{ {
VALUE_LAZY (arg1) = 1; VALUE_LAZY (arg1) = 1;
@ -1006,7 +988,6 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
/* Reinstantiate the function pointer with the correct type. */ /* Reinstantiate the function pointer with the correct type. */
VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)); VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
*arg1p = arg1;
return vfn; return vfn;
} }
@ -1122,67 +1103,6 @@ value_from_vtable_info (arg, type)
return value_headof (arg, 0, type); return value_headof (arg, 0, type);
} }
/* Compute the offset of the baseclass which is
the INDEXth baseclass of class TYPE, for a value ARG,
wih extra offset of OFFSET.
The result is the offste of the baseclass value relative
to (the address of)(ARG) + OFFSET.
-1 is returned on error. */
int
baseclass_offset (type, index, arg, offset)
struct type *type;
int index;
value arg;
int offset;
{
struct type *basetype = TYPE_BASECLASS (type, index);
if (BASETYPE_VIA_VIRTUAL (type, index))
{
/* Must hunt for the pointer to this virtual baseclass. */
register int i, len = TYPE_NFIELDS (type);
register int n_baseclasses = TYPE_N_BASECLASSES (type);
char *vbase_name, *type_name = type_name_no_tag (basetype);
vbase_name = (char *)alloca (strlen (type_name) + 8);
sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name);
/* First look for the virtual baseclass pointer
in the fields. */
for (i = n_baseclasses; i < len; i++)
{
if (! strcmp (vbase_name, TYPE_FIELD_NAME (type, i)))
{
CORE_ADDR addr
= unpack_pointer (TYPE_FIELD_TYPE (type, i),
VALUE_CONTENTS (arg) + VALUE_OFFSET (arg)
+ offset
+ (TYPE_FIELD_BITPOS (type, i) / 8));
if (VALUE_LVAL (arg) != lval_memory)
return -1;
return addr -
(LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset);
}
}
/* Not in the fields, so try looking through the baseclasses. */
for (i = index+1; i < n_baseclasses; i++)
{
int boffset =
baseclass_offset (type, i, arg, offset);
if (boffset)
return boffset;
}
/* Not found. */
return -1;
}
/* Baseclass is easily computed. */
return TYPE_BASECLASS_BITPOS (type, index) / 8;
}
/* Compute the address of the baseclass which is /* Compute the address of the baseclass which is
the INDEXth baseclass of class TYPE. The TYPE base the INDEXth baseclass of class TYPE. The TYPE base
of the object is at VALADDR. of the object is at VALADDR.
@ -1192,8 +1112,6 @@ baseclass_offset (type, index, arg, offset)
of the baseclasss, but the address which could not be read of the baseclasss, but the address which could not be read
successfully. */ successfully. */
/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */
char * char *
baseclass_addr (type, index, valaddr, valuep, errp) baseclass_addr (type, index, valaddr, valuep, errp)
struct type *type; struct type *type;