15796c8dcSSimon Schubert /* Abstraction of GNU v3 abi.
25796c8dcSSimon Schubert Contributed by Jim Blandy <jimb@redhat.com>
35796c8dcSSimon Schubert
4*ef5ccd6cSJohn Marino Copyright (C) 2001-2013 Free Software Foundation, Inc.
55796c8dcSSimon Schubert
65796c8dcSSimon Schubert This file is part of GDB.
75796c8dcSSimon Schubert
85796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert (at your option) any later version.
125796c8dcSSimon Schubert
135796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
165796c8dcSSimon Schubert GNU General Public License for more details.
175796c8dcSSimon Schubert
185796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
205796c8dcSSimon Schubert
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "value.h"
235796c8dcSSimon Schubert #include "cp-abi.h"
245796c8dcSSimon Schubert #include "cp-support.h"
255796c8dcSSimon Schubert #include "demangle.h"
265796c8dcSSimon Schubert #include "objfiles.h"
275796c8dcSSimon Schubert #include "valprint.h"
28cf7f2e2dSJohn Marino #include "c-lang.h"
29*ef5ccd6cSJohn Marino #include "exceptions.h"
30*ef5ccd6cSJohn Marino #include "typeprint.h"
315796c8dcSSimon Schubert
325796c8dcSSimon Schubert #include "gdb_assert.h"
335796c8dcSSimon Schubert #include "gdb_string.h"
345796c8dcSSimon Schubert
355796c8dcSSimon Schubert static struct cp_abi_ops gnu_v3_abi_ops;
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert static int
gnuv3_is_vtable_name(const char * name)385796c8dcSSimon Schubert gnuv3_is_vtable_name (const char *name)
395796c8dcSSimon Schubert {
405796c8dcSSimon Schubert return strncmp (name, "_ZTV", 4) == 0;
415796c8dcSSimon Schubert }
425796c8dcSSimon Schubert
435796c8dcSSimon Schubert static int
gnuv3_is_operator_name(const char * name)445796c8dcSSimon Schubert gnuv3_is_operator_name (const char *name)
455796c8dcSSimon Schubert {
465796c8dcSSimon Schubert return strncmp (name, "operator", 8) == 0;
475796c8dcSSimon Schubert }
485796c8dcSSimon Schubert
495796c8dcSSimon Schubert
505796c8dcSSimon Schubert /* To help us find the components of a vtable, we build ourselves a
515796c8dcSSimon Schubert GDB type object representing the vtable structure. Following the
525796c8dcSSimon Schubert V3 ABI, it goes something like this:
535796c8dcSSimon Schubert
545796c8dcSSimon Schubert struct gdb_gnu_v3_abi_vtable {
555796c8dcSSimon Schubert
565796c8dcSSimon Schubert / * An array of virtual call and virtual base offsets. The real
575796c8dcSSimon Schubert length of this array depends on the class hierarchy; we use
585796c8dcSSimon Schubert negative subscripts to access the elements. Yucky, but
595796c8dcSSimon Schubert better than the alternatives. * /
605796c8dcSSimon Schubert ptrdiff_t vcall_and_vbase_offsets[0];
615796c8dcSSimon Schubert
625796c8dcSSimon Schubert / * The offset from a virtual pointer referring to this table
635796c8dcSSimon Schubert to the top of the complete object. * /
645796c8dcSSimon Schubert ptrdiff_t offset_to_top;
655796c8dcSSimon Schubert
665796c8dcSSimon Schubert / * The type_info pointer for this class. This is really a
675796c8dcSSimon Schubert std::type_info *, but GDB doesn't really look at the
685796c8dcSSimon Schubert type_info object itself, so we don't bother to get the type
695796c8dcSSimon Schubert exactly right. * /
705796c8dcSSimon Schubert void *type_info;
715796c8dcSSimon Schubert
725796c8dcSSimon Schubert / * Virtual table pointers in objects point here. * /
735796c8dcSSimon Schubert
745796c8dcSSimon Schubert / * Virtual function pointers. Like the vcall/vbase array, the
755796c8dcSSimon Schubert real length of this table depends on the class hierarchy. * /
765796c8dcSSimon Schubert void (*virtual_functions[0]) ();
775796c8dcSSimon Schubert
785796c8dcSSimon Schubert };
795796c8dcSSimon Schubert
805796c8dcSSimon Schubert The catch, of course, is that the exact layout of this table
815796c8dcSSimon Schubert depends on the ABI --- word size, endianness, alignment, etc. So
825796c8dcSSimon Schubert the GDB type object is actually a per-architecture kind of thing.
835796c8dcSSimon Schubert
845796c8dcSSimon Schubert vtable_type_gdbarch_data is a gdbarch per-architecture data pointer
855796c8dcSSimon Schubert which refers to the struct type * for this structure, laid out
865796c8dcSSimon Schubert appropriately for the architecture. */
875796c8dcSSimon Schubert static struct gdbarch_data *vtable_type_gdbarch_data;
885796c8dcSSimon Schubert
895796c8dcSSimon Schubert
905796c8dcSSimon Schubert /* Human-readable names for the numbers of the fields above. */
915796c8dcSSimon Schubert enum {
925796c8dcSSimon Schubert vtable_field_vcall_and_vbase_offsets,
935796c8dcSSimon Schubert vtable_field_offset_to_top,
945796c8dcSSimon Schubert vtable_field_type_info,
955796c8dcSSimon Schubert vtable_field_virtual_functions
965796c8dcSSimon Schubert };
975796c8dcSSimon Schubert
985796c8dcSSimon Schubert
995796c8dcSSimon Schubert /* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable',
1005796c8dcSSimon Schubert described above, laid out appropriately for ARCH.
1015796c8dcSSimon Schubert
1025796c8dcSSimon Schubert We use this function as the gdbarch per-architecture data
1035796c8dcSSimon Schubert initialization function. */
1045796c8dcSSimon Schubert static void *
build_gdb_vtable_type(struct gdbarch * arch)1055796c8dcSSimon Schubert build_gdb_vtable_type (struct gdbarch *arch)
1065796c8dcSSimon Schubert {
1075796c8dcSSimon Schubert struct type *t;
1085796c8dcSSimon Schubert struct field *field_list, *field;
1095796c8dcSSimon Schubert int offset;
1105796c8dcSSimon Schubert
1115796c8dcSSimon Schubert struct type *void_ptr_type
1125796c8dcSSimon Schubert = builtin_type (arch)->builtin_data_ptr;
1135796c8dcSSimon Schubert struct type *ptr_to_void_fn_type
1145796c8dcSSimon Schubert = builtin_type (arch)->builtin_func_ptr;
1155796c8dcSSimon Schubert
1165796c8dcSSimon Schubert /* ARCH can't give us the true ptrdiff_t type, so we guess. */
1175796c8dcSSimon Schubert struct type *ptrdiff_type
1185796c8dcSSimon Schubert = arch_integer_type (arch, gdbarch_ptr_bit (arch), 0, "ptrdiff_t");
1195796c8dcSSimon Schubert
1205796c8dcSSimon Schubert /* We assume no padding is necessary, since GDB doesn't know
1215796c8dcSSimon Schubert anything about alignment at the moment. If this assumption bites
1225796c8dcSSimon Schubert us, we should add a gdbarch method which, given a type, returns
1235796c8dcSSimon Schubert the alignment that type requires, and then use that here. */
1245796c8dcSSimon Schubert
1255796c8dcSSimon Schubert /* Build the field list. */
1265796c8dcSSimon Schubert field_list = xmalloc (sizeof (struct field [4]));
1275796c8dcSSimon Schubert memset (field_list, 0, sizeof (struct field [4]));
1285796c8dcSSimon Schubert field = &field_list[0];
1295796c8dcSSimon Schubert offset = 0;
1305796c8dcSSimon Schubert
1315796c8dcSSimon Schubert /* ptrdiff_t vcall_and_vbase_offsets[0]; */
1325796c8dcSSimon Schubert FIELD_NAME (*field) = "vcall_and_vbase_offsets";
1335796c8dcSSimon Schubert FIELD_TYPE (*field) = lookup_array_range_type (ptrdiff_type, 0, -1);
134*ef5ccd6cSJohn Marino SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
1355796c8dcSSimon Schubert offset += TYPE_LENGTH (FIELD_TYPE (*field));
1365796c8dcSSimon Schubert field++;
1375796c8dcSSimon Schubert
1385796c8dcSSimon Schubert /* ptrdiff_t offset_to_top; */
1395796c8dcSSimon Schubert FIELD_NAME (*field) = "offset_to_top";
1405796c8dcSSimon Schubert FIELD_TYPE (*field) = ptrdiff_type;
141*ef5ccd6cSJohn Marino SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
1425796c8dcSSimon Schubert offset += TYPE_LENGTH (FIELD_TYPE (*field));
1435796c8dcSSimon Schubert field++;
1445796c8dcSSimon Schubert
1455796c8dcSSimon Schubert /* void *type_info; */
1465796c8dcSSimon Schubert FIELD_NAME (*field) = "type_info";
1475796c8dcSSimon Schubert FIELD_TYPE (*field) = void_ptr_type;
148*ef5ccd6cSJohn Marino SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
1495796c8dcSSimon Schubert offset += TYPE_LENGTH (FIELD_TYPE (*field));
1505796c8dcSSimon Schubert field++;
1515796c8dcSSimon Schubert
1525796c8dcSSimon Schubert /* void (*virtual_functions[0]) (); */
1535796c8dcSSimon Schubert FIELD_NAME (*field) = "virtual_functions";
1545796c8dcSSimon Schubert FIELD_TYPE (*field) = lookup_array_range_type (ptr_to_void_fn_type, 0, -1);
155*ef5ccd6cSJohn Marino SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
1565796c8dcSSimon Schubert offset += TYPE_LENGTH (FIELD_TYPE (*field));
1575796c8dcSSimon Schubert field++;
1585796c8dcSSimon Schubert
1595796c8dcSSimon Schubert /* We assumed in the allocation above that there were four fields. */
1605796c8dcSSimon Schubert gdb_assert (field == (field_list + 4));
1615796c8dcSSimon Schubert
1625796c8dcSSimon Schubert t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
1635796c8dcSSimon Schubert TYPE_NFIELDS (t) = field - field_list;
1645796c8dcSSimon Schubert TYPE_FIELDS (t) = field_list;
1655796c8dcSSimon Schubert TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable";
1665796c8dcSSimon Schubert INIT_CPLUS_SPECIFIC (t);
1675796c8dcSSimon Schubert
1685796c8dcSSimon Schubert return t;
1695796c8dcSSimon Schubert }
1705796c8dcSSimon Schubert
1715796c8dcSSimon Schubert
1725796c8dcSSimon Schubert /* Return the ptrdiff_t type used in the vtable type. */
1735796c8dcSSimon Schubert static struct type *
vtable_ptrdiff_type(struct gdbarch * gdbarch)1745796c8dcSSimon Schubert vtable_ptrdiff_type (struct gdbarch *gdbarch)
1755796c8dcSSimon Schubert {
1765796c8dcSSimon Schubert struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
1775796c8dcSSimon Schubert
1785796c8dcSSimon Schubert /* The "offset_to_top" field has the appropriate (ptrdiff_t) type. */
1795796c8dcSSimon Schubert return TYPE_FIELD_TYPE (vtable_type, vtable_field_offset_to_top);
1805796c8dcSSimon Schubert }
1815796c8dcSSimon Schubert
1825796c8dcSSimon Schubert /* Return the offset from the start of the imaginary `struct
1835796c8dcSSimon Schubert gdb_gnu_v3_abi_vtable' object to the vtable's "address point"
1845796c8dcSSimon Schubert (i.e., where objects' virtual table pointers point). */
1855796c8dcSSimon Schubert static int
vtable_address_point_offset(struct gdbarch * gdbarch)1865796c8dcSSimon Schubert vtable_address_point_offset (struct gdbarch *gdbarch)
1875796c8dcSSimon Schubert {
1885796c8dcSSimon Schubert struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
1895796c8dcSSimon Schubert
1905796c8dcSSimon Schubert return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
1915796c8dcSSimon Schubert / TARGET_CHAR_BIT);
1925796c8dcSSimon Schubert }
1935796c8dcSSimon Schubert
1945796c8dcSSimon Schubert
195cf7f2e2dSJohn Marino /* Determine whether structure TYPE is a dynamic class. Cache the
196cf7f2e2dSJohn Marino result. */
197cf7f2e2dSJohn Marino
198cf7f2e2dSJohn Marino static int
gnuv3_dynamic_class(struct type * type)199cf7f2e2dSJohn Marino gnuv3_dynamic_class (struct type *type)
200cf7f2e2dSJohn Marino {
201cf7f2e2dSJohn Marino int fieldnum, fieldelem;
202cf7f2e2dSJohn Marino
203cf7f2e2dSJohn Marino if (TYPE_CPLUS_DYNAMIC (type))
204cf7f2e2dSJohn Marino return TYPE_CPLUS_DYNAMIC (type) == 1;
205cf7f2e2dSJohn Marino
206cf7f2e2dSJohn Marino ALLOCATE_CPLUS_STRUCT_TYPE (type);
207cf7f2e2dSJohn Marino
208cf7f2e2dSJohn Marino for (fieldnum = 0; fieldnum < TYPE_N_BASECLASSES (type); fieldnum++)
209cf7f2e2dSJohn Marino if (BASETYPE_VIA_VIRTUAL (type, fieldnum)
210cf7f2e2dSJohn Marino || gnuv3_dynamic_class (TYPE_FIELD_TYPE (type, fieldnum)))
211cf7f2e2dSJohn Marino {
212cf7f2e2dSJohn Marino TYPE_CPLUS_DYNAMIC (type) = 1;
213cf7f2e2dSJohn Marino return 1;
214cf7f2e2dSJohn Marino }
215cf7f2e2dSJohn Marino
216cf7f2e2dSJohn Marino for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
217cf7f2e2dSJohn Marino for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
218cf7f2e2dSJohn Marino fieldelem++)
219cf7f2e2dSJohn Marino {
220cf7f2e2dSJohn Marino struct fn_field *f = TYPE_FN_FIELDLIST1 (type, fieldnum);
221cf7f2e2dSJohn Marino
222cf7f2e2dSJohn Marino if (TYPE_FN_FIELD_VIRTUAL_P (f, fieldelem))
223cf7f2e2dSJohn Marino {
224cf7f2e2dSJohn Marino TYPE_CPLUS_DYNAMIC (type) = 1;
225cf7f2e2dSJohn Marino return 1;
226cf7f2e2dSJohn Marino }
227cf7f2e2dSJohn Marino }
228cf7f2e2dSJohn Marino
229cf7f2e2dSJohn Marino TYPE_CPLUS_DYNAMIC (type) = -1;
230cf7f2e2dSJohn Marino return 0;
231cf7f2e2dSJohn Marino }
232cf7f2e2dSJohn Marino
233cf7f2e2dSJohn Marino /* Find the vtable for a value of CONTAINER_TYPE located at
234cf7f2e2dSJohn Marino CONTAINER_ADDR. Return a value of the correct vtable type for this
235cf7f2e2dSJohn Marino architecture, or NULL if CONTAINER does not have a vtable. */
236cf7f2e2dSJohn Marino
237cf7f2e2dSJohn Marino static struct value *
gnuv3_get_vtable(struct gdbarch * gdbarch,struct type * container_type,CORE_ADDR container_addr)238cf7f2e2dSJohn Marino gnuv3_get_vtable (struct gdbarch *gdbarch,
239cf7f2e2dSJohn Marino struct type *container_type, CORE_ADDR container_addr)
240cf7f2e2dSJohn Marino {
241cf7f2e2dSJohn Marino struct type *vtable_type = gdbarch_data (gdbarch,
242cf7f2e2dSJohn Marino vtable_type_gdbarch_data);
243cf7f2e2dSJohn Marino struct type *vtable_pointer_type;
244cf7f2e2dSJohn Marino struct value *vtable_pointer;
245cf7f2e2dSJohn Marino CORE_ADDR vtable_address;
246cf7f2e2dSJohn Marino
247cf7f2e2dSJohn Marino /* If this type does not have a virtual table, don't read the first
248cf7f2e2dSJohn Marino field. */
249cf7f2e2dSJohn Marino if (!gnuv3_dynamic_class (check_typedef (container_type)))
250cf7f2e2dSJohn Marino return NULL;
251cf7f2e2dSJohn Marino
252cf7f2e2dSJohn Marino /* We do not consult the debug information to find the virtual table.
253cf7f2e2dSJohn Marino The ABI specifies that it is always at offset zero in any class,
254cf7f2e2dSJohn Marino and debug information may not represent it.
255cf7f2e2dSJohn Marino
256cf7f2e2dSJohn Marino We avoid using value_contents on principle, because the object might
257cf7f2e2dSJohn Marino be large. */
258cf7f2e2dSJohn Marino
259cf7f2e2dSJohn Marino /* Find the type "pointer to virtual table". */
260cf7f2e2dSJohn Marino vtable_pointer_type = lookup_pointer_type (vtable_type);
261cf7f2e2dSJohn Marino
262cf7f2e2dSJohn Marino /* Load it from the start of the class. */
263cf7f2e2dSJohn Marino vtable_pointer = value_at (vtable_pointer_type, container_addr);
264cf7f2e2dSJohn Marino vtable_address = value_as_address (vtable_pointer);
265cf7f2e2dSJohn Marino
266cf7f2e2dSJohn Marino /* Correct it to point at the start of the virtual table, rather
267cf7f2e2dSJohn Marino than the address point. */
268cf7f2e2dSJohn Marino return value_at_lazy (vtable_type,
269c50c785cSJohn Marino vtable_address
270c50c785cSJohn Marino - vtable_address_point_offset (gdbarch));
271cf7f2e2dSJohn Marino }
272cf7f2e2dSJohn Marino
273cf7f2e2dSJohn Marino
2745796c8dcSSimon Schubert static struct type *
gnuv3_rtti_type(struct value * value,int * full_p,int * top_p,int * using_enc_p)2755796c8dcSSimon Schubert gnuv3_rtti_type (struct value *value,
2765796c8dcSSimon Schubert int *full_p, int *top_p, int *using_enc_p)
2775796c8dcSSimon Schubert {
2785796c8dcSSimon Schubert struct gdbarch *gdbarch;
2795796c8dcSSimon Schubert struct type *values_type = check_typedef (value_type (value));
2805796c8dcSSimon Schubert struct value *vtable;
2815796c8dcSSimon Schubert struct minimal_symbol *vtable_symbol;
2825796c8dcSSimon Schubert const char *vtable_symbol_name;
2835796c8dcSSimon Schubert const char *class_name;
2845796c8dcSSimon Schubert struct type *run_time_type;
2855796c8dcSSimon Schubert LONGEST offset_to_top;
2865796c8dcSSimon Schubert
2875796c8dcSSimon Schubert /* We only have RTTI for class objects. */
2885796c8dcSSimon Schubert if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
2895796c8dcSSimon Schubert return NULL;
2905796c8dcSSimon Schubert
291a45ae5f8SJohn Marino /* Java doesn't have RTTI following the C++ ABI. */
292a45ae5f8SJohn Marino if (TYPE_CPLUS_REALLY_JAVA (values_type))
293a45ae5f8SJohn Marino return NULL;
294a45ae5f8SJohn Marino
2955796c8dcSSimon Schubert /* Determine architecture. */
2965796c8dcSSimon Schubert gdbarch = get_type_arch (values_type);
2975796c8dcSSimon Schubert
2985796c8dcSSimon Schubert if (using_enc_p)
2995796c8dcSSimon Schubert *using_enc_p = 0;
3005796c8dcSSimon Schubert
301cf7f2e2dSJohn Marino vtable = gnuv3_get_vtable (gdbarch, value_type (value),
302cf7f2e2dSJohn Marino value_as_address (value_addr (value)));
303cf7f2e2dSJohn Marino if (vtable == NULL)
304cf7f2e2dSJohn Marino return NULL;
3055796c8dcSSimon Schubert
3065796c8dcSSimon Schubert /* Find the linker symbol for this vtable. */
3075796c8dcSSimon Schubert vtable_symbol
3085796c8dcSSimon Schubert = lookup_minimal_symbol_by_pc (value_address (vtable)
3095796c8dcSSimon Schubert + value_embedded_offset (vtable));
3105796c8dcSSimon Schubert if (! vtable_symbol)
3115796c8dcSSimon Schubert return NULL;
3125796c8dcSSimon Schubert
3135796c8dcSSimon Schubert /* The symbol's demangled name should be something like "vtable for
3145796c8dcSSimon Schubert CLASS", where CLASS is the name of the run-time type of VALUE.
3155796c8dcSSimon Schubert If we didn't like this approach, we could instead look in the
3165796c8dcSSimon Schubert type_info object itself to get the class name. But this way
3175796c8dcSSimon Schubert should work just as well, and doesn't read target memory. */
3185796c8dcSSimon Schubert vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol);
3195796c8dcSSimon Schubert if (vtable_symbol_name == NULL
3205796c8dcSSimon Schubert || strncmp (vtable_symbol_name, "vtable for ", 11))
3215796c8dcSSimon Schubert {
3225796c8dcSSimon Schubert warning (_("can't find linker symbol for virtual table for `%s' value"),
323a45ae5f8SJohn Marino TYPE_SAFE_NAME (values_type));
3245796c8dcSSimon Schubert if (vtable_symbol_name)
3255796c8dcSSimon Schubert warning (_(" found `%s' instead"), vtable_symbol_name);
3265796c8dcSSimon Schubert return NULL;
3275796c8dcSSimon Schubert }
3285796c8dcSSimon Schubert class_name = vtable_symbol_name + 11;
3295796c8dcSSimon Schubert
3305796c8dcSSimon Schubert /* Try to look up the class name as a type name. */
3315796c8dcSSimon Schubert /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */
3325796c8dcSSimon Schubert run_time_type = cp_lookup_rtti_type (class_name, NULL);
3335796c8dcSSimon Schubert if (run_time_type == NULL)
3345796c8dcSSimon Schubert return NULL;
3355796c8dcSSimon Schubert
3365796c8dcSSimon Schubert /* Get the offset from VALUE to the top of the complete object.
3375796c8dcSSimon Schubert NOTE: this is the reverse of the meaning of *TOP_P. */
3385796c8dcSSimon Schubert offset_to_top
3395796c8dcSSimon Schubert = value_as_long (value_field (vtable, vtable_field_offset_to_top));
3405796c8dcSSimon Schubert
3415796c8dcSSimon Schubert if (full_p)
3425796c8dcSSimon Schubert *full_p = (- offset_to_top == value_embedded_offset (value)
3435796c8dcSSimon Schubert && (TYPE_LENGTH (value_enclosing_type (value))
3445796c8dcSSimon Schubert >= TYPE_LENGTH (run_time_type)));
3455796c8dcSSimon Schubert if (top_p)
3465796c8dcSSimon Schubert *top_p = - offset_to_top;
3475796c8dcSSimon Schubert return run_time_type;
3485796c8dcSSimon Schubert }
3495796c8dcSSimon Schubert
3505796c8dcSSimon Schubert /* Return a function pointer for CONTAINER's VTABLE_INDEX'th virtual
3515796c8dcSSimon Schubert function, of type FNTYPE. */
3525796c8dcSSimon Schubert
3535796c8dcSSimon Schubert static struct value *
gnuv3_get_virtual_fn(struct gdbarch * gdbarch,struct value * container,struct type * fntype,int vtable_index)3545796c8dcSSimon Schubert gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
3555796c8dcSSimon Schubert struct type *fntype, int vtable_index)
3565796c8dcSSimon Schubert {
357cf7f2e2dSJohn Marino struct value *vtable, *vfn;
358cf7f2e2dSJohn Marino
359cf7f2e2dSJohn Marino /* Every class with virtual functions must have a vtable. */
360cf7f2e2dSJohn Marino vtable = gnuv3_get_vtable (gdbarch, value_type (container),
361cf7f2e2dSJohn Marino value_as_address (value_addr (container)));
362cf7f2e2dSJohn Marino gdb_assert (vtable != NULL);
3635796c8dcSSimon Schubert
3645796c8dcSSimon Schubert /* Fetch the appropriate function pointer from the vtable. */
3655796c8dcSSimon Schubert vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
3665796c8dcSSimon Schubert vtable_index);
3675796c8dcSSimon Schubert
3685796c8dcSSimon Schubert /* If this architecture uses function descriptors directly in the vtable,
3695796c8dcSSimon Schubert then the address of the vtable entry is actually a "function pointer"
3705796c8dcSSimon Schubert (i.e. points to the descriptor). We don't need to scale the index
3715796c8dcSSimon Schubert by the size of a function descriptor; GCC does that before outputing
3725796c8dcSSimon Schubert debug information. */
3735796c8dcSSimon Schubert if (gdbarch_vtable_function_descriptors (gdbarch))
3745796c8dcSSimon Schubert vfn = value_addr (vfn);
3755796c8dcSSimon Schubert
3765796c8dcSSimon Schubert /* Cast the function pointer to the appropriate type. */
3775796c8dcSSimon Schubert vfn = value_cast (lookup_pointer_type (fntype), vfn);
3785796c8dcSSimon Schubert
3795796c8dcSSimon Schubert return vfn;
3805796c8dcSSimon Schubert }
3815796c8dcSSimon Schubert
3825796c8dcSSimon Schubert /* GNU v3 implementation of value_virtual_fn_field. See cp-abi.h
3835796c8dcSSimon Schubert for a description of the arguments. */
3845796c8dcSSimon Schubert
3855796c8dcSSimon Schubert static struct value *
gnuv3_virtual_fn_field(struct value ** value_p,struct fn_field * f,int j,struct type * vfn_base,int offset)3865796c8dcSSimon Schubert gnuv3_virtual_fn_field (struct value **value_p,
3875796c8dcSSimon Schubert struct fn_field *f, int j,
3885796c8dcSSimon Schubert struct type *vfn_base, int offset)
3895796c8dcSSimon Schubert {
3905796c8dcSSimon Schubert struct type *values_type = check_typedef (value_type (*value_p));
3915796c8dcSSimon Schubert struct gdbarch *gdbarch;
3925796c8dcSSimon Schubert
3935796c8dcSSimon Schubert /* Some simple sanity checks. */
3945796c8dcSSimon Schubert if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
3955796c8dcSSimon Schubert error (_("Only classes can have virtual functions."));
3965796c8dcSSimon Schubert
3975796c8dcSSimon Schubert /* Determine architecture. */
3985796c8dcSSimon Schubert gdbarch = get_type_arch (values_type);
3995796c8dcSSimon Schubert
4005796c8dcSSimon Schubert /* Cast our value to the base class which defines this virtual
4015796c8dcSSimon Schubert function. This takes care of any necessary `this'
4025796c8dcSSimon Schubert adjustments. */
4035796c8dcSSimon Schubert if (vfn_base != values_type)
4045796c8dcSSimon Schubert *value_p = value_cast (vfn_base, *value_p);
4055796c8dcSSimon Schubert
4065796c8dcSSimon Schubert return gnuv3_get_virtual_fn (gdbarch, *value_p, TYPE_FN_FIELD_TYPE (f, j),
4075796c8dcSSimon Schubert TYPE_FN_FIELD_VOFFSET (f, j));
4085796c8dcSSimon Schubert }
4095796c8dcSSimon Schubert
4105796c8dcSSimon Schubert /* Compute the offset of the baseclass which is
4115796c8dcSSimon Schubert the INDEXth baseclass of class TYPE,
4125796c8dcSSimon Schubert for value at VALADDR (in host) at ADDRESS (in target).
4135796c8dcSSimon Schubert The result is the offset of the baseclass value relative
4145796c8dcSSimon Schubert to (the address of)(ARG) + OFFSET.
4155796c8dcSSimon Schubert
4165796c8dcSSimon Schubert -1 is returned on error. */
417c50c785cSJohn Marino
4185796c8dcSSimon Schubert static int
gnuv3_baseclass_offset(struct type * type,int index,const bfd_byte * valaddr,int embedded_offset,CORE_ADDR address,const struct value * val)419c50c785cSJohn Marino gnuv3_baseclass_offset (struct type *type, int index,
420c50c785cSJohn Marino const bfd_byte *valaddr, int embedded_offset,
421c50c785cSJohn Marino CORE_ADDR address, const struct value *val)
4225796c8dcSSimon Schubert {
4235796c8dcSSimon Schubert struct gdbarch *gdbarch;
4245796c8dcSSimon Schubert struct type *ptr_type;
4255796c8dcSSimon Schubert struct value *vtable;
4265796c8dcSSimon Schubert struct value *vbase_array;
4275796c8dcSSimon Schubert long int cur_base_offset, base_offset;
4285796c8dcSSimon Schubert
4295796c8dcSSimon Schubert /* Determine architecture. */
4305796c8dcSSimon Schubert gdbarch = get_type_arch (type);
4315796c8dcSSimon Schubert ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
4325796c8dcSSimon Schubert
4335796c8dcSSimon Schubert /* If it isn't a virtual base, this is easy. The offset is in the
434*ef5ccd6cSJohn Marino type definition. Likewise for Java, which doesn't really have
435*ef5ccd6cSJohn Marino virtual inheritance in the C++ sense. */
436*ef5ccd6cSJohn Marino if (!BASETYPE_VIA_VIRTUAL (type, index) || TYPE_CPLUS_REALLY_JAVA (type))
4375796c8dcSSimon Schubert return TYPE_BASECLASS_BITPOS (type, index) / 8;
4385796c8dcSSimon Schubert
4395796c8dcSSimon Schubert /* To access a virtual base, we need to use the vbase offset stored in
4405796c8dcSSimon Schubert our vtable. Recent GCC versions provide this information. If it isn't
4415796c8dcSSimon Schubert available, we could get what we needed from RTTI, or from drawing the
4425796c8dcSSimon Schubert complete inheritance graph based on the debug info. Neither is
4435796c8dcSSimon Schubert worthwhile. */
4445796c8dcSSimon Schubert cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8;
4455796c8dcSSimon Schubert if (cur_base_offset >= - vtable_address_point_offset (gdbarch))
4465796c8dcSSimon Schubert error (_("Expected a negative vbase offset (old compiler?)"));
4475796c8dcSSimon Schubert
4485796c8dcSSimon Schubert cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch);
4495796c8dcSSimon Schubert if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0)
4505796c8dcSSimon Schubert error (_("Misaligned vbase offset."));
4515796c8dcSSimon Schubert cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type));
4525796c8dcSSimon Schubert
453c50c785cSJohn Marino vtable = gnuv3_get_vtable (gdbarch, type, address + embedded_offset);
454cf7f2e2dSJohn Marino gdb_assert (vtable != NULL);
4555796c8dcSSimon Schubert vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
4565796c8dcSSimon Schubert base_offset = value_as_long (value_subscript (vbase_array, cur_base_offset));
4575796c8dcSSimon Schubert return base_offset;
4585796c8dcSSimon Schubert }
4595796c8dcSSimon Schubert
4605796c8dcSSimon Schubert /* Locate a virtual method in DOMAIN or its non-virtual base classes
4615796c8dcSSimon Schubert which has virtual table index VOFFSET. The method has an associated
4625796c8dcSSimon Schubert "this" adjustment of ADJUSTMENT bytes. */
4635796c8dcSSimon Schubert
4645796c8dcSSimon Schubert static const char *
gnuv3_find_method_in(struct type * domain,CORE_ADDR voffset,LONGEST adjustment)4655796c8dcSSimon Schubert gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset,
4665796c8dcSSimon Schubert LONGEST adjustment)
4675796c8dcSSimon Schubert {
4685796c8dcSSimon Schubert int i;
4695796c8dcSSimon Schubert
4705796c8dcSSimon Schubert /* Search this class first. */
4715796c8dcSSimon Schubert if (adjustment == 0)
4725796c8dcSSimon Schubert {
4735796c8dcSSimon Schubert int len;
4745796c8dcSSimon Schubert
4755796c8dcSSimon Schubert len = TYPE_NFN_FIELDS (domain);
4765796c8dcSSimon Schubert for (i = 0; i < len; i++)
4775796c8dcSSimon Schubert {
4785796c8dcSSimon Schubert int len2, j;
4795796c8dcSSimon Schubert struct fn_field *f;
4805796c8dcSSimon Schubert
4815796c8dcSSimon Schubert f = TYPE_FN_FIELDLIST1 (domain, i);
4825796c8dcSSimon Schubert len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
4835796c8dcSSimon Schubert
4845796c8dcSSimon Schubert check_stub_method_group (domain, i);
4855796c8dcSSimon Schubert for (j = 0; j < len2; j++)
4865796c8dcSSimon Schubert if (TYPE_FN_FIELD_VOFFSET (f, j) == voffset)
4875796c8dcSSimon Schubert return TYPE_FN_FIELD_PHYSNAME (f, j);
4885796c8dcSSimon Schubert }
4895796c8dcSSimon Schubert }
4905796c8dcSSimon Schubert
4915796c8dcSSimon Schubert /* Next search non-virtual bases. If it's in a virtual base,
4925796c8dcSSimon Schubert we're out of luck. */
4935796c8dcSSimon Schubert for (i = 0; i < TYPE_N_BASECLASSES (domain); i++)
4945796c8dcSSimon Schubert {
4955796c8dcSSimon Schubert int pos;
4965796c8dcSSimon Schubert struct type *basetype;
4975796c8dcSSimon Schubert
4985796c8dcSSimon Schubert if (BASETYPE_VIA_VIRTUAL (domain, i))
4995796c8dcSSimon Schubert continue;
5005796c8dcSSimon Schubert
5015796c8dcSSimon Schubert pos = TYPE_BASECLASS_BITPOS (domain, i) / 8;
5025796c8dcSSimon Schubert basetype = TYPE_FIELD_TYPE (domain, i);
5035796c8dcSSimon Schubert /* Recurse with a modified adjustment. We don't need to adjust
5045796c8dcSSimon Schubert voffset. */
5055796c8dcSSimon Schubert if (adjustment >= pos && adjustment < pos + TYPE_LENGTH (basetype))
5065796c8dcSSimon Schubert return gnuv3_find_method_in (basetype, voffset, adjustment - pos);
5075796c8dcSSimon Schubert }
5085796c8dcSSimon Schubert
5095796c8dcSSimon Schubert return NULL;
5105796c8dcSSimon Schubert }
5115796c8dcSSimon Schubert
5125796c8dcSSimon Schubert /* Decode GNU v3 method pointer. */
5135796c8dcSSimon Schubert
5145796c8dcSSimon Schubert static int
gnuv3_decode_method_ptr(struct gdbarch * gdbarch,const gdb_byte * contents,CORE_ADDR * value_p,LONGEST * adjustment_p)5155796c8dcSSimon Schubert gnuv3_decode_method_ptr (struct gdbarch *gdbarch,
5165796c8dcSSimon Schubert const gdb_byte *contents,
5175796c8dcSSimon Schubert CORE_ADDR *value_p,
5185796c8dcSSimon Schubert LONGEST *adjustment_p)
5195796c8dcSSimon Schubert {
5205796c8dcSSimon Schubert struct type *funcptr_type = builtin_type (gdbarch)->builtin_func_ptr;
5215796c8dcSSimon Schubert struct type *offset_type = vtable_ptrdiff_type (gdbarch);
5225796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5235796c8dcSSimon Schubert CORE_ADDR ptr_value;
5245796c8dcSSimon Schubert LONGEST voffset, adjustment;
5255796c8dcSSimon Schubert int vbit;
5265796c8dcSSimon Schubert
5275796c8dcSSimon Schubert /* Extract the pointer to member. The first element is either a pointer
5285796c8dcSSimon Schubert or a vtable offset. For pointers, we need to use extract_typed_address
5295796c8dcSSimon Schubert to allow the back-end to convert the pointer to a GDB address -- but
5305796c8dcSSimon Schubert vtable offsets we must handle as integers. At this point, we do not
5315796c8dcSSimon Schubert yet know which case we have, so we extract the value under both
5325796c8dcSSimon Schubert interpretations and choose the right one later on. */
5335796c8dcSSimon Schubert ptr_value = extract_typed_address (contents, funcptr_type);
5345796c8dcSSimon Schubert voffset = extract_signed_integer (contents,
5355796c8dcSSimon Schubert TYPE_LENGTH (funcptr_type), byte_order);
5365796c8dcSSimon Schubert contents += TYPE_LENGTH (funcptr_type);
5375796c8dcSSimon Schubert adjustment = extract_signed_integer (contents,
5385796c8dcSSimon Schubert TYPE_LENGTH (offset_type), byte_order);
5395796c8dcSSimon Schubert
5405796c8dcSSimon Schubert if (!gdbarch_vbit_in_delta (gdbarch))
5415796c8dcSSimon Schubert {
5425796c8dcSSimon Schubert vbit = voffset & 1;
5435796c8dcSSimon Schubert voffset = voffset ^ vbit;
5445796c8dcSSimon Schubert }
5455796c8dcSSimon Schubert else
5465796c8dcSSimon Schubert {
5475796c8dcSSimon Schubert vbit = adjustment & 1;
5485796c8dcSSimon Schubert adjustment = adjustment >> 1;
5495796c8dcSSimon Schubert }
5505796c8dcSSimon Schubert
5515796c8dcSSimon Schubert *value_p = vbit? voffset : ptr_value;
5525796c8dcSSimon Schubert *adjustment_p = adjustment;
5535796c8dcSSimon Schubert return vbit;
5545796c8dcSSimon Schubert }
5555796c8dcSSimon Schubert
5565796c8dcSSimon Schubert /* GNU v3 implementation of cplus_print_method_ptr. */
5575796c8dcSSimon Schubert
5585796c8dcSSimon Schubert static void
gnuv3_print_method_ptr(const gdb_byte * contents,struct type * type,struct ui_file * stream)5595796c8dcSSimon Schubert gnuv3_print_method_ptr (const gdb_byte *contents,
5605796c8dcSSimon Schubert struct type *type,
5615796c8dcSSimon Schubert struct ui_file *stream)
5625796c8dcSSimon Schubert {
5635796c8dcSSimon Schubert struct type *domain = TYPE_DOMAIN_TYPE (type);
5645796c8dcSSimon Schubert struct gdbarch *gdbarch = get_type_arch (domain);
5655796c8dcSSimon Schubert CORE_ADDR ptr_value;
5665796c8dcSSimon Schubert LONGEST adjustment;
5675796c8dcSSimon Schubert int vbit;
5685796c8dcSSimon Schubert
5695796c8dcSSimon Schubert /* Extract the pointer to member. */
5705796c8dcSSimon Schubert vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);
5715796c8dcSSimon Schubert
5725796c8dcSSimon Schubert /* Check for NULL. */
5735796c8dcSSimon Schubert if (ptr_value == 0 && vbit == 0)
5745796c8dcSSimon Schubert {
5755796c8dcSSimon Schubert fprintf_filtered (stream, "NULL");
5765796c8dcSSimon Schubert return;
5775796c8dcSSimon Schubert }
5785796c8dcSSimon Schubert
5795796c8dcSSimon Schubert /* Search for a virtual method. */
5805796c8dcSSimon Schubert if (vbit)
5815796c8dcSSimon Schubert {
5825796c8dcSSimon Schubert CORE_ADDR voffset;
5835796c8dcSSimon Schubert const char *physname;
5845796c8dcSSimon Schubert
5855796c8dcSSimon Schubert /* It's a virtual table offset, maybe in this class. Search
5865796c8dcSSimon Schubert for a field with the correct vtable offset. First convert it
5875796c8dcSSimon Schubert to an index, as used in TYPE_FN_FIELD_VOFFSET. */
5885796c8dcSSimon Schubert voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
5895796c8dcSSimon Schubert
5905796c8dcSSimon Schubert physname = gnuv3_find_method_in (domain, voffset, adjustment);
5915796c8dcSSimon Schubert
5925796c8dcSSimon Schubert /* If we found a method, print that. We don't bother to disambiguate
5935796c8dcSSimon Schubert possible paths to the method based on the adjustment. */
5945796c8dcSSimon Schubert if (physname)
5955796c8dcSSimon Schubert {
5965796c8dcSSimon Schubert char *demangled_name = cplus_demangle (physname,
5975796c8dcSSimon Schubert DMGL_ANSI | DMGL_PARAMS);
598cf7f2e2dSJohn Marino
5995796c8dcSSimon Schubert fprintf_filtered (stream, "&virtual ");
600cf7f2e2dSJohn Marino if (demangled_name == NULL)
601cf7f2e2dSJohn Marino fputs_filtered (physname, stream);
602cf7f2e2dSJohn Marino else
603cf7f2e2dSJohn Marino {
6045796c8dcSSimon Schubert fputs_filtered (demangled_name, stream);
6055796c8dcSSimon Schubert xfree (demangled_name);
606cf7f2e2dSJohn Marino }
6075796c8dcSSimon Schubert return;
6085796c8dcSSimon Schubert }
6095796c8dcSSimon Schubert }
610cf7f2e2dSJohn Marino else if (ptr_value != 0)
611cf7f2e2dSJohn Marino {
612cf7f2e2dSJohn Marino /* Found a non-virtual function: print out the type. */
613cf7f2e2dSJohn Marino fputs_filtered ("(", stream);
614*ef5ccd6cSJohn Marino c_print_type (type, "", stream, -1, 0, &type_print_raw_options);
615cf7f2e2dSJohn Marino fputs_filtered (") ", stream);
6165796c8dcSSimon Schubert }
6175796c8dcSSimon Schubert
6185796c8dcSSimon Schubert /* We didn't find it; print the raw data. */
6195796c8dcSSimon Schubert if (vbit)
6205796c8dcSSimon Schubert {
6215796c8dcSSimon Schubert fprintf_filtered (stream, "&virtual table offset ");
6225796c8dcSSimon Schubert print_longest (stream, 'd', 1, ptr_value);
6235796c8dcSSimon Schubert }
6245796c8dcSSimon Schubert else
625*ef5ccd6cSJohn Marino {
626*ef5ccd6cSJohn Marino struct value_print_options opts;
627*ef5ccd6cSJohn Marino
628*ef5ccd6cSJohn Marino get_user_print_options (&opts);
629*ef5ccd6cSJohn Marino print_address_demangle (&opts, gdbarch, ptr_value, stream, demangle);
630*ef5ccd6cSJohn Marino }
6315796c8dcSSimon Schubert
6325796c8dcSSimon Schubert if (adjustment)
6335796c8dcSSimon Schubert {
6345796c8dcSSimon Schubert fprintf_filtered (stream, ", this adjustment ");
6355796c8dcSSimon Schubert print_longest (stream, 'd', 1, adjustment);
6365796c8dcSSimon Schubert }
6375796c8dcSSimon Schubert }
6385796c8dcSSimon Schubert
6395796c8dcSSimon Schubert /* GNU v3 implementation of cplus_method_ptr_size. */
6405796c8dcSSimon Schubert
6415796c8dcSSimon Schubert static int
gnuv3_method_ptr_size(struct type * type)6425796c8dcSSimon Schubert gnuv3_method_ptr_size (struct type *type)
6435796c8dcSSimon Schubert {
644c50c785cSJohn Marino struct gdbarch *gdbarch = get_type_arch (type);
645cf7f2e2dSJohn Marino
6465796c8dcSSimon Schubert return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
6475796c8dcSSimon Schubert }
6485796c8dcSSimon Schubert
6495796c8dcSSimon Schubert /* GNU v3 implementation of cplus_make_method_ptr. */
6505796c8dcSSimon Schubert
6515796c8dcSSimon Schubert static void
gnuv3_make_method_ptr(struct type * type,gdb_byte * contents,CORE_ADDR value,int is_virtual)6525796c8dcSSimon Schubert gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
6535796c8dcSSimon Schubert CORE_ADDR value, int is_virtual)
6545796c8dcSSimon Schubert {
655c50c785cSJohn Marino struct gdbarch *gdbarch = get_type_arch (type);
6565796c8dcSSimon Schubert int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
6575796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
6585796c8dcSSimon Schubert
6595796c8dcSSimon Schubert /* FIXME drow/2006-12-24: The adjustment of "this" is currently
6605796c8dcSSimon Schubert always zero, since the method pointer is of the correct type.
6615796c8dcSSimon Schubert But if the method pointer came from a base class, this is
6625796c8dcSSimon Schubert incorrect - it should be the offset to the base. The best
6635796c8dcSSimon Schubert fix might be to create the pointer to member pointing at the
6645796c8dcSSimon Schubert base class and cast it to the derived class, but that requires
6655796c8dcSSimon Schubert support for adjusting pointers to members when casting them -
6665796c8dcSSimon Schubert not currently supported by GDB. */
6675796c8dcSSimon Schubert
6685796c8dcSSimon Schubert if (!gdbarch_vbit_in_delta (gdbarch))
6695796c8dcSSimon Schubert {
6705796c8dcSSimon Schubert store_unsigned_integer (contents, size, byte_order, value | is_virtual);
6715796c8dcSSimon Schubert store_unsigned_integer (contents + size, size, byte_order, 0);
6725796c8dcSSimon Schubert }
6735796c8dcSSimon Schubert else
6745796c8dcSSimon Schubert {
6755796c8dcSSimon Schubert store_unsigned_integer (contents, size, byte_order, value);
6765796c8dcSSimon Schubert store_unsigned_integer (contents + size, size, byte_order, is_virtual);
6775796c8dcSSimon Schubert }
6785796c8dcSSimon Schubert }
6795796c8dcSSimon Schubert
6805796c8dcSSimon Schubert /* GNU v3 implementation of cplus_method_ptr_to_value. */
6815796c8dcSSimon Schubert
6825796c8dcSSimon Schubert static struct value *
gnuv3_method_ptr_to_value(struct value ** this_p,struct value * method_ptr)6835796c8dcSSimon Schubert gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
6845796c8dcSSimon Schubert {
6855796c8dcSSimon Schubert struct gdbarch *gdbarch;
6865796c8dcSSimon Schubert const gdb_byte *contents = value_contents (method_ptr);
6875796c8dcSSimon Schubert CORE_ADDR ptr_value;
6885796c8dcSSimon Schubert struct type *domain_type, *final_type, *method_type;
6895796c8dcSSimon Schubert LONGEST adjustment;
6905796c8dcSSimon Schubert int vbit;
6915796c8dcSSimon Schubert
6925796c8dcSSimon Schubert domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
6935796c8dcSSimon Schubert final_type = lookup_pointer_type (domain_type);
6945796c8dcSSimon Schubert
6955796c8dcSSimon Schubert method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
6965796c8dcSSimon Schubert
6975796c8dcSSimon Schubert /* Extract the pointer to member. */
6985796c8dcSSimon Schubert gdbarch = get_type_arch (domain_type);
6995796c8dcSSimon Schubert vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);
7005796c8dcSSimon Schubert
7015796c8dcSSimon Schubert /* First convert THIS to match the containing type of the pointer to
7025796c8dcSSimon Schubert member. This cast may adjust the value of THIS. */
7035796c8dcSSimon Schubert *this_p = value_cast (final_type, *this_p);
7045796c8dcSSimon Schubert
7055796c8dcSSimon Schubert /* Then apply whatever adjustment is necessary. This creates a somewhat
7065796c8dcSSimon Schubert strange pointer: it claims to have type FINAL_TYPE, but in fact it
7075796c8dcSSimon Schubert might not be a valid FINAL_TYPE. For instance, it might be a
7085796c8dcSSimon Schubert base class of FINAL_TYPE. And if it's not the primary base class,
7095796c8dcSSimon Schubert then printing it out as a FINAL_TYPE object would produce some pretty
7105796c8dcSSimon Schubert garbage.
7115796c8dcSSimon Schubert
7125796c8dcSSimon Schubert But we don't really know the type of the first argument in
7135796c8dcSSimon Schubert METHOD_TYPE either, which is why this happens. We can't
7145796c8dcSSimon Schubert dereference this later as a FINAL_TYPE, but once we arrive in the
7155796c8dcSSimon Schubert called method we'll have debugging information for the type of
7165796c8dcSSimon Schubert "this" - and that'll match the value we produce here.
7175796c8dcSSimon Schubert
7185796c8dcSSimon Schubert You can provoke this case by casting a Base::* to a Derived::*, for
7195796c8dcSSimon Schubert instance. */
7205796c8dcSSimon Schubert *this_p = value_cast (builtin_type (gdbarch)->builtin_data_ptr, *this_p);
7215796c8dcSSimon Schubert *this_p = value_ptradd (*this_p, adjustment);
7225796c8dcSSimon Schubert *this_p = value_cast (final_type, *this_p);
7235796c8dcSSimon Schubert
7245796c8dcSSimon Schubert if (vbit)
7255796c8dcSSimon Schubert {
7265796c8dcSSimon Schubert LONGEST voffset;
727cf7f2e2dSJohn Marino
7285796c8dcSSimon Schubert voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
7295796c8dcSSimon Schubert return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
7305796c8dcSSimon Schubert method_type, voffset);
7315796c8dcSSimon Schubert }
7325796c8dcSSimon Schubert else
7335796c8dcSSimon Schubert return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
7345796c8dcSSimon Schubert }
7355796c8dcSSimon Schubert
736*ef5ccd6cSJohn Marino /* Objects of this type are stored in a hash table and a vector when
737*ef5ccd6cSJohn Marino printing the vtables for a class. */
738*ef5ccd6cSJohn Marino
739*ef5ccd6cSJohn Marino struct value_and_voffset
740*ef5ccd6cSJohn Marino {
741*ef5ccd6cSJohn Marino /* The value representing the object. */
742*ef5ccd6cSJohn Marino struct value *value;
743*ef5ccd6cSJohn Marino
744*ef5ccd6cSJohn Marino /* The maximum vtable offset we've found for any object at this
745*ef5ccd6cSJohn Marino offset in the outermost object. */
746*ef5ccd6cSJohn Marino int max_voffset;
747*ef5ccd6cSJohn Marino };
748*ef5ccd6cSJohn Marino
749*ef5ccd6cSJohn Marino typedef struct value_and_voffset *value_and_voffset_p;
750*ef5ccd6cSJohn Marino DEF_VEC_P (value_and_voffset_p);
751*ef5ccd6cSJohn Marino
752*ef5ccd6cSJohn Marino /* Hash function for value_and_voffset. */
753*ef5ccd6cSJohn Marino
754*ef5ccd6cSJohn Marino static hashval_t
hash_value_and_voffset(const void * p)755*ef5ccd6cSJohn Marino hash_value_and_voffset (const void *p)
756*ef5ccd6cSJohn Marino {
757*ef5ccd6cSJohn Marino const struct value_and_voffset *o = p;
758*ef5ccd6cSJohn Marino
759*ef5ccd6cSJohn Marino return value_address (o->value) + value_embedded_offset (o->value);
760*ef5ccd6cSJohn Marino }
761*ef5ccd6cSJohn Marino
762*ef5ccd6cSJohn Marino /* Equality function for value_and_voffset. */
763*ef5ccd6cSJohn Marino
764*ef5ccd6cSJohn Marino static int
eq_value_and_voffset(const void * a,const void * b)765*ef5ccd6cSJohn Marino eq_value_and_voffset (const void *a, const void *b)
766*ef5ccd6cSJohn Marino {
767*ef5ccd6cSJohn Marino const struct value_and_voffset *ova = a;
768*ef5ccd6cSJohn Marino const struct value_and_voffset *ovb = b;
769*ef5ccd6cSJohn Marino
770*ef5ccd6cSJohn Marino return (value_address (ova->value) + value_embedded_offset (ova->value)
771*ef5ccd6cSJohn Marino == value_address (ovb->value) + value_embedded_offset (ovb->value));
772*ef5ccd6cSJohn Marino }
773*ef5ccd6cSJohn Marino
774*ef5ccd6cSJohn Marino /* qsort comparison function for value_and_voffset. */
775*ef5ccd6cSJohn Marino
776*ef5ccd6cSJohn Marino static int
compare_value_and_voffset(const void * a,const void * b)777*ef5ccd6cSJohn Marino compare_value_and_voffset (const void *a, const void *b)
778*ef5ccd6cSJohn Marino {
779*ef5ccd6cSJohn Marino const struct value_and_voffset * const *ova = a;
780*ef5ccd6cSJohn Marino CORE_ADDR addra = (value_address ((*ova)->value)
781*ef5ccd6cSJohn Marino + value_embedded_offset ((*ova)->value));
782*ef5ccd6cSJohn Marino const struct value_and_voffset * const *ovb = b;
783*ef5ccd6cSJohn Marino CORE_ADDR addrb = (value_address ((*ovb)->value)
784*ef5ccd6cSJohn Marino + value_embedded_offset ((*ovb)->value));
785*ef5ccd6cSJohn Marino
786*ef5ccd6cSJohn Marino if (addra < addrb)
787*ef5ccd6cSJohn Marino return -1;
788*ef5ccd6cSJohn Marino if (addra > addrb)
789*ef5ccd6cSJohn Marino return 1;
790*ef5ccd6cSJohn Marino return 0;
791*ef5ccd6cSJohn Marino }
792*ef5ccd6cSJohn Marino
793*ef5ccd6cSJohn Marino /* A helper function used when printing vtables. This determines the
794*ef5ccd6cSJohn Marino key (most derived) sub-object at each address and also computes the
795*ef5ccd6cSJohn Marino maximum vtable offset seen for the corresponding vtable. Updates
796*ef5ccd6cSJohn Marino OFFSET_HASH and OFFSET_VEC with a new value_and_voffset object, if
797*ef5ccd6cSJohn Marino needed. VALUE is the object to examine. */
798*ef5ccd6cSJohn Marino
799*ef5ccd6cSJohn Marino static void
compute_vtable_size(htab_t offset_hash,VEC (value_and_voffset_p)** offset_vec,struct value * value)800*ef5ccd6cSJohn Marino compute_vtable_size (htab_t offset_hash,
801*ef5ccd6cSJohn Marino VEC (value_and_voffset_p) **offset_vec,
802*ef5ccd6cSJohn Marino struct value *value)
803*ef5ccd6cSJohn Marino {
804*ef5ccd6cSJohn Marino int i;
805*ef5ccd6cSJohn Marino struct type *type = check_typedef (value_type (value));
806*ef5ccd6cSJohn Marino void **slot;
807*ef5ccd6cSJohn Marino struct value_and_voffset search_vo, *current_vo;
808*ef5ccd6cSJohn Marino
809*ef5ccd6cSJohn Marino /* If the object is not dynamic, then we are done; as it cannot have
810*ef5ccd6cSJohn Marino dynamic base types either. */
811*ef5ccd6cSJohn Marino if (!gnuv3_dynamic_class (type))
812*ef5ccd6cSJohn Marino return;
813*ef5ccd6cSJohn Marino
814*ef5ccd6cSJohn Marino /* Update the hash and the vec, if needed. */
815*ef5ccd6cSJohn Marino search_vo.value = value;
816*ef5ccd6cSJohn Marino slot = htab_find_slot (offset_hash, &search_vo, INSERT);
817*ef5ccd6cSJohn Marino if (*slot)
818*ef5ccd6cSJohn Marino current_vo = *slot;
819*ef5ccd6cSJohn Marino else
820*ef5ccd6cSJohn Marino {
821*ef5ccd6cSJohn Marino current_vo = XNEW (struct value_and_voffset);
822*ef5ccd6cSJohn Marino current_vo->value = value;
823*ef5ccd6cSJohn Marino current_vo->max_voffset = -1;
824*ef5ccd6cSJohn Marino *slot = current_vo;
825*ef5ccd6cSJohn Marino VEC_safe_push (value_and_voffset_p, *offset_vec, current_vo);
826*ef5ccd6cSJohn Marino }
827*ef5ccd6cSJohn Marino
828*ef5ccd6cSJohn Marino /* Update the value_and_voffset object with the highest vtable
829*ef5ccd6cSJohn Marino offset from this class. */
830*ef5ccd6cSJohn Marino for (i = 0; i < TYPE_NFN_FIELDS (type); ++i)
831*ef5ccd6cSJohn Marino {
832*ef5ccd6cSJohn Marino int j;
833*ef5ccd6cSJohn Marino struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, i);
834*ef5ccd6cSJohn Marino
835*ef5ccd6cSJohn Marino for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
836*ef5ccd6cSJohn Marino {
837*ef5ccd6cSJohn Marino if (TYPE_FN_FIELD_VIRTUAL_P (fn, j))
838*ef5ccd6cSJohn Marino {
839*ef5ccd6cSJohn Marino int voffset = TYPE_FN_FIELD_VOFFSET (fn, j);
840*ef5ccd6cSJohn Marino
841*ef5ccd6cSJohn Marino if (voffset > current_vo->max_voffset)
842*ef5ccd6cSJohn Marino current_vo->max_voffset = voffset;
843*ef5ccd6cSJohn Marino }
844*ef5ccd6cSJohn Marino }
845*ef5ccd6cSJohn Marino }
846*ef5ccd6cSJohn Marino
847*ef5ccd6cSJohn Marino /* Recurse into base classes. */
848*ef5ccd6cSJohn Marino for (i = 0; i < TYPE_N_BASECLASSES (type); ++i)
849*ef5ccd6cSJohn Marino compute_vtable_size (offset_hash, offset_vec, value_field (value, i));
850*ef5ccd6cSJohn Marino }
851*ef5ccd6cSJohn Marino
852*ef5ccd6cSJohn Marino /* Helper for gnuv3_print_vtable that prints a single vtable. */
853*ef5ccd6cSJohn Marino
854*ef5ccd6cSJohn Marino static void
print_one_vtable(struct gdbarch * gdbarch,struct value * value,int max_voffset,struct value_print_options * opts)855*ef5ccd6cSJohn Marino print_one_vtable (struct gdbarch *gdbarch, struct value *value,
856*ef5ccd6cSJohn Marino int max_voffset,
857*ef5ccd6cSJohn Marino struct value_print_options *opts)
858*ef5ccd6cSJohn Marino {
859*ef5ccd6cSJohn Marino int i;
860*ef5ccd6cSJohn Marino struct type *type = check_typedef (value_type (value));
861*ef5ccd6cSJohn Marino struct value *vtable;
862*ef5ccd6cSJohn Marino CORE_ADDR vt_addr;
863*ef5ccd6cSJohn Marino
864*ef5ccd6cSJohn Marino vtable = gnuv3_get_vtable (gdbarch, type,
865*ef5ccd6cSJohn Marino value_address (value)
866*ef5ccd6cSJohn Marino + value_embedded_offset (value));
867*ef5ccd6cSJohn Marino vt_addr = value_address (value_field (vtable,
868*ef5ccd6cSJohn Marino vtable_field_virtual_functions));
869*ef5ccd6cSJohn Marino
870*ef5ccd6cSJohn Marino printf_filtered (_("vtable for '%s' @ %s (subobject @ %s):\n"),
871*ef5ccd6cSJohn Marino TYPE_SAFE_NAME (type),
872*ef5ccd6cSJohn Marino paddress (gdbarch, vt_addr),
873*ef5ccd6cSJohn Marino paddress (gdbarch, (value_address (value)
874*ef5ccd6cSJohn Marino + value_embedded_offset (value))));
875*ef5ccd6cSJohn Marino
876*ef5ccd6cSJohn Marino for (i = 0; i <= max_voffset; ++i)
877*ef5ccd6cSJohn Marino {
878*ef5ccd6cSJohn Marino /* Initialize it just to avoid a GCC false warning. */
879*ef5ccd6cSJohn Marino CORE_ADDR addr = 0;
880*ef5ccd6cSJohn Marino struct value *vfn;
881*ef5ccd6cSJohn Marino volatile struct gdb_exception ex;
882*ef5ccd6cSJohn Marino
883*ef5ccd6cSJohn Marino printf_filtered ("[%d]: ", i);
884*ef5ccd6cSJohn Marino
885*ef5ccd6cSJohn Marino vfn = value_subscript (value_field (vtable,
886*ef5ccd6cSJohn Marino vtable_field_virtual_functions),
887*ef5ccd6cSJohn Marino i);
888*ef5ccd6cSJohn Marino
889*ef5ccd6cSJohn Marino if (gdbarch_vtable_function_descriptors (gdbarch))
890*ef5ccd6cSJohn Marino vfn = value_addr (vfn);
891*ef5ccd6cSJohn Marino
892*ef5ccd6cSJohn Marino TRY_CATCH (ex, RETURN_MASK_ERROR)
893*ef5ccd6cSJohn Marino {
894*ef5ccd6cSJohn Marino addr = value_as_address (vfn);
895*ef5ccd6cSJohn Marino }
896*ef5ccd6cSJohn Marino if (ex.reason < 0)
897*ef5ccd6cSJohn Marino printf_filtered (_("<error: %s>"), ex.message);
898*ef5ccd6cSJohn Marino else
899*ef5ccd6cSJohn Marino print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
900*ef5ccd6cSJohn Marino printf_filtered ("\n");
901*ef5ccd6cSJohn Marino }
902*ef5ccd6cSJohn Marino }
903*ef5ccd6cSJohn Marino
904*ef5ccd6cSJohn Marino /* Implementation of the print_vtable method. */
905*ef5ccd6cSJohn Marino
906*ef5ccd6cSJohn Marino static void
gnuv3_print_vtable(struct value * value)907*ef5ccd6cSJohn Marino gnuv3_print_vtable (struct value *value)
908*ef5ccd6cSJohn Marino {
909*ef5ccd6cSJohn Marino struct gdbarch *gdbarch;
910*ef5ccd6cSJohn Marino struct type *type;
911*ef5ccd6cSJohn Marino struct value *vtable;
912*ef5ccd6cSJohn Marino struct value_print_options opts;
913*ef5ccd6cSJohn Marino htab_t offset_hash;
914*ef5ccd6cSJohn Marino struct cleanup *cleanup;
915*ef5ccd6cSJohn Marino VEC (value_and_voffset_p) *result_vec = NULL;
916*ef5ccd6cSJohn Marino struct value_and_voffset *iter;
917*ef5ccd6cSJohn Marino int i, count;
918*ef5ccd6cSJohn Marino
919*ef5ccd6cSJohn Marino value = coerce_ref (value);
920*ef5ccd6cSJohn Marino type = check_typedef (value_type (value));
921*ef5ccd6cSJohn Marino if (TYPE_CODE (type) == TYPE_CODE_PTR)
922*ef5ccd6cSJohn Marino {
923*ef5ccd6cSJohn Marino value = value_ind (value);
924*ef5ccd6cSJohn Marino type = check_typedef (value_type (value));
925*ef5ccd6cSJohn Marino }
926*ef5ccd6cSJohn Marino
927*ef5ccd6cSJohn Marino get_user_print_options (&opts);
928*ef5ccd6cSJohn Marino
929*ef5ccd6cSJohn Marino /* Respect 'set print object'. */
930*ef5ccd6cSJohn Marino if (opts.objectprint)
931*ef5ccd6cSJohn Marino {
932*ef5ccd6cSJohn Marino value = value_full_object (value, NULL, 0, 0, 0);
933*ef5ccd6cSJohn Marino type = check_typedef (value_type (value));
934*ef5ccd6cSJohn Marino }
935*ef5ccd6cSJohn Marino
936*ef5ccd6cSJohn Marino gdbarch = get_type_arch (type);
937*ef5ccd6cSJohn Marino vtable = gnuv3_get_vtable (gdbarch, type,
938*ef5ccd6cSJohn Marino value_as_address (value_addr (value)));
939*ef5ccd6cSJohn Marino
940*ef5ccd6cSJohn Marino if (!vtable)
941*ef5ccd6cSJohn Marino {
942*ef5ccd6cSJohn Marino printf_filtered (_("This object does not have a virtual function table\n"));
943*ef5ccd6cSJohn Marino return;
944*ef5ccd6cSJohn Marino }
945*ef5ccd6cSJohn Marino
946*ef5ccd6cSJohn Marino offset_hash = htab_create_alloc (1, hash_value_and_voffset,
947*ef5ccd6cSJohn Marino eq_value_and_voffset,
948*ef5ccd6cSJohn Marino xfree, xcalloc, xfree);
949*ef5ccd6cSJohn Marino cleanup = make_cleanup_htab_delete (offset_hash);
950*ef5ccd6cSJohn Marino make_cleanup (VEC_cleanup (value_and_voffset_p), &result_vec);
951*ef5ccd6cSJohn Marino
952*ef5ccd6cSJohn Marino compute_vtable_size (offset_hash, &result_vec, value);
953*ef5ccd6cSJohn Marino
954*ef5ccd6cSJohn Marino qsort (VEC_address (value_and_voffset_p, result_vec),
955*ef5ccd6cSJohn Marino VEC_length (value_and_voffset_p, result_vec),
956*ef5ccd6cSJohn Marino sizeof (value_and_voffset_p),
957*ef5ccd6cSJohn Marino compare_value_and_voffset);
958*ef5ccd6cSJohn Marino
959*ef5ccd6cSJohn Marino count = 0;
960*ef5ccd6cSJohn Marino for (i = 0; VEC_iterate (value_and_voffset_p, result_vec, i, iter); ++i)
961*ef5ccd6cSJohn Marino {
962*ef5ccd6cSJohn Marino if (iter->max_voffset >= 0)
963*ef5ccd6cSJohn Marino {
964*ef5ccd6cSJohn Marino if (count > 0)
965*ef5ccd6cSJohn Marino printf_filtered ("\n");
966*ef5ccd6cSJohn Marino print_one_vtable (gdbarch, iter->value, iter->max_voffset, &opts);
967*ef5ccd6cSJohn Marino ++count;
968*ef5ccd6cSJohn Marino }
969*ef5ccd6cSJohn Marino }
970*ef5ccd6cSJohn Marino
971*ef5ccd6cSJohn Marino do_cleanups (cleanup);
972*ef5ccd6cSJohn Marino }
973*ef5ccd6cSJohn Marino
9745796c8dcSSimon Schubert /* Determine if we are currently in a C++ thunk. If so, get the address
9755796c8dcSSimon Schubert of the routine we are thunking to and continue to there instead. */
9765796c8dcSSimon Schubert
9775796c8dcSSimon Schubert static CORE_ADDR
gnuv3_skip_trampoline(struct frame_info * frame,CORE_ADDR stop_pc)9785796c8dcSSimon Schubert gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
9795796c8dcSSimon Schubert {
9805796c8dcSSimon Schubert CORE_ADDR real_stop_pc, method_stop_pc;
9815796c8dcSSimon Schubert struct gdbarch *gdbarch = get_frame_arch (frame);
9825796c8dcSSimon Schubert struct minimal_symbol *thunk_sym, *fn_sym;
9835796c8dcSSimon Schubert struct obj_section *section;
984*ef5ccd6cSJohn Marino const char *thunk_name, *fn_name;
9855796c8dcSSimon Schubert
9865796c8dcSSimon Schubert real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
9875796c8dcSSimon Schubert if (real_stop_pc == 0)
9885796c8dcSSimon Schubert real_stop_pc = stop_pc;
9895796c8dcSSimon Schubert
9905796c8dcSSimon Schubert /* Find the linker symbol for this potential thunk. */
9915796c8dcSSimon Schubert thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc);
9925796c8dcSSimon Schubert section = find_pc_section (real_stop_pc);
9935796c8dcSSimon Schubert if (thunk_sym == NULL || section == NULL)
9945796c8dcSSimon Schubert return 0;
9955796c8dcSSimon Schubert
9965796c8dcSSimon Schubert /* The symbol's demangled name should be something like "virtual
9975796c8dcSSimon Schubert thunk to FUNCTION", where FUNCTION is the name of the function
9985796c8dcSSimon Schubert being thunked to. */
9995796c8dcSSimon Schubert thunk_name = SYMBOL_DEMANGLED_NAME (thunk_sym);
10005796c8dcSSimon Schubert if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL)
10015796c8dcSSimon Schubert return 0;
10025796c8dcSSimon Schubert
10035796c8dcSSimon Schubert fn_name = strstr (thunk_name, " thunk to ") + strlen (" thunk to ");
10045796c8dcSSimon Schubert fn_sym = lookup_minimal_symbol (fn_name, NULL, section->objfile);
10055796c8dcSSimon Schubert if (fn_sym == NULL)
10065796c8dcSSimon Schubert return 0;
10075796c8dcSSimon Schubert
10085796c8dcSSimon Schubert method_stop_pc = SYMBOL_VALUE_ADDRESS (fn_sym);
10095796c8dcSSimon Schubert real_stop_pc = gdbarch_skip_trampoline_code
10105796c8dcSSimon Schubert (gdbarch, frame, method_stop_pc);
10115796c8dcSSimon Schubert if (real_stop_pc == 0)
10125796c8dcSSimon Schubert real_stop_pc = method_stop_pc;
10135796c8dcSSimon Schubert
10145796c8dcSSimon Schubert return real_stop_pc;
10155796c8dcSSimon Schubert }
10165796c8dcSSimon Schubert
10175796c8dcSSimon Schubert /* Return nonzero if a type should be passed by reference.
10185796c8dcSSimon Schubert
10195796c8dcSSimon Schubert The rule in the v3 ABI document comes from section 3.1.1. If the
10205796c8dcSSimon Schubert type has a non-trivial copy constructor or destructor, then the
10215796c8dcSSimon Schubert caller must make a copy (by calling the copy constructor if there
10225796c8dcSSimon Schubert is one or perform the copy itself otherwise), pass the address of
10235796c8dcSSimon Schubert the copy, and then destroy the temporary (if necessary).
10245796c8dcSSimon Schubert
10255796c8dcSSimon Schubert For return values with non-trivial copy constructors or
10265796c8dcSSimon Schubert destructors, space will be allocated in the caller, and a pointer
10275796c8dcSSimon Schubert will be passed as the first argument (preceding "this").
10285796c8dcSSimon Schubert
10295796c8dcSSimon Schubert We don't have a bulletproof mechanism for determining whether a
10305796c8dcSSimon Schubert constructor or destructor is trivial. For GCC and DWARF2 debug
10315796c8dcSSimon Schubert information, we can check the artificial flag.
10325796c8dcSSimon Schubert
10335796c8dcSSimon Schubert We don't do anything with the constructors or destructors,
10345796c8dcSSimon Schubert but we have to get the argument passing right anyway. */
10355796c8dcSSimon Schubert static int
gnuv3_pass_by_reference(struct type * type)10365796c8dcSSimon Schubert gnuv3_pass_by_reference (struct type *type)
10375796c8dcSSimon Schubert {
10385796c8dcSSimon Schubert int fieldnum, fieldelem;
10395796c8dcSSimon Schubert
10405796c8dcSSimon Schubert CHECK_TYPEDEF (type);
10415796c8dcSSimon Schubert
10425796c8dcSSimon Schubert /* We're only interested in things that can have methods. */
10435796c8dcSSimon Schubert if (TYPE_CODE (type) != TYPE_CODE_STRUCT
10445796c8dcSSimon Schubert && TYPE_CODE (type) != TYPE_CODE_CLASS
10455796c8dcSSimon Schubert && TYPE_CODE (type) != TYPE_CODE_UNION)
10465796c8dcSSimon Schubert return 0;
10475796c8dcSSimon Schubert
10485796c8dcSSimon Schubert for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
10495796c8dcSSimon Schubert for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
10505796c8dcSSimon Schubert fieldelem++)
10515796c8dcSSimon Schubert {
10525796c8dcSSimon Schubert struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum);
1053*ef5ccd6cSJohn Marino const char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum);
10545796c8dcSSimon Schubert struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem);
10555796c8dcSSimon Schubert
10565796c8dcSSimon Schubert /* If this function is marked as artificial, it is compiler-generated,
10575796c8dcSSimon Schubert and we assume it is trivial. */
10585796c8dcSSimon Schubert if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem))
10595796c8dcSSimon Schubert continue;
10605796c8dcSSimon Schubert
10615796c8dcSSimon Schubert /* If we've found a destructor, we must pass this by reference. */
10625796c8dcSSimon Schubert if (name[0] == '~')
10635796c8dcSSimon Schubert return 1;
10645796c8dcSSimon Schubert
10655796c8dcSSimon Schubert /* If the mangled name of this method doesn't indicate that it
10665796c8dcSSimon Schubert is a constructor, we're not interested.
10675796c8dcSSimon Schubert
10685796c8dcSSimon Schubert FIXME drow/2007-09-23: We could do this using the name of
10695796c8dcSSimon Schubert the method and the name of the class instead of dealing
10705796c8dcSSimon Schubert with the mangled name. We don't have a convenient function
10715796c8dcSSimon Schubert to strip off both leading scope qualifiers and trailing
10725796c8dcSSimon Schubert template arguments yet. */
1073*ef5ccd6cSJohn Marino if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem))
1074*ef5ccd6cSJohn Marino && !TYPE_FN_FIELD_CONSTRUCTOR (fn, fieldelem))
10755796c8dcSSimon Schubert continue;
10765796c8dcSSimon Schubert
10775796c8dcSSimon Schubert /* If this method takes two arguments, and the second argument is
10785796c8dcSSimon Schubert a reference to this class, then it is a copy constructor. */
10795796c8dcSSimon Schubert if (TYPE_NFIELDS (fieldtype) == 2
10805796c8dcSSimon Schubert && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF
1081c50c785cSJohn Marino && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype,
1082c50c785cSJohn Marino 1))) == type)
10835796c8dcSSimon Schubert return 1;
10845796c8dcSSimon Schubert }
10855796c8dcSSimon Schubert
10865796c8dcSSimon Schubert /* Even if all the constructors and destructors were artificial, one
10875796c8dcSSimon Schubert of them may have invoked a non-artificial constructor or
10885796c8dcSSimon Schubert destructor in a base class. If any base class needs to be passed
10895796c8dcSSimon Schubert by reference, so does this class. Similarly for members, which
10905796c8dcSSimon Schubert are constructed whenever this class is. We do not need to worry
10915796c8dcSSimon Schubert about recursive loops here, since we are only looking at members
1092c50c785cSJohn Marino of complete class type. Also ignore any static members. */
10935796c8dcSSimon Schubert for (fieldnum = 0; fieldnum < TYPE_NFIELDS (type); fieldnum++)
1094c50c785cSJohn Marino if (! field_is_static (&TYPE_FIELD (type, fieldnum))
1095c50c785cSJohn Marino && gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum)))
10965796c8dcSSimon Schubert return 1;
10975796c8dcSSimon Schubert
10985796c8dcSSimon Schubert return 0;
10995796c8dcSSimon Schubert }
11005796c8dcSSimon Schubert
11015796c8dcSSimon Schubert static void
init_gnuv3_ops(void)11025796c8dcSSimon Schubert init_gnuv3_ops (void)
11035796c8dcSSimon Schubert {
1104c50c785cSJohn Marino vtable_type_gdbarch_data
1105c50c785cSJohn Marino = gdbarch_data_register_post_init (build_gdb_vtable_type);
11065796c8dcSSimon Schubert
11075796c8dcSSimon Schubert gnu_v3_abi_ops.shortname = "gnu-v3";
11085796c8dcSSimon Schubert gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";
11095796c8dcSSimon Schubert gnu_v3_abi_ops.doc = "G++ Version 3 ABI";
11105796c8dcSSimon Schubert gnu_v3_abi_ops.is_destructor_name =
11115796c8dcSSimon Schubert (enum dtor_kinds (*) (const char *))is_gnu_v3_mangled_dtor;
11125796c8dcSSimon Schubert gnu_v3_abi_ops.is_constructor_name =
11135796c8dcSSimon Schubert (enum ctor_kinds (*) (const char *))is_gnu_v3_mangled_ctor;
11145796c8dcSSimon Schubert gnu_v3_abi_ops.is_vtable_name = gnuv3_is_vtable_name;
11155796c8dcSSimon Schubert gnu_v3_abi_ops.is_operator_name = gnuv3_is_operator_name;
11165796c8dcSSimon Schubert gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type;
11175796c8dcSSimon Schubert gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field;
11185796c8dcSSimon Schubert gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;
11195796c8dcSSimon Schubert gnu_v3_abi_ops.print_method_ptr = gnuv3_print_method_ptr;
11205796c8dcSSimon Schubert gnu_v3_abi_ops.method_ptr_size = gnuv3_method_ptr_size;
11215796c8dcSSimon Schubert gnu_v3_abi_ops.make_method_ptr = gnuv3_make_method_ptr;
11225796c8dcSSimon Schubert gnu_v3_abi_ops.method_ptr_to_value = gnuv3_method_ptr_to_value;
1123*ef5ccd6cSJohn Marino gnu_v3_abi_ops.print_vtable = gnuv3_print_vtable;
11245796c8dcSSimon Schubert gnu_v3_abi_ops.skip_trampoline = gnuv3_skip_trampoline;
11255796c8dcSSimon Schubert gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
11265796c8dcSSimon Schubert }
11275796c8dcSSimon Schubert
11285796c8dcSSimon Schubert extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
11295796c8dcSSimon Schubert
11305796c8dcSSimon Schubert void
_initialize_gnu_v3_abi(void)11315796c8dcSSimon Schubert _initialize_gnu_v3_abi (void)
11325796c8dcSSimon Schubert {
11335796c8dcSSimon Schubert init_gnuv3_ops ();
11345796c8dcSSimon Schubert
11355796c8dcSSimon Schubert register_cp_abi (&gnu_v3_abi_ops);
1136*ef5ccd6cSJohn Marino set_cp_abi_as_auto_default (gnu_v3_abi_ops.shortname);
11375796c8dcSSimon Schubert }
1138