diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 8b5bc21..c5aa2c5 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -280,7 +280,10 @@ c_type_print_varspec_prefix (struct type *type, case TYPE_CODE_REF: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); - fprintf_filtered (stream, "&"); + if (TYPE_RVALUE_REFERENCE_TYPE (TYPE_TARGET_TYPE (type)) == type) + fprintf_filtered (stream, "&&"); + else + fprintf_filtered (stream, "&"); c_type_print_modifier (type, stream, 1, need_post_space); break; diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 2dcba20..00a7ef7 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -7069,6 +7069,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_pointer_type: case DW_TAG_ptr_to_member_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_string_type: break; @@ -11481,7 +11482,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu) the user defined type vector. */ static struct type * -read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) +do_read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu, + int rvalue_ref) { struct comp_unit_head *cu_header = &cu->header; struct type *type, *target_type; @@ -11494,7 +11496,11 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) if (type) return type; - type = lookup_reference_type (target_type); + if (rvalue_ref) + type = lookup_rvalue_reference_type (target_type); + else + type = lookup_reference_type (target_type); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { @@ -11508,6 +11514,18 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) } static struct type * +read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) +{ + return do_read_tag_reference_type (die, cu, 0); +} + +static struct type * +read_tag_rvalue_reference_type (struct die_info *die, struct dwarf2_cu *cu) +{ + return do_read_tag_reference_type (die, cu, 1); +} + +static struct type * read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *base_type, *cv_type; @@ -15721,6 +15739,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_reference_type: this_type = read_tag_reference_type (die, cu); break; + case DW_TAG_rvalue_reference_type: + this_type = read_tag_rvalue_reference_type (die, cu); + break; case DW_TAG_const_type: this_type = read_tag_const_type (die, cu); break; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 149d31f..a588066 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -359,15 +359,21 @@ lookup_pointer_type (struct type *type) /* Lookup a C++ `reference' to a type TYPE. TYPEPTR, if nonzero, points to a pointer to memory where the reference type should be stored. If *TYPEPTR is zero, update it to point to the reference - type we return. We allocate new memory if needed. */ + type we return. We allocate new memory if needed. If RVALUE_REF + is zero lookup lvalue reference type, otherwise rvalue reference + type. */ -struct type * -make_reference_type (struct type *type, struct type **typeptr) +static struct type * +do_make_reference_type (struct type *type, struct type **typeptr, + int rvalue_ref) { struct type *ntype; /* New type */ struct type *chain; - ntype = TYPE_REFERENCE_TYPE (type); + if (rvalue_ref) + ntype = TYPE_RVALUE_REFERENCE_TYPE (type); + else + ntype = TYPE_REFERENCE_TYPE (type); if (ntype) { @@ -396,7 +402,10 @@ make_reference_type (struct type *type, struct type **typeptr) } TYPE_TARGET_TYPE (ntype) = type; - TYPE_REFERENCE_TYPE (type) = ntype; + if (rvalue_ref) + TYPE_RVALUE_REFERENCE_TYPE (type) = ntype; + else + TYPE_REFERENCE_TYPE (type) = ntype; /* FIXME! Assume the machine has only one representation for references, and that it matches the (only) representation for @@ -406,9 +415,6 @@ make_reference_type (struct type *type, struct type **typeptr) gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT; TYPE_CODE (ntype) = TYPE_CODE_REF; - if (!TYPE_REFERENCE_TYPE (type)) /* Remember it, if don't have one. */ - TYPE_REFERENCE_TYPE (type) = ntype; - /* Update the length of all the other variants of this type. */ chain = TYPE_CHAIN (ntype); while (chain != ntype) @@ -420,13 +426,38 @@ make_reference_type (struct type *type, struct type **typeptr) return ntype; } +/* Same as above, looking up lvalue reference type. */ + +struct type * +make_reference_type (struct type *type, struct type **typeptr) +{ + return do_make_reference_type (type, (struct type **) 0, 0); +} + /* Same as above, but caller doesn't care about memory allocation details. */ struct type * lookup_reference_type (struct type *type) { - return make_reference_type (type, (struct type **) 0); + return do_make_reference_type (type, (struct type **) 0, 0); +} + +/* Same as make_reference_type, but looking up rvalue reference type. */ + +struct type * +make_rvalue_reference_type (struct type *type, struct type **typeptr) +{ + return do_make_reference_type (type, (struct type **) 0, 1); +} + +/* Same as above, but caller doesn't care about memory allocation + details. */ + +struct type * +lookup_rvalue_reference_type (struct type *type) +{ + return do_make_reference_type (type, (struct type **) 0, 1); } /* Lookup a function type that returns type TYPE. TYPEPTR, if @@ -586,6 +617,7 @@ make_qualified_type (struct type *type, int new_flags, the new type. */ TYPE_POINTER_TYPE (ntype) = (struct type *) 0; TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0; + TYPE_RVALUE_REFERENCE_TYPE (ntype) = (struct type *) 0; /* Chain the new qualified type to the old type. */ TYPE_CHAIN (ntype) = TYPE_CHAIN (type); @@ -3165,6 +3197,9 @@ recursive_dump_type (struct type *type, int spaces) printfi_filtered (spaces, "reference_type "); gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout); printf_filtered ("\n"); + printfi_filtered (spaces, "rvalue_reference_type "); + gdb_print_host_address (TYPE_RVALUE_REFERENCE_TYPE (type), gdb_stdout); + printf_filtered ("\n"); printfi_filtered (spaces, "type_chain "); gdb_print_host_address (TYPE_CHAIN (type), gdb_stdout); printf_filtered ("\n"); diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 59a6a65..6345e7d 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -650,9 +650,10 @@ struct type struct type *pointer_type; - /* C++: also need a reference type. */ + /* C++: also need reference types. */ struct type *reference_type; + struct type *rvalue_reference_type; /* Variant chain. This points to a type that differs from this one only in qualifiers and length. Currently, the possible qualifiers are @@ -1050,6 +1051,7 @@ extern void allocate_gnat_aux_type (struct type *); #define TYPE_TARGET_TYPE(thistype) TYPE_MAIN_TYPE(thistype)->target_type #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type +#define TYPE_RVALUE_REFERENCE_TYPE(thistype) (thistype)->rvalue_reference_type #define TYPE_CHAIN(thistype) (thistype)->chain /* Note that if thistype is a TYPEDEF type, you have to call check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF type, @@ -1475,8 +1477,12 @@ extern struct type *init_vector_type (struct type *elt_type, int n); extern struct type *lookup_reference_type (struct type *); +extern struct type *lookup_rvalue_reference_type (struct type *); + extern struct type *make_reference_type (struct type *, struct type **); +extern struct type *make_rvalue_reference_type (struct type *, struct type **); + extern struct type *make_cv_type (int, int, struct type *, struct type **); extern void replace_type (struct type *, struct type *);