mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 04:25:10 +08:00
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:
parent
5148923360
commit
2640f7e138
@ -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)
|
||||||
|
|
||||||
|
80
gdb/c-exp.y
80
gdb/c-exp.y
@ -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
|
||||||
|
@ -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>",
|
||||||
|
@ -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
|
||||||
|
12
gdb/parse.c
12
gdb/parse.c
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
25
gdb/symtab.c
25
gdb/symtab.c
@ -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.
|
||||||
|
40
gdb/valops.c
40
gdb/valops.c
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
100
gdb/values.c
100
gdb/values.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user