/* Abstraction of GNU v3 abi.
Contributed by Jim Blandy <jimb@redhat.com>
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "valprint.h"
#include "c-lang.h"
#include "typeprint.h"
+#include <algorithm>
+#include "cli/cli-style.h"
static struct cp_abi_ops gnu_v3_abi_ops;
static int
gnuv3_is_operator_name (const char *name)
{
- return startswith (name, "operator");
+ return startswith (name, CP_OPERATOR_STR);
}
/* We assumed in the allocation above that there were four fields. */
gdb_assert (field == (field_list + 4));
- t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
+ t = arch_type (arch, TYPE_CODE_STRUCT, offset * TARGET_CHAR_BIT, NULL);
TYPE_NFIELDS (t) = field - field_list;
TYPE_FIELDS (t) = field_list;
- TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable";
+ TYPE_NAME (t) = "gdb_gnu_v3_abi_vtable";
INIT_CPLUS_SPECIFIC (t);
return make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
LONGEST offset_to_top;
const char *atsign;
- /* We only have RTTI for class objects. */
- if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
+ /* We only have RTTI for dynamic class objects. */
+ if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT
+ || !gnuv3_dynamic_class (values_type))
return NULL;
/* Determine architecture. */
If we didn't like this approach, we could instead look in the
type_info object itself to get the class name. But this way
should work just as well, and doesn't read target memory. */
- vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
+ vtable_symbol_name = vtable_symbol->demangled_name ();
if (vtable_symbol_name == NULL
|| !startswith (vtable_symbol_name, "vtable for "))
{
/* If this architecture uses function descriptors directly in the vtable,
then the address of the vtable entry is actually a "function pointer"
(i.e. points to the descriptor). We don't need to scale the index
- by the size of a function descriptor; GCC does that before outputing
+ by the size of a function descriptor; GCC does that before outputting
debug information. */
if (gdbarch_vtable_function_descriptors (gdbarch))
vfn = value_addr (vfn);
{
struct gdbarch *gdbarch = get_type_arch (type);
int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
/* FIXME drow/2006-12-24: The adjustment of "this" is currently
always zero, since the method pointer is of the correct type.
int max_voffset;
};
-typedef struct value_and_voffset *value_and_voffset_p;
-DEF_VEC_P (value_and_voffset_p);
-
/* Hash function for value_and_voffset. */
static hashval_t
== value_address (ovb->value) + value_embedded_offset (ovb->value));
}
-/* qsort comparison function for value_and_voffset. */
+/* Comparison function for value_and_voffset. */
-static int
-compare_value_and_voffset (const void *a, const void *b)
+static bool
+compare_value_and_voffset (const struct value_and_voffset *va,
+ const struct value_and_voffset *vb)
{
- const struct value_and_voffset * const *ova
- = (const struct value_and_voffset * const *) a;
- CORE_ADDR addra = (value_address ((*ova)->value)
- + value_embedded_offset ((*ova)->value));
- const struct value_and_voffset * const *ovb
- = (const struct value_and_voffset * const *) b;
- CORE_ADDR addrb = (value_address ((*ovb)->value)
- + value_embedded_offset ((*ovb)->value));
-
- if (addra < addrb)
- return -1;
- if (addra > addrb)
- return 1;
- return 0;
+ CORE_ADDR addra = (value_address (va->value)
+ + value_embedded_offset (va->value));
+ CORE_ADDR addrb = (value_address (vb->value)
+ + value_embedded_offset (vb->value));
+
+ return addra < addrb;
}
/* A helper function used when printing vtables. This determines the
static void
compute_vtable_size (htab_t offset_hash,
- VEC (value_and_voffset_p) **offset_vec,
+ std::vector<value_and_voffset *> *offset_vec,
struct value *value)
{
int i;
current_vo->value = value;
current_vo->max_voffset = -1;
*slot = current_vo;
- VEC_safe_push (value_and_voffset_p, *offset_vec, current_vo);
+ offset_vec->push_back (current_vo);
}
/* Update the value_and_voffset object with the highest vtable
if (gdbarch_vtable_function_descriptors (gdbarch))
vfn = value_addr (vfn);
- TRY
+ try
{
addr = value_as_address (vfn);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
- printf_filtered (_("<error: %s>"), ex.message);
+ fprintf_styled (gdb_stdout, metadata_style.style (),
+ _("<error: %s>"), ex.what ());
got_error = 1;
}
- END_CATCH
if (!got_error)
print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
struct type *type;
struct value *vtable;
struct value_print_options opts;
- htab_t offset_hash;
- struct cleanup *cleanup;
- VEC (value_and_voffset_p) *result_vec = NULL;
- struct value_and_voffset *iter;
- int i, count;
+ int count;
value = coerce_ref (value);
type = check_typedef (value_type (value));
return;
}
- offset_hash = htab_create_alloc (1, hash_value_and_voffset,
- eq_value_and_voffset,
- xfree, xcalloc, xfree);
- cleanup = make_cleanup_htab_delete (offset_hash);
- make_cleanup (VEC_cleanup (value_and_voffset_p), &result_vec);
-
- compute_vtable_size (offset_hash, &result_vec, value);
+ htab_up offset_hash (htab_create_alloc (1, hash_value_and_voffset,
+ eq_value_and_voffset,
+ xfree, xcalloc, xfree));
+ std::vector<value_and_voffset *> result_vec;
- qsort (VEC_address (value_and_voffset_p, result_vec),
- VEC_length (value_and_voffset_p, result_vec),
- sizeof (value_and_voffset_p),
- compare_value_and_voffset);
+ compute_vtable_size (offset_hash.get (), &result_vec, value);
+ std::sort (result_vec.begin (), result_vec.end (),
+ compare_value_and_voffset);
count = 0;
- for (i = 0; VEC_iterate (value_and_voffset_p, result_vec, i, iter); ++i)
+ for (value_and_voffset *iter : result_vec)
{
if (iter->max_voffset >= 0)
{
++count;
}
}
-
- do_cleanups (cleanup);
}
/* Return a GDB type representing `struct std::type_info', laid out
gdb_assert (field == (field_list + 2));
- t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
+ t = arch_type (arch, TYPE_CODE_STRUCT, offset * TARGET_CHAR_BIT, NULL);
TYPE_NFIELDS (t) = field - field_list;
TYPE_FIELDS (t) = field_list;
- TYPE_TAG_NAME (t) = "gdb_gnu_v3_type_info";
+ TYPE_NAME (t) = "gdb_gnu_v3_type_info";
INIT_CPLUS_SPECIFIC (t);
return t;
struct type *typeinfo_type;
struct type *type;
struct gdbarch *gdbarch;
- struct cleanup *cleanup;
struct value *result;
std::string type_name, canonical;
#define TYPEINFO_PREFIX "typeinfo for "
#define TYPEINFO_PREFIX_LEN (sizeof (TYPEINFO_PREFIX) - 1)
- symname = MSYMBOL_DEMANGLED_NAME (typeinfo_sym.minsym);
+ symname = typeinfo_sym.minsym->demangled_name ();
if (symname == NULL || strncmp (symname, TYPEINFO_PREFIX,
TYPEINFO_PREFIX_LEN))
error (_("typeinfo symbol '%s' has unexpected name"),
- MSYMBOL_LINKAGE_NAME (typeinfo_sym.minsym));
+ typeinfo_sym.minsym->linkage_name ());
class_name = symname + TYPEINFO_PREFIX_LEN;
/* Strip off @plt and version suffixes. */
/* The symbol's demangled name should be something like "virtual
thunk to FUNCTION", where FUNCTION is the name of the function
being thunked to. */
- thunk_name = MSYMBOL_DEMANGLED_NAME (thunk_sym.minsym);
+ thunk_name = thunk_sym.minsym->demangled_name ();
if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL)
return 0;
of the real function from the function descriptor before passing on
the address to other layers of GDB. */
func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, method_stop_pc,
- ¤t_target);
+ current_top_target ());
if (func_addr != 0)
method_stop_pc = func_addr;
gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
}
-extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
-
void
_initialize_gnu_v3_abi (void)
{