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)
* 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)
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
here from demangle.h (which is now in ../include).
* 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)
* symtab.c (completion_list_add_symbol): restructured to optimize
for time. First clip names that cannot match. Then clip any
names we've already considered. Drop a redundant strncpy. Drop
a redundant malloc and associated free for demangled names.
for time. First clip names that cannot match. Then clip any
names we've already considered. Drop a redundant strncpy. Drop
a redundant malloc and associated free for demangled names.
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 "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!
Note that this are a combined list of variables that can be produced
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 <tval> type typebase typebase_coloncolon qualified_type
%type <tval> type typebase
%type <tvec> nonempty_typelist
/* %type <bval> block */
@ -152,7 +144,6 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
%token <sval> STRING
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
%token <tsym> TYPENAME
%token <tval> NESTED_TYPE
%type <sval> name
%type <ssym> name_not_typename
%type <tsym> typename
@ -274,16 +265,16 @@ exp : SIZEOF exp %prec UNARY
exp : exp ARROW name
{ write_exp_elt_opcode (STRUCTOP_PTR);
write_exp_elt_type (NULL);
write_exp_string ($3);
write_exp_elt_opcode (STRUCTOP_PTR); }
;
exp : exp ARROW typebase_coloncolon name
{ write_exp_elt_opcode (STRUCTOP_PTR);
write_exp_elt_type ($3);
write_exp_string ($4);
write_exp_elt_opcode (STRUCTOP_PTR); }
exp : exp ARROW qualified_name
{ /* exp->type::name becomes exp->*(&type::name) */
/* Note: this doesn't work if name is a
static member! FIXME */
write_exp_elt_opcode (UNOP_ADDR);
write_exp_elt_opcode (STRUCTOP_MPTR); }
;
exp : exp ARROW '*' exp
{ write_exp_elt_opcode (STRUCTOP_MPTR); }
@ -291,16 +282,16 @@ exp : exp ARROW '*' exp
exp : exp '.' name
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
write_exp_elt_type (NULL);
write_exp_string ($3);
write_exp_elt_opcode (STRUCTOP_STRUCT); }
;
exp : exp '.' typebase_coloncolon name
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
write_exp_elt_type ($3);
write_exp_string ($4);
write_exp_elt_opcode (STRUCTOP_STRUCT); }
exp : exp '.' qualified_name
{ /* exp.type::name becomes exp.*(&type::name) */
/* Note: this doesn't work if name is a
static member! FIXME */
write_exp_elt_opcode (UNOP_ADDR);
write_exp_elt_opcode (STRUCTOP_MEMBER); }
;
exp : exp '.' '*' exp
@ -585,9 +576,7 @@ variable: block COLONCOLON name
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;
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_type (type);
write_exp_string ($2);
write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE);
current_type = NULL;
}
| typebase_coloncolon '~' name
| typebase COLONCOLON '~' name
{
struct type *type = $1;
struct stoken tmp_token;
@ -610,20 +598,19 @@ qualified_name: typebase_coloncolon name
error ("`%s' is not defined as an aggregate 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'",
type_name_no_tag (type), $3.ptr);
type_name_no_tag (type), $4.ptr);
tmp_token.ptr = (char*) alloca ($3.length + 2);
tmp_token.length = $3.length + 1;
tmp_token.ptr = (char*) alloca ($4.length + 2);
tmp_token.length = $4.length + 1;
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;
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
write_exp_string (tmp_token);
write_exp_elt_opcode (OP_SCOPE);
current_type = NULL;
}
;
@ -835,15 +822,9 @@ func_mod: '(' ')'
{ free ((PTR)$2); $$ = 0; }
;
qualified_type: typebase_coloncolon NESTED_TYPE
{ $$ = $2; current_type = NULL; }
;
type : ptype
| qualified_type
| typebase_coloncolon '*'
{ $$ = lookup_member_type (builtin_type_int, $1);
current_type = NULL; }
| typebase COLONCOLON '*'
{ $$ = lookup_member_type (builtin_type_int, $1); }
| type '(' typebase COLONCOLON '*' ')'
{ $$ = lookup_member_type ($1, $3); }
| type '(' typebase COLONCOLON '*' ')' '(' ')'
@ -895,10 +876,6 @@ typebase
| ENUM name
{ $$ = lookup_enum (copy_name ($2),
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
{ $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
| UNSIGNED
@ -1442,17 +1419,6 @@ yylex ()
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
functions or symtabs. If this is not so, then ...
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);
}
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",
visible in lexical block BLOCK. */
@ -539,16 +530,11 @@ lookup_struct (name, block)
{
error ("No struct type named %s.", name);
}
return check_struct (SYMBOL_TYPE (sym));
}
struct type *
check_union (type)
struct type *type;
{
if (TYPE_CODE (type) != TYPE_CODE_UNION)
error ("This context has %s, not a union.", TYPE_NAME (type));
return type;
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
{
error ("This context has class, union or enum %s, not a struct.", name);
}
return (SYMBOL_TYPE (sym));
}
/* Lookup a union type named "union NAME",
@ -568,16 +554,11 @@ lookup_union (name, block)
{
error ("No union type named %s.", name);
}
return check_union (SYMBOL_TYPE (sym));
}
struct type *
check_enum (type)
struct type *type;
{
if (TYPE_CODE (type) != TYPE_CODE_ENUM)
error ("This context has %s, not an enum.", TYPE_NAME (type));
return type;
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
{
error ("This context has class, struct or enum %s, not a union.", name);
}
return (SYMBOL_TYPE (sym));
}
/* Lookup an enum type named "enum NAME",
@ -596,7 +577,11 @@ lookup_enum (name, block)
{
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>",

View File

@ -435,7 +435,6 @@ allocate_cplus_struct_type PARAMS ((struct type *));
B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
#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_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists

View File

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

View File

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

View File

@ -1269,31 +1269,6 @@ find_pc_line_pc_range (pc, startptr, endptr)
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
some legitimate operator text, return a pointer to the
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));
static value
search_struct_method PARAMS ((char *, value *, value *, int, int *,
search_struct_method PARAMS ((char *, value, value *, int, int *,
struct type *));
static int
@ -1038,7 +1038,6 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
if (BASETYPE_VIA_VIRTUAL (type, i))
{
value v2;
/* Fix to use baseclass_offset instead. FIXME */
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
&v2, (int *)NULL);
if (v2 == 0)
@ -1066,9 +1065,9 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
If found, return value, else return NULL. */
static value
search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
search_struct_method (name, arg1, args, offset, static_memfuncp, type)
char *name;
register value *arg1p, *args;
register value arg1, *args;
int offset, *static_memfuncp;
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))
{
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)
*static_memfuncp = 1;
return (value)value_fn_field (arg1p, f, j, type, offset);
return (value)value_fn_field (f, 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--)
{
value v;
value v, v2;
int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
base_offset =
baseclass_offset (type, i, *arg1p, offset);
if (base_offset == -1)
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
&v2, (int *)NULL);
if (v2 == 0)
error ("virtual baseclass botch");
base_offset = 0;
}
else
{
v2 = arg1;
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));
if (v)
{
/* *arg1p = arg1_tmp;*/
return v;
}
if (v) return v;
}
return NULL;
}
@ -1196,7 +1193,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
if (destructor_name_p (name, t))
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)
{
@ -1213,9 +1210,8 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
if (!args[1])
{
/* destructors are a special case. */
return (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
TYPE_FN_FIELDLIST_LENGTH (t, 0),
0, 0);
return (value)value_fn_field (TYPE_FN_FIELDLIST1 (t, 0),
TYPE_FN_FIELDLIST_LENGTH (t, 0));
}
else
{
@ -1223,7 +1219,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
}
}
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)
{
@ -1418,7 +1414,7 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
(lookup_reference_type
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
domain)),
METHOD_PTR_FROM_VOFFSET((LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)));
(LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
}
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++)
{
/* Check if static field */
if (TYPE_FIELD_STATIC (type, i) || TYPE_FIELD_NESTED (type, i))
if (TYPE_FIELD_STATIC (type, i))
continue;
if (fields_seen)
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));
}
/* Fix to use baseclass_offset instead. FIXME */
baddr = baseclass_addr (type, i, valaddr, 0, &err);
if (err == 0 && baddr == 0)
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),
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);
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++)
{
QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
if (TYPE_FN_FIELD_VOFFSET (f, j) == addr)
{
kind = "virtual ";
kind = "virtual";
goto common;
}
}
@ -1847,14 +1845,10 @@ type_print_base (type, stream, show, level)
{
fprintf_filtered (stream, "static ");
}
if (TYPE_FIELD_NESTED (type, i))
{
fprintf_filtered (stream, "typedef ");
}
type_print_1 (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i),
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))
{
/* It is a bitfield. This code does not attempt
@ -1868,13 +1862,8 @@ type_print_base (type, stream, show, level)
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 */
len = TYPE_NFN_FIELDS (type);
for (i = 0; i < len; 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. */
value
value_fn_field (arg1p, f, j, type, offset)
value *arg1p;
value_fn_field (f, j)
struct fn_field *f;
int j;
struct type *type;
int offset;
{
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;
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",
TYPE_FN_FIELD_PHYSNAME (f, j));
v = allocate_value (ftype);
v = allocate_value (type);
VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
VALUE_TYPE (v) = ftype;
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;
}
VALUE_TYPE (v) = type;
return v;
}
/* Return a virtual function as a value.
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
function.
J is an index into F which provides the desired virtual function.
TYPE is the type in which F is located. */
value
value_virtual_fn_field (arg1p, f, j, type, offset)
value *arg1p;
value_virtual_fn_field (arg1, f, j, type)
value arg1;
struct fn_field *f;
int j;
struct type *type;
int offset;
{
value arg1 = *arg1p;
/* First, get the virtual function table pointer. That comes
with a strange type, so cast it to type `pointer to long' (which
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
which have the form { int16 offset, delta; void *pfn; }. */
vtbl = value_ind (value_primitive_field (arg1, 0,
TYPE_VPTR_FIELDNO (context),
TYPE_VPTR_BASETYPE (context)));
vtbl = value_ind (value_field (arg1, TYPE_VPTR_FIELDNO (context)));
/* 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
@ -995,7 +977,7 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
entry = value_subscript (vtbl, vi);
/* 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))
{
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. */
VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
*arg1p = arg1;
return vfn;
}
@ -1122,67 +1103,6 @@ value_from_vtable_info (arg, 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
the INDEXth baseclass of class TYPE. The TYPE base
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
successfully. */
/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */
char *
baseclass_addr (type, index, valaddr, valuep, errp)
struct type *type;