Skip to content

Commit

Permalink
redo type allocation
Browse files Browse the repository at this point in the history
Close #26
  • Loading branch information
tromey committed Apr 19, 2016
1 parent 1278423 commit 7c45476
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 87 deletions.
70 changes: 13 additions & 57 deletions gdb/gdbtypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -4594,7 +4594,7 @@ copy_type (const struct type *type)

struct type *
arch_type (struct gdbarch *gdbarch,
enum type_code code, int length, const char *name)
enum type_code code, int length, char *name)
{
struct type *type;

Expand All @@ -4614,7 +4614,7 @@ arch_type (struct gdbarch *gdbarch,

struct type *
arch_integer_type (struct gdbarch *gdbarch,
int bit, int unsigned_p, const char *name)
int bit, int unsigned_p, char *name)
{
struct type *t;

Expand All @@ -4633,7 +4633,7 @@ arch_integer_type (struct gdbarch *gdbarch,

struct type *
arch_character_type (struct gdbarch *gdbarch,
int bit, int unsigned_p, const char *name)
int bit, int unsigned_p, char *name)
{
struct type *t;

Expand All @@ -4650,7 +4650,7 @@ arch_character_type (struct gdbarch *gdbarch,

struct type *
arch_boolean_type (struct gdbarch *gdbarch,
int bit, int unsigned_p, const char *name)
int bit, int unsigned_p, char *name)
{
struct type *t;

Expand All @@ -4668,8 +4668,7 @@ arch_boolean_type (struct gdbarch *gdbarch,

struct type *
arch_float_type (struct gdbarch *gdbarch,
int bit, const char *name,
const struct floatformat **floatformats)
int bit, char *name, const struct floatformat **floatformats)
{
struct type *t;

Expand Down Expand Up @@ -4700,7 +4699,7 @@ arch_float_type (struct gdbarch *gdbarch,

struct type *
arch_complex_type (struct gdbarch *gdbarch,
const char *name, struct type *target_type)
char *name, struct type *target_type)
{
struct type *t;

Expand All @@ -4714,7 +4713,7 @@ arch_complex_type (struct gdbarch *gdbarch,
NAME is the type name. LENGTH is the size of the flag word in bytes. */

struct type *
arch_flags_type (struct gdbarch *gdbarch, const char *name, int length)
arch_flags_type (struct gdbarch *gdbarch, char *name, int length)
{
int max_nfields = length * TARGET_CHAR_BIT;
struct type *type;
Expand All @@ -4735,7 +4734,7 @@ arch_flags_type (struct gdbarch *gdbarch, const char *name, int length)

void
append_flags_type_field (struct type *type, int start_bitpos, int nr_bits,
struct type *field_type, const char *name)
struct type *field_type, char *name)
{
int type_bitsize = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
int field_nr = TYPE_NFIELDS (type);
Expand All @@ -4758,7 +4757,7 @@ append_flags_type_field (struct type *type, int start_bitpos, int nr_bits,
position BITPOS is called NAME. */

void
append_flags_type_flag (struct type *type, int bitpos, const char *name)
append_flags_type_flag (struct type *type, int bitpos, char *name)
{
struct gdbarch *gdbarch = get_type_arch (type);

Expand All @@ -4771,8 +4770,7 @@ append_flags_type_flag (struct type *type, int bitpos, const char *name)
specified by CODE) associated with GDBARCH. NAME is the type name. */

struct type *
arch_composite_type (struct gdbarch *gdbarch, const char *name,
enum type_code code)
arch_composite_type (struct gdbarch *gdbarch, char *name, enum type_code code)
{
struct type *t;

Expand All @@ -4788,7 +4786,7 @@ arch_composite_type (struct gdbarch *gdbarch, const char *name,
the caller should do so. Return the new field. */

struct field *
append_composite_type_field_raw (struct type *t, const char *name,
append_composite_type_field_raw (struct type *t, char *name,
struct type *field)
{
struct field *f;
Expand All @@ -4807,7 +4805,7 @@ append_composite_type_field_raw (struct type *t, const char *name,
ALIGNMENT (if non-zero) specifies the minimum field alignment. */

void
append_composite_type_field_aligned (struct type *t, const char *name,
append_composite_type_field_aligned (struct type *t, char *name,
struct type *field, int alignment)
{
struct field *f = append_composite_type_field_raw (t, name, field);
Expand Down Expand Up @@ -4847,54 +4845,12 @@ append_composite_type_field_aligned (struct type *t, const char *name,
/* Add new field with name NAME and type FIELD to composite type T. */

void
append_composite_type_field (struct type *t, const char *name,
append_composite_type_field (struct type *t, char *name,
struct type *field)
{
append_composite_type_field_aligned (t, name, field, 0);
}

/* Compute the alignment of the type T according to the given
architecture. */

int
arch_type_alignment (struct gdbarch *gdbarch, struct type *t)
{
t = check_typedef (t);
switch (TYPE_CODE (t))
{
default:
error (_("could not compute alignment of type"));

case TYPE_CODE_PTR:
case TYPE_CODE_ENUM:
case TYPE_CODE_INT:
case TYPE_CODE_FLT:
case TYPE_CODE_REF:
case TYPE_CODE_CHAR:
case TYPE_CODE_BOOL:
return TYPE_LENGTH (t);

case TYPE_CODE_ARRAY:
case TYPE_CODE_COMPLEX:
return arch_type_alignment (gdbarch, TYPE_TARGET_TYPE (t));

case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
{
int i;
int align = 1;

for (i = 0; i < TYPE_NFIELDS (t); ++i)
{
int a = arch_type_alignment (gdbarch, TYPE_FIELD_TYPE (t, i));
if (a > align)
align = a;
}
return align;
}
}
}

static struct gdbarch_data *gdbtypes_data;

const struct builtin_type *
Expand Down
32 changes: 13 additions & 19 deletions gdb/gdbtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1676,17 +1676,13 @@ extern struct type *init_type (enum type_code, int, int, const char *,
struct objfile *);

/* Helper functions to construct architecture-owned types. */
extern struct type *arch_type (struct gdbarch *, enum type_code, int,
const char *);
extern struct type *arch_integer_type (struct gdbarch *, int, int,
const char *);
extern struct type *arch_character_type (struct gdbarch *, int, int,
const char *);
extern struct type *arch_boolean_type (struct gdbarch *, int, int,
const char *);
extern struct type *arch_float_type (struct gdbarch *, int, const char *,
extern struct type *arch_type (struct gdbarch *, enum type_code, int, char *);
extern struct type *arch_integer_type (struct gdbarch *, int, int, char *);
extern struct type *arch_character_type (struct gdbarch *, int, int, char *);
extern struct type *arch_boolean_type (struct gdbarch *, int, int, char *);
extern struct type *arch_float_type (struct gdbarch *, int, char *,
const struct floatformat **);
extern struct type *arch_complex_type (struct gdbarch *, const char *,
extern struct type *arch_complex_type (struct gdbarch *, char *,
struct type *);

/* Helper functions to construct a struct or record type. An
Expand All @@ -1696,27 +1692,25 @@ extern struct type *arch_complex_type (struct gdbarch *, const char *,
field packed against the previous. */

extern struct type *arch_composite_type (struct gdbarch *gdbarch,
const char *name, enum type_code code);
extern void append_composite_type_field (struct type *t, const char *name,
char *name, enum type_code code);
extern void append_composite_type_field (struct type *t, char *name,
struct type *field);
extern void append_composite_type_field_aligned (struct type *t,
const char *name,
char *name,
struct type *field,
int alignment);
struct field *append_composite_type_field_raw (struct type *t, const char *name,
struct field *append_composite_type_field_raw (struct type *t, char *name,
struct type *field);
extern int arch_type_alignment (struct gdbarch *, struct type *);

/* Helper functions to construct a bit flags type. An initially empty
type is created using arch_flag_type(). Flags are then added using
append_flag_type_field() and append_flag_type_flag(). */
extern struct type *arch_flags_type (struct gdbarch *gdbarch,
const char *name, int length);
char *name, int length);
extern void append_flags_type_field (struct type *type,
int start_bitpos, int nr_bits,
struct type *field_type, const char *name);
extern void append_flags_type_flag (struct type *type, int bitpos,
const char *name);
struct type *field_type, char *name);
extern void append_flags_type_flag (struct type *type, int bitpos, char *name);

extern void make_vector_type (struct type *array_type);
extern struct type *init_vector_type (struct type *elt_type, int n);
Expand Down
127 changes: 116 additions & 11 deletions gdb/rust-lang.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "f-lang.h"
#include "gdbarch.h"
#include "infcall.h"
#include "objfiles.h"
#include "rust-lang.h"
#include "valprint.h"
#include "varobj.h"
Expand Down Expand Up @@ -543,6 +544,111 @@ rust_language_arch_info (struct gdbarch *gdbarch,



/* Compute the alignment of the type T. */

static int
rust_type_alignment (struct type *t)
{
t = check_typedef (t);
switch (TYPE_CODE (t))
{
default:
error (_("could not compute alignment of type"));

case TYPE_CODE_PTR:
case TYPE_CODE_ENUM:
case TYPE_CODE_INT:
case TYPE_CODE_FLT:
case TYPE_CODE_REF:
case TYPE_CODE_CHAR:
case TYPE_CODE_BOOL:
return TYPE_LENGTH (t);

case TYPE_CODE_ARRAY:
case TYPE_CODE_COMPLEX:
return rust_type_alignment (TYPE_TARGET_TYPE (t));

case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
{
int i;
int align = 1;

for (i = 0; i < TYPE_NFIELDS (t); ++i)
{
int a = rust_type_alignment (TYPE_FIELD_TYPE (t, i));
if (a > align)
align = a;
}
return align;
}
}
}

/* Like arch_composite_type, but uses TYPE to decide how to allocate
-- either on an obstack or on a gdbarch. */

static struct type *
rust_composite_type (struct type *original,
const char *name,
const char *field1, struct type *type1,
const char *field2, struct type *type2)
{
struct type *result = alloc_type_copy (original);
int i, nfields, bitpos;

nfields = 0;
if (field1 != NULL)
++nfields;
if (field2 != NULL)
++nfields;

TYPE_CODE (result) = TYPE_CODE_STRUCT;
TYPE_NAME (result) = name;
TYPE_TAG_NAME (result) = name;

TYPE_NFIELDS (result) = nfields;
TYPE_FIELDS (result)
= (struct field *) TYPE_ZALLOC (result, nfields * sizeof (struct field));

i = 0;
bitpos = 0;
if (field1 != NULL)
{
struct field *field = &TYPE_FIELD (result, i);

SET_FIELD_BITPOS (*field, bitpos);
bitpos += TYPE_LENGTH (type1) * TARGET_CHAR_BIT;

FIELD_NAME (*field) = field1;
FIELD_TYPE (*field) = type1;
++i;
}
if (field2 != NULL)
{
struct field *field = &TYPE_FIELD (result, i);
int align = rust_type_alignment (type2);

if (align != 0)
{
int delta;

align *= TARGET_CHAR_BIT;
delta = bitpos % align;
if (delta != 0)
bitpos += align - delta;
}
SET_FIELD_BITPOS (*field, bitpos);

FIELD_NAME (*field) = field2;
FIELD_TYPE (*field) = type2;
}

return result;
}



/* A helper for rust_evaluate_subexp that handles OP_FUNCALL. */

static struct value *
Expand Down Expand Up @@ -633,8 +739,8 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
CORE_ADDR addr;
struct type *range_type;
struct type *index_type;
struct type *temp_type;
const char *name;
int alignment;

kind = (enum f90_range_type) longest_to_int (exp->elts[*pos + 1].longconst);
*pos += 3;
Expand Down Expand Up @@ -676,16 +782,15 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
}
}

range_type = arch_composite_type (exp->gdbarch, name, TYPE_CODE_STRUCT);

alignment = index_type == NULL ? 0 : arch_type_alignment (exp->gdbarch,
index_type);
if (low != NULL)
append_composite_type_field_aligned (range_type, "start", index_type,
alignment);
if (high != NULL)
append_composite_type_field_aligned (range_type, "end", index_type,
alignment);
/* If we don't have an index type, just allocate this on the
arch. Here any type will do. */
temp_type = (index_type == NULL
? language_bool_type (exp->language_defn, exp->gdbarch)
: index_type);
/* It would be nicer to cache the range type. */
range_type = rust_composite_type (temp_type, name,
low == NULL ? NULL : "start", index_type,
high == NULL ? NULL : "end", index_type);

if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value_zero (range_type, lval_memory);
Expand Down

0 comments on commit 7c45476

Please sign in to comment.