If noerr is
set, then the returned tuple will set the field pointer to NULL to
indicate a missing component rather than throwing an error.
lookup_struct_elt_type is now reimplemented in terms of this new
function. It simply returns the type of the returned field.
gdb/ChangeLog:
* gdbtypes.c (lookup_struct_elt): New function.
(lookup_struct_elt_type): Reimplement via lookup_struct_elt.
* gdbtypes.h (struct struct_elt): New type.
(lookup_struct_elt): New prototype.
---
gdb/ChangeLog | 7 ++++++
gdb/gdbtypes.c | 60 ++++++++++++++++++++++++++++++++------------------
gdb/gdbtypes.h | 19 ++++++++++++++++
3 files changed, 65 insertions(+), 21 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cebd63bcb5..c7fee7eb11 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2019-02-08 John Baldwin <jhb@FreeBSD.org>
+
+ * gdbtypes.c (lookup_struct_elt): New function.
+ (lookup_struct_elt_type): Reimplement via lookup_struct_elt.
+ * gdbtypes.h (struct struct_elt): New type.
+ (lookup_struct_elt): New prototype.
+
2019-02-08 John Baldwin <jhb@FreeBSD.org>
* gdbtypes.c (lookup_struct_elt_type): Update comment and
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index e4acb0e985..0f3a450f9f 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1644,7 +1644,8 @@ lookup_template_type (char *name, struct type *type,
return (SYMBOL_TYPE (sym));
}
-/* Given a type TYPE, lookup the type of the component named NAME.
+/* Given a type TYPE, lookup the field and offset of the component named
+ NAME.
TYPE can be either a struct or union, or a pointer or reference to
a struct or union. If it is a pointer or reference, its target
@@ -1652,11 +1653,11 @@ lookup_template_type (char *name, struct type *type,
as specified for the definitions of the expression element types
STRUCTOP_STRUCT and STRUCTOP_PTR.
- If NOERR is nonzero, return NULL if there is no component named
- NAME. */
+ If NOERR is nonzero, the returned structure will have field set to
+ NULL if there is no component named NAME. */
-struct type *
-lookup_struct_elt_type (struct type *type, const char *name, int noerr)
+struct_elt
+lookup_struct_elt (struct type *type, const char *name, int noerr) > {
int i;
@@ -1683,39 +1684,56 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr)
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
- return TYPE_FIELD_TYPE (type, i);
+ return struct_elt (&TYPE_FIELD(type, i), TYPE_FIELD_BITPOS (type, i));
}
else if (!t_field_name || *t_field_name == '\0')
{
- struct type *subtype
- = lookup_struct_elt_type (TYPE_FIELD_TYPE (type, i), name, 1);
-
- if (subtype != NULL)
- return subtype;
+ struct_elt elt
+ = lookup_struct_elt (TYPE_FIELD_TYPE (type, i), name, 1);
+ if (elt.field != NULL)
+ {
+ elt.offset += TYPE_FIELD_BITPOS (type, i);
+ return elt;
+ }
}
}
/* OK, it's not in this class. Recursively check the baseclasses. */
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
- struct type *t;
-
- t = lookup_struct_elt_type (TYPE_BASECLASS (type, i), name, 1);
- if (t != NULL)
- {
- return t;
- }
+ struct_elt elt = lookup_struct_elt (TYPE_BASECLASS (type, i), name, 1);
+ if (elt.field != NULL)
+ return elt;
}
if (noerr)
- {
- return NULL;
- }
+ return struct_elt ();
std::string type_name = type_to_string (type);
error (_("Type %s has no component named %s."), type_name.c_str (), name);
}
+/* Given a type TYPE, lookup the type of the component named NAME.
+
+ TYPE can be either a struct or union, or a pointer or reference to
+ a struct or union. If it is a pointer or reference, its target
+ type is automatically used. Thus '.' and '->' are interchangable,
+ as specified for the definitions of the expression element types
+ STRUCTOP_STRUCT and STRUCTOP_PTR.
+
+ If NOERR is nonzero, return NULL if there is no component named
+ NAME. */
+
+struct type *
+lookup_struct_elt_type (struct type *type, const char *name, int noerr)
+{
+ struct_elt elt = lookup_struct_elt (type, name, noerr);
+ if (elt.field != NULL)
+ return FIELD_TYPE (*elt.field);
+ else
+ return NULL;
+}
+
/* Store in *MAX the largest number representable by unsigned integer type
TYPE. */
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index a6d4f64e9b..894c7b2fc6 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1873,6 +1873,25 @@ extern struct type *allocate_stub_method (struct type *);
extern const char *type_name_or_error (struct type *type);
+struct struct_elt
+{
+ /* The field of the element, or NULL if no element was found. */
+ struct field *field;
+
+ /* The bit offset of the element in the parent structure. */
+ LONGEST offset;
+
+ struct_elt ()
+ : field (nullptr), offset (0)
+ {}
+
+ struct_elt (struct field *field, LONGEST offset)
+ : field (field), offset (offset)
+ {}
+};