/* Scheme interface to types.
- Copyright (C) 2008-2016 Free Software Foundation, Inc.
+ Copyright (C) 2008-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbtypes.h"
#include "objfiles.h"
#include "language.h"
-#include "vec.h"
#include "bcache.h"
-#include "dwarf2loc.h"
+#include "dwarf2/loc.h"
#include "typeprint.h"
#include "guile-internal.h"
/* The <gdb:type> smob.
The type is chained with all types associated with its objfile, if any.
This lets us copy the underlying struct type when the objfile is
- deleted.
- The typedef for this struct is in guile-internal.h. */
+ deleted. */
-struct _type_smob
+struct type_smob
{
/* This always appears first.
eqable_gdb_smob is used so that types are eq?-able.
/* A field smob. */
-typedef struct
+struct field_smob
{
/* This always appears first. */
gdb_smob base;
/* The field number in TYPE_SCM. */
int field_num;
-} field_smob;
+};
static const char type_smob_name[] = "gdb:type";
static const char field_smob_name[] = "gdb:field";
static std::string
tyscm_type_name (struct type *type)
{
- TRY
+ SCM excp;
+ try
{
- struct cleanup *old_chain;
- struct ui_file *stb;
-
- stb = mem_fileopen ();
- old_chain = make_cleanup_ui_file_delete (stb);
-
- LA_PRINT_TYPE (type, "", stb, -1, 0, &type_print_raw_options);
+ string_file stb;
- std::string name = ui_file_as_string (stb);
- do_cleanups (old_chain);
-
- return name;
+ LA_PRINT_TYPE (type, "", &stb, -1, 0, &type_print_raw_options);
+ return std::move (stb.string ());
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- SCM excp = gdbscm_scm_from_gdb_exception (except);
- gdbscm_throw (excp);
+ excp = gdbscm_scm_from_gdb_exception (unpack (except));
}
- END_CATCH
- gdb_assert_not_reached ("no way to get here");
+ gdbscm_throw (excp);
}
\f
/* Administrivia for type smobs. */
static htab_t
tyscm_type_map (struct type *type)
{
- struct objfile *objfile = TYPE_OBJFILE (type);
+ struct objfile *objfile = type->objfile_owner ();
htab_t htab;
if (objfile == NULL)
{
type_smob *type1_smob, *type2_smob;
struct type *type1, *type2;
- int result = 0;
+ bool result = false;
SCM_ASSERT_TYPE (tyscm_is_type (type1_scm), type1_scm, SCM_ARG1, FUNC_NAME,
type_smob_name);
type1 = type1_smob->type;
type2 = type2_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
result = types_deeply_equal (type1, type2);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return scm_from_bool (result);
}
return t_smob;
}
+/* Return the type field of T_SCM, an object of type <gdb:type>.
+ This exists so that we don't have to export the struct's contents. */
+
+struct type *
+tyscm_scm_to_type (SCM t_scm)
+{
+ type_smob *t_smob;
+
+ gdb_assert (tyscm_is_type (t_scm));
+ t_smob = (type_smob *) SCM_SMOB_DATA (t_scm);
+ return t_smob->type;
+}
+
/* Helper function for save_objfile_types to make a deep copy of the type. */
static int
{
type_smob *t_smob = (type_smob *) *slot;
htab_t copied_types = (htab_t) info;
- struct objfile *objfile = TYPE_OBJFILE (t_smob->type);
+ struct objfile *objfile = t_smob->type->objfile_owner ();
htab_t htab;
eqable_gdb_smob **new_slot;
type_smob t_smob_for_lookup;
save_objfile_types (struct objfile *objfile, void *datum)
{
htab_t htab = (htab_t) datum;
- htab_t copied_types;
if (!gdb_scheme_initialized)
return;
- copied_types = create_copied_types_hash (objfile);
+ htab_up copied_types = create_copied_types_hash (objfile);
if (htab != NULL)
{
- htab_traverse_noresize (htab, tyscm_copy_type_recursive, copied_types);
+ htab_traverse_noresize (htab, tyscm_copy_type_recursive, copied_types.get ());
htab_delete (htab);
}
-
- htab_delete (copied_types);
}
\f
/* Administrivia for field smobs. */
struct type *type = tyscm_field_smob_containing_type (f_smob);
/* This should be non-NULL by construction. */
- gdb_assert (TYPE_FIELDS (type) != NULL);
+ gdb_assert (type->fields () != NULL);
- return &TYPE_FIELD (type, f_smob->field_num);
+ return &type->field (f_smob->field_num);
}
\f
/* Type smob accessors. */
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- return scm_from_int (TYPE_CODE (type));
+ return scm_from_int (type->code ());
}
/* (type-fields <gdb:type>) -> list
containing_type_scm = tyscm_scm_from_type (containing_type);
result = SCM_EOL;
- for (i = 0; i < TYPE_NFIELDS (containing_type); ++i)
+ for (i = 0; i < containing_type->num_fields (); ++i)
result = scm_cons (tyscm_make_field_smob (containing_type_scm, i), result);
return scm_reverse_x (result, SCM_EOL);
type_smob *t_smob
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
+ const char *tagname = nullptr;
+
+ if (type->code () == TYPE_CODE_STRUCT
+ || type->code () == TYPE_CODE_UNION
+ || type->code () == TYPE_CODE_ENUM)
+ tagname = type->name ();
- if (!TYPE_TAG_NAME (type))
+ if (tagname == nullptr)
return SCM_BOOL_F;
- return gdbscm_scm_from_c_string (TYPE_TAG_NAME (type));
+ return gdbscm_scm_from_c_string (tagname);
}
/* (type-name <gdb:type>) -> string
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- if (!TYPE_NAME (type))
+ if (!type->name ())
return SCM_BOOL_F;
- return gdbscm_scm_from_c_string (TYPE_NAME (type));
+ return gdbscm_scm_from_c_string (type->name ());
}
/* (type-print-name <gdb:type>) -> string
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ try
{
check_typedef (type);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
}
- END_CATCH
/* Ignore exceptions. */
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
type = check_typedef (type);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (type);
}
for (;;)
{
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
type = check_typedef (type);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
- if (TYPE_CODE (type) != TYPE_CODE_PTR
- && TYPE_CODE (type) != TYPE_CODE_REF)
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
+ if (type->code () != TYPE_CODE_PTR
+ && type->code () != TYPE_CODE_REF)
break;
type = TYPE_TARGET_TYPE (type);
}
/* If this is not a struct, union, or enum type, raise TypeError
exception. */
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT
- && TYPE_CODE (type) != TYPE_CODE_UNION
- && TYPE_CODE (type) != TYPE_CODE_ENUM)
+ if (type->code () != TYPE_CODE_STRUCT
+ && type->code () != TYPE_CODE_UNION
+ && type->code () != TYPE_CODE_ENUM)
return NULL;
return type;
_("Array length must not be negative"));
}
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
array = lookup_array_range_type (type, n1, n2);
if (is_vector)
make_vector_type (array);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (array);
}
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
type = lookup_pointer_type (type);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (type);
}
/* Initialize these to appease GCC warnings. */
LONGEST low = 0, high = 0;
- SCM_ASSERT_TYPE (TYPE_CODE (type) == TYPE_CODE_ARRAY
- || TYPE_CODE (type) == TYPE_CODE_STRING
- || TYPE_CODE (type) == TYPE_CODE_RANGE,
+ SCM_ASSERT_TYPE (type->code () == TYPE_CODE_ARRAY
+ || type->code () == TYPE_CODE_STRING
+ || type->code () == TYPE_CODE_RANGE,
self, SCM_ARG1, FUNC_NAME, _("ranged type"));
- switch (TYPE_CODE (type))
+ switch (type->code ())
{
case TYPE_CODE_ARRAY:
case TYPE_CODE_STRING:
- low = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
- high = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (type));
- break;
case TYPE_CODE_RANGE:
- low = TYPE_LOW_BOUND (type);
- high = TYPE_HIGH_BOUND (type);
+ if (type->bounds ()->low.kind () == PROP_CONST)
+ low = type->bounds ()->low.const_val ();
+ else
+ low = 0;
+
+ if (type->bounds ()->high.kind () == PROP_CONST)
+ high = type->bounds ()->high.const_val ();
+ else
+ high = 0;
break;
}
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
- type = lookup_reference_type (type);
+ type = lookup_lvalue_reference_type (type);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (type);
}
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
type = make_cv_type (1, 0, type, NULL);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (type);
}
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
type = make_cv_type (0, 1, type, NULL);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (type);
}
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- TRY
+ gdbscm_gdb_exception exc {};
+ try
{
type = make_cv_type (0, 0, type, NULL);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
- GDBSCM_HANDLE_GDB_EXCEPTION (except);
+ exc = unpack (except);
}
- END_CATCH
+ GDBSCM_HANDLE_GDB_EXCEPTION (exc);
return tyscm_scm_from_type (type);
}
\f
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
_(not_composite_error));
- return scm_from_long (TYPE_NFIELDS (type));
+ return scm_from_long (type->num_fields ());
}
/* (type-field <gdb:type> string) -> <gdb:field>
type_smob *t_smob
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- char *field;
- int i;
- struct cleanup *cleanups;
SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
_("string"));
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
_(not_composite_error));
- field = gdbscm_scm_to_c_string (field_scm);
- cleanups = make_cleanup (xfree, field);
+ {
+ gdb::unique_xmalloc_ptr<char> field = gdbscm_scm_to_c_string (field_scm);
- for (i = 0; i < TYPE_NFIELDS (type); i++)
- {
- const char *t_field_name = TYPE_FIELD_NAME (type, i);
+ for (int i = 0; i < type->num_fields (); i++)
+ {
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
- if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
- {
- do_cleanups (cleanups);
+ if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0))
+ {
+ field.reset (nullptr);
return tyscm_make_field_smob (self, i);
- }
- }
-
- do_cleanups (cleanups);
+ }
+ }
+ }
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, field_scm,
_("Unknown field"));
type_smob *t_smob
= tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
struct type *type = t_smob->type;
- char *field;
- int i;
- struct cleanup *cleanups;
SCM_ASSERT_TYPE (scm_is_string (field_scm), field_scm, SCM_ARG2, FUNC_NAME,
_("string"));
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
_(not_composite_error));
- field = gdbscm_scm_to_c_string (field_scm);
- cleanups = make_cleanup (xfree, field);
+ {
+ gdb::unique_xmalloc_ptr<char> field
+ = gdbscm_scm_to_c_string (field_scm);
- for (i = 0; i < TYPE_NFIELDS (type); i++)
- {
- const char *t_field_name = TYPE_FIELD_NAME (type, i);
-
- if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
- {
- do_cleanups (cleanups);
- return SCM_BOOL_T;
- }
- }
+ for (int i = 0; i < type->num_fields (); i++)
+ {
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
- do_cleanups (cleanups);
+ if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0))
+ return SCM_BOOL_T;
+ }
+ }
return SCM_BOOL_F;
}
type_smob *t_smob;
struct type *type;
SCM it_scm, result, progress, object;
- int field, rc;
+ int field;
it_scm = itscm_get_iterator_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
i_smob = (iterator_smob *) SCM_SMOB_DATA (it_scm);
type = t_smob->type;
SCM_ASSERT_TYPE (scm_is_signed_integer (progress,
- 0, TYPE_NFIELDS (type)),
+ 0, type->num_fields ()),
progress, SCM_ARG1, FUNC_NAME, _("integer"));
field = scm_to_int (progress);
- if (field < TYPE_NFIELDS (type))
+ if (field < type->num_fields ())
{
result = tyscm_make_field_smob (object, field);
itscm_set_iterator_smob_progress_x (i_smob, scm_from_int (field + 1));
struct field *field = tyscm_field_smob_to_field (f_smob);
/* A field can have a NULL type in some situations. */
- if (FIELD_TYPE (*field))
- return tyscm_scm_from_type (FIELD_TYPE (*field));
+ if (field->type ())
+ return tyscm_scm_from_type (field->type ());
return SCM_BOOL_F;
}
struct field *field = tyscm_field_smob_to_field (f_smob);
struct type *type = tyscm_field_smob_containing_type (f_smob);
- SCM_ASSERT_TYPE (TYPE_CODE (type) == TYPE_CODE_ENUM,
+ SCM_ASSERT_TYPE (type->code () == TYPE_CODE_ENUM,
self, SCM_ARG1, FUNC_NAME, _("enum type"));
return scm_from_long (FIELD_ENUMVAL (*field));
struct field *field = tyscm_field_smob_to_field (f_smob);
struct type *type = tyscm_field_smob_containing_type (f_smob);
- SCM_ASSERT_TYPE (TYPE_CODE (type) != TYPE_CODE_ENUM,
+ SCM_ASSERT_TYPE (type->code () != TYPE_CODE_ENUM,
self, SCM_ARG1, FUNC_NAME, _("non-enum type"));
return scm_from_long (FIELD_BITPOS (*field));
{
field_smob *f_smob
= tyscm_get_field_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
- struct field *field = tyscm_field_smob_to_field (f_smob);
struct type *type = tyscm_field_smob_containing_type (f_smob);
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ if (type->code () == TYPE_CODE_STRUCT)
return scm_from_bool (f_smob->field_num < TYPE_N_BASECLASSES (type));
return SCM_BOOL_F;
}
{
struct type *type = NULL;
- TRY
+ try
{
if (startswith (type_name, "struct "))
type = lookup_struct (type_name + 7, NULL);
else if (startswith (type_name, "enum "))
type = lookup_enum (type_name + 5, NULL);
else
- type = lookup_typename (current_language, get_current_arch (),
+ type = lookup_typename (current_language,
type_name, block, 0);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
return NULL;
}
- END_CATCH
return type;
}
X (TYPE_CODE_METHODPTR),
X (TYPE_CODE_MEMBERPTR),
X (TYPE_CODE_REF),
+ X (TYPE_CODE_RVALUE_REF),
X (TYPE_CODE_CHAR),
X (TYPE_CODE_BOOL),
X (TYPE_CODE_COMPLEX),
block_keyword = scm_from_latin1_keyword ("block");
+ global_types_map = gdbscm_create_eqable_gsmob_ptr_map (tyscm_hash_type_smob,
+ tyscm_eq_type_smob);
+}
+
+void _initialize_scm_type ();
+void
+_initialize_scm_type ()
+{
/* Register an objfile "free" callback so we can properly copy types
associated with the objfile when it's about to be deleted. */
tyscm_objfile_data_key
= register_objfile_data_with_cleanup (save_objfile_types, NULL);
-
- global_types_map = gdbscm_create_eqable_gsmob_ptr_map (tyscm_hash_type_smob,
- tyscm_eq_type_smob);
}