diff options
author | Joel Brobecker <brobecker@gnat.com> | 2008-09-30 21:36:21 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2008-09-30 21:36:21 +0000 |
commit | b1f33ddde15312e8d7bdf4750a443ffd7dfbbea9 (patch) | |
tree | b1f0f75a5209b4a0bf9ad5041fd75277faa0fc71 | |
parent | 3d0b0fa396d73f8c06709d0c2001366d9d8d5239 (diff) | |
download | gdb-b1f33ddde15312e8d7bdf4750a443ffd7dfbbea9.zip gdb-b1f33ddde15312e8d7bdf4750a443ffd7dfbbea9.tar.gz gdb-b1f33ddde15312e8d7bdf4750a443ffd7dfbbea9.tar.bz2 |
* ada-lang.c (ada_lookup_struct_elt_type): Handle case of a "naked"
variant branch.
(empty_record): Use INIT_CPLUS_SPECIFIC, since this field is not
supposed to be null. Fixes debugger segfaults.
(is_unchecked_variant): New function.
(to_fixed_variant_branch_type): Modify to leave unchecked unions
untouched.
(ada_template_to_fixed_record_type_1): Fix comment.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/ada-lang.c | 36 |
2 files changed, 43 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4a02fb7..d67ea1c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2008-09-30 Paul Hilfinger <brobecker@adacore.com> + + * ada-lang.c (ada_lookup_struct_elt_type): Handle case of a "naked" + variant branch. + (empty_record): Use INIT_CPLUS_SPECIFIC, since this field is not + supposed to be null. Fixes debugger segfaults. + (is_unchecked_variant): New function. + (to_fixed_variant_branch_type): Modify to leave unchecked unions + untouched. + (ada_template_to_fixed_record_type_1): Fix comment. + 2008-09-30 Joel Brobecker <brobecker@adacore.com> * ada-lang.c (standard_exc): New static constant. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 45a59f2..5350516 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -6403,9 +6403,19 @@ ada_lookup_struct_elt_type (struct type *type, char *name, int refok, for (j = TYPE_NFIELDS (field_type) - 1; j >= 0; j -= 1) { + /* FIXME pnh 2008/01/26: We check for a field that is + NOT wrapped in a struct, since the compiler sometimes + generates these for unchecked variant types. Revisit + if the compiler changes this practice. */ + char *v_field_name = TYPE_FIELD_NAME (field_type, j); disp = 0; - t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (field_type, j), - name, 0, 1, &disp); + if (v_field_name != NULL + && field_name_match (v_field_name, name)) + t = ada_check_typedef (TYPE_FIELD_TYPE (field_type, j)); + else + t = ada_lookup_struct_elt_type (TYPE_FIELD_TYPE (field_type, j), + name, 0, 1, &disp); + if (t != NULL) { if (dispp != NULL) @@ -6442,6 +6452,20 @@ BadName: } /* Assuming that VAR_TYPE is the type of a variant part of a record (a union), + within a value of type OUTER_TYPE, return true iff VAR_TYPE + represents an unchecked union (that is, the variant part of a + record that is named in an Unchecked_Union pragma). */ + +static int +is_unchecked_variant (struct type *var_type, struct type *outer_type) +{ + char *discrim_name = ada_variant_discrim_name (var_type); + return (ada_lookup_struct_elt_type (outer_type, discrim_name, 0, 1, NULL) + == NULL); +} + + +/* Assuming that VAR_TYPE is the type of a variant part of a record (a union), within a value of type OUTER_TYPE that is stored in GDB at OUTER_VALADDR, determine which variant clause (field number in VAR_TYPE, numbering from 0) is applicable. Returns -1 if none are. */ @@ -6812,6 +6836,7 @@ empty_record (struct objfile *objfile) TYPE_CODE (type) = TYPE_CODE_STRUCT; TYPE_NFIELDS (type) = 0; TYPE_FIELDS (type) = NULL; + INIT_CPLUS_SPECIFIC (type); TYPE_NAME (type) = "<empty>"; TYPE_TAG_NAME (type) = NULL; TYPE_LENGTH (type) = 0; @@ -6933,7 +6958,7 @@ ada_template_to_fixed_record_type_1 (struct type *type, } /* We handle the variant part, if any, at the end because of certain - odd cases in which it is re-ordered so as NOT the last field of + odd cases in which it is re-ordered so as NOT to be the last field of the record. This can happen in the presence of representation clauses. */ if (variant_field >= 0) @@ -7180,7 +7205,8 @@ to_fixed_record_type (struct type *type0, const gdb_byte *valaddr, union type. Any necessary discriminants' values should be in DVAL, a record value. That is, this routine selects the appropriate branch of the union at ADDR according to the discriminant value - indicated in the union's type name. */ + indicated in the union's type name. Returns VAR_TYPE0 itself if + it represents a variant subject to a pragma Unchecked_Union. */ static struct type * to_fixed_variant_branch_type (struct type *var_type0, const gdb_byte *valaddr, @@ -7200,6 +7226,8 @@ to_fixed_variant_branch_type (struct type *var_type0, const gdb_byte *valaddr, if (templ_type != NULL) var_type = templ_type; + if (is_unchecked_variant (var_type, value_type (dval))) + return var_type0; which = ada_which_variant_applies (var_type, value_type (dval), value_contents (dval)); |