static int ada_varobj_get_struct_number_of_children (struct value *parent_value, struct type *parent_type) { int n_children = 0; int i; gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT || TYPE_CODE (parent_type) == TYPE_CODE_UNION); for (i = 0; i < TYPE_NFIELDS (parent_type); i++) { if (ada_is_ignored_field (parent_type, i)) continue; if (ada_is_wrapper_field (parent_type, i)) { struct value *elt_value; struct type *elt_type; ada_varobj_struct_elt (parent_value, parent_type, i, &elt_value, &elt_type); if (ada_is_tagged_type (elt_type, 0)) { /* We must not use ada_varobj_get_number_of_children to determine is element's number of children, because this function first calls ada_varobj_decode_var, which "fixes" the element. For tagged types, this includes reading the object's tag to determine its real type, which happens to be the parent_type, and leads to an infinite loop (because the element gets fixed back into the parent). */ n_children += ada_varobj_get_struct_number_of_children (elt_value, elt_type); } else n_children += ada_varobj_get_number_of_children (elt_value, elt_type); } else if (ada_is_variant_part (parent_type, i)) { /* In normal situations, the variant part of the record should have been "fixed". Or, in other words, it should have been replaced by the branch of the variant part that is relevant for our value. But there are still situations where this can happen, however (Eg. when our parent is a NULL pointer). We do not support showing this part of the record for now, so just pretend this field does not exist. */ } else n_children++; } return n_children; }
static int print_selected_record_field_types (struct type *type, struct type *outer_type, int fld0, int fld1, struct ui_file *stream, int show, int level, const struct type_print_options *flags) { int i, flds; flds = 0; if (fld0 > fld1 && TYPE_STUB (type)) return -1; for (i = fld0; i <= fld1; i += 1) { QUIT; if (ada_is_parent_field (type, i) || ada_is_ignored_field (type, i)) ; else if (ada_is_wrapper_field (type, i)) flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type, stream, show, level, flags); else if (ada_is_variant_part (type, i)) { print_variant_part (type, i, outer_type, stream, show, level, flags); flds = 1; } else { flds += 1; fprintf_filtered (stream, "\n%*s", level + 4, ""); ada_print_type (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4, flags); fprintf_filtered (stream, ";"); } } return flds; }
static int print_record_field_types (struct type *type, struct type *outer_type, struct ui_file *stream, int show, int level) { int len, i, flds; flds = 0; len = TYPE_NFIELDS (type); if (len == 0 && (TYPE_FLAGS (type) & TYPE_FLAG_STUB) != 0) return -1; for (i = 0; i < len; i += 1) { QUIT; if (ada_is_parent_field (type, i) || ada_is_ignored_field (type, i)) ; else if (ada_is_wrapper_field (type, i)) flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type, stream, show, level); else if (ada_is_variant_part (type, i)) { print_variant_part (type, i, outer_type, stream, show, level); flds = 1; } else { flds += 1; fprintf_filtered (stream, "\n%*s", level + 4, ""); ada_print_type (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4); fprintf_filtered (stream, ";"); } } return flds; }
static void ada_varobj_describe_struct_child (struct value *parent_value, struct type *parent_type, const char *parent_name, const char *parent_path_expr, int child_index, char **child_name, struct value **child_value, struct type **child_type, char **child_path_expr) { int fieldno; int childno = 0; gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT); for (fieldno = 0; fieldno < TYPE_NFIELDS (parent_type); fieldno++) { if (ada_is_ignored_field (parent_type, fieldno)) continue; if (ada_is_wrapper_field (parent_type, fieldno)) { struct value *elt_value; struct type *elt_type; int elt_n_children; ada_varobj_struct_elt (parent_value, parent_type, fieldno, &elt_value, &elt_type); if (ada_is_tagged_type (elt_type, 0)) { /* Same as in ada_varobj_get_struct_number_of_children: For tagged types, we must be careful to not call ada_varobj_get_number_of_children, to prevent our element from being fixed back into the parent. */ elt_n_children = ada_varobj_get_struct_number_of_children (elt_value, elt_type); } else elt_n_children = ada_varobj_get_number_of_children (elt_value, elt_type); /* Is the child we're looking for one of the children of this wrapper field? */ if (child_index - childno < elt_n_children) { if (ada_is_tagged_type (elt_type, 0)) { /* Same as in ada_varobj_get_struct_number_of_children: For tagged types, we must be careful to not call ada_varobj_describe_child, to prevent our element from being fixed back into the parent. */ ada_varobj_describe_struct_child (elt_value, elt_type, parent_name, parent_path_expr, child_index - childno, child_name, child_value, child_type, child_path_expr); } else ada_varobj_describe_child (elt_value, elt_type, parent_name, parent_path_expr, child_index - childno, child_name, child_value, child_type, child_path_expr); return; } /* The child we're looking for is beyond this wrapper field, so skip all its children. */ childno += elt_n_children; continue; } else if (ada_is_variant_part (parent_type, fieldno)) { /* In normal situations, the variant part of the record should have been "fixed". Or, in other words, it should have been replaced by the branch of the variant part that is relevant for our value. But there are still situations where this can happen, however (Eg. when our parent is a NULL pointer). We do not support showing this part of the record for now, so just pretend this field does not exist. */ continue; } if (childno == child_index) { if (child_name) { /* The name of the child is none other than the field's name, except that we need to strip suffixes from it. For instance, fields with alignment constraints will have an __XVA suffix added to them. */ const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno); int child_name_len = ada_name_prefix_len (field_name); *child_name = xstrprintf ("%.*s", child_name_len, field_name); } if (child_value && parent_value) ada_varobj_struct_elt (parent_value, parent_type, fieldno, child_value, NULL); if (child_type) ada_varobj_struct_elt (parent_value, parent_type, fieldno, NULL, child_type); if (child_path_expr) { /* The name of the child is none other than the field's name, except that we need to strip suffixes from it. For instance, fields with alignment constraints will have an __XVA suffix added to them. */ const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno); int child_name_len = ada_name_prefix_len (field_name); *child_path_expr = xstrprintf ("(%s).%.*s", parent_path_expr, child_name_len, field_name); } return; } childno++; } /* Something went wrong. Either we miscounted the number of children, or CHILD_INDEX was too high. But we should never reach here. We don't have enough information to recover nicely, so just raise an assertion failure. */ gdb_assert_not_reached ("unexpected code path"); }
static int print_field_values (struct type *type, const gdb_byte *valaddr, int offset, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options, int comma_needed, struct type *outer_type, int outer_offset, const struct language_defn *language) { int i, len; len = TYPE_NFIELDS (type); for (i = 0; i < len; i += 1) { if (ada_is_ignored_field (type, i)) continue; if (ada_is_wrapper_field (type, i)) { comma_needed = print_field_values (TYPE_FIELD_TYPE (type, i), valaddr, (offset + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT), stream, recurse, val, options, comma_needed, type, offset, language); continue; } else if (ada_is_variant_part (type, i)) { comma_needed = print_variant_part (type, i, valaddr, offset, stream, recurse, val, options, comma_needed, outer_type, outer_offset, language); continue; } if (comma_needed) fprintf_filtered (stream, ", "); comma_needed = 1; if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } annotate_field_begin (TYPE_FIELD_TYPE (type, i)); fprintf_filtered (stream, "%.*s", ada_name_prefix_len (TYPE_FIELD_NAME (type, i)), TYPE_FIELD_NAME (type, i)); annotate_field_name_end (); fputs_filtered (" => ", stream); annotate_field_value (); if (TYPE_FIELD_PACKED (type, i)) { /* Bitfields require special handling, especially due to byte order problems. */ if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i)) { fputs_filtered (_("<optimized out or zero length>"), stream); } else { struct value *v; int bit_pos = TYPE_FIELD_BITPOS (type, i); int bit_size = TYPE_FIELD_BITSIZE (type, i); struct value_print_options opts; adjust_type_signedness (TYPE_FIELD_TYPE (type, i)); v = ada_value_primitive_packed_val (NULL, valaddr, offset + bit_pos / HOST_CHAR_BIT, bit_pos % HOST_CHAR_BIT, bit_size, TYPE_FIELD_TYPE (type, i)); opts = *options; opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), value_embedded_offset (v), 0, stream, recurse + 1, v, &opts, language); } } else { struct value_print_options opts = *options; opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), (offset + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT), 0, stream, recurse + 1, val, &opts, language); } annotate_field_end (); } return comma_needed; }
static int print_field_values (struct type *type, char *valaddr, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty, int comma_needed, struct type *outer_type, char *outer_valaddr) { int i, len; len = TYPE_NFIELDS (type); for (i = 0; i < len; i += 1) { if (ada_is_ignored_field (type, i)) continue; if (ada_is_wrapper_field (type, i)) { comma_needed = print_field_values (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, stream, format, recurse, pretty, comma_needed, type, valaddr); continue; } else if (ada_is_variant_part (type, i)) { comma_needed = print_variant_part (type, i, valaddr, stream, format, recurse, pretty, comma_needed, outer_type, outer_valaddr); continue; } if (comma_needed) fprintf_filtered (stream, ", "); comma_needed = 1; if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } if (inspect_it) { if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) fputs_filtered ("\"( ptr \"", stream); else fputs_filtered ("\"( nodef \"", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_NO_OPTS); fputs_filtered ("\" \"", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_NO_OPTS); fputs_filtered ("\") \"", stream); } else { annotate_field_begin (TYPE_FIELD_TYPE (type, i)); fprintf_filtered (stream, "%.*s", ada_name_prefix_len (TYPE_FIELD_NAME (type, i)), TYPE_FIELD_NAME (type, i)); annotate_field_name_end (); fputs_filtered (" => ", stream); annotate_field_value (); } if (TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (TYPE_CPLUS_SPECIFIC (type) != NULL && TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else { int bit_pos = TYPE_FIELD_BITPOS (type, i); int bit_size = TYPE_FIELD_BITSIZE (type, i); adjust_type_signedness (TYPE_FIELD_TYPE (type, i)); v = ada_value_primitive_packed_val (NULL, valaddr, bit_pos / HOST_CHAR_BIT, bit_pos % HOST_CHAR_BIT, bit_size, TYPE_FIELD_TYPE (type, i)); val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0, stream, format, 0, recurse + 1, pretty); } } else ada_val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT, 0, 0, stream, format, 0, recurse + 1, pretty); annotate_field_end (); } return comma_needed; }