aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-03-12 13:39:02 -0700
committerJohn Baldwin <jhb@FreeBSD.org>2019-03-12 13:45:48 -0700
commitef0bd2046f58fac69577892c2d3b44b20d027476 (patch)
tree8332b9f3c74edc4dd4f903494cc95c2d9a1f2138
parent36c53a0262f84ad11d738471789dadfa9c4eb320 (diff)
downloadgdb-ef0bd2046f58fac69577892c2d3b44b20d027476.zip
gdb-ef0bd2046f58fac69577892c2d3b44b20d027476.tar.gz
gdb-ef0bd2046f58fac69577892c2d3b44b20d027476.tar.bz2
Add a more general version of lookup_struct_elt_type.
lookup_struct_elt is a new function which returns a tuple of information about a component of a structure or union. The returned tuple contains a pointer to the struct field object for the component as well as a bit offset of that field within the structure. If the field names a field in an anonymous substructure, the offset is the "global" offset relative to the original structure type. 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.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/gdbtypes.c55
-rw-r--r--gdb/gdbtypes.h38
3 files changed, 72 insertions, 28 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fe2d3e4..2adc64e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
2019-03-12 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-03-12 John Baldwin <jhb@FreeBSD.org>
+
* gdbtypes.c (lookup_struct_elt_type): Update comment and
remove disabled code block.
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 5924b15..db470da 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1644,19 +1644,10 @@ lookup_template_type (char *name, struct type *type,
return (SYMBOL_TYPE (sym));
}
-/* 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. */
+/* See gdbtypes.h. */
-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 +1674,47 @@ 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 {&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 {nullptr, 0};
std::string type_name = type_to_string (type);
error (_("Type %s has no component named %s."), type_name.c_str (), name);
}
+/* See gdbtypes.h. */
+
+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 a6d4f64..66051cf 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1873,6 +1873,44 @@ 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;
+};
+
+/* 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
+ 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, the returned structure will have field set to
+ NULL if there is no component named NAME.
+
+ If the component NAME is a field in an anonymous substructure of
+ TYPE, the returned offset is a "global" offset relative to TYPE
+ rather than an offset within the substructure. */
+
+extern struct_elt lookup_struct_elt (struct type *, const char *, int);
+
+/* 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. */
+
extern struct type *lookup_struct_elt_type (struct type *, const char *, int);
extern struct type *make_pointer_type (struct type *, struct type **);