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)
|
Thu Mar 19 13:54:11 1992 Fred Fish (fnf@cygnus.com)
|
||||||
|
|
||||||
* coffread.c, mipsread.c, xcoffread.c, coffread.c, dbxread.c,
|
* 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 *));
|
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 <tval> type typebase
|
||||||
%type <tvec> nonempty_typelist
|
%type <tvec> nonempty_typelist
|
||||||
/* %type <bval> block */
|
/* %type <bval> block */
|
||||||
|
@ -257,6 +257,13 @@ exp : exp ARROW name
|
||||||
write_exp_elt_opcode (STRUCTOP_PTR); }
|
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
|
exp : exp ARROW '*' exp
|
||||||
{ write_exp_elt_opcode (STRUCTOP_MPTR); }
|
{ write_exp_elt_opcode (STRUCTOP_MPTR); }
|
||||||
;
|
;
|
||||||
|
@ -267,6 +274,14 @@ exp : exp '.' name
|
||||||
write_exp_elt_opcode (STRUCTOP_STRUCT); }
|
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
|
exp : exp '.' '*' exp
|
||||||
{ write_exp_elt_opcode (STRUCTOP_MEMBER); }
|
{ write_exp_elt_opcode (STRUCTOP_MEMBER); }
|
||||||
;
|
;
|
||||||
|
@ -549,7 +564,7 @@ variable: block COLONCOLON name
|
||||||
write_exp_elt_opcode (OP_VAR_VALUE); }
|
write_exp_elt_opcode (OP_VAR_VALUE); }
|
||||||
;
|
;
|
||||||
|
|
||||||
variable: 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
|
||||||
|
@ -565,6 +580,7 @@ variable: typebase COLONCOLON name
|
||||||
| typebase COLONCOLON '~' name
|
| typebase COLONCOLON '~' name
|
||||||
{
|
{
|
||||||
struct type *type = $1;
|
struct type *type = $1;
|
||||||
|
struct stoken tmp_token;
|
||||||
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
||||||
&& TYPE_CODE (type) != TYPE_CODE_UNION)
|
&& TYPE_CODE (type) != TYPE_CODE_UNION)
|
||||||
error ("`%s' is not defined as an aggregate type.",
|
error ("`%s' is not defined as an aggregate type.",
|
||||||
|
@ -574,12 +590,19 @@ variable: typebase COLONCOLON name
|
||||||
error ("invalid destructor `%s::~%s'",
|
error ("invalid destructor `%s::~%s'",
|
||||||
type_name_no_tag (type), $4.ptr);
|
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_opcode (OP_SCOPE);
|
||||||
write_exp_elt_type (type);
|
write_exp_elt_type (type);
|
||||||
write_exp_string ($4);
|
write_exp_string (tmp_token);
|
||||||
write_exp_elt_opcode (OP_SCOPE);
|
write_exp_elt_opcode (OP_SCOPE);
|
||||||
write_exp_elt_opcode (UNOP_LOGNOT);
|
|
||||||
}
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
variable: qualified_name
|
||||||
| COLONCOLON name
|
| COLONCOLON name
|
||||||
{
|
{
|
||||||
char *name = copy_name ($2);
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
#include "gdbtypes.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "frame.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,
|
/* 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);
|
struct expression *expr = parse_expression (exp);
|
||||||
register CORE_ADDR addr;
|
register CORE_ADDR addr;
|
||||||
register struct cleanup *old_chain
|
register struct cleanup *old_chain =
|
||||||
= make_cleanup (free_current_contents, &expr);
|
make_cleanup (free_current_contents, &expr);
|
||||||
|
|
||||||
addr = value_as_pointer (evaluate_expression (expr));
|
addr = value_as_pointer (evaluate_expression (expr));
|
||||||
do_cleanups (old_chain);
|
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);
|
struct expression *expr = parse_exp_1 (expptr, (struct block *)0, 0);
|
||||||
register CORE_ADDR addr;
|
register CORE_ADDR addr;
|
||||||
register struct cleanup *old_chain
|
register struct cleanup *old_chain =
|
||||||
= make_cleanup (free_current_contents, &expr);
|
make_cleanup (free_current_contents, &expr);
|
||||||
|
|
||||||
addr = value_as_pointer (evaluate_expression (expr));
|
addr = value_as_pointer (evaluate_expression (expr));
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
|
@ -104,21 +134,6 @@ static value evaluate_subexp_for_address ();
|
||||||
static value evaluate_subexp_for_sizeof ();
|
static value evaluate_subexp_for_sizeof ();
|
||||||
static value evaluate_subexp_with_coercion ();
|
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
|
value
|
||||||
evaluate_expression (exp)
|
evaluate_expression (exp)
|
||||||
struct expression *exp;
|
struct expression *exp;
|
||||||
|
@ -149,6 +164,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||||
int tem;
|
int tem;
|
||||||
register int pc, pc2, oldpos;
|
register int pc, pc2, oldpos;
|
||||||
register value arg1, arg2, arg3;
|
register value arg1, arg2, arg3;
|
||||||
|
struct type *type;
|
||||||
int nargs;
|
int nargs;
|
||||||
value *argvec;
|
value *argvec;
|
||||||
|
|
||||||
|
@ -161,8 +177,10 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||||
tem = strlen (&exp->elts[pc + 2].string);
|
tem = strlen (&exp->elts[pc + 2].string);
|
||||||
(*pos) += 3 + ((tem + sizeof (union exp_element))
|
(*pos) += 3 + ((tem + sizeof (union exp_element))
|
||||||
/ sizeof (union exp_element));
|
/ sizeof (union exp_element));
|
||||||
arg1 = value_static_field (exp->elts[pc + 1].type,
|
arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
|
||||||
&exp->elts[pc + 2].string, -1);
|
exp->elts[pc + 1].type,
|
||||||
|
&exp->elts[pc + 2].string,
|
||||||
|
expect_type);
|
||||||
if (arg1 == NULL)
|
if (arg1 == NULL)
|
||||||
error ("There is no field named %s", &exp->elts[pc + 2].string);
|
error ("There is no field named %s", &exp->elts[pc + 2].string);
|
||||||
return arg1;
|
return arg1;
|
||||||
|
@ -448,35 +466,28 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||||
|
|
||||||
case STRUCTOP_MEMBER:
|
case STRUCTOP_MEMBER:
|
||||||
arg1 = evaluate_subexp_for_address (exp, pos, noside);
|
arg1 = evaluate_subexp_for_address (exp, pos, noside);
|
||||||
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
goto handle_pointer_to_member;
|
||||||
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);
|
|
||||||
|
|
||||||
case STRUCTOP_MPTR:
|
case STRUCTOP_MPTR:
|
||||||
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||||
|
handle_pointer_to_member:
|
||||||
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||||
if (noside == EVAL_SKIP)
|
if (noside == EVAL_SKIP)
|
||||||
goto nosideret;
|
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. */
|
/* Now, convert these values to an address. */
|
||||||
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
|
arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
|
||||||
|| (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER
|
arg1);
|
||||||
&& TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD))
|
arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
|
||||||
error ("non-pointer-to-member value used in pointer-to-member construct");
|
value_as_long (arg1) + value_as_long (arg2));
|
||||||
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);
|
return value_ind (arg3);
|
||||||
|
bad_pointer_to_member:
|
||||||
|
error("non-pointer-to-member value used in pointer-to-member construct");
|
||||||
|
|
||||||
case BINOP_ASSIGN:
|
case BINOP_ASSIGN:
|
||||||
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
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. */
|
/* C++: check for and handle destructor names. */
|
||||||
op = exp->elts[*pos].opcode;
|
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);
|
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||||
if (noside == EVAL_SKIP)
|
if (noside == EVAL_SKIP)
|
||||||
goto nosideret;
|
goto nosideret;
|
||||||
|
@ -795,19 +802,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
|
||||||
goto nosideret;
|
goto nosideret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == OP_SCOPE)
|
return evaluate_subexp_for_address (exp, pos, noside);
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
case UNOP_SIZEOF:
|
case UNOP_SIZEOF:
|
||||||
if (noside == EVAL_SKIP)
|
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
#include "gdbtypes.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
@ -29,7 +29,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/* Local functions. */
|
/* 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.
|
/* 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,
|
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 */
|
int v; /* FIXME, this won't work for large bitfields */
|
||||||
read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||||
&v, sizeof v);
|
(char *) &v, sizeof v);
|
||||||
modify_field ((char *) &v, (int) value_as_long (fromval),
|
modify_field ((char *) &v, (int) value_as_long (fromval),
|
||||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||||
write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||||
|
@ -450,7 +469,6 @@ value
|
||||||
value_addr (arg1)
|
value_addr (arg1)
|
||||||
value arg1;
|
value arg1;
|
||||||
{
|
{
|
||||||
extern value value_copy ();
|
|
||||||
struct type *type = VALUE_TYPE (arg1);
|
struct type *type = VALUE_TYPE (arg1);
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_REF)
|
if (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||||
{
|
{
|
||||||
|
@ -543,7 +561,7 @@ push_bytes (sp, buffer, len)
|
||||||
|
|
||||||
/* Push onto the stack the specified value VALUE. */
|
/* Push onto the stack the specified value VALUE. */
|
||||||
|
|
||||||
CORE_ADDR
|
static CORE_ADDR
|
||||||
value_push (sp, arg)
|
value_push (sp, arg)
|
||||||
register CORE_ADDR sp;
|
register CORE_ADDR sp;
|
||||||
value arg;
|
value arg;
|
||||||
|
@ -588,7 +606,7 @@ value_arg_coerce (arg)
|
||||||
/* Push the value ARG, first coercing it as an argument
|
/* Push the value ARG, first coercing it as an argument
|
||||||
to a C function. */
|
to a C function. */
|
||||||
|
|
||||||
CORE_ADDR
|
static CORE_ADDR
|
||||||
value_arg_push (sp, arg)
|
value_arg_push (sp, arg)
|
||||||
register CORE_ADDR sp;
|
register CORE_ADDR sp;
|
||||||
value arg;
|
value arg;
|
||||||
|
@ -599,7 +617,7 @@ value_arg_push (sp, arg)
|
||||||
/* Determine a function's address and its return type from its value.
|
/* Determine a function's address and its return type from its value.
|
||||||
Calls error() if the function is not valid for calling. */
|
Calls error() if the function is not valid for calling. */
|
||||||
|
|
||||||
CORE_ADDR
|
static CORE_ADDR
|
||||||
find_function_addr (function, retval_type)
|
find_function_addr (function, retval_type)
|
||||||
value function;
|
value function;
|
||||||
struct type **retval_type;
|
struct type **retval_type;
|
||||||
|
@ -941,13 +959,13 @@ value_string (ptr, len)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
register int j;
|
struct minimal_symbol *msymbol;
|
||||||
j = lookup_misc_func ("malloc");
|
msymbol = lookup_minimal_symbol ("malloc", (struct objfile *) NULL);
|
||||||
if (j >= 0)
|
if (msymbol != NULL)
|
||||||
val = value_from_longest (
|
val =
|
||||||
lookup_pointer_type (lookup_function_type (
|
value_from_longest (lookup_pointer_type (lookup_function_type (
|
||||||
lookup_pointer_type (builtin_type_char))),
|
lookup_pointer_type (builtin_type_char))),
|
||||||
(LONGEST) misc_function_vector[j].address);
|
(LONGEST) msymbol -> address);
|
||||||
else
|
else
|
||||||
error ("String constants require the program to have a function \"malloc\".");
|
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))
|
if (t_field_name && !strcmp (t_field_name, name))
|
||||||
{
|
{
|
||||||
value v = (TYPE_FIELD_STATIC (type, i)
|
value v;
|
||||||
? value_static_field (type, name, i)
|
if (TYPE_FIELD_STATIC (type, i))
|
||||||
: value_primitive_field (arg1, offset, i, type));
|
{
|
||||||
|
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)
|
if (v == 0)
|
||||||
error("there is no field named %s", name);
|
error("there is no field named %s", name);
|
||||||
return v;
|
return v;
|
||||||
|
@ -1016,10 +1045,8 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
||||||
return v2;
|
return v2;
|
||||||
v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
|
v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
|
||||||
looking_for_baseclass);
|
looking_for_baseclass);
|
||||||
if (v) return v;
|
|
||||||
else continue;
|
|
||||||
}
|
}
|
||||||
if (found_baseclass)
|
else if (found_baseclass)
|
||||||
v = value_primitive_field (arg1, offset, i, type);
|
v = value_primitive_field (arg1, offset, i, type);
|
||||||
else
|
else
|
||||||
v = search_struct_field (name, arg1,
|
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--)
|
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
value v;
|
value v, v2;
|
||||||
|
int base_offset;
|
||||||
|
|
||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
{
|
{
|
||||||
value v2;
|
|
||||||
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)
|
||||||
error ("virtual baseclass botch");
|
error ("virtual baseclass botch");
|
||||||
v = search_struct_method (name, v2, args, 0,
|
base_offset = 0;
|
||||||
static_memfuncp, TYPE_BASECLASS (type, i));
|
|
||||||
if (v) return v;
|
|
||||||
else continue;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
v = search_struct_method (name, arg1, args,
|
{
|
||||||
TYPE_BASECLASS_BITPOS (type, i) / 8,
|
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));
|
static_memfuncp, TYPE_BASECLASS (type, i));
|
||||||
if (v) return v;
|
if (v) return v;
|
||||||
}
|
}
|
||||||
|
@ -1234,7 +1261,7 @@ destructor_name_p (name, type)
|
||||||
static int
|
static int
|
||||||
check_field_in (type, name)
|
check_field_in (type, name)
|
||||||
register struct type *type;
|
register struct type *type;
|
||||||
char *name;
|
const char *name;
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
|
@ -1272,7 +1299,7 @@ check_field_in (type, name)
|
||||||
|
|
||||||
int
|
int
|
||||||
check_field (arg1, name)
|
check_field (arg1, name)
|
||||||
register const value arg1;
|
register value arg1;
|
||||||
const char *name;
|
const char *name;
|
||||||
{
|
{
|
||||||
register struct type *t;
|
register struct type *t;
|
||||||
|
@ -1296,70 +1323,56 @@ check_field (arg1, name)
|
||||||
return check_field_in (t, 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"
|
return the address of this member as a "pointer to member"
|
||||||
type. If INTYPE is non-null, then it will be the type
|
type. If INTYPE is non-null, then it will be the type
|
||||||
of the member we are looking for. This will help us resolve
|
of the member we are looking for. This will help us resolve
|
||||||
"pointers to member functions". This function is only used
|
"pointers to member functions". This function is used
|
||||||
to resolve user expressions of the form "&class::member". */
|
to resolve user expressions of the form "DOMAIN::NAME". */
|
||||||
|
|
||||||
value
|
value
|
||||||
value_struct_elt_for_address (domain, intype, name)
|
value_struct_elt_for_reference (domain, curtype, name, intype)
|
||||||
struct type *domain, *intype;
|
struct type *domain, *curtype, *intype;
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
register struct type *t = domain;
|
register struct type *t = curtype;
|
||||||
register int i;
|
register int i;
|
||||||
value v;
|
value v;
|
||||||
|
|
||||||
struct type *baseclass;
|
|
||||||
|
|
||||||
if ( TYPE_CODE (t) != TYPE_CODE_STRUCT
|
if ( TYPE_CODE (t) != TYPE_CODE_STRUCT
|
||||||
&& TYPE_CODE (t) != TYPE_CODE_UNION)
|
&& 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;
|
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
|
||||||
|
|
||||||
while (t)
|
|
||||||
{
|
{
|
||||||
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 (TYPE_FIELD_STATIC (t, i))
|
||||||
|
|
||||||
if (t_field_name && !strcmp (t_field_name, name))
|
|
||||||
{
|
{
|
||||||
if (TYPE_FIELD_STATIC (t, i))
|
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
|
||||||
{
|
struct symbol *sym =
|
||||||
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
|
lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
|
||||||
struct symbol *sym =
|
if (! sym)
|
||||||
lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
|
error (
|
||||||
if (! sym)
|
"Internal error: could not find physical static variable named %s",
|
||||||
error (
|
phys_name);
|
||||||
"Internal error: could not find physical static variable named %s",
|
return value_at (SYMBOL_TYPE (sym),
|
||||||
phys_name);
|
(CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
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
|
/* C++: If it was not found as a data field, then try to
|
||||||
return it as a pointer to a method. */
|
return it as a pointer to a method. */
|
||||||
t = baseclass;
|
|
||||||
|
|
||||||
/* Destructors are a special case. */
|
/* Destructors are a special case. */
|
||||||
if (destructor_name_p (name, t))
|
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)
|
while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR)
|
||||||
intype = TYPE_TARGET_TYPE (intype);
|
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);
|
while (j--)
|
||||||
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
|
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
|
||||||
|
break;
|
||||||
if (intype == 0 && j > 1)
|
if (j < 0)
|
||||||
error ("non-unique member `%s' requires type instantiation", name);
|
error ("no member function matches that type instantiation");
|
||||||
if (intype)
|
}
|
||||||
{
|
else
|
||||||
while (j--)
|
j = 0;
|
||||||
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
|
|
||||||
break;
|
if (TYPE_FN_FIELD_STUB (f, j))
|
||||||
if (j < 0)
|
check_stub_method (t, i, j);
|
||||||
error ("no member function matches that type instantiation");
|
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
|
||||||
}
|
{
|
||||||
else
|
return value_from_longest
|
||||||
j = 0;
|
(lookup_reference_type
|
||||||
|
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||||
if (TYPE_FN_FIELD_STUB (f, j))
|
domain)),
|
||||||
check_stub_method (t, i, j);
|
(LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
|
||||||
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
|
}
|
||||||
{
|
else
|
||||||
return value_from_longest (
|
{
|
||||||
lookup_pointer_type (
|
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
|
||||||
lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
0, VAR_NAMESPACE, 0, NULL);
|
||||||
baseclass)),
|
v = read_var_value (s, 0);
|
||||||
(LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
|
#if 0
|
||||||
}
|
VALUE_TYPE (v) = lookup_reference_type
|
||||||
else
|
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
||||||
{
|
domain));
|
||||||
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
|
#endif
|
||||||
0, VAR_NAMESPACE, 0, NULL);
|
return v;
|
||||||
v = locate_var_value (s, 0);
|
|
||||||
VALUE_TYPE (v) = lookup_pointer_type (
|
|
||||||
lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
|
|
||||||
baseclass));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TYPE_N_BASECLASSES (t) == 0)
|
for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--)
|
||||||
break;
|
{
|
||||||
|
v = value_struct_elt_for_reference (domain,
|
||||||
t = TYPE_BASECLASS (t, 0);
|
TYPE_BASECLASS (t, i),
|
||||||
|
name,
|
||||||
|
intype);
|
||||||
|
if (v)
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
return 0;
|
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)
|
#if !defined (VALUE_H)
|
||||||
#define VALUE_H 1
|
#define VALUE_H 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The structure which defines the type of a value. It should never
|
* 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
|
* 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_RAW(val) ((char *) (val)->aligner.contents)
|
||||||
#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\
|
#define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\
|
||||||
VALUE_CONTENTS_RAW(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_LVAL(val) (val)->lval
|
||||||
#define VALUE_ADDRESS(val) (val)->location.address
|
#define VALUE_ADDRESS(val) (val)->location.address
|
||||||
#define VALUE_INTERNALVAR(val) (val)->location.internalvar
|
#define VALUE_INTERNALVAR(val) (val)->location.internalvar
|
||||||
|
@ -178,124 +181,287 @@ struct internalvar
|
||||||
char *name;
|
char *name;
|
||||||
value value;
|
value value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
LONGEST value_as_long (
|
#include "gdbtypes.h"
|
||||||
#ifdef __STDC__
|
#include "expression.h"
|
||||||
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 ();
|
|
||||||
|
|
||||||
value value_binop ();
|
#ifdef __STDC__
|
||||||
value value_add ();
|
struct frame_info;
|
||||||
value value_sub ();
|
#endif
|
||||||
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 ();
|
|
||||||
|
|
||||||
value value_being_returned ();
|
extern void
|
||||||
int using_struct_return ();
|
print_address_demangle PARAMS ((CORE_ADDR, FILE *, int));
|
||||||
void set_return_value ();
|
|
||||||
|
|
||||||
value evaluate_expression ();
|
extern LONGEST
|
||||||
value evaluate_type ();
|
value_as_long PARAMS ((value val));
|
||||||
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 ();
|
|
||||||
|
|
||||||
value access_value_history ();
|
extern double
|
||||||
value value_of_internalvar ();
|
value_as_double PARAMS ((value val));
|
||||||
void set_internalvar ();
|
|
||||||
void set_internalvar_component ();
|
|
||||||
struct internalvar *lookup_internalvar ();
|
|
||||||
|
|
||||||
int value_equal ();
|
extern CORE_ADDR
|
||||||
int value_less ();
|
value_as_pointer PARAMS ((value val));
|
||||||
int value_zerop ();
|
|
||||||
|
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++ */
|
/* C++ */
|
||||||
value value_of_this ();
|
|
||||||
value value_static_field ();
|
extern value
|
||||||
value value_x_binop ();
|
value_of_this PARAMS ((int complain));
|
||||||
value value_x_unop ();
|
|
||||||
value value_fn_field ();
|
extern value
|
||||||
value value_virtual_fn_field ();
|
value_x_binop PARAMS ((value arg1, value arg2, enum exp_opcode op,
|
||||||
int binop_user_defined_p ();
|
enum exp_opcode otherop));
|
||||||
int unop_user_defined_p ();
|
|
||||||
int typecmp ();
|
extern value
|
||||||
void fill_in_vptr_fieldno ();
|
value_x_unop PARAMS ((value arg1, enum exp_opcode op));
|
||||||
int destructor_name_p ();
|
|
||||||
|
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)
|
#define value_free(val) free (val)
|
||||||
void free_all_values ();
|
|
||||||
void release_value ();
|
|
||||||
int record_latest_value ();
|
|
||||||
|
|
||||||
void registers_changed ();
|
extern void
|
||||||
void read_register_bytes ();
|
free_all_values PARAMS ((void));
|
||||||
void write_register_bytes ();
|
|
||||||
void read_register_gen ();
|
|
||||||
CORE_ADDR read_register ();
|
|
||||||
void write_register ();
|
|
||||||
void supply_register ();
|
|
||||||
void get_saved_register ();
|
|
||||||
|
|
||||||
void modify_field ();
|
extern void
|
||||||
void type_print ();
|
release_value PARAMS ((value val));
|
||||||
void type_print_1 ();
|
|
||||||
|
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
|
/* Possibilities for prettyprint parameters to routines which print
|
||||||
things. */
|
things. */
|
||||||
|
@ -306,17 +472,53 @@ enum val_prettyprint {
|
||||||
Val_pretty_default
|
Val_pretty_default
|
||||||
};
|
};
|
||||||
|
|
||||||
char *baseclass_addr ();
|
extern char *
|
||||||
void print_floating ();
|
baseclass_addr PARAMS ((struct type *type, int index, char *valaddr,
|
||||||
int value_print ();
|
value *valuep, int *errp));
|
||||||
int val_print ();
|
|
||||||
void print_variable_value ();
|
extern void
|
||||||
void typedef_print ();
|
print_floating PARAMS ((char *valaddr, struct type *type, FILE *stream));
|
||||||
char *internalvar_name ();
|
|
||||||
void clear_value_history ();
|
extern int
|
||||||
void clear_internalvars ();
|
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
|
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);
|
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
|
/* 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.
|
||||||
|
@ -1343,7 +1268,8 @@ value_from_longest (type, num)
|
||||||
/* FIXME, we assume that pointers have the same form and byte order as
|
/* FIXME, we assume that pointers have the same form and byte order as
|
||||||
integers, and that all pointers have the same form. */
|
integers, and that all pointers have the same form. */
|
||||||
if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM ||
|
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))
|
if (len == sizeof (char))
|
||||||
* (char *) VALUE_CONTENTS_RAW (val) = num;
|
* (char *) VALUE_CONTENTS_RAW (val) = num;
|
||||||
|
|
Loading…
Reference in a new issue