+/* Generate bytecodes for field number FIELDNO of type TYPE. OFFSET
+ is an accumulated offset (in bytes), will be nonzero for objects
+ embedded in other objects, like C++ base classes. Behavior should
+ generally follow value_primitive_field. */
+
+static void
+gen_primitive_field (struct expression *exp,
+ struct agent_expr *ax, struct axs_value *value,
+ int offset, int fieldno, struct type *type)
+{
+ /* Is this a bitfield? */
+ if (TYPE_FIELD_PACKED (type, fieldno))
+ gen_bitfield_ref (exp, ax, value, TYPE_FIELD_TYPE (type, fieldno),
+ (offset * TARGET_CHAR_BIT
+ + TYPE_FIELD_BITPOS (type, fieldno)),
+ (offset * TARGET_CHAR_BIT
+ + TYPE_FIELD_BITPOS (type, fieldno)
+ + TYPE_FIELD_BITSIZE (type, fieldno)));
+ else
+ {
+ gen_offset (ax, offset
+ + TYPE_FIELD_BITPOS (type, fieldno) / TARGET_CHAR_BIT);
+ value->kind = axs_lvalue_memory;
+ value->type = TYPE_FIELD_TYPE (type, fieldno);
+ }
+}
+
+/* Search for the given field in either the given type or one of its
+ base classes. Return 1 if found, 0 if not. */
+
+static int
+gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax,
+ struct axs_value *value,
+ char *field, int offset, struct type *type)
+{
+ int i, rslt;
+ int nbases = TYPE_N_BASECLASSES (type);
+
+ CHECK_TYPEDEF (type);
+
+ for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
+ {
+ const char *this_name = TYPE_FIELD_NAME (type, i);
+
+ if (this_name)
+ {
+ if (strcmp (field, this_name) == 0)
+ {
+ /* Note that bytecodes for the struct's base (aka
+ "this") will have been generated already, which will
+ be unnecessary but not harmful if the static field is
+ being handled as a global. */
+ if (field_is_static (&TYPE_FIELD (type, i)))
+ {
+ gen_static_field (exp->gdbarch, ax, value, type, i);
+ if (value->optimized_out)
+ error (_("static field `%s' has been "
+ "optimized out, cannot use"),
+ field);
+ return 1;
+ }
+
+ gen_primitive_field (exp, ax, value, offset, i, type);
+ return 1;
+ }
+#if 0 /* is this right? */
+ if (this_name[0] == '\0')
+ internal_error (__FILE__, __LINE__,
+ _("find_field: anonymous unions not supported"));
+#endif
+ }
+ }
+
+ /* Now scan through base classes recursively. */
+ for (i = 0; i < nbases; i++)
+ {
+ struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
+
+ rslt = gen_struct_ref_recursive (exp, ax, value, field,
+ offset + TYPE_BASECLASS_BITPOS (type, i)
+ / TARGET_CHAR_BIT,
+ basetype);
+ if (rslt)
+ return 1;
+ }
+
+ /* Not found anywhere, flag so caller can complain. */
+ return 0;
+}