along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include <string.h>
#include "bfd.h"
#include "symtab.h"
#include "symfile.h"
#include "complaints.h"
#include "gdbcmd.h"
#include "cp-abi.h"
-#include "gdb_assert.h"
#include "hashtab.h"
-#include "exceptions.h"
#include "cp-support.h"
#include "bcache.h"
#include "dwarf2loc.h"
NULL);
}
+/* Make a type without const, volatile, or restrict. */
+
+struct type *
+make_unqualified_type (struct type *type)
+{
+ return make_qualified_type (type,
+ (TYPE_INSTANCE_FLAGS (type)
+ & ~(TYPE_INSTANCE_FLAG_CONST
+ | TYPE_INSTANCE_FLAG_VOLATILE
+ | TYPE_INSTANCE_FLAG_RESTRICT)),
+ NULL);
+}
+
/* Replace the contents of ntype with the type *type. This changes the
contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
the changes are propogated to all types in the TYPE_CHAIN.
if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0)
TYPE_UNSIGNED (result_type) = 1;
+ /* Ada allows the declaration of range types whose upper bound is
+ less than the lower bound, so checking the lower bound is not
+ enough. Make sure we do not mark a range type whose upper bound
+ is negative as unsigned. */
+ if (high_bound->kind == PROP_CONST && high_bound->data.const_val < 0)
+ TYPE_UNSIGNED (result_type) = 0;
+
return result_type;
}
if (top_level && TYPE_CODE (type) == TYPE_CODE_REF)
type = check_typedef (TYPE_TARGET_TYPE (type));
+ /* Types that have a dynamic TYPE_DATA_LOCATION are considered
+ dynamic, even if the type itself is statically defined.
+ From a user's point of view, this may appear counter-intuitive;
+ but it makes sense in this context, because the point is to determine
+ whether any part of the type needs to be resolved before it can
+ be exploited. */
+ if (TYPE_DATA_LOCATION (type) != NULL
+ && (TYPE_DATA_LOCATION_KIND (type) == PROP_LOCEXPR
+ || TYPE_DATA_LOCATION_KIND (type) == PROP_LOCLIST))
+ return 1;
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
CORE_ADDR addr,
int top_level);
-/* Given a dynamic range type (dyn_range_type), return a static version
- of that type. */
+/* Given a dynamic range type (dyn_range_type) and address,
+ return a static version of that type. */
static struct type *
-resolve_dynamic_range (struct type *dyn_range_type)
+resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr)
{
CORE_ADDR value;
struct type *static_range_type;
gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
- if (dwarf2_evaluate_property (prop, &value))
+ if (dwarf2_evaluate_property (prop, addr, &value))
{
low_bound.kind = PROP_CONST;
low_bound.data.const_val = value;
}
prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
- if (dwarf2_evaluate_property (prop, &value))
+ if (dwarf2_evaluate_property (prop, addr, &value))
{
high_bound.kind = PROP_CONST;
high_bound.data.const_val = value;
of the associated array. */
static struct type *
-resolve_dynamic_array (struct type *type)
+resolve_dynamic_array (struct type *type, CORE_ADDR addr)
{
CORE_ADDR value;
struct type *elt_type;
elt_type = type;
range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
- range_type = resolve_dynamic_range (range_type);
+ range_type = resolve_dynamic_range (range_type, addr);
ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
- elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type));
+ elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type), addr);
else
elt_type = TYPE_TARGET_TYPE (type);
{
struct type *real_type = check_typedef (type);
struct type *resolved_type = type;
+ const struct dynamic_prop *prop;
+ CORE_ADDR value;
if (!is_dynamic_type_internal (real_type, top_level))
return type;
switch (TYPE_CODE (type))
{
- case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TYPEDEF:
+ resolved_type = copy_type (type);
+ TYPE_TARGET_TYPE (resolved_type)
+ = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type), addr,
+ top_level);
+ break;
+
+ case TYPE_CODE_REF:
+ {
+ CORE_ADDR target_addr = read_memory_typed_address (addr, type);
+
resolved_type = copy_type (type);
TYPE_TARGET_TYPE (resolved_type)
- = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type), addr,
- top_level);
+ = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type),
+ target_addr, top_level);
break;
+ }
- case TYPE_CODE_REF:
- {
- CORE_ADDR target_addr = read_memory_typed_address (addr, type);
-
- resolved_type = copy_type (type);
- TYPE_TARGET_TYPE (resolved_type)
- = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type),
- target_addr, top_level);
- break;
- }
-
- case TYPE_CODE_ARRAY:
- resolved_type = resolve_dynamic_array (type);
- break;
+ case TYPE_CODE_ARRAY:
+ resolved_type = resolve_dynamic_array (type, addr);
+ break;
- case TYPE_CODE_RANGE:
- resolved_type = resolve_dynamic_range (type);
- break;
+ case TYPE_CODE_RANGE:
+ resolved_type = resolve_dynamic_range (type, addr);
+ break;
case TYPE_CODE_UNION:
resolved_type = resolve_dynamic_union (type, addr);
break;
}
+ /* Resolve data_location attribute. */
+ prop = TYPE_DATA_LOCATION (resolved_type);
+ if (dwarf2_evaluate_property (prop, addr, &value))
+ {
+ TYPE_DATA_LOCATION_ADDR (resolved_type) = value;
+ TYPE_DATA_LOCATION_KIND (resolved_type) = PROP_CONST;
+ }
+ else
+ TYPE_DATA_LOCATION (resolved_type) = NULL;
+
return resolved_type;
}
return 0;
}
+/* Return true is T is a class or a union. False otherwise. */
+
+int
+class_or_union_p (const struct type *t)
+{
+ return (TYPE_CODE (t) == TYPE_CODE_STRUCT
+ || TYPE_CODE (t) == TYPE_CODE_UNION);
+}
+
/* A helper function which returns true if types A and B represent the
"same" class type. This is true if the types have the same main
type, or the same name. */
}
break;
case TYPE_CODE_STRUCT:
- /* currently same as TYPE_CODE_CLASS. */
switch (TYPE_CODE (arg))
{
case TYPE_CODE_STRUCT:
situation. */
static void
-print_arg_types (struct field *args, int nargs, int spaces)
+print_args (struct field *args, int nargs, int spaces)
{
if (args != NULL)
{
int i;
for (i = 0; i < nargs; i++)
- recursive_dump_type (args[i].type, spaces + 2);
+ {
+ printfi_filtered (spaces, "[%d] name '%s'\n", i,
+ args[i].name != NULL ? args[i].name : "<NULL>");
+ recursive_dump_type (args[i].type, spaces + 2);
+ }
}
}
gdb_print_host_address (TYPE_FN_FIELD_ARGS (f, overload_idx),
gdb_stdout);
printf_filtered ("\n");
-
- print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx),
- TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f,
- overload_idx)),
- spaces);
+ print_args (TYPE_FN_FIELD_ARGS (f, overload_idx),
+ TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, overload_idx)),
+ spaces + 8 + 2);
printfi_filtered (spaces + 8, "fcontext ");
gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
gdb_stdout);
*TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
}
+ /* Copy the data location information. */
+ if (TYPE_DATA_LOCATION (type) != NULL)
+ {
+ TYPE_DATA_LOCATION (new_type)
+ = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
+ memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
+ sizeof (struct dynamic_prop));
+ }
+
/* Copy pointers to other types. */
if (TYPE_TARGET_TYPE (type))
TYPE_TARGET_TYPE (new_type) =
TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
sizeof (struct main_type));
+ if (TYPE_DATA_LOCATION (type) != NULL)
+ {
+ TYPE_DATA_LOCATION (new_type)
+ = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
+ memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
+ sizeof (struct dynamic_prop));
+ }
return new_type;
}