aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPer Bothner <per@bothner.com>1992-03-20 21:57:17 +0000
committerPer Bothner <per@bothner.com>1992-03-20 21:57:17 +0000
commit01be69139ed994faaf4119d193bec3816e4c9a09 (patch)
tree5e5099cdfa7f5bba0f559b85cbc86453891f6e37 /gdb
parent52963fb7e9af7fc83cbdad45299edaf2dc9cc59a (diff)
downloadgdb-01be69139ed994faaf4119d193bec3816e4c9a09.zip
gdb-01be69139ed994faaf4119d193bec3816e4c9a09.tar.gz
gdb-01be69139ed994faaf4119d193bec3816e4c9a09.tar.bz2
More C++ improvements (pointers to members, qualified names). See ChangeLog.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog32
-rw-r--r--gdb/c-exp.y31
-rw-r--r--gdb/eval.c119
-rw-r--r--gdb/valops.c247
-rw-r--r--gdb/value.h446
-rw-r--r--gdb/values.c78
6 files changed, 574 insertions, 379 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6fb9b11..346d718 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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,
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index c131643..bbf66e0 100644
--- a/gdb/c-exp.y
+++ b/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);
diff --git a/gdb/eval.c b/gdb/eval.c
index aff3a3a..c4ba5ab 100644
--- a/gdb/eval.c
+++ b/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)
diff --git a/gdb/valops.c b/gdb/valops.c
index 83d6ec8..1213e9e 100644
--- a/gdb/valops.c
+++ b/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");
-
- baseclass = t;
+ error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
- 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;
}
diff --git a/gdb/value.h b/gdb/value.h
index a6840d1..7333578 100644
--- a/gdb/value.h
+++ b/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 (
+#include "gdbtypes.h"
+#include "expression.h"
+
#ifdef __STDC__
- struct type *, char *
+struct frame_info;
#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 ();
-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 ();
-
-value value_being_returned ();
-int using_struct_return ();
-void set_return_value ();
-
-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 ();
-
-value access_value_history ();
-value value_of_internalvar ();
-void set_internalvar ();
-void set_internalvar_component ();
-struct internalvar *lookup_internalvar ();
-
-int value_equal ();
-int value_less ();
-int value_zerop ();
+
+extern void
+print_address_demangle PARAMS ((CORE_ADDR, FILE *, int));
+
+extern LONGEST
+value_as_long PARAMS ((value val));
+
+extern double
+value_as_double PARAMS ((value val));
+
+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 ();
-
-void modify_field ();
-void type_print ();
-void type_print_1 ();
+
+extern void
+free_all_values PARAMS ((void));
+
+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
+value_arg_coerce PARAMS ((value));
+
+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 *));
+call_function_by_hand PARAMS ((value, int, value *));
-#endif /* value.h not already included. */
+#endif /* !defined (VALUE_H) */
diff --git a/gdb/values.c b/gdb/values.c
index bb5fa68..3dc1acc 100644
--- a/gdb/values.c
+++ b/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;