X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fgdbtypes.c;h=2a51372a0372468ea12889f068dbf2b7c92dc1e4;hb=c76d61da4a65eaadca861bf6c77d579a5cc3f422;hp=1769796ab336225e5a149a6fc9fb6489debb5ece;hpb=552f1157c6262e274295e9c8a131de13fa7b00a3;p=binutils-gdb.git diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 1769796ab33..2a51372a037 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -47,6 +47,9 @@ /* The value of an invalid conversion badness. */ #define INVALID_CONVERSION 100 +static struct dynamic_prop_list * +copy_dynamic_prop_list (struct obstack *, struct dynamic_prop_list *); + /* Initialize BADNESS constants. */ const struct rank LENGTH_MISMATCH_BADNESS = {INVALID_CONVERSION,0}; @@ -2194,27 +2197,34 @@ static struct type *resolve_dynamic_type_internal and stride information set to undefined. The RESOLVE_P set to false case will be used when evaluating a dynamic array that is not allocated, or not associated, i.e. the bounds information might not be - initialized yet. */ + initialized yet. + + RANK is the array rank for which we are resolving this range, and is a + zero based count. The rank should never be negative. +*/ static struct type * resolve_dynamic_range (struct type *dyn_range_type, struct property_addr_info *addr_stack, - bool resolve_p = true) + int rank, bool resolve_p = true) { CORE_ADDR value; struct type *static_range_type, *static_target_type; struct dynamic_prop low_bound, high_bound, stride; gdb_assert (dyn_range_type->code () == TYPE_CODE_RANGE); + gdb_assert (rank >= 0); const struct dynamic_prop *prop = &dyn_range_type->bounds ()->low; - if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value, + { (CORE_ADDR) rank })) low_bound.set_const_val (value); else low_bound.set_undefined (); prop = &dyn_range_type->bounds ()->high; - if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value, + { (CORE_ADDR) rank })) { high_bound.set_const_val (value); @@ -2227,7 +2237,8 @@ resolve_dynamic_range (struct type *dyn_range_type, bool byte_stride_p = dyn_range_type->bounds ()->flag_is_byte_stride; prop = &dyn_range_type->bounds ()->stride; - if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value, + { (CORE_ADDR) rank })) { stride.set_const_val (value); @@ -2258,18 +2269,29 @@ resolve_dynamic_range (struct type *dyn_range_type, return static_range_type; } -/* Resolves dynamic bound values of an array or string type TYPE to static - ones. ADDR_STACK is a stack of struct property_addr_info to be used if - needed during the dynamic resolution. +/* Helper function for resolve_dynamic_array_or_string. This function + resolves the properties for a single array at RANK within a nested array + of arrays structure. The RANK value is greater than or equal to 0, and + starts at it's maximum value and goes down by 1 for each recursive call + to this function. So, for a 3-dimensional array, the first call to this + function has RANK == 2, then we call ourselves recursively with RANK == + 1, than again with RANK == 0, and at that point we should return. + + TYPE is updated as the dynamic properties are resolved, and so, should + be a copy of the dynamic type, rather than the original dynamic type + itself. + + ADDR_STACK is a stack of struct property_addr_info to be used if needed + during the dynamic resolution. When RESOLVE_P is true then the dynamic properties of TYPE are evaluated, otherwise the dynamic properties of TYPE are not evaluated, instead we assume the array is not allocated/associated yet. */ static struct type * -resolve_dynamic_array_or_string (struct type *type, - struct property_addr_info *addr_stack, - bool resolve_p = true) +resolve_dynamic_array_or_string_1 (struct type *type, + struct property_addr_info *addr_stack, + int rank, bool resolve_p) { CORE_ADDR value; struct type *elt_type; @@ -2283,7 +2305,9 @@ resolve_dynamic_array_or_string (struct type *type, gdb_assert (type->code () == TYPE_CODE_ARRAY || type->code () == TYPE_CODE_STRING); - type = copy_type (type); + /* As the rank is a zero based count we expect this to never be + negative. */ + gdb_assert (rank >= 0); /* Resolve the allocated and associated properties before doing anything else. If an array is not allocated or not associated then (at least @@ -2313,11 +2337,16 @@ resolve_dynamic_array_or_string (struct type *type, } range_type = check_typedef (type->index_type ()); - range_type = resolve_dynamic_range (range_type, addr_stack, resolve_p); + range_type + = resolve_dynamic_range (range_type, addr_stack, rank, resolve_p); ary_dim = check_typedef (TYPE_TARGET_TYPE (type)); if (ary_dim != NULL && ary_dim->code () == TYPE_CODE_ARRAY) - elt_type = resolve_dynamic_array_or_string (ary_dim, addr_stack, resolve_p); + { + ary_dim = copy_type (ary_dim); + elt_type = resolve_dynamic_array_or_string_1 (ary_dim, addr_stack, + rank - 1, resolve_p); + } else elt_type = TYPE_TARGET_TYPE (type); @@ -2345,6 +2374,97 @@ resolve_dynamic_array_or_string (struct type *type, bit_stride); } +/* Resolve an array or string type with dynamic properties, return a new + type with the dynamic properties resolved to actual values. The + ADDR_STACK represents the location of the object being resolved. */ + +static struct type * +resolve_dynamic_array_or_string (struct type *type, + struct property_addr_info *addr_stack) +{ + CORE_ADDR value; + int rank = 0; + + /* For dynamic type resolution strings can be treated like arrays of + characters. */ + gdb_assert (type->code () == TYPE_CODE_ARRAY + || type->code () == TYPE_CODE_STRING); + + type = copy_type (type); + + /* Resolve the rank property to get rank value. */ + struct dynamic_prop *prop = TYPE_RANK_PROP (type); + if (dwarf2_evaluate_property (prop, nullptr, addr_stack, &value)) + { + prop->set_const_val (value); + rank = value; + + if (rank == 0) + { + /* Rank is zero, if a variable is passed as an argument to a + function. In this case the resolved type should not be an + array, but should instead be that of an array element. */ + struct type *dynamic_array_type = type; + type = copy_type (TYPE_TARGET_TYPE (dynamic_array_type)); + struct dynamic_prop_list *prop_list + = TYPE_MAIN_TYPE (dynamic_array_type)->dyn_prop_list; + if (prop_list != nullptr) + { + struct obstack *obstack + = &type->objfile_owner ()->objfile_obstack; + TYPE_MAIN_TYPE (type)->dyn_prop_list + = copy_dynamic_prop_list (obstack, prop_list); + } + return type; + } + else if (type->code () == TYPE_CODE_STRING && rank != 1) + { + /* What would this even mean? A string with a dynamic rank + greater than 1. */ + error (_("unable to handle string with dynamic rank greater than 1")); + } + else if (rank > 1) + { + /* Arrays with dynamic rank are initially just an array type + with a target type that is the array element. + + However, now we know the rank of the array we need to build + the array of arrays structure that GDB expects, that is we + need an array type that has a target which is an array type, + and so on, until eventually, we have the element type at the + end of the chain. Create all the additional array types here + by copying the top level array type. */ + struct type *element_type = TYPE_TARGET_TYPE (type); + struct type *rank_type = type; + for (int i = 1; i < rank; i++) + { + TYPE_TARGET_TYPE (rank_type) = copy_type (rank_type); + rank_type = TYPE_TARGET_TYPE (rank_type); + } + TYPE_TARGET_TYPE (rank_type) = element_type; + } + } + else + { + rank = 1; + + for (struct type *tmp_type = check_typedef (TYPE_TARGET_TYPE (type)); + tmp_type->code () == TYPE_CODE_ARRAY; + tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type))) + ++rank; + } + + /* The rank that we calculated above is actually a count of the number of + ranks. However, when we resolve the type of each individual array + rank we should actually use a rank "offset", e.g. an array with a rank + count of 1 (calculated above) will use the rank offset 0 in order to + resolve the details of the first array dimension. As a result, we + reduce the rank by 1 here. */ + --rank; + + return resolve_dynamic_array_or_string_1 (type, addr_stack, rank, true); +} + /* Resolve dynamic bounds of members of the union TYPE to static bounds. ADDR_STACK is a stack of struct property_addr_info to be used if needed during the dynamic resolution. */ @@ -2601,7 +2721,7 @@ resolve_dynamic_struct (struct type *type, CORE_ADDR addr; if (dwarf2_evaluate_property (&prop, nullptr, addr_stack, &addr, - true)) + {addr_stack->addr})) resolved_type->field (i).set_loc_bitpos (TARGET_CHAR_BIT * (addr - addr_stack->addr)); } @@ -2730,7 +2850,12 @@ resolve_dynamic_type_internal (struct type *type, break; case TYPE_CODE_RANGE: - resolved_type = resolve_dynamic_range (type, addr_stack); + /* Pass 0 for the rank value here, which indicates this is a + range for the first rank of an array. The assumption is that + this rank value is not actually required for the resolution of + the dynamic range, otherwise, we'd be resolving this range + within the context of a dynamic array. */ + resolved_type = resolve_dynamic_range (type, addr_stack, 0); break; case TYPE_CODE_UNION: