Move TYPE_SELF_TYPE into new field type_specific.
This patch moves TYPE_SELF_TYPE into new field type_specific.self_type for MEMBERPTR,METHODPTR types, and into type_specific.func_stuff for METHODs, and then updates everything to use that. TYPE_CODE_METHOD could share some things with TYPE_CODE_FUNC (e.g. TYPE_NO_RETURN) and it seemed simplest to keep them together. Moving TYPE_SELF_TYPE into type_specific.func_stuff for TYPE_CODE_METHOD is also nice because when we allocate space for function types we assume they're TYPE_CODE_FUNCs. If TYPE_CODE_METHODs don't need or use that space then that space would be wasted, and cleaning that up would involve more invasive changes. In order to catch errant uses I've added accessor functions that do some checking. One can no longer assign to TYPE_SELF_TYPE like this: TYPE_SELF_TYPE (foo) = bar; One instead has to do: set_type_self_type (foo, bar); But I've left reading of the type to the macro: bar = TYPE_SELF_TYPE (foo); In order to discourage bypassing the TYPE_SELF_TYPE macro I've named the underlying function that implements it internal_type_self_type. While testing this I found the stabs reader leaving methods as TYPE_CODE_FUNCs, hitting my newly added asserts. Since the dwarf reader smashes functions to methods (via smash_to_method) I've done a similar thing for stabs. gdb/ChangeLog: * cp-valprint.c (cp_find_class_member): Rename parameter domain_p to self_p. (cp_print_class_member): Rename local domain to self_type. * dwarf2read.c (quirk_gcc_member_function_pointer): Rename local domain_type to self_type. (set_die_type) <need_gnat_info>: Handle TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, TYPE_CODE_METHOD. * gdb-gdb.py (StructMainTypePrettyPrinter): Handle TYPE_SPECIFIC_SELF_TYPE. * gdbtypes.c (internal_type_self_type): New function. (set_type_self_type): New function. (smash_to_memberptr_type): Rename parameter domain to self_type. Update setting of TYPE_SELF_TYPE. (smash_to_methodptr_type): Update setting of TYPE_SELF_TYPE. (smash_to_method_type): Rename parameter domain to self_type. Update setting of TYPE_SELF_TYPE. (check_stub_method): Call smash_to_method_type. (recursive_dump_type): Handle TYPE_SPECIFIC_SELF_TYPE. (copy_type_recursive): Ditto. * gdbtypes.h (enum type_specific_kind): New value TYPE_SPECIFIC_SELF_TYPE. (struct main_type) <type_specific>: New member self_type. (struct cplus_struct_type) <fn_field.type>: Update comment. (TYPE_SELF_TYPE): Rewrite. (internal_type_self_type, set_type_self_type): Declare. * gnu-v3-abi.c (gnuv3_print_method_ptr): Rename local domain to self_type. (gnuv3_method_ptr_to_value): Rename local domain_type to self_type. * m2-typeprint.c (m2_range): Replace TYPE_SELF_TYPE with TYPE_TARGET_TYPE. * stabsread.c (read_member_functions): Mark methods with TYPE_CODE_METHOD, not TYPE_CODE_FUNC. Update setting of TYPE_SELF_TYPE.
This commit is contained in:
parent
4bfb94b864
commit
09e2d7c720
9 changed files with 190 additions and 68 deletions
|
@ -1188,7 +1188,58 @@ init_vector_type (struct type *elt_type, int n)
|
|||
return array_type;
|
||||
}
|
||||
|
||||
/* Smash TYPE to be a type of pointers to members of DOMAIN with type
|
||||
/* Internal routine called by TYPE_SELF_TYPE to return the type that TYPE
|
||||
belongs to. In c++ this is the class of "this", but TYPE_THIS_TYPE is too
|
||||
confusing. "self" is a common enough replacement for "this".
|
||||
TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
|
||||
TYPE_CODE_METHOD. */
|
||||
|
||||
struct type *
|
||||
internal_type_self_type (struct type *type)
|
||||
{
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_METHODPTR:
|
||||
case TYPE_CODE_MEMBERPTR:
|
||||
gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
|
||||
return TYPE_MAIN_TYPE (type)->type_specific.self_type;
|
||||
case TYPE_CODE_METHOD:
|
||||
gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
|
||||
return TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type;
|
||||
default:
|
||||
gdb_assert_not_reached ("bad type");
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the type of the class that TYPE belongs to.
|
||||
In c++ this is the class of "this".
|
||||
TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
|
||||
TYPE_CODE_METHOD. */
|
||||
|
||||
void
|
||||
set_type_self_type (struct type *type, struct type *self_type)
|
||||
{
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_METHODPTR:
|
||||
case TYPE_CODE_MEMBERPTR:
|
||||
if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
|
||||
TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_SELF_TYPE;
|
||||
gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
|
||||
TYPE_MAIN_TYPE (type)->type_specific.self_type = self_type;
|
||||
break;
|
||||
case TYPE_CODE_METHOD:
|
||||
if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
|
||||
INIT_FUNC_SPECIFIC (type);
|
||||
gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
|
||||
TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type = self_type;
|
||||
break;
|
||||
default:
|
||||
gdb_assert_not_reached ("bad type");
|
||||
}
|
||||
}
|
||||
|
||||
/* Smash TYPE to be a type of pointers to members of SELF_TYPE with type
|
||||
TO_TYPE. A member pointer is a wierd thing -- it amounts to a
|
||||
typed offset into a struct, e.g. "an int at offset 8". A MEMBER
|
||||
TYPE doesn't include the offset (that's the value of the MEMBER
|
||||
|
@ -1200,17 +1251,17 @@ init_vector_type (struct type *elt_type, int n)
|
|||
allocated. */
|
||||
|
||||
void
|
||||
smash_to_memberptr_type (struct type *type, struct type *domain,
|
||||
smash_to_memberptr_type (struct type *type, struct type *self_type,
|
||||
struct type *to_type)
|
||||
{
|
||||
smash_type (type);
|
||||
TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
|
||||
TYPE_TARGET_TYPE (type) = to_type;
|
||||
TYPE_SELF_TYPE (type) = domain;
|
||||
set_type_self_type (type, self_type);
|
||||
/* Assume that a data member pointer is the same size as a normal
|
||||
pointer. */
|
||||
TYPE_LENGTH (type)
|
||||
= gdbarch_ptr_bit (get_type_arch (to_type)) / TARGET_CHAR_BIT;
|
||||
TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
|
||||
}
|
||||
|
||||
/* Smash TYPE to be a type of pointer to methods type TO_TYPE.
|
||||
|
@ -1223,13 +1274,13 @@ void
|
|||
smash_to_methodptr_type (struct type *type, struct type *to_type)
|
||||
{
|
||||
smash_type (type);
|
||||
TYPE_TARGET_TYPE (type) = to_type;
|
||||
TYPE_SELF_TYPE (type) = TYPE_SELF_TYPE (to_type);
|
||||
TYPE_LENGTH (type) = cplus_method_ptr_size (to_type);
|
||||
TYPE_CODE (type) = TYPE_CODE_METHODPTR;
|
||||
TYPE_TARGET_TYPE (type) = to_type;
|
||||
set_type_self_type (type, TYPE_SELF_TYPE (to_type));
|
||||
TYPE_LENGTH (type) = cplus_method_ptr_size (to_type);
|
||||
}
|
||||
|
||||
/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
|
||||
/* Smash TYPE to be a type of method of SELF_TYPE with type TO_TYPE.
|
||||
METHOD just means `function that gets an extra "this" argument'.
|
||||
|
||||
When "smashing" the type, we preserve the objfile that the old type
|
||||
|
@ -1237,19 +1288,19 @@ smash_to_methodptr_type (struct type *type, struct type *to_type)
|
|||
allocated. */
|
||||
|
||||
void
|
||||
smash_to_method_type (struct type *type, struct type *domain,
|
||||
smash_to_method_type (struct type *type, struct type *self_type,
|
||||
struct type *to_type, struct field *args,
|
||||
int nargs, int varargs)
|
||||
{
|
||||
smash_type (type);
|
||||
TYPE_CODE (type) = TYPE_CODE_METHOD;
|
||||
TYPE_TARGET_TYPE (type) = to_type;
|
||||
TYPE_SELF_TYPE (type) = domain;
|
||||
set_type_self_type (type, self_type);
|
||||
TYPE_FIELDS (type) = args;
|
||||
TYPE_NFIELDS (type) = nargs;
|
||||
if (varargs)
|
||||
TYPE_VARARGS (type) = 1;
|
||||
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
|
||||
TYPE_CODE (type) = TYPE_CODE_METHOD;
|
||||
}
|
||||
|
||||
/* Return a typename for a struct/union/enum type without "struct ",
|
||||
|
@ -2311,13 +2362,12 @@ check_stub_method (struct type *type, int method_id, int signature_id)
|
|||
|
||||
/* Now update the old "stub" type into a real type. */
|
||||
mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
|
||||
TYPE_SELF_TYPE (mtype) = type;
|
||||
TYPE_FIELDS (mtype) = argtypes;
|
||||
TYPE_NFIELDS (mtype) = argcount;
|
||||
/* MTYPE may currently be a function (TYPE_CODE_FUNC).
|
||||
We want a method (TYPE_CODE_METHOD). */
|
||||
smash_to_method_type (mtype, type, TYPE_TARGET_TYPE (mtype),
|
||||
argtypes, argcount, p[-2] == '.');
|
||||
TYPE_STUB (mtype) = 0;
|
||||
TYPE_FN_FIELD_STUB (f, signature_id) = 0;
|
||||
if (p[-2] == '.')
|
||||
TYPE_VARARGS (mtype) = 1;
|
||||
|
||||
xfree (demangled_name);
|
||||
}
|
||||
|
@ -4051,6 +4101,12 @@ recursive_dump_type (struct type *type, int spaces)
|
|||
TYPE_CALLING_CONVENTION (type));
|
||||
/* tail_call_list is not printed. */
|
||||
break;
|
||||
|
||||
case TYPE_SPECIFIC_SELF_TYPE:
|
||||
printfi_filtered (spaces, "self_type ");
|
||||
gdb_print_host_address (TYPE_SELF_TYPE (type), gdb_stdout);
|
||||
puts_filtered ("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (spaces == 0)
|
||||
|
@ -4243,6 +4299,11 @@ copy_type_recursive (struct objfile *objfile,
|
|||
case TYPE_SPECIFIC_GNAT_STUFF:
|
||||
INIT_GNAT_SPECIFIC (new_type);
|
||||
break;
|
||||
case TYPE_SPECIFIC_SELF_TYPE:
|
||||
set_type_self_type (new_type,
|
||||
copy_type_recursive (objfile, TYPE_SELF_TYPE (type),
|
||||
copied_types));
|
||||
break;
|
||||
default:
|
||||
gdb_assert_not_reached ("bad type_specific_kind");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue