+Wed Sep 9 16:50:22 1992 John Gilmore (gnu@cygnus.com)
+
+ Removed a large number of changes inserted by Per Bothner
+ for C++ support. These will go back in when they've been
+ examined.
+
Tue Sep 8 21:05:18 1992 Stu Grossman (grossman at cygnus.com)
* serial.h: Fix prototye for serial_raw().
Fri Sep 4 00:34:30 1992 Per Bothner (bothner@rtl.cygnus.com)
- A bunch of changes mostly to improve debugging of C++ programs.
- Specifically, nested types are supported, and the calling
- of inferiors methods is improved.
-
- * expression.h, c-exp.y: STRUCTOP_PTR and STRUCTOP_STRUCT
- expression types now take an extra parameter that is used
- for an (optional) type qualifier, as in: EXP.TYPE::NAME.
- If there is no qualifier (as in EXP.NAME), the TYPE is NULL.
- (Before, there was a cute but not-quote-valid re-write to
- EXP.*(&TYPE::NAME .)
- * parse.c (length_of_subexp, prefixify_subexp), expprint.c
- (print_subexp), eval.c (evaluate_subexp): Handle the extra
- operand of STRUCTOP_STRUCT and STRUCTOP_PTR.
-
- * value.h: New macros METHOD_PTR_IS_VIRTUAL,
- METHOD_PTR_FROM_VOFFSET, METHOD_PTR_TO_VOFFSET to partially
- hide the implementation details of pointer-to-method objects.
- How to tell if the pointer points to a virtual method is
- still very dependent on the particular compiler, but this
- should make it easier to find the places to change.
- * eval.c (evaluate_subexp [case OP_FUNCALL]), valprint.c
- (val_print [case TYPE_CODE_PTR]): Use the new METHOD_PTR_*
- macros, instead of a hard-wired-in code that incorrectly
- assumed a no-longerused representation of pointer-to-method
- values. And otherwise fix the relevant bit-rotted code.
-
- * valprint.c (type_print_base [case TYPE_CODE_STRUCT]):
- If there are both fields and methods, put a space between.
-
- * gdbtypes.h: New macro TYPE_FIELD_NESTED.
- * symtab.C, syntab.h: New function find_nested_type()
- searches a class recursively for a nested type.
- * c-exp.y: Support nested type syntax: TYPE1::TYPE2.
- This required some nasty interactions between the lexer
- and the parser (surprise, surprise), using the current_type
- global variable (see comment above its declaration),
- and the new function find_nested_type().
- * expprint.c (print_subexp), valprint.c (val_print_fields,
- type_print_base [case TYPE_CODE_STRUCT]): Support nested types.
- * stabsread.c (read_struct_type): Recognize types fields
- nested in classes.
-
- * gdbtypes.c, symtab.h: New functions check_struct,
- check_union, and check_enum (factored out from lookup_struct,
- lookup_union, lookup_enum).
- * c-exp.y: Support 'enum Foo::Bar' syntax as just the same
- as 'Foo::Bar' followed by a call to check_enum. Similarly
- for struct and union.
-
- * stabsread.c (read_struct_type): Fix bug in handling of
- GNU C++ anonymous type (indicated by CPLUS_MARKER followed
- by '_'). (It used to prematurely exit the loop reading in
- the fields, so it would think it should start reading
- methods while still in the fields. This could crash gdb
- given a gcc that can emit nested type information.)
-
- * valops.c (search_struct_method): Pass 'this' value by
- reference instead of by value. This provides a more
- consistent interface through a recursive search where the
- "bottom" functions may need to adjust offsets (due to multiple
- inheritance).
- * valops.c, value.h, values.c: Pass extra parameters to
- value_fn_field and value_virtual_fn_field so we can
- correctly adjust offset for multiple inheritance.
- * eval.c (evaluate_subexp [case OP_FUNCALL]): Simplify
- virtual function calls by using value_virtual_fn_field().
- * values.c: New function baseclass_offset, derived from
- baseclass_addr (which perhaps can be made obsolete?).
- It returns an offset rather than an address. This is a
- cleaner interface since it doesn't mess around allocating
- new values.
- * valops.c (search_struct_method): Use baseclass_offset
- rather than baseclass_addr.
-
* symfile.h: Declaration of set_demangling_style() moved
here from demangle.h (which is now in ../include).
* i386-xdep.c: Update comment.
- * utils.c (strcmp_iw): Add a hack to allow "FOO(ARGS)" to
- match "FOO". This allows 'break Foo' to work when Foo is
- a mangled C++ function. (See comment before function.)
Thu Sep 3 13:44:46 1992 K. Richard Pixley (rich@sendai.cygnus.com)
* symtab.c (completion_list_add_symbol): restructured to optimize
- for time. First clip names that cannot match. Then clip any
- names we've already considered. Drop a redundant strncpy. Drop
- a redundant malloc and associated free for demangled names.
+ for time. First clip names that cannot match. Then clip any
+ names we've already considered. Drop a redundant strncpy. Drop
+ a redundant malloc and associated free for demangled names.
Thu Sep 3 09:17:05 1992 Stu Grossman (grossman at cygnus.com)
#include "symfile.h"
#include "objfiles.h"
-/* If current_type is non-NULL, it is a signal to the lexer that we have
- just parsed: 'TYPE ::' and so if an identifier is seen, the lexer must
- search for it in TYPE. This lex-time search is needed to parse
- C++ nested types, as in: 'TYPE :: NESTED_TYPE', since this must
- parse as a type, not a (non-type) identifier. */
-
-static struct type *current_type = NULL;
-
/* These MUST be included in any grammar file!!!! Please choose unique names!
Note that this are a combined list of variables that can be produced
by any one of bison, byacc, or yacc. */
%}
%type <voidval> exp exp1 type_exp start variable qualified_name
-%type <tval> type typebase typebase_coloncolon qualified_type
+%type <tval> type typebase
%type <tvec> nonempty_typelist
/* %type <bval> block */
%token <sval> STRING
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
%token <tsym> TYPENAME
-%token <tval> NESTED_TYPE
%type <sval> name
%type <ssym> name_not_typename
%type <tsym> typename
exp : exp ARROW name
{ write_exp_elt_opcode (STRUCTOP_PTR);
- write_exp_elt_type (NULL);
write_exp_string ($3);
write_exp_elt_opcode (STRUCTOP_PTR); }
;
-exp : exp ARROW typebase_coloncolon name
- { write_exp_elt_opcode (STRUCTOP_PTR);
- write_exp_elt_type ($3);
- write_exp_string ($4);
- write_exp_elt_opcode (STRUCTOP_PTR); }
+exp : exp ARROW qualified_name
+ { /* exp->type::name becomes exp->*(&type::name) */
+ /* Note: this doesn't work if name is a
+ static member! FIXME */
+ write_exp_elt_opcode (UNOP_ADDR);
+ write_exp_elt_opcode (STRUCTOP_MPTR); }
;
exp : exp ARROW '*' exp
{ write_exp_elt_opcode (STRUCTOP_MPTR); }
exp : exp '.' name
{ write_exp_elt_opcode (STRUCTOP_STRUCT);
- write_exp_elt_type (NULL);
write_exp_string ($3);
write_exp_elt_opcode (STRUCTOP_STRUCT); }
;
-exp : exp '.' typebase_coloncolon name
- { write_exp_elt_opcode (STRUCTOP_STRUCT);
- write_exp_elt_type ($3);
- write_exp_string ($4);
- write_exp_elt_opcode (STRUCTOP_STRUCT); }
+exp : exp '.' qualified_name
+ { /* exp.type::name becomes exp.*(&type::name) */
+ /* Note: this doesn't work if name is a
+ static member! FIXME */
+ write_exp_elt_opcode (UNOP_ADDR);
+ write_exp_elt_opcode (STRUCTOP_MEMBER); }
;
exp : exp '.' '*' exp
write_exp_elt_opcode (OP_VAR_VALUE); }
;
-typebase_coloncolon : typebase COLONCOLON { current_type = $1; $$ = $1; }
-
-qualified_name: typebase_coloncolon name
+qualified_name: typebase COLONCOLON name
{
struct type *type = $1;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
- write_exp_string ($2);
+ write_exp_string ($3);
write_exp_elt_opcode (OP_SCOPE);
- current_type = NULL;
}
- | typebase_coloncolon '~' name
+ | typebase COLONCOLON '~' name
{
struct type *type = $1;
struct stoken tmp_token;
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
- if (strcmp (type_name_no_tag (type), $3.ptr))
+ if (strcmp (type_name_no_tag (type), $4.ptr))
error ("invalid destructor `%s::~%s'",
- type_name_no_tag (type), $3.ptr);
+ type_name_no_tag (type), $4.ptr);
- tmp_token.ptr = (char*) alloca ($3.length + 2);
- tmp_token.length = $3.length + 1;
+ tmp_token.ptr = (char*) alloca ($4.length + 2);
+ tmp_token.length = $4.length + 1;
tmp_token.ptr[0] = '~';
- memcpy (tmp_token.ptr+1, $3.ptr, $3.length);
+ memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
tmp_token.ptr[tmp_token.length] = 0;
write_exp_elt_opcode (OP_SCOPE);
write_exp_elt_type (type);
write_exp_string (tmp_token);
write_exp_elt_opcode (OP_SCOPE);
- current_type = NULL;
}
;
{ free ((PTR)$2); $$ = 0; }
;
-qualified_type: typebase_coloncolon NESTED_TYPE
- { $$ = $2; current_type = NULL; }
- ;
-
type : ptype
- | qualified_type
- | typebase_coloncolon '*'
- { $$ = lookup_member_type (builtin_type_int, $1);
- current_type = NULL; }
+ | typebase COLONCOLON '*'
+ { $$ = lookup_member_type (builtin_type_int, $1); }
| type '(' typebase COLONCOLON '*' ')'
{ $$ = lookup_member_type ($1, $3); }
| type '(' typebase COLONCOLON '*' ')' '(' ')'
| ENUM name
{ $$ = lookup_enum (copy_name ($2),
expression_context_block); }
- | STRUCT qualified_type { $$ = check_struct ($2); }
- | CLASS qualified_type { $$ = check_struct ($2); }
- | UNION qualified_type { $$ = check_union ($2); }
- | ENUM qualified_type { $$ = check_enum ($2); }
| UNSIGNED typename
{ $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
| UNSIGNED
return VARIABLE;
}
- if (current_type)
- {
- struct type *t =
- find_nested_type (current_type, copy_name (yylval.sval));
- if (t)
- {
- yylval.tval = t;
- return NESTED_TYPE;
- }
- }
-
/* Use token-type BLOCKNAME for symbols that happen to be defined as
functions or symtabs. If this is not so, then ...
Use token-type TYPENAME for symbols that happen to be defined
return lookup_typename (name, (struct block *) NULL, 0);
}
-struct type *
-check_struct (type)
- struct type *type;
-{
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
- error ("This context has %s, not a struct or class.", TYPE_NAME (type));
- return type;
-}
-
/* Lookup a structure type named "struct NAME",
visible in lexical block BLOCK. */
{
error ("No struct type named %s.", name);
}
- return check_struct (SYMBOL_TYPE (sym));
-}
-
-struct type *
-check_union (type)
- struct type *type;
-{
- if (TYPE_CODE (type) != TYPE_CODE_UNION)
- error ("This context has %s, not a union.", TYPE_NAME (type));
- return type;
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
+ {
+ error ("This context has class, union or enum %s, not a struct.", name);
+ }
+ return (SYMBOL_TYPE (sym));
}
/* Lookup a union type named "union NAME",
{
error ("No union type named %s.", name);
}
- return check_union (SYMBOL_TYPE (sym));
-}
-
-struct type *
-check_enum (type)
- struct type *type;
-{
- if (TYPE_CODE (type) != TYPE_CODE_ENUM)
- error ("This context has %s, not an enum.", TYPE_NAME (type));
- return type;
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
+ {
+ error ("This context has class, struct or enum %s, not a union.", name);
+ }
+ return (SYMBOL_TYPE (sym));
}
/* Lookup an enum type named "enum NAME",
{
error ("No enum type named %s.", name);
}
- return check_enum (SYMBOL_TYPE (sym));
+ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
+ {
+ error ("This context has class, struct or union %s, not an enum.", name);
+ }
+ return (SYMBOL_TYPE (sym));
}
/* Lookup a template type named "template NAME<TYPE>",
B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1)
-#define TYPE_FIELD_NESTED(thistype, n) ((thistype)->fields[n].bitpos == -2)
#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize)
#define TYPE_FN_FIELDLISTS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->fn_fieldlists
switch (i)
{
- case STRUCTOP_STRUCT:
- case STRUCTOP_PTR:
- args = 1;
/* C++ */
case OP_SCOPE:
oplen = 4 + ((expr->elts[endpos - 2].longconst
args = 1;
break;
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ args = 1;
case OP_M2_STRING:
case OP_STRING:
oplen = 3 + ((expr->elts[endpos - 2].longconst
opcode = inexpr->elts[inend - 1].opcode;
switch (opcode)
{
- case STRUCTOP_STRUCT:
- case STRUCTOP_PTR:
- args = 1;
/* C++ */
case OP_SCOPE:
oplen = 4 + ((inexpr->elts[inend - 2].longconst
args=1;
break;
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ args = 1;
case OP_M2_STRING:
case OP_STRING:
oplen = 3 + ((inexpr->elts[inend - 2].longconst
case '#': /* Method (class & fn) type */
if ((*pp)[0] == '#')
{
- /* This "minimized" format bogus, because it doesn't yield
- enough information. I've changed gcc to not emit it. --Per */
+ /* We'll get the parameter types from the name. */
struct type *return_type;
*pp += 1;
p = *pp;
if (*p == CPLUS_MARKER)
{
- if (*p == '_') /* GNU C++ anonymous type. */
- ;
/* Special GNU C++ name. */
- else if (*++p == 'v')
+ if (*++p == 'v')
{
const char *prefix;
char *name = 0;
list->field.bitsize = 0;
list->visibility = 0; /* private */
non_public_fields++;
-
- nfields++;
- continue;
}
+ /* GNU C++ anonymous type. */
+ else if (*p == '_')
+ break;
else
complain (&invalid_cpp_abbrev_complaint, *pp);
+
+ nfields++;
+ continue;
}
while (*p != ':') p++;
if (**pp == ':')
{
p = ++(*pp);
+#if 0
+ /* Possible future hook for nested types. */
if (**pp == '!')
- { /* C++ nested type -as in FOO::BAR */
- list->field.bitpos = (long)(-2); /* nested type */
+ {
+ list->field.bitpos = (long)-2; /* nested type */
p = ++(*pp);
- if (TYPE_NAME (list->field.type) == NULL && **pp == '\'')
- {
- for (p = ++(*pp); *p != '\''; ) p++;
- TYPE_NAME (list->field.type) = savestring (*pp, p - *pp);
- }
- while (*p != ';') p++;
- list->field.bitsize = 0;
- *pp = p + 1;
}
else
+#endif
{ /* Static class member. */
- list->field.bitpos = (long)(-1);
- while (*p != ';') p++;
- list->field.bitsize = (long) savestring (*pp, p - *pp);
- *pp = p + 1;
+ list->field.bitpos = (long)-1;
}
+ while (*p != ';') p++;
+ list->field.bitsize = (long) savestring (*pp, p - *pp);
+ *pp = p + 1;
nfields++;
continue;
}
return sal.symtab != 0;
}
\f
-struct type *
-find_nested_type (type, name)
- struct type *type;
- char *name;
-{
- int i;
- for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
- {
- char *t_field_name = TYPE_FIELD_NAME (type, i);
-
- if (t_field_name && !strcmp (t_field_name, name))
- if (TYPE_FIELD_NESTED (type, i))
- {
- return TYPE_FIELD_TYPE (type, i);
- }
- }
- for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
- {
- struct type * t = find_nested_type (TYPE_BASECLASS (type, i), name);
- if (t)
- return t;
- }
- return NULL;
-}
-
/* If P is of the form "operator[ \t]+..." where `...' is
some legitimate operator text, return a pointer to the
beginning of the substring of the operator text.
search_struct_field PARAMS ((char *, value, int, struct type *, int));
static value
-search_struct_method PARAMS ((char *, value *, value *, int, int *,
+search_struct_method PARAMS ((char *, value, value *, int, int *,
struct type *));
static int
if (BASETYPE_VIA_VIRTUAL (type, i))
{
value v2;
- /* Fix to use baseclass_offset instead. FIXME */
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
&v2, (int *)NULL);
if (v2 == 0)
If found, return value, else return NULL. */
static value
-search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
+search_struct_method (name, arg1, args, offset, static_memfuncp, type)
char *name;
- register value *arg1p, *args;
+ register value arg1, *args;
int offset, *static_memfuncp;
register struct type *type;
{
TYPE_FN_FIELD_ARGS (f, j), args))
{
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
- return (value)value_virtual_fn_field (arg1p, f, j, type, offset);
+ return (value)value_virtual_fn_field (arg1, f, j, type);
if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
*static_memfuncp = 1;
- return (value)value_fn_field (arg1p, f, j, type, offset);
+ return (value)value_fn_field (f, j);
}
j--;
}
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
- value v;
+ value v, v2;
int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- base_offset =
- baseclass_offset (type, i, *arg1p, offset);
- if (base_offset == -1)
+ baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
+ &v2, (int *)NULL);
+ if (v2 == 0)
error ("virtual baseclass botch");
+ base_offset = 0;
}
else
{
+ v2 = arg1;
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
}
- v = search_struct_method (name, arg1p, args, base_offset + offset,
+ v = search_struct_method (name, v2, args, base_offset,
static_memfuncp, TYPE_BASECLASS (type, i));
- if (v)
- {
-/* *arg1p = arg1_tmp;*/
- return v;
- }
+ if (v) return v;
}
return NULL;
}
if (destructor_name_p (name, t))
error ("Cannot get value of destructor");
- v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
+ v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
if (v == 0)
{
if (!args[1])
{
/* destructors are a special case. */
- return (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
- TYPE_FN_FIELDLIST_LENGTH (t, 0),
- 0, 0);
+ return (value)value_fn_field (TYPE_FN_FIELDLIST1 (t, 0),
+ TYPE_FN_FIELDLIST_LENGTH (t, 0));
}
else
{
}
}
else
- v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
+ v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
if (v == 0)
{
(lookup_reference_type
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
domain)),
- METHOD_PTR_FROM_VOFFSET((LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)));
+ (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
}
else
{
for (i = n_baseclasses; i < len; i++)
{
/* Check if static field */
- if (TYPE_FIELD_STATIC (type, i) || TYPE_FIELD_NESTED (type, i))
+ if (TYPE_FIELD_STATIC (type, i))
continue;
if (fields_seen)
fprintf_filtered (stream, ", ");
obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i));
}
- /* Fix to use baseclass_offset instead. FIXME */
baddr = baseclass_addr (type, i, valaddr, 0, &err);
if (err == 0 && baddr == 0)
error ("could not find virtual baseclass `%s'\n",
addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr);
- if (METHOD_PTR_IS_VIRTUAL(addr))
+ if (addr < 128) /* FIXME! What is this 128? */
{
- int offset = METHOD_PTR_TO_VOFFSET(addr);
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
for (j = 0; j < len2; j++)
{
QUIT;
- if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
+ if (TYPE_FN_FIELD_VOFFSET (f, j) == addr)
{
- kind = "virtual ";
+ kind = "virtual";
goto common;
}
}
{
fprintf_filtered (stream, "static ");
}
- if (TYPE_FIELD_NESTED (type, i))
- {
- fprintf_filtered (stream, "typedef ");
- }
type_print_1 (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4);
- if (!TYPE_FIELD_STATIC (type, i) && !TYPE_FIELD_NESTED (type, i)
+ if (!TYPE_FIELD_STATIC (type, i)
&& TYPE_FIELD_PACKED (type, i))
{
/* It is a bitfield. This code does not attempt
fprintf_filtered (stream, ";\n");
}
- /* If there are both fields and methods, put a space between. */
- len = TYPE_NFN_FIELDS (type);
- if (len && section_type != s_none)
- fprintf_filtered (stream, "\n");
-
/* C++: print out the methods */
-
+ len = TYPE_NFN_FIELDS (type);
for (i = 0; i < len; i++)
{
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
J is an index into F which provides the desired method. */
value
-value_fn_field (arg1p, f, j, type, offset)
- value *arg1p;
+value_fn_field (f, j)
struct fn_field *f;
int j;
- struct type *type;
- int offset;
{
register value v;
- register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+ register struct type *type = TYPE_FN_FIELD_TYPE (f, j);
struct symbol *sym;
sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
if (! sym) error ("Internal error: could not find physical method named %s",
TYPE_FN_FIELD_PHYSNAME (f, j));
- v = allocate_value (ftype);
+ v = allocate_value (type);
VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- VALUE_TYPE (v) = ftype;
-
- if (arg1p)
- {
- if (type != VALUE_TYPE (*arg1p))
- *arg1p = value_ind (value_cast (lookup_pointer_type (type),
- value_addr (*arg1p)));
-
- /* Move the `this' pointer according to the offset. */
- VALUE_OFFSET (*arg1p) += offset;
- }
-
+ VALUE_TYPE (v) = type;
return v;
}
/* Return a virtual function as a value.
ARG1 is the object which provides the virtual function
- table pointer. *ARG1P is side-effected in calling this function.
+ table pointer. ARG1 is side-effected in calling this function.
F is the list of member functions which contains the desired virtual
function.
J is an index into F which provides the desired virtual function.
TYPE is the type in which F is located. */
value
-value_virtual_fn_field (arg1p, f, j, type, offset)
- value *arg1p;
+value_virtual_fn_field (arg1, f, j, type)
+ value arg1;
struct fn_field *f;
int j;
struct type *type;
- int offset;
{
- value arg1 = *arg1p;
/* First, get the virtual function table pointer. That comes
with a strange type, so cast it to type `pointer to long' (which
should serve just fine as a function type). Then, index into
/* The virtual function table is now an array of structures
which have the form { int16 offset, delta; void *pfn; }. */
- vtbl = value_ind (value_primitive_field (arg1, 0,
- TYPE_VPTR_FIELDNO (context),
- TYPE_VPTR_BASETYPE (context)));
+ vtbl = value_ind (value_field (arg1, TYPE_VPTR_FIELDNO (context)));
/* Index into the virtual function table. This is hard-coded because
looking up a field is not cheap, and it may be important to save
entry = value_subscript (vtbl, vi);
/* Move the `this' pointer according to the virtual function table. */
- VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)) + offset;
+ VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
if (! VALUE_LAZY (arg1))
{
VALUE_LAZY (arg1) = 1;
/* Reinstantiate the function pointer with the correct type. */
VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
- *arg1p = arg1;
return vfn;
}
return value_headof (arg, 0, type);
}
-/* Compute the offset of the baseclass which is
- the INDEXth baseclass of class TYPE, for a value ARG,
- wih extra offset of OFFSET.
- The result is the offste of the baseclass value relative
- to (the address of)(ARG) + OFFSET.
-
- -1 is returned on error. */
-
-int
-baseclass_offset (type, index, arg, offset)
- struct type *type;
- int index;
- value arg;
- int offset;
-{
- struct type *basetype = TYPE_BASECLASS (type, index);
-
- if (BASETYPE_VIA_VIRTUAL (type, index))
- {
- /* Must hunt for the pointer to this virtual baseclass. */
- register int i, len = TYPE_NFIELDS (type);
- register int n_baseclasses = TYPE_N_BASECLASSES (type);
- char *vbase_name, *type_name = type_name_no_tag (basetype);
-
- vbase_name = (char *)alloca (strlen (type_name) + 8);
- sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name);
- /* First look for the virtual baseclass pointer
- in the fields. */
- for (i = n_baseclasses; i < len; i++)
- {
- if (! strcmp (vbase_name, TYPE_FIELD_NAME (type, i)))
- {
- CORE_ADDR addr
- = unpack_pointer (TYPE_FIELD_TYPE (type, i),
- VALUE_CONTENTS (arg) + VALUE_OFFSET (arg)
- + offset
- + (TYPE_FIELD_BITPOS (type, i) / 8));
-
- if (VALUE_LVAL (arg) != lval_memory)
- return -1;
-
- return addr -
- (LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset);
- }
- }
- /* Not in the fields, so try looking through the baseclasses. */
- for (i = index+1; i < n_baseclasses; i++)
- {
- int boffset =
- baseclass_offset (type, i, arg, offset);
- if (boffset)
- return boffset;
- }
- /* Not found. */
- return -1;
- }
-
- /* Baseclass is easily computed. */
- return TYPE_BASECLASS_BITPOS (type, index) / 8;
-}
-
/* Compute the address of the baseclass which is
the INDEXth baseclass of class TYPE. The TYPE base
of the object is at VALADDR.
of the baseclasss, but the address which could not be read
successfully. */
-/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */
-
char *
baseclass_addr (type, index, valaddr, valuep, errp)
struct type *type;