More C++ improvements (pointers to members, qualified names). See ChangeLog.
This commit is contained in:
parent
52963fb7e9
commit
01be69139e
6 changed files with 569 additions and 374 deletions
|
@ -1,3 +1,35 @@
|
|||
Thu Mar 19 18:49:45 1992 Per Bothner (bothner@cygnus.com)
|
||||
|
||||
More C++ improvements (pointers to members, qualified names).
|
||||
* c-exp.y: Support exp.type::name and exp->type::name
|
||||
syntaxes. (Unfortunately, doesn't work for static members.)
|
||||
* c-exp.y, eval.c: Make type::~type work better.
|
||||
* eval.c (evaluate_subexp: OP_SCOPE): Replace use of
|
||||
value_static_field by value_struct_elt_for_reference.
|
||||
* eval.c (evaluate_subexp): Merge code for STRUCTOP_MEMBER
|
||||
and STRUCTOP_MPTR; cast arg1 to domain-type of arg2.
|
||||
* eval.c (evaluate_subexp): Remove special case for UNOP_ADDR
|
||||
for OP_SCOPE operand; no point in it now that we use lazy
|
||||
reading of values, and use "reference to member" objects.
|
||||
* gdbtypes.h: Clarify comment.
|
||||
* valops.c: Change value_struct_elt_for_address to return
|
||||
a reference (or variable), rather than a pointer. Change
|
||||
the name to value_struct_elt_for_reference to reflect this.
|
||||
Returning a reference instead of a address provides a
|
||||
generalization, since we can use the routine for both
|
||||
class::name as well as &class::name.
|
||||
Also, recurse to handle multiple inheritance properly.
|
||||
* valprint.c: Moved code to print pointer-to-members
|
||||
to new function point_class_member. This allows a
|
||||
"reference-to-member" to be printed using the same code.
|
||||
* valprint.c (type_print_varspec_prefix): Avoid printing
|
||||
"struct " for domains of class-member types.
|
||||
* valops.c (search_struct_field): Inline code for simplified
|
||||
version of value_static_field (which can then be deleted).
|
||||
* value.h: Rename value_struct_elt_for_address to
|
||||
value_struct_elt_for_reference. Delete value_static_field.
|
||||
* values.c: Remove no longer used function value_static_field.
|
||||
|
||||
Thu Mar 19 13:54:11 1992 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* coffread.c, mipsread.c, xcoffread.c, coffread.c, dbxread.c,
|
||||
|
|
31
gdb/c-exp.y
31
gdb/c-exp.y
|
@ -120,7 +120,7 @@ static int
|
|||
parse_number PARAMS ((char *, int, int, YYSTYPE *));
|
||||
%}
|
||||
|
||||
%type <voidval> exp exp1 type_exp start variable
|
||||
%type <voidval> exp exp1 type_exp start variable qualified_name
|
||||
%type <tval> type typebase
|
||||
%type <tvec> nonempty_typelist
|
||||
/* %type <bval> block */
|
||||
|
@ -257,6 +257,13 @@ exp : exp ARROW name
|
|||
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); }
|
||||
;
|
||||
|
@ -267,6 +274,14 @@ exp : exp '.' name
|
|||
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
|
||||
{ write_exp_elt_opcode (STRUCTOP_MEMBER); }
|
||||
;
|
||||
|
@ -549,7 +564,7 @@ variable: block COLONCOLON name
|
|||
write_exp_elt_opcode (OP_VAR_VALUE); }
|
||||
;
|
||||
|
||||
variable: typebase COLONCOLON name
|
||||
qualified_name: typebase COLONCOLON name
|
||||
{
|
||||
struct type *type = $1;
|
||||
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
||||
|
@ -565,6 +580,7 @@ variable: typebase COLONCOLON name
|
|||
| typebase COLONCOLON '~' name
|
||||
{
|
||||
struct type *type = $1;
|
||||
struct stoken tmp_token;
|
||||
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
||||
&& TYPE_CODE (type) != TYPE_CODE_UNION)
|
||||
error ("`%s' is not defined as an aggregate type.",
|
||||
|
@ -574,12 +590,19 @@ variable: typebase COLONCOLON name
|
|||
error ("invalid destructor `%s::~%s'",
|
||||
type_name_no_tag (type), $4.ptr);
|
||||
|
||||
tmp_token.ptr = (char*) alloca ($4.length + 2);
|
||||
tmp_token.length = $4.length + 1;
|
||||
tmp_token.ptr[0] = '~';
|
||||
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 ($4);
|
||||
write_exp_string (tmp_token);
|
||||
write_exp_elt_opcode (OP_SCOPE);
|
||||
write_exp_elt_opcode (UNOP_LOGNOT);
|
||||
}
|
||||
;
|
||||
|
||||
variable: qualified_name
|
||||
| COLONCOLON name
|
||||
{
|
||||
char *name = copy_name ($2);
|
||||
|
|
119
gdb/eval.c
119
gdb/eval.c
|
@ -17,15 +17,45 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "value.h"
|
||||
#include "expression.h"
|
||||
#include "target.h"
|
||||
#include "frame.h"
|
||||
|
||||
#define NULL_TYPE ((struct type *)0)
|
||||
/* Values of NOSIDE argument to eval_subexp. */
|
||||
enum noside
|
||||
{ EVAL_NORMAL,
|
||||
EVAL_SKIP, /* Only effect is to increment pos. */
|
||||
EVAL_AVOID_SIDE_EFFECTS /* Don't modify any variables or
|
||||
call any functions. The value
|
||||
returned will have the correct
|
||||
type, and will have an
|
||||
approximately correct lvalue
|
||||
type (inaccuracy: anything that is
|
||||
listed as being in a register in
|
||||
the function in which it was
|
||||
declared will be lval_register). */
|
||||
};
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static value
|
||||
evaluate_subexp_for_sizeof PARAMS ((struct expression *, int *));
|
||||
|
||||
static value
|
||||
evaluate_subexp_with_coercion PARAMS ((struct expression *, int *,
|
||||
enum noside));
|
||||
|
||||
static value
|
||||
evaluate_subexp_for_address PARAMS ((struct expression *, int *,
|
||||
enum noside));
|
||||
|
||||
static value
|
||||
evaluate_subexp PARAMS ((struct type *, struct expression *, int *,
|
||||
enum noside));
|
||||
|
||||
|
||||
/* Parse the string EXP as a C expression, evaluate it,
|
||||
|
@ -37,8 +67,8 @@ parse_and_eval_address (exp)
|
|||
{
|
||||
struct expression *expr = parse_expression (exp);
|
||||
register CORE_ADDR addr;
|
||||
register struct cleanup *old_chain
|
||||
= make_cleanup (free_current_contents, &expr);
|
||||
register struct cleanup *old_chain =
|
||||
make_cleanup (free_current_contents, &expr);
|
||||
|
||||
addr = value_as_pointer (evaluate_expression (expr));
|
||||
do_cleanups (old_chain);
|
||||
|
@ -54,8 +84,8 @@ parse_and_eval_address_1 (expptr)
|
|||
{
|
||||
struct expression *expr = parse_exp_1 (expptr, (struct block *)0, 0);
|
||||
register CORE_ADDR addr;
|
||||
register struct cleanup *old_chain
|
||||
= make_cleanup (free_current_contents, &expr);
|
||||
register struct cleanup *old_chain =
|
||||
make_cleanup (free_current_contents, &expr);
|
||||
|
||||
addr = value_as_pointer (evaluate_expression (expr));
|
||||
do_cleanups (old_chain);
|
||||
|
@ -104,21 +134,6 @@ static value evaluate_subexp_for_address ();
|
|||
static value evaluate_subexp_for_sizeof ();
|
||||
static value evaluate_subexp_with_coercion ();
|
||||
|
||||
/* Values of NOSIDE argument to eval_subexp. */
|
||||
enum noside
|
||||
{ EVAL_NORMAL,
|
||||
EVAL_SKIP, /* Only effect is to increment pos. */
|
||||
EVAL_AVOID_SIDE_EFFECTS /* Don't modify any variables or
|
||||
call any functions. The value
|
||||
returned will have the correct
|
||||
type, and will have an
|
||||
approximately correct lvalue
|
||||
type (inaccuracy: anything that is
|
||||
listed as being in a register in
|
||||
the function in which it was
|
||||
declared will be lval_register). */
|
||||
};
|
||||
|
||||
value
|
||||
evaluate_expression (exp)
|
||||
struct expression *exp;
|
||||
|
@ -149,6 +164,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
|||
int tem;
|
||||
register int pc, pc2, oldpos;
|
||||
register value arg1, arg2, arg3;
|
||||
struct type *type;
|
||||
int nargs;
|
||||
value *argvec;
|
||||
|
||||
|
@ -161,8 +177,10 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
|||
tem = strlen (&exp->elts[pc + 2].string);
|
||||
(*pos) += 3 + ((tem + sizeof (union exp_element))
|
||||
/ sizeof (union exp_element));
|
||||
arg1 = value_static_field (exp->elts[pc + 1].type,
|
||||
&exp->elts[pc + 2].string, -1);
|
||||
arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
|
||||
exp->elts[pc + 1].type,
|
||||
&exp->elts[pc + 2].string,
|
||||
expect_type);
|
||||
if (arg1 == NULL)
|
||||
error ("There is no field named %s", &exp->elts[pc + 2].string);
|
||||
return arg1;
|
||||
|
@ -448,35 +466,28 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
|||
|
||||
case STRUCTOP_MEMBER:
|
||||
arg1 = evaluate_subexp_for_address (exp, pos, noside);
|
||||
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
/* Now, convert these values to an address. */
|
||||
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
|
||||
|| ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))
|
||||
!= TYPE_CODE_MEMBER)
|
||||
&& (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))
|
||||
!= TYPE_CODE_METHOD)))
|
||||
error ("non-pointer-to-member value used in pointer-to-member construct");
|
||||
arg3 = value_from_longest (
|
||||
lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))),
|
||||
value_as_long (arg1) + value_as_long (arg2));
|
||||
return value_ind (arg3);
|
||||
|
||||
goto handle_pointer_to_member;
|
||||
case STRUCTOP_MPTR:
|
||||
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
handle_pointer_to_member:
|
||||
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR)
|
||||
goto bad_pointer_to_member;
|
||||
type = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
|
||||
if (TYPE_CODE (type) == TYPE_CODE_METHOD)
|
||||
error ("not implemented: pointer-to-method in pointer-to-member construct");
|
||||
if (TYPE_CODE (type) != TYPE_CODE_MEMBER)
|
||||
goto bad_pointer_to_member;
|
||||
/* Now, convert these values to an address. */
|
||||
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
|
||||
|| (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER
|
||||
&& TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD))
|
||||
error ("non-pointer-to-member value used in pointer-to-member construct");
|
||||
arg3 = value_from_longest (
|
||||
lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))),
|
||||
value_as_long (arg1) + value_as_long (arg2));
|
||||
arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
|
||||
arg1);
|
||||
arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
|
||||
value_as_long (arg1) + value_as_long (arg2));
|
||||
return value_ind (arg3);
|
||||
bad_pointer_to_member:
|
||||
error("non-pointer-to-member value used in pointer-to-member construct");
|
||||
|
||||
case BINOP_ASSIGN:
|
||||
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
|
@ -732,10 +743,6 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
|||
/* C++: check for and handle destructor names. */
|
||||
op = exp->elts[*pos].opcode;
|
||||
|
||||
/* FIXME-tiemann: this is a cop-out. */
|
||||
if (op == OP_SCOPE)
|
||||
error ("destructor in eval");
|
||||
|
||||
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
|
@ -795,19 +802,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
|||
goto nosideret;
|
||||
}
|
||||
|
||||
if (op == OP_SCOPE)
|
||||
{
|
||||
char *name = &exp->elts[pc+3].string;
|
||||
int temm = strlen (name);
|
||||
struct type *domain = exp->elts[pc+2].type;
|
||||
(*pos) += 2 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
|
||||
arg1 = value_struct_elt_for_address (domain, expect_type, name);
|
||||
if (arg1)
|
||||
return arg1;
|
||||
error ("no field `%s' in structure", name);
|
||||
}
|
||||
else
|
||||
return evaluate_subexp_for_address (exp, pos, noside);
|
||||
return evaluate_subexp_for_address (exp, pos, noside);
|
||||
|
||||
case UNOP_SIZEOF:
|
||||
if (noside == EVAL_SKIP)
|
||||
|
|
247
gdb/valops.c
247
gdb/valops.c
|
@ -17,9 +17,9 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "value.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
@ -29,7 +29,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include <errno.h>
|
||||
|
||||
/* Local functions. */
|
||||
static value search_struct_field ();
|
||||
|
||||
static CORE_ADDR
|
||||
find_function_addr PARAMS ((value, struct type **));
|
||||
|
||||
static CORE_ADDR
|
||||
value_push PARAMS ((CORE_ADDR, value));
|
||||
|
||||
static CORE_ADDR
|
||||
value_arg_push PARAMS ((CORE_ADDR, value));
|
||||
|
||||
static value
|
||||
search_struct_field PARAMS ((char *, value, int, struct type *, int));
|
||||
|
||||
static value
|
||||
search_struct_method PARAMS ((char *, value, value *, int, int *,
|
||||
struct type *));
|
||||
|
||||
static int
|
||||
check_field_in PARAMS ((struct type *, const char *));
|
||||
|
||||
|
||||
/* Cast value ARG2 to type TYPE and return as a value.
|
||||
More general than a C cast: accepts any two types of the same length,
|
||||
|
@ -238,7 +257,7 @@ value_assign (toval, fromval)
|
|||
{
|
||||
int v; /* FIXME, this won't work for large bitfields */
|
||||
read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
&v, sizeof v);
|
||||
(char *) &v, sizeof v);
|
||||
modify_field ((char *) &v, (int) value_as_long (fromval),
|
||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||
write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
|
@ -450,7 +469,6 @@ value
|
|||
value_addr (arg1)
|
||||
value arg1;
|
||||
{
|
||||
extern value value_copy ();
|
||||
struct type *type = VALUE_TYPE (arg1);
|
||||
if (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
{
|
||||
|
@ -543,7 +561,7 @@ push_bytes (sp, buffer, len)
|
|||
|
||||
/* Push onto the stack the specified value VALUE. */
|
||||
|
||||
CORE_ADDR
|
||||
static CORE_ADDR
|
||||
value_push (sp, arg)
|
||||
register CORE_ADDR sp;
|
||||
value arg;
|
||||
|
@ -588,7 +606,7 @@ value_arg_coerce (arg)
|
|||
/* Push the value ARG, first coercing it as an argument
|
||||
to a C function. */
|
||||
|
||||
CORE_ADDR
|
||||
static CORE_ADDR
|
||||
value_arg_push (sp, arg)
|
||||
register CORE_ADDR sp;
|
||||
value arg;
|
||||
|
@ -599,7 +617,7 @@ value_arg_push (sp, arg)
|
|||
/* Determine a function's address and its return type from its value.
|
||||
Calls error() if the function is not valid for calling. */
|
||||
|
||||
CORE_ADDR
|
||||
static CORE_ADDR
|
||||
find_function_addr (function, retval_type)
|
||||
value function;
|
||||
struct type **retval_type;
|
||||
|
@ -941,13 +959,13 @@ value_string (ptr, len)
|
|||
}
|
||||
else
|
||||
{
|
||||
register int j;
|
||||
j = lookup_misc_func ("malloc");
|
||||
if (j >= 0)
|
||||
val = value_from_longest (
|
||||
lookup_pointer_type (lookup_function_type (
|
||||
lookup_pointer_type (builtin_type_char))),
|
||||
(LONGEST) misc_function_vector[j].address);
|
||||
struct minimal_symbol *msymbol;
|
||||
msymbol = lookup_minimal_symbol ("malloc", (struct objfile *) NULL);
|
||||
if (msymbol != NULL)
|
||||
val =
|
||||
value_from_longest (lookup_pointer_type (lookup_function_type (
|
||||
lookup_pointer_type (builtin_type_char))),
|
||||
(LONGEST) msymbol -> address);
|
||||
else
|
||||
error ("String constants require the program to have a function \"malloc\".");
|
||||
}
|
||||
|
@ -988,9 +1006,20 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||
|
||||
if (t_field_name && !strcmp (t_field_name, name))
|
||||
{
|
||||
value v = (TYPE_FIELD_STATIC (type, i)
|
||||
? value_static_field (type, name, i)
|
||||
: value_primitive_field (arg1, offset, i, type));
|
||||
value v;
|
||||
if (TYPE_FIELD_STATIC (type, i))
|
||||
{
|
||||
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, i);
|
||||
struct symbol *sym =
|
||||
lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
|
||||
if (! sym) error (
|
||||
"Internal error: could not find physical static variable named %s",
|
||||
phys_name);
|
||||
v = value_at (TYPE_FIELD_TYPE (type, i),
|
||||
(CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
|
||||
}
|
||||
else
|
||||
v = value_primitive_field (arg1, offset, i, type);
|
||||
if (v == 0)
|
||||
error("there is no field named %s", name);
|
||||
return v;
|
||||
|
@ -1016,10 +1045,8 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||
return v2;
|
||||
v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
|
||||
looking_for_baseclass);
|
||||
if (v) return v;
|
||||
else continue;
|
||||
}
|
||||
if (found_baseclass)
|
||||
else if (found_baseclass)
|
||||
v = value_primitive_field (arg1, offset, i, type);
|
||||
else
|
||||
v = search_struct_field (name, arg1,
|
||||
|
@ -1076,23 +1103,23 @@ search_struct_method (name, arg1, 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))
|
||||
{
|
||||
value v2;
|
||||
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
|
||||
&v2, (int *)NULL);
|
||||
if (v2 == 0)
|
||||
error ("virtual baseclass botch");
|
||||
v = search_struct_method (name, v2, args, 0,
|
||||
static_memfuncp, TYPE_BASECLASS (type, i));
|
||||
if (v) return v;
|
||||
else continue;
|
||||
base_offset = 0;
|
||||
}
|
||||
|
||||
v = search_struct_method (name, arg1, args,
|
||||
TYPE_BASECLASS_BITPOS (type, i) / 8,
|
||||
else
|
||||
{
|
||||
v2 = arg1;
|
||||
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
|
||||
}
|
||||
v = search_struct_method (name, v2, args, base_offset,
|
||||
static_memfuncp, TYPE_BASECLASS (type, i));
|
||||
if (v) return v;
|
||||
}
|
||||
|
@ -1234,7 +1261,7 @@ destructor_name_p (name, type)
|
|||
static int
|
||||
check_field_in (type, name)
|
||||
register struct type *type;
|
||||
char *name;
|
||||
const char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
|
@ -1272,7 +1299,7 @@ check_field_in (type, name)
|
|||
|
||||
int
|
||||
check_field (arg1, name)
|
||||
register const value arg1;
|
||||
register value arg1;
|
||||
const char *name;
|
||||
{
|
||||
register struct type *t;
|
||||
|
@ -1296,70 +1323,56 @@ check_field (arg1, name)
|
|||
return check_field_in (t, name);
|
||||
}
|
||||
|
||||
/* C++: Given an aggregate type DOMAIN, and a member name NAME,
|
||||
/* C++: Given an aggregate type CURTYPE, and a member name NAME,
|
||||
return the address of this member as a "pointer to member"
|
||||
type. If INTYPE is non-null, then it will be the type
|
||||
of the member we are looking for. This will help us resolve
|
||||
"pointers to member functions". This function is only used
|
||||
to resolve user expressions of the form "&class::member". */
|
||||
"pointers to member functions". This function is used
|
||||
to resolve user expressions of the form "DOMAIN::NAME". */
|
||||
|
||||
value
|
||||
value_struct_elt_for_address (domain, intype, name)
|
||||
struct type *domain, *intype;
|
||||
value_struct_elt_for_reference (domain, curtype, name, intype)
|
||||
struct type *domain, *curtype, *intype;
|
||||
char *name;
|
||||
{
|
||||
register struct type *t = domain;
|
||||
register struct type *t = curtype;
|
||||
register int i;
|
||||
value v;
|
||||
|
||||
struct type *baseclass;
|
||||
|
||||
if ( TYPE_CODE (t) != TYPE_CODE_STRUCT
|
||||
&& TYPE_CODE (t) != TYPE_CODE_UNION)
|
||||
error ("Internal error: non-aggregate type to value_struct_elt_for_address");
|
||||
error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
|
||||
|
||||
baseclass = t;
|
||||
|
||||
while (t)
|
||||
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
|
||||
{
|
||||
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
|
||||
char *t_field_name = TYPE_FIELD_NAME (t, i);
|
||||
|
||||
if (t_field_name && !strcmp (t_field_name, name))
|
||||
{
|
||||
char *t_field_name = TYPE_FIELD_NAME (t, i);
|
||||
|
||||
if (t_field_name && !strcmp (t_field_name, name))
|
||||
if (TYPE_FIELD_STATIC (t, i))
|
||||
{
|
||||
if (TYPE_FIELD_STATIC (t, i))
|
||||
{
|
||||
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
|
||||
struct symbol *sym =
|
||||
lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
|
||||
if (! sym)
|
||||
error (
|
||||
"Internal error: could not find physical static variable named %s",
|
||||
phys_name);
|
||||
return value_from_longest (
|
||||
lookup_pointer_type (TYPE_FIELD_TYPE (t, i)),
|
||||
(LONGEST)SYMBOL_BLOCK_VALUE (sym));
|
||||
}
|
||||
if (TYPE_FIELD_PACKED (t, i))
|
||||
error ("pointers to bitfield members not allowed");
|
||||
|
||||
return value_from_longest (
|
||||
lookup_pointer_type (
|
||||
lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass)),
|
||||
(LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
|
||||
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
|
||||
struct symbol *sym =
|
||||
lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
|
||||
if (! sym)
|
||||
error (
|
||||
"Internal error: could not find physical static variable named %s",
|
||||
phys_name);
|
||||
return value_at (SYMBOL_TYPE (sym),
|
||||
(CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
|
||||
}
|
||||
if (TYPE_FIELD_PACKED (t, i))
|
||||
error ("pointers to bitfield members not allowed");
|
||||
|
||||
return value_from_longest
|
||||
(lookup_reference_type (lookup_member_type (TYPE_FIELD_TYPE (t, i),
|
||||
domain)),
|
||||
(LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
|
||||
}
|
||||
|
||||
if (TYPE_N_BASECLASSES (t) == 0)
|
||||
break;
|
||||
|
||||
t = TYPE_BASECLASS (t, 0);
|
||||
}
|
||||
|
||||
/* C++: If it was not found as a data field, then try to
|
||||
return it as a pointer to a method. */
|
||||
t = baseclass;
|
||||
|
||||
/* Destructors are a special case. */
|
||||
if (destructor_name_p (name, t))
|
||||
|
@ -1371,55 +1384,59 @@ value_struct_elt_for_address (domain, intype, name)
|
|||
while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR)
|
||||
intype = TYPE_TARGET_TYPE (intype);
|
||||
|
||||
while (t)
|
||||
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
|
||||
{
|
||||
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
|
||||
if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
|
||||
{
|
||||
if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
|
||||
int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
|
||||
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
|
||||
|
||||
if (intype == 0 && j > 1)
|
||||
error ("non-unique member `%s' requires type instantiation", name);
|
||||
if (intype)
|
||||
{
|
||||
int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
|
||||
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
|
||||
|
||||
if (intype == 0 && j > 1)
|
||||
error ("non-unique member `%s' requires type instantiation", name);
|
||||
if (intype)
|
||||
{
|
||||
while (j--)
|
||||
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
|
||||
break;
|
||||
if (j < 0)
|
||||
error ("no member function matches that type instantiation");
|
||||
}
|
||||
else
|
||||
j = 0;
|
||||
|
||||
if (TYPE_FN_FIELD_STUB (f, j))
|
||||
check_stub_method (t, i, j);
|
||||
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
|
||||
{
|
||||
return value_from_longest (
|
||||
lookup_pointer_type (
|
||||
lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||
baseclass)),
|
||||
(LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
|
||||
0, VAR_NAMESPACE, 0, NULL);
|
||||
v = locate_var_value (s, 0);
|
||||
VALUE_TYPE (v) = lookup_pointer_type (
|
||||
lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||
baseclass));
|
||||
return v;
|
||||
while (j--)
|
||||
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
|
||||
break;
|
||||
if (j < 0)
|
||||
error ("no member function matches that type instantiation");
|
||||
}
|
||||
else
|
||||
j = 0;
|
||||
|
||||
if (TYPE_FN_FIELD_STUB (f, j))
|
||||
check_stub_method (t, i, j);
|
||||
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
|
||||
{
|
||||
return value_from_longest
|
||||
(lookup_reference_type
|
||||
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||
domain)),
|
||||
(LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
|
||||
0, VAR_NAMESPACE, 0, NULL);
|
||||
v = read_var_value (s, 0);
|
||||
#if 0
|
||||
VALUE_TYPE (v) = lookup_reference_type
|
||||
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||
domain));
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TYPE_N_BASECLASSES (t) == 0)
|
||||
break;
|
||||
|
||||
t = TYPE_BASECLASS (t, 0);
|
||||
for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--)
|
||||
{
|
||||
v = value_struct_elt_for_reference (domain,
|
||||
TYPE_BASECLASS (t, i),
|
||||
name,
|
||||
intype);
|
||||
if (v)
|
||||
return v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
436
gdb/value.h
436
gdb/value.h
|
@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
|
||||
#if !defined (VALUE_H)
|
||||
#define VALUE_H 1
|
||||
|
||||
/*
|
||||
* The structure which defines the type of a value. It should never
|
||||
* be possible for a program lval value to survive over a call to the inferior
|
||||
|
@ -120,7 +121,9 @@ typedef struct value *value;
|
|||
#define VALUE_CONTENTS_RAW(val) ((char *) (val)->aligner.contents)
|
||||
#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\
|
||||
VALUE_CONTENTS_RAW(val))
|
||||
extern int value_fetch_lazy ();
|
||||
extern int
|
||||
value_fetch_lazy PARAMS ((value val));
|
||||
|
||||
#define VALUE_LVAL(val) (val)->lval
|
||||
#define VALUE_ADDRESS(val) (val)->location.address
|
||||
#define VALUE_INTERNALVAR(val) (val)->location.internalvar
|
||||
|
@ -178,124 +181,287 @@ struct internalvar
|
|||
char *name;
|
||||
value value;
|
||||
};
|
||||
|
||||
|
||||
#include "symtab.h"
|
||||
LONGEST value_as_long (
|
||||
#ifdef __STDC__
|
||||
value
|
||||
#endif
|
||||
);
|
||||
double value_as_double (
|
||||
#ifdef __STDC__
|
||||
value
|
||||
#endif
|
||||
);
|
||||
CORE_ADDR value_as_pointer (
|
||||
#ifdef __STDC__
|
||||
value
|
||||
#endif
|
||||
);
|
||||
LONGEST unpack_long (
|
||||
#ifdef __STDC__
|
||||
struct type *, char *
|
||||
#endif
|
||||
);
|
||||
double unpack_double (
|
||||
#ifdef __STDC__
|
||||
struct type *, char *, int *
|
||||
#endif
|
||||
);
|
||||
CORE_ADDR unpack_pointer (
|
||||
#ifdef __STDC__
|
||||
struct type *, char *
|
||||
#endif
|
||||
);
|
||||
long unpack_field_as_long ();
|
||||
value value_from_longest ();
|
||||
value value_from_double ();
|
||||
value value_at ();
|
||||
value value_at_lazy ();
|
||||
value value_from_register ();
|
||||
value value_of_variable ();
|
||||
value value_of_register ();
|
||||
value read_var_value ();
|
||||
value locate_var_value ();
|
||||
value allocate_value ();
|
||||
value allocate_repeat_value ();
|
||||
value value_mark ();
|
||||
void value_free_to_mark ();
|
||||
value value_string ();
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
|
||||
value value_binop ();
|
||||
value value_add ();
|
||||
value value_sub ();
|
||||
value value_coerce_array ();
|
||||
value value_coerce_function ();
|
||||
value value_ind ();
|
||||
value value_addr ();
|
||||
value value_assign ();
|
||||
value value_neg ();
|
||||
value value_lognot ();
|
||||
value value_struct_elt (), value_struct_elt_for_address ();
|
||||
value value_field (), value_primitive_field ();
|
||||
value value_cast ();
|
||||
value value_zero ();
|
||||
value value_repeat ();
|
||||
value value_subscript ();
|
||||
value value_from_vtable_info ();
|
||||
#ifdef __STDC__
|
||||
struct frame_info;
|
||||
#endif
|
||||
|
||||
value value_being_returned ();
|
||||
int using_struct_return ();
|
||||
void set_return_value ();
|
||||
extern void
|
||||
print_address_demangle PARAMS ((CORE_ADDR, FILE *, int));
|
||||
|
||||
value evaluate_expression ();
|
||||
value evaluate_type ();
|
||||
value parse_and_eval ();
|
||||
value parse_to_comma_and_eval ();
|
||||
struct type *parse_and_eval_type ();
|
||||
extern CORE_ADDR parse_and_eval_address ();
|
||||
extern CORE_ADDR parse_and_eval_address_1 ();
|
||||
extern LONGEST
|
||||
value_as_long PARAMS ((value val));
|
||||
|
||||
value access_value_history ();
|
||||
value value_of_internalvar ();
|
||||
void set_internalvar ();
|
||||
void set_internalvar_component ();
|
||||
struct internalvar *lookup_internalvar ();
|
||||
extern double
|
||||
value_as_double PARAMS ((value val));
|
||||
|
||||
int value_equal ();
|
||||
int value_less ();
|
||||
int value_zerop ();
|
||||
extern CORE_ADDR
|
||||
value_as_pointer PARAMS ((value val));
|
||||
|
||||
extern LONGEST
|
||||
unpack_long PARAMS ((struct type *type, char *valaddr));
|
||||
|
||||
extern double
|
||||
unpack_double PARAMS ((struct type *type, char *valaddr, int *invp));
|
||||
|
||||
extern CORE_ADDR
|
||||
unpack_pointer PARAMS ((struct type *type, char *valaddr));
|
||||
|
||||
extern long
|
||||
unpack_field_as_long PARAMS ((struct type *type, char *valaddr,
|
||||
int fieldno));
|
||||
|
||||
extern value
|
||||
value_from_longest PARAMS ((struct type *type, LONGEST num));
|
||||
|
||||
extern value
|
||||
value_from_double PARAMS ((struct type *type, double num));
|
||||
|
||||
extern value
|
||||
value_at PARAMS ((struct type *type, CORE_ADDR addr));
|
||||
|
||||
extern value
|
||||
value_at_lazy PARAMS ((struct type *type, CORE_ADDR addr));
|
||||
|
||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||
extern value
|
||||
value_from_register PARAMS ((struct type *type, int regnum,
|
||||
struct frame_info * frame));
|
||||
|
||||
extern value
|
||||
value_of_variable PARAMS ((struct symbol *var));
|
||||
|
||||
extern value
|
||||
value_of_register PARAMS ((int regnum));
|
||||
|
||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||
extern value
|
||||
read_var_value PARAMS ((struct symbol *var, struct frame_info *frame));
|
||||
|
||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||
extern value
|
||||
locate_var_value PARAMS ((struct symbol *var, struct frame_info *frame));
|
||||
|
||||
extern value
|
||||
allocate_value PARAMS ((struct type *type));
|
||||
|
||||
extern value
|
||||
allocate_repeat_value PARAMS ((struct type *type, int count));
|
||||
|
||||
extern value
|
||||
value_mark PARAMS ((void));
|
||||
|
||||
extern void
|
||||
value_free_to_mark PARAMS ((value mark));
|
||||
|
||||
extern value
|
||||
value_string PARAMS ((char *ptr, int len));
|
||||
|
||||
extern value
|
||||
value_binop PARAMS ((value arg1, value arg2, enum exp_opcode op));
|
||||
|
||||
extern value
|
||||
value_add PARAMS ((value arg1, value arg2));
|
||||
|
||||
extern value
|
||||
value_sub PARAMS ((value arg1, value arg2));
|
||||
|
||||
extern value
|
||||
value_coerce_array PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_coerce_function PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_ind PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_addr PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_assign PARAMS ((value toval, value fromval));
|
||||
|
||||
extern value
|
||||
value_neg PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_lognot PARAMS ((value arg1));
|
||||
|
||||
extern value
|
||||
value_struct_elt PARAMS ((value *argp, value *args, char *name,
|
||||
int *static_memfuncp, char *err));
|
||||
|
||||
extern value
|
||||
value_struct_elt_for_reference PARAMS ((struct type *domain,
|
||||
struct type *curtype,
|
||||
char *name,
|
||||
struct type *intype));
|
||||
|
||||
extern value
|
||||
value_field PARAMS ((value arg1, int fieldno));
|
||||
|
||||
extern value
|
||||
value_primitive_field PARAMS ((value arg1, int offset, int fieldno,
|
||||
struct type *arg_type));
|
||||
|
||||
extern value
|
||||
value_cast PARAMS ((struct type *type, value arg2));
|
||||
|
||||
extern value
|
||||
value_zero PARAMS ((struct type *type, enum lval_type lv));
|
||||
|
||||
extern value
|
||||
value_repeat PARAMS ((value arg1, int count));
|
||||
|
||||
extern value
|
||||
value_subscript PARAMS ((value array, value idx));
|
||||
|
||||
extern value
|
||||
value_from_vtable_info PARAMS ((value arg, struct type *type));
|
||||
|
||||
extern value
|
||||
value_being_returned PARAMS ((struct type *valtype,
|
||||
char retbuf[REGISTER_BYTES],
|
||||
int struct_return));
|
||||
|
||||
extern int
|
||||
using_struct_return PARAMS ((value function, CORE_ADDR funcaddr,
|
||||
struct type *value_type, int gcc_p));
|
||||
|
||||
extern void
|
||||
set_return_value PARAMS ((value val));
|
||||
|
||||
extern value
|
||||
evaluate_expression PARAMS ((struct expression *exp));
|
||||
|
||||
extern value
|
||||
evaluate_type PARAMS ((struct expression *exp));
|
||||
|
||||
extern value
|
||||
parse_and_eval PARAMS ((char *exp));
|
||||
|
||||
extern value
|
||||
parse_to_comma_and_eval PARAMS ((char **expp));
|
||||
|
||||
extern struct type *
|
||||
parse_and_eval_type PARAMS ((char *p, int length));
|
||||
|
||||
extern CORE_ADDR
|
||||
parse_and_eval_address PARAMS ((char *exp));
|
||||
|
||||
extern CORE_ADDR
|
||||
parse_and_eval_address_1 PARAMS ((char **expptr));
|
||||
|
||||
extern value
|
||||
access_value_history PARAMS ((int num));
|
||||
|
||||
extern value
|
||||
value_of_internalvar PARAMS ((struct internalvar *var));
|
||||
|
||||
extern void
|
||||
set_internalvar PARAMS ((struct internalvar *var, value val));
|
||||
|
||||
extern void
|
||||
set_internalvar_component PARAMS ((struct internalvar *var, int offset,
|
||||
int bitpos, int bitsize,
|
||||
value newvalue));
|
||||
|
||||
extern struct internalvar *
|
||||
lookup_internalvar PARAMS ((char *name));
|
||||
|
||||
extern int
|
||||
value_equal PARAMS ((value arg1, value arg2));
|
||||
|
||||
extern int
|
||||
value_less PARAMS ((value arg1, value arg2));
|
||||
|
||||
extern int
|
||||
value_zerop PARAMS ((value arg1));
|
||||
|
||||
/* C++ */
|
||||
value value_of_this ();
|
||||
value value_static_field ();
|
||||
value value_x_binop ();
|
||||
value value_x_unop ();
|
||||
value value_fn_field ();
|
||||
value value_virtual_fn_field ();
|
||||
int binop_user_defined_p ();
|
||||
int unop_user_defined_p ();
|
||||
int typecmp ();
|
||||
void fill_in_vptr_fieldno ();
|
||||
int destructor_name_p ();
|
||||
|
||||
extern value
|
||||
value_of_this PARAMS ((int complain));
|
||||
|
||||
extern value
|
||||
value_x_binop PARAMS ((value arg1, value arg2, enum exp_opcode op,
|
||||
enum exp_opcode otherop));
|
||||
|
||||
extern value
|
||||
value_x_unop PARAMS ((value arg1, enum exp_opcode op));
|
||||
|
||||
extern value
|
||||
value_fn_field PARAMS ((struct fn_field *f, int j));
|
||||
|
||||
extern value
|
||||
value_virtual_fn_field PARAMS ((value arg1, struct fn_field *f, int j,
|
||||
struct type *type));
|
||||
|
||||
extern int
|
||||
binop_user_defined_p PARAMS ((enum exp_opcode op, value arg1, value arg2));
|
||||
|
||||
extern int
|
||||
unop_user_defined_p PARAMS ((enum exp_opcode op, value arg1));
|
||||
|
||||
extern int
|
||||
typecmp PARAMS ((int staticp, struct type *t1[], value t2[]));
|
||||
|
||||
extern int
|
||||
destructor_name_p PARAMS ((const char *name, const struct type *type));
|
||||
|
||||
#define value_free(val) free (val)
|
||||
void free_all_values ();
|
||||
void release_value ();
|
||||
int record_latest_value ();
|
||||
|
||||
void registers_changed ();
|
||||
void read_register_bytes ();
|
||||
void write_register_bytes ();
|
||||
void read_register_gen ();
|
||||
CORE_ADDR read_register ();
|
||||
void write_register ();
|
||||
void supply_register ();
|
||||
void get_saved_register ();
|
||||
extern void
|
||||
free_all_values PARAMS ((void));
|
||||
|
||||
void modify_field ();
|
||||
void type_print ();
|
||||
void type_print_1 ();
|
||||
extern void
|
||||
release_value PARAMS ((value val));
|
||||
|
||||
extern int
|
||||
record_latest_value PARAMS ((value val));
|
||||
|
||||
extern void
|
||||
registers_changed PARAMS ((void));
|
||||
|
||||
extern void
|
||||
read_register_bytes PARAMS ((int regbyte, char *myaddr, int len));
|
||||
|
||||
extern void
|
||||
write_register_bytes PARAMS ((int regbyte, char *myaddr, int len));
|
||||
|
||||
extern void
|
||||
read_register_gen PARAMS ((int regno, char *myaddr));
|
||||
|
||||
extern CORE_ADDR
|
||||
read_register PARAMS ((int regno));
|
||||
|
||||
extern void
|
||||
write_register PARAMS ((int regno, int val));
|
||||
|
||||
extern void
|
||||
supply_register PARAMS ((int regno, char *val));
|
||||
|
||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||
extern void
|
||||
get_saved_register PARAMS ((char *raw_buffer, int *optimized,
|
||||
CORE_ADDR *addrp, struct frame_info *frame,
|
||||
int regnum, enum lval_type *lval));
|
||||
|
||||
extern void
|
||||
modify_field PARAMS ((char *addr, int fieldval, int bitpos, int bitsize));
|
||||
|
||||
extern void
|
||||
type_print PARAMS ((struct type *type, char *varstring, FILE *stream,
|
||||
int show));
|
||||
|
||||
extern void
|
||||
type_print_1 PARAMS ((struct type *type, char *varstring, FILE *stream,
|
||||
int show, int level));
|
||||
|
||||
/* Possibilities for prettyprint parameters to routines which print
|
||||
things. */
|
||||
|
@ -306,17 +472,53 @@ enum val_prettyprint {
|
|||
Val_pretty_default
|
||||
};
|
||||
|
||||
char *baseclass_addr ();
|
||||
void print_floating ();
|
||||
int value_print ();
|
||||
int val_print ();
|
||||
void print_variable_value ();
|
||||
void typedef_print ();
|
||||
char *internalvar_name ();
|
||||
void clear_value_history ();
|
||||
void clear_internalvars ();
|
||||
extern char *
|
||||
baseclass_addr PARAMS ((struct type *type, int index, char *valaddr,
|
||||
value *valuep, int *errp));
|
||||
|
||||
extern void
|
||||
print_floating PARAMS ((char *valaddr, struct type *type, FILE *stream));
|
||||
|
||||
extern int
|
||||
value_print PARAMS ((value val, FILE *stream, int format,
|
||||
enum val_prettyprint pretty));
|
||||
|
||||
extern int
|
||||
val_print PARAMS ((struct type *type, char *valaddr, CORE_ADDR address,
|
||||
FILE *stream, int format, int deref_ref,
|
||||
int recurse, enum val_prettyprint pretty));
|
||||
|
||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||
extern void
|
||||
print_variable_value PARAMS ((struct symbol *var, struct frame_info *frame,
|
||||
FILE *stream));
|
||||
|
||||
extern value
|
||||
call_function_by_hand PARAMS ((value, int value *));
|
||||
value_arg_coerce PARAMS ((value));
|
||||
|
||||
#endif /* value.h not already included. */
|
||||
extern int
|
||||
check_field PARAMS ((value, const char *));
|
||||
|
||||
extern void
|
||||
typedef_print PARAMS ((struct type *type, struct symbol *new, FILE *stream));
|
||||
|
||||
extern char *
|
||||
internalvar_name PARAMS ((struct internalvar *var));
|
||||
|
||||
extern void
|
||||
clear_value_history PARAMS ((void));
|
||||
|
||||
extern void
|
||||
clear_internalvars PARAMS ((void));
|
||||
|
||||
/* From values.c */
|
||||
|
||||
extern value
|
||||
value_copy PARAMS ((value));
|
||||
|
||||
/* From valops.c */
|
||||
|
||||
extern value
|
||||
call_function_by_hand PARAMS ((value, int, value *));
|
||||
|
||||
#endif /* !defined (VALUE_H) */
|
||||
|
|
78
gdb/values.c
78
gdb/values.c
|
@ -1101,81 +1101,6 @@ value_from_vtable_info (arg, type)
|
|||
return value_headof (arg, 0, type);
|
||||
}
|
||||
|
||||
/* The value of a static class member does not depend
|
||||
on its instance, only on its type. If FIELDNO >= 0,
|
||||
then fieldno is a valid field number and is used directly.
|
||||
Otherwise, FIELDNAME is the name of the field we are
|
||||
searching for. If it is not a static field name, an
|
||||
error is signaled. TYPE is the type in which we look for the
|
||||
static field member.
|
||||
|
||||
Return zero if we couldn't find anything; the caller may signal
|
||||
an error in that case. */
|
||||
|
||||
value
|
||||
value_static_field (type, fieldname, fieldno)
|
||||
register struct type *type;
|
||||
char *fieldname;
|
||||
register int fieldno;
|
||||
{
|
||||
register value v;
|
||||
struct symbol *sym;
|
||||
char *phys_name;
|
||||
|
||||
if (fieldno < 0)
|
||||
{
|
||||
char **physnames;
|
||||
struct symbol **sym_arr;
|
||||
/* Look for static field. */
|
||||
int i;
|
||||
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
|
||||
if (! strcmp (TYPE_FIELD_NAME (type, i), fieldname))
|
||||
{
|
||||
if (TYPE_FIELD_STATIC (type, i))
|
||||
{
|
||||
fieldno = i;
|
||||
goto found;
|
||||
}
|
||||
else
|
||||
error ("field `%s' is not static", fieldname);
|
||||
}
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
v = value_static_field (TYPE_BASECLASS (type, i), fieldname, -1);
|
||||
if (v != 0)
|
||||
return v;
|
||||
}
|
||||
|
||||
sym_arr = (struct symbol **)
|
||||
alloca(TYPE_NFN_FIELDS_TOTAL (type) * sizeof(struct symbol*));
|
||||
physnames = (char **)
|
||||
alloca (TYPE_NFN_FIELDS_TOTAL (type) * sizeof(char*));
|
||||
/* Note: This does duplicate work, since find_methods does a
|
||||
recursive search *and* so does value_static_field. FIXME */
|
||||
i = find_methods (type, fieldname, physnames, sym_arr);
|
||||
if (i > 1)
|
||||
error ("Cannot get value of overloaded method \"%s\"", fieldname);
|
||||
else if (i)
|
||||
{
|
||||
struct symbol *sym = sym_arr[0];
|
||||
value val = read_var_value (sym, (FRAME) 0);
|
||||
if (val == 0)
|
||||
error ("Address of method \"%s\" is unknown (possibly inlined).",
|
||||
fieldname);
|
||||
return val;
|
||||
}
|
||||
error("there is no field named %s", fieldname);
|
||||
}
|
||||
|
||||
found:
|
||||
phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
|
||||
sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
|
||||
if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name);
|
||||
|
||||
type = TYPE_FIELD_TYPE (type, fieldno);
|
||||
return value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
|
||||
}
|
||||
|
||||
/* Compute the address of the baseclass which is
|
||||
the INDEXth baseclass of class TYPE. The TYPE base
|
||||
of the object is at VALADDR.
|
||||
|
@ -1343,7 +1268,8 @@ value_from_longest (type, num)
|
|||
/* FIXME, we assume that pointers have the same form and byte order as
|
||||
integers, and that all pointers have the same form. */
|
||||
if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM ||
|
||||
code == TYPE_CODE_CHAR || code == TYPE_CODE_PTR)
|
||||
code == TYPE_CODE_CHAR || code == TYPE_CODE_PTR ||
|
||||
code == TYPE_CODE_REF)
|
||||
{
|
||||
if (len == sizeof (char))
|
||||
* (char *) VALUE_CONTENTS_RAW (val) = num;
|
||||
|
|
Loading…
Reference in a new issue