public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
@ 2015-12-20 22:35 Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
                   ` (12 more replies)
  0 siblings, 13 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

Hi all,

this is my take on fixing gdb/14441 which deals with C++0x rvalue references.

The approach is rather straightforward and the work for the most part consisted
of mimicking the behavior for regular references. In gdbtypes.c, several helper
functions were introduced and some parameterized by the reference kind to
simplify the access to reference type objects API.

The only interesting part is the addition of overloading resolution rules
with regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
13.3.3.2 were accounted for at the beginning of rank_one_type(). 

With this patch it is now also possible to fix the evaluation of decltype,
which should return a plain type object, an lvalue reference or an rvalue
reference depending on a type category of the type of its operand. However,
this would require introduction of the type catyegory notion to gdb, which I
think only needs adding a new constant to lval_type and propagating the type
category through different parts of an expression in gdb/valops.c. I'm willing
to do this if this patchset turns out to be OK.

Artemiy Volkov (11):
  gdb: gdbtypes: add definitions for rvalue reference type
  gdb: gdbtypes: change {lookup,make}_reference_type() API
  gdb: valops: add ability to return rvalue reference values from
    value_ref()
  gdb: parse: support rvalue reference type
  gdb: demangle: implement demangling for rvalue reference typenames
  gdb: print: implement correct printing of rvalue reference types and
    values
  gdb: dwarf2read: support DW_AT_rvalue_reference type
  gdb: convert lvalue reference type check to general reference type
    check
  gdb: gdbtypes: add rvalue references to overloading resolution
  gdb: python: support rvalue references in the gdb module
  gdb: testsuite: add rvalue reference tests

 gdb/aarch64-tdep.c                    |   5 +-
 gdb/ada-lang.c                        |   2 +-
 gdb/amd64-tdep.c                      |   2 +-
 gdb/amd64-windows-tdep.c              |   1 +
 gdb/arm-tdep.c                        |   5 +-
 gdb/ax-gdb.c                          |   2 +
 gdb/c-exp.y                           |   6 +-
 gdb/c-typeprint.c                     |  10 +-
 gdb/c-valprint.c                      |  13 ++-
 gdb/c-varobj.c                        |  10 +-
 gdb/compile/compile-c-symbols.c       |   2 +-
 gdb/completer.c                       |   3 +-
 gdb/cp-name-parser.y                  |   4 +
 gdb/cp-support.c                      |   3 +-
 gdb/darwin-nat-info.c                 |   2 +-
 gdb/dwarf2loc.c                       |   4 +-
 gdb/dwarf2read.c                      |  15 ++-
 gdb/eval.c                            |  16 ++--
 gdb/f-exp.y                           |   2 +-
 gdb/findvar.c                         |   6 +-
 gdb/gdbtypes.c                        |  96 ++++++++++++++++---
 gdb/gdbtypes.h                        |  21 ++++-
 gdb/guile/scm-type.c                  |   2 +-
 gdb/guile/scm-value.c                 |   2 +-
 gdb/hppa-tdep.c                       |   1 +
 gdb/infcall.c                         |   5 +-
 gdb/language.c                        |   3 +-
 gdb/m32c-tdep.c                       |   8 +-
 gdb/m88k-tdep.c                       |   1 +
 gdb/mn10300-tdep.c                    |   1 +
 gdb/msp430-tdep.c                     |   2 +-
 gdb/parse.c                           |  41 ++++----
 gdb/parser-defs.h                     |   1 +
 gdb/ppc-sysv-tdep.c                   |  10 +-
 gdb/printcmd.c                        |   4 +-
 gdb/python/lib/gdb/command/explore.py |  21 +++++
 gdb/python/lib/gdb/types.py           |   4 +-
 gdb/python/py-type.c                  |  14 ++-
 gdb/python/py-value.c                 |  45 +++++++--
 gdb/python/py-xmethods.c              |  19 +++-
 gdb/s390-linux-tdep.c                 |   2 +-
 gdb/sparc-tdep.c                      |   1 +
 gdb/sparc64-tdep.c                    |   1 +
 gdb/spu-tdep.c                        |   1 +
 gdb/stabsread.c                       |   2 +-
 gdb/symtab.c                          |   3 +-
 gdb/testsuite/gdb.cp/casts.cc         |   8 +-
 gdb/testsuite/gdb.cp/casts.exp        |  34 ++++++-
 gdb/testsuite/gdb.cp/cpsizeof.cc      |   4 +
 gdb/testsuite/gdb.cp/cpsizeof.exp     |   2 +-
 gdb/testsuite/gdb.cp/demangle.exp     | 172 +++++++++++++++++++++++++++++++++-
 gdb/testsuite/gdb.cp/overload.cc      |   9 ++
 gdb/testsuite/gdb.cp/overload.exp     |  14 ++-
 gdb/testsuite/gdb.cp/ref-params.cc    |  29 +++++-
 gdb/testsuite/gdb.cp/ref-params.exp   |  20 +++-
 gdb/testsuite/gdb.cp/ref-types.cc     |  24 +++++
 gdb/testsuite/gdb.cp/ref-types.exp    | 136 ++++++++++++++++++++++++++-
 gdb/typeprint.c                       |   4 +-
 gdb/valarith.c                        |   6 +-
 gdb/valops.c                          |  68 +++++++-------
 gdb/valprint.c                        |   5 +-
 gdb/value.c                           |  12 ++-
 gdb/value.h                           |   2 +-
 gdb/varobj.c                          |   2 +-
 libiberty/cplus-dem.c                 |  14 ++-
 65 files changed, 805 insertions(+), 184 deletions(-)

-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (6 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-30 19:17   ` Pedro Alves
  2015-12-20 22:35 ` [PATCH 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch fixes demangling of names containing rvalue reference typenames by
handling DEMANGLE_COMPONENT_RVALUE_REFERENCE in gdb and handling the 'O' type
code in libiberty.

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/cp-name-parser.y: Handle the '&&' token in typename.
        * gdb/cp-support.c (replace_typedefs): Handle
        DEMANGLE_COMPONENT_RVALUE_REFERENCE.
        * gdb/python/py-type.c (typy_lookup_type): Likewise.

libiberty/ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * cplus-dem.c (enum type_kind_t): Add tk_rvalue_reference
        constant.
        (demangle_template_value_parm): Handle tk_rvalue_reference
        type kind.
        (do_type): Support 'O' type id (rvalue references).
---
 gdb/cp-name-parser.y  |  4 ++++
 gdb/cp-support.c      |  1 +
 gdb/python/py-type.c  |  6 +++++-
 libiberty/cplus-dem.c | 14 +++++++++++---
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index c7a3f12..b5601b9 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -769,6 +769,10 @@ ptr_operator	:	'*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
 			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
 			  $$.last = &d_left ($$.comp); }
+		|	ANDAND
+			{ $$.comp = make_empty (DEMANGLE_COMPONENT_RVALUE_REFERENCE);
+			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+			  $$.last = &d_left ($$.comp); }
 		|	nested_name '*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
 			  $$.comp->u.s_binary.left = $1.comp;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index a14455a..6f85c4c 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -520,6 +520,7 @@ replace_typedefs (struct demangle_parse_info *info,
 	case DEMANGLE_COMPONENT_RESTRICT_THIS:
 	case DEMANGLE_COMPONENT_POINTER:
 	case DEMANGLE_COMPONENT_REFERENCE:
+	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
 	  replace_typedefs (info, d_left (ret_comp), finder, data);
 	  break;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 676ab63..ad2f952 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -811,6 +811,7 @@ typy_lookup_type (struct demangle_component *demangled,
 
   if (demangled_type == DEMANGLE_COMPONENT_POINTER
       || demangled_type == DEMANGLE_COMPONENT_REFERENCE
+      || demangled_type == DEMANGLE_COMPONENT_RVALUE_REFERENCE
       || demangled_type == DEMANGLE_COMPONENT_CONST
       || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
     {
@@ -827,7 +828,10 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-             rtype = lookup_lvalue_reference_type (type);
+              rtype = lookup_lvalue_reference_type (type);
+	      break;
+	    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+              rtype = lookup_rvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index c68b981..89baf07 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -237,6 +237,7 @@ typedef enum type_kind_t
   tk_none,
   tk_pointer,
   tk_reference,
+  tk_rvalue_reference,
   tk_integral,
   tk_bool,
   tk_char,
@@ -2033,7 +2034,8 @@ demangle_template_value_parm (struct work_stuff *work, const char **mangled,
     }
   else if (tk == tk_real)
     success = demangle_real_value (work, mangled, s);
-  else if (tk == tk_pointer || tk == tk_reference)
+  else if (tk == tk_pointer || tk == tk_reference
+           || tk == tk_rvalue_reference)
     {
       if (**mangled == 'Q')
 	success = demangle_qualified (work, mangled, s,
@@ -3574,6 +3576,14 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
 	    tk = tk_reference;
 	  break;
 
+          /* An rvalue reference type */
+	case 'O':
+          (*mangled)++;
+          string_prepend (&decl, "&&");
+          if (tk == tk_none)
+            tk = tk_rvalue_reference;
+          break;
+
 	  /* An array */
 	case 'A':
 	  {
@@ -3631,11 +3641,9 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
 	  break;
 
 	case 'M':
-	case 'O':
 	  {
 	    type_quals = TYPE_UNQUALIFIED;
 
-	    member = **mangled == 'M';
 	    (*mangled)++;
 
 	    string_append (&decl, ")");
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (9 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-28 21:09 ` [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch introduces preliminal definitions regarding C++0x rvalue references
to the gdb type system. In addition to an enum type_code entry, a field in
struct type and an accessor macro for that which are created similarly to the
lvalue references' counterparts, we also introduce a TYPE_REFERENCE convenience
macro used to check for both kinds of references simultaneously as they are
equivalent in many contexts.

./Changelog:

2015-12-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/gdbtypes.h (enum type_code): Add TYPE_CODE_RVALUE_REF
        constant.
        (TYPE_REFERENCE): New macro.
        (struct type): Add rvalue_reference_type field.
        (TYPE_RVALUE_REFERENCE_TYPE): New macro.
---
 gdb/gdbtypes.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index acfa16a..2ef38ca 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -160,6 +160,8 @@ enum type_code
 
     TYPE_CODE_REF,		/**< C++ Reference types */
 
+    TYPE_CODE_RVALUE_REF,	/**< C++ rvalue reference types */
+
     TYPE_CODE_CHAR,		/**< *real* character type */
 
     /* * Boolean type.  0 is false, 1 is true, and other values are
@@ -362,6 +364,12 @@ enum type_instance_flag_value
 #define TYPE_ATOMIC(t) \
   (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
 
+/* * C++ lvalue and rvalue references are equivalent in many contexts,
+   thus create a convenience macro that checks if a type is either of them. */
+
+#define TYPE_REFERENCE(t) \
+  (TYPE_CODE(t) == TYPE_CODE_REF || TYPE_CODE(t) == TYPE_CODE_RVALUE_REF)
+
 /* * Instruction-space delimited type.  This is for Harvard architectures
    which have separate instruction and data address spaces (and perhaps
    others).
@@ -767,6 +775,10 @@ struct type
 
   struct type *reference_type;
 
+  /* * A C++ rvalue reference type added in C++0x. */
+
+  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 const, volatile, code-space, data-space, and
@@ -1229,6 +1241,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,
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (3 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch introduces changes to rank_one_type() dealing with ranking an rvalue
reference type when selecting a best viable function from a set of candidate
functions. The 3 new added rules for rvalue references are:

1) An rvalue argument cannot be bound to a non-const lvalue reference parameter
and an lvalue argument cannot be bound to an rvalue reference parameter.
[C++11 13.3.3.1.4p3]

2) If a conversion to one type of reference is an identity conversion, and a
conversion to the second type of reference is a non-identity conversion, choose
the first type. [C++11 13.3.3.2p3]

3) An rvalue should be first tried to bind to an rvalue reference, and then to
an lvalue reference. [C++11 13.3.3.2p3]

4) An lvalue reference to a function gets higher priority than an rvalue
reference to a function. [C++11 13.3.3.2p3]

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/gdbtypes.c (rank_one_type): Implement overloading
        resolution rules regarding rvalue references.
---
 gdb/gdbtypes.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 0cf7d2e..a6d74a1 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -58,6 +58,8 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
 const struct rank BOOL_CONVERSION_BADNESS = {3,0};
 const struct rank BASE_CONVERSION_BADNESS = {2,0};
 const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0};
+const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0};
 const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
 const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
 const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
@@ -3464,6 +3466,20 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 {
   struct rank rank = {0,0};
 
+  /* Disallow an rvalue argument to bind to a non-const lvalue reference
+     parameter and an lvalue argument to bind to an rvalue reference
+     parameter. */
+
+  if ((value != NULL)
+      &&
+      ((TYPE_CODE (parm) == TYPE_CODE_REF
+       && !TYPE_CONST (parm->main_type->target_type)
+       && VALUE_LVAL (value) == not_lval)
+      ||
+       (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF
+       && VALUE_LVAL (value) != not_lval)))
+    return INCOMPATIBLE_TYPE_BADNESS;
+
   if (types_equal (parm, arg))
     return EXACT_MATCH_BADNESS;
 
@@ -3473,6 +3489,36 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
   if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
     arg = check_typedef (arg);
 
+  /* An lvalue reference to a function should get higher priority than an
+     rvalue reference to a function. */
+
+  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
+      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
+    return (sum_ranks (rank_one_type (parm,
+            lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
+            DIFFERENT_REFERENCE_TYPE_BADNESS));
+
+  /* If a conversion to one type of reference is an identity conversion, and a
+     conversion to the second type of reference is a non-identity conversion,
+     choose the first type. */
+
+  if (value != NULL && TYPE_REFERENCE (parm) && TYPE_REFERENCE (arg)
+     && TYPE_CODE (parm) != TYPE_CODE (arg))
+    return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
+            TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
+
+  /* An rvalue should be first tried to bind to an rvalue reference, and then to
+     an lvalue reference. */
+
+  if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
+      && VALUE_LVAL (value) == not_lval)
+    {
+      if (TYPE_REFERENCE (arg))
+	arg = TYPE_TARGET_TYPE (arg);
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
+			 LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
+    }
+
   /* See through references, since we can almost make non-references
      references.  */
 
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (4 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

In almost all contexts (except for overload resolution rules and expression
semantics), lvalue and rvalue references are equivalent. That means that in
all but these cases we can replace a TYPE_CODE_REF check to TYPE_REFERENCE
check. This patch does exactly that.

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/aarch64-tdep.c (aarch64_type_align): Change TYPE_CODE_REF
        check to TYPE_REFERENCE check.
        (aarch64_extract_return_value): Likewise.
        (aarch64_store_return_value): Likewise.
        * gdb/amd64-tdep.c (amd64_classify): Likewise.
        * gdb/amd64-windows-tdep.c (amd64_windows_passed_by_integer_register):
        Likewise.
        * gdb/arm-tdep.c (arm_type_align): Likewise.
        (arm_extract_return_value): Likewise.
        (arm_store_return_value): Likewise.
        * gdb/ax-gdb.c (gen_fetch): Likewise.
        (gen_cast): Likewise.
        * gdb/c-typeprint.c (c_print_type): Likewise.
        * gdb/c-varobj.c (adjust_value_for_child_access): Likewise.
        (c_value_of_variable): Likewise.
        (cplus_number_of_children): Likewise.
        (cplus_describe_child): Likewise.
        * gdb/compile/compile-c-symbols.c (generate_vla_size): Likewise.
        * gdb/completer.c (expression_completer): Likewise.
        * gdb/cp-support.c (make_symbol_overload_list_adl_namespace):
        Likewise.
        * gdb/darwin-nat-info.c (info_mach_region_command): Likewise.
        * gdb/dwarf2loc.c (entry_data_value_coerce_ref): Likewise.
        (value_of_dwarf_reg_entry): Likewise.
        * gdb/eval.c (ptrmath_type_p): Likewise.
        (evaluate_subexp_standard): Likewise.
        (evaluate_subexp_for_address): Likewise.
        (evaluate_subexp_for_sizeof): Likewise.
        * gdb/findvar.c (extract_typed_address): Likewise.
        (store_typed_address): Likewise.
        * gdb/gdbtypes.c (rank_one_type): Likewise.
        * gdb/hppa-tdep.c (hppa64_integral_or_pointer_p): Likewise.
        * gdb/infcall.c (value_arg_coerce): Likewise.
        * gdb/language.c (pointer_type): Likewise.
        * gdb/m32c-tdep.c (m32c_reg_arg_type): Likewise.
        (m32c_m16c_address_to_pointer): Likewise.
        (m32c_m16c_pointer_to_address): Likewise.
        * gdb/m88k-tdep.c (m88k_integral_or_pointer_p): Likewise.
        * gdb/mn10300-tdep.c (mn10300_type_align): Likewise.
        * gdb/msp430-tdep.c (msp430_push_dummy_call): Likewise.
        * gdb/ppc-sysv-tdep.c (do_ppc_sysv_return_value): Likewise.
        (ppc64_sysv_abi_push_param): Likewise.
        (ppc64_sysv_abi_return_value): Likewise.
        * gdb/printcmd.c (print_formatted): Likewise.
        (x_command): Likewise.
        * gdb/python/py-type.c (typy_get_composite): Likewise.
        (typy_template_argument): Likewise.
        * gdb/python/py-value.c (valpy_referenced_value): Likewise.
        (valpy_get_dynamic_type): Likewise.
        (value_has_field): Likewise.
        (valpy_getitem): Likewise.
        * gdb/python/py-xmethods.c (gdbpy_get_xmethod_result_type):
        Handle TYPE_CODE_VALUE_REF type.
        (gdbpy_invoke_xmethod): Likewise.
        * gdb/s390-linux-tdep.c (s390_function_arg_integer): Change
        TYPE_CODE_REF check to TYPE_REFERENCE check.
        * gdb/sparc-tdep.c (sparc_integral_or_pointer_p): Likewise.
        * gdb/sparc64-tdep.c (sparc64_integral_or_pointer_p): Likewise.
        * gdb/spu-tdep.c (spu_scalar_value_p): Likewise.
        * gdb/symtab.c (lookup_symbol_aux): Likewise.
        * gdb/typeprint.c (whatis_exp): Likewise.
        (print_type_scalar): Likewise.
        * gdb/valarith.c (binop_types_user_defined_p): Likewise.
        (unop_user_defined_p): Likewise.
        * gdb/valops.c (value_cast_pointers): Likewise.
        (value_cast): Likewise.
        (value_reinterpret_cast): Likewise.
        (value_dynamic_cast): Likewise.
        (value_addr): Likewise.
        (typecmp): Likewise.
        (value_struct_elt): Likewise.
        (value_struct_elt_bitpos): Likewise.
        (value_find_oload_method_list): Likewise.
        (find_overload_match): Likewise.
        (value_rtti_indirect_type): Likewise.
        * gdb/valprint.c (val_print_scalar_type_p): Likewise.
        (generic_val_print): Likewise.
        * gdb/value.c (value_actual_type): Likewise.
        (value_as_address): Likewise.
        (unpack_long): Likewise.
        (pack_long): Likewise.
        (pack_unsigned_long): Likewise.
        (coerce_ref_if_computed): Likewise.
        (coerce_ref): Likewise. Likewise.
        * gdb/varobj.c (varobj_get_value_type): Likewise.
---
 gdb/aarch64-tdep.c              |  5 +++--
 gdb/amd64-tdep.c                |  2 +-
 gdb/amd64-windows-tdep.c        |  1 +
 gdb/arm-tdep.c                  |  5 +++--
 gdb/ax-gdb.c                    |  2 ++
 gdb/c-typeprint.c               |  2 +-
 gdb/c-varobj.c                  | 10 ++++-----
 gdb/compile/compile-c-symbols.c |  2 +-
 gdb/completer.c                 |  3 +--
 gdb/cp-support.c                |  2 +-
 gdb/darwin-nat-info.c           |  2 +-
 gdb/dwarf2loc.c                 |  4 ++--
 gdb/eval.c                      | 16 +++++++-------
 gdb/findvar.c                   |  6 ++----
 gdb/gdbtypes.c                  |  5 +++--
 gdb/hppa-tdep.c                 |  1 +
 gdb/infcall.c                   |  3 ++-
 gdb/language.c                  |  3 +--
 gdb/m32c-tdep.c                 |  8 +++----
 gdb/m88k-tdep.c                 |  1 +
 gdb/mn10300-tdep.c              |  1 +
 gdb/msp430-tdep.c               |  2 +-
 gdb/ppc-sysv-tdep.c             | 10 ++++-----
 gdb/printcmd.c                  |  4 ++--
 gdb/python/py-type.c            |  5 ++---
 gdb/python/py-value.c           | 13 +++++------
 gdb/python/py-xmethods.c        | 15 +++++++++++++
 gdb/s390-linux-tdep.c           |  2 +-
 gdb/sparc-tdep.c                |  1 +
 gdb/sparc64-tdep.c              |  1 +
 gdb/spu-tdep.c                  |  1 +
 gdb/symtab.c                    |  3 +--
 gdb/typeprint.c                 |  4 ++--
 gdb/valarith.c                  |  6 +++---
 gdb/valops.c                    | 48 ++++++++++++++++++-----------------------
 gdb/valprint.c                  |  5 +++--
 gdb/value.c                     | 12 ++++++-----
 gdb/varobj.c                    |  2 +-
 38 files changed, 117 insertions(+), 101 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index f4763bb..ae743bc 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -890,6 +890,7 @@ aarch64_type_align (struct type *t)
     case TYPE_CODE_RANGE:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -1613,7 +1614,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the the type is a plain integer, then the access is
@@ -1754,7 +1755,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 6096ce9..250e686 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -643,7 +643,7 @@ amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_CHAR
-       || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
+       || code == TYPE_CODE_PTR || TYPE_REFERENCE (type))
       && (len == 1 || len == 2 || len == 4 || len == 8))
     theclass[0] = AMD64_INTEGER;
 
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index c04b730..32e4075 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -55,6 +55,7 @@ amd64_windows_passed_by_integer_register (struct type *type)
       case TYPE_CODE_CHAR:
       case TYPE_CODE_PTR:
       case TYPE_CODE_REF:
+      case TYPE_CODE_RVALUE_REF:
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
 	return (TYPE_LENGTH (type) == 1
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 0e10dfd..a19ed59 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3240,6 +3240,7 @@ arm_type_align (struct type *t)
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -7826,7 +7827,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the type is a plain integer, then the access is
@@ -8031,7 +8032,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= 4)
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 7091a4a..f9e5551 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -492,6 +492,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
@@ -1002,6 +1003,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* It's implementation-defined, and I'll bet this is what GCC
          does.  */
       break;
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 1ed8cdc..0037562 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-                 || TYPE_REFERENCE (type))))
+		  || TYPE_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index b39a113..1457655 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -78,7 +78,7 @@ adjust_value_for_child_access (struct value **value,
      to us, is already supposed to be
      reference-stripped.  */
 
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+  gdb_assert (!TYPE_REFERENCE (*type));
 
   /* Pointers to structures are treated just like
      structures when accessing children.  Don't
@@ -489,7 +489,7 @@ c_value_of_variable (const struct varobj *var,
   struct type *type = get_type (var);
 
   /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
@@ -586,7 +586,7 @@ cplus_number_of_children (const struct varobj *var)
       if (opts.objectprint)
         {
           value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+          lookup_actual_type = (TYPE_REFERENCE (var->type)
 				|| TYPE_CODE (var->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -623,7 +623,7 @@ cplus_number_of_children (const struct varobj *var)
 	  const struct varobj *parent = var->parent;
 
 	  value = parent->value;
-	  lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+	  lookup_actual_type = (TYPE_REFERENCE (parent->type)
 				|| TYPE_CODE (parent->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -728,7 +728,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
   var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
   if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+    lookup_actual_type = (TYPE_REFERENCE (var->type)
 			  || TYPE_CODE (var->type) == TYPE_CODE_PTR);
   value = var->value;
   type = varobj_get_value_type (var);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index f5ca15c..1181a6b 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -593,7 +593,7 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
diff --git a/gdb/completer.c b/gdb/completer.c
index bafcb50..c0dbaaf 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -610,8 +610,7 @@ expression_completer (struct cmd_list_element *ignore,
       for (;;)
 	{
 	  type = check_typedef (type);
-	  if (TYPE_CODE (type) != TYPE_CODE_PTR
-	      && TYPE_CODE (type) != TYPE_CODE_REF)
+	  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
 	    break;
 	  type = TYPE_TARGET_TYPE (type);
 	}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 6f85c4c..458a649 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1279,7 +1279,7 @@ make_symbol_overload_list_adl_namespace (struct type *type,
   int i, prefix_len;
 
   while (TYPE_CODE (type) == TYPE_CODE_PTR
-	 || TYPE_CODE (type) == TYPE_CODE_REF
+	 || TYPE_REFERENCE (type)
          || TYPE_CODE (type) == TYPE_CODE_ARRAY
          || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
     {
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 90e61da..d8faa14 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -732,7 +732,7 @@ info_mach_region_command (char *exp, int from_tty)
 
   expr = parse_expression (exp);
   val = evaluate_expression (expr);
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (value_type (val)))
     {
       val = value_ind (val);
     }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index b8e7fa0..fdd6028 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1337,7 +1337,7 @@ entry_data_value_coerce_ref (const struct value *value)
   struct type *checked_type = check_typedef (value_type (value));
   struct value *target_val;
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+  if (!TYPE_REFERENCE (checked_type))
     return NULL;
 
   target_val = (struct value *) value_computed_closure (value);
@@ -1412,7 +1412,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      TYPE_CODE_REF with non-entry data value would give current value - not the
      entry value.  */
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+  if (!TYPE_REFERENCE (checked_type)
       || TYPE_TARGET_TYPE (checked_type) == NULL)
     return outer_val;
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 3d408e4..bce06e8 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -640,7 +640,7 @@ static int
 ptrmath_type_p (const struct language_defn *lang, struct type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     type = TYPE_TARGET_TYPE (type);
 
   switch (TYPE_CODE (type))
@@ -2509,7 +2509,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	{
 	  type = check_typedef (value_type (arg1));
 	  if (TYPE_CODE (type) == TYPE_CODE_PTR
-	      || TYPE_CODE (type) == TYPE_CODE_REF
+	      || TYPE_REFERENCE (type)
 	  /* In C you can dereference an array to get the 1st elt.  */
 	      || TYPE_CODE (type) == TYPE_CODE_ARRAY
 	    )
@@ -2787,9 +2787,9 @@ evaluate_subexp_standard (struct type *expect_type,
 	    {
 	      struct type *type = value_type (result);
 
-	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+	      if (!TYPE_REFERENCE (type))
 		{
-                 type = lookup_lvalue_reference_type (type);
+		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
@@ -2890,7 +2890,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (SYMBOL_TYPE (var)))
 	goto default_case;
 
       (*pos) += 4;
@@ -2929,7 +2929,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 	{
 	  struct type *type = check_typedef (value_type (x));
 
-	  if (TYPE_CODE (type) == TYPE_CODE_REF)
+	  if (TYPE_REFERENCE (type))
 	    return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			       not_lval);
 	  else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
@@ -3019,7 +3019,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = check_typedef (value_type (val));
       if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF
+	  && !TYPE_REFERENCE (type)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
@@ -3091,7 +3091,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
      the size of the referenced type."  */
   type = check_typedef (type);
   if (exp->language_defn->la_language == language_cplus
-      && TYPE_CODE (type) == TYPE_CODE_REF)
+      && (TYPE_REFERENCE (type)))
     type = check_typedef (TYPE_TARGET_TYPE (type));
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 855947d..aa6e81d 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -169,8 +169,7 @@ extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
 CORE_ADDR
 extract_typed_address (const gdb_byte *buf, struct type *type)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("extract_typed_address: "
 		    "type is not a pointer or reference"));
@@ -242,8 +241,7 @@ store_unsigned_integer (gdb_byte *addr, int len,
 void
 store_typed_address (gdb_byte *buf, struct type *type, CORE_ADDR addr)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("store_typed_address: "
 		    "type is not a pointer or reference"));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 49e5bf2..0cf7d2e 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3475,10 +3475,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   /* See through references, since we can almost make non-references
      references.  */
-  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+  if (TYPE_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                        REFERENCE_CONVERSION_BADNESS));
-  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                        REFERENCE_CONVERSION_BADNESS));
   if (overload_debug)
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 3206729..bc0c21c 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -902,6 +902,7 @@ hppa64_integral_or_pointer_p (const struct type *type)
       }
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return (TYPE_LENGTH (type) == 8);
     default:
       break;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index eafd812..0dc897a 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -158,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	struct value *new_value;
 
-	if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+	if (TYPE_REFERENCE (arg_type))
 	  return value_cast_pointers (type, arg, 0);
 
 	/* Cast the value to the reference's target type, and then
diff --git a/gdb/language.c b/gdb/language.c
index 6a10539..25bc644 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -410,8 +410,7 @@ language_info (int quietly)
 int
 pointer_type (struct type *type)
 {
-  return TYPE_CODE (type) == TYPE_CODE_PTR ||
-    TYPE_CODE (type) == TYPE_CODE_REF;
+  return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type);
 }
 
 \f
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index e31397c..1f5628b 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2031,7 +2031,7 @@ m32c_reg_arg_type (struct type *type)
   return (code == TYPE_CODE_INT
 	  || code == TYPE_CODE_ENUM
 	  || code == TYPE_CODE_PTR
-	  || code == TYPE_CODE_REF
+	  || TYPE_REFERENCE (type)
 	  || code == TYPE_CODE_BOOL
 	  || code == TYPE_CODE_CHAR);
 }
@@ -2453,8 +2453,7 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   enum type_code target_code;
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type));
 
   target_code = TYPE_CODE (TYPE_TARGET_TYPE (type));
 
@@ -2533,8 +2532,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR ptr;
   enum type_code target_code;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type));
 
   ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index 94ea409..445ea2e 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -165,6 +165,7 @@ m88k_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	/* Allow only 32-bit pointers.  */
 	return (TYPE_LENGTH (type) == 4);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 5603333..ddd27e8 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -96,6 +96,7 @@ mn10300_type_align (struct type *type)
     case TYPE_CODE_FLT:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type);
 
     case TYPE_CODE_COMPLEX:
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 5368025..ccaeb39 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -769,7 +769,7 @@ msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 		  if (code_model == MSP_LARGE_CODE_MODEL
 		      && (TYPE_CODE (arg_type) == TYPE_CODE_PTR
-		          || TYPE_CODE (arg_type) == TYPE_CODE_REF
+		          || TYPE_REFERENCE (arg_type)
 			  || TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
 			  || TYPE_CODE (arg_type) == TYPE_CODE_UNION))
 		    {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 1c2644d..035c8c3 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -805,7 +805,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF
+	    || TYPE_REFERENCE (type)
 	    || TYPE_CODE (type) == TYPE_CODE_ENUM)
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -1493,7 +1493,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF)
+	    || TYPE_REFERENCE (type))
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1505,8 +1505,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 
 	  /* Convert any function code addresses into descriptors.  */
 	  if (tdep->elf_abi == POWERPC_ELF_V1
-	      && (TYPE_CODE (type) == TYPE_CODE_PTR
-		  || TYPE_CODE (type) == TYPE_CODE_REF))
+	      && (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type)))
 	    {
 	      struct type *target_type
 		= check_typedef (TYPE_TARGET_TYPE (type));
@@ -1999,8 +1998,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index c676fc7..3a59ad5 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -306,7 +306,7 @@ print_formatted (struct value *val, int size,
     }
 
   if (options->format == 0 || options->format == 's'
-      || TYPE_CODE (type) == TYPE_CODE_REF
+      || TYPE_REFERENCE (type)
       || TYPE_CODE (type) == TYPE_CODE_ARRAY
       || TYPE_CODE (type) == TYPE_CODE_STRING
       || TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -1449,7 +1449,7 @@ x_command (char *exp, int from_tty)
 	*exp = 0;
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
-      if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index ad2f952..2c071cc 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -485,8 +485,7 @@ typy_get_composite (struct type *type)
 	}
       END_CATCH
 
-      if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF)
+      if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
 	break;
       type = TYPE_TARGET_TYPE (type);
     }
@@ -966,7 +965,7 @@ typy_template_argument (PyObject *self, PyObject *args)
   TRY
     {
       type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (type))
 	type = check_typedef (TYPE_TARGET_TYPE (type));
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index f9231fb..e97a040 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -217,6 +217,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -358,8 +359,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
 	  struct value *target;
@@ -598,9 +598,8 @@ value_has_field (struct value *v, PyObject *field)
     {
       val_type = value_type (v);
       val_type = check_typedef (val_type);
-      if (TYPE_CODE (val_type) == TYPE_CODE_REF
-	  || TYPE_CODE (val_type) == TYPE_CODE_PTR)
-      val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
+      if (TYPE_REFERENCE (val_type) || TYPE_CODE (val_type) == TYPE_CODE_PTR)
+        val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
 
       type_code = TYPE_CODE (val_type);
       if ((type_code == TYPE_CODE_STRUCT || type_code == TYPE_CODE_UNION)
@@ -767,6 +766,8 @@ valpy_getitem (PyObject *self, PyObject *key)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
            res_val = value_cast (lookup_lvalue_reference_type (base_class_type), tmp);
+	  else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+           res_val = value_cast (lookup_rvalue_reference_type (base_class_type), tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
@@ -1016,7 +1017,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 0cda83d..7eb4118 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -555,6 +555,13 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
+  else if (TYPE_CODE (obj_type) == TYPE_CODE_RVALUE_REF)
+    {
+      struct type *this_ref = lookup_rvalue_reference_type (this_type);
+
+      if (!types_equal (obj_type, this_ref))
+	obj = value_cast (this_ref, obj);
+    }
   else
     {
       if (!types_equal (obj_type, this_type))
@@ -641,6 +648,14 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
+  else if (TYPE_CODE (obj_type) == TYPE_CODE_RVALUE_REF)
+    {
+      struct type *this_ref = lookup_rvalue_reference_type (this_type);
+
+      if (!types_equal (obj_type, this_ref))
+	obj = value_cast (this_ref, obj);
+    }
+
   else
     {
       if (!types_equal (obj_type, this_type))
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 0f8a3a8..85d94de 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3004,7 +3004,7 @@ s390_function_arg_integer (struct type *type)
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_BOOL
       || code == TYPE_CODE_PTR
-      || code == TYPE_CODE_REF)
+      || TYPE_REFERENCE (type))
     return 1;
 
   return ((code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index b2bba26..8a415b8 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -225,6 +225,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index a23740e..200f08d 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -67,6 +67,7 @@ sparc64_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	int len = TYPE_LENGTH (type);
 	gdb_assert (len == 8);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index c94b46e..6ec0771 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1338,6 +1338,7 @@ spu_scalar_value_p (struct type *type)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type) <= 16;
 
     default:
diff --git a/gdb/symtab.c b/gdb/symtab.c
index c42f5b6..153d603 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2145,8 +2145,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
 	  /* I'm not really sure that type of this can ever
 	     be typedefed; just be safe.  */
 	  t = check_typedef (t);
-	  if (TYPE_CODE (t) == TYPE_CODE_PTR
-	      || TYPE_CODE (t) == TYPE_CODE_REF)
+	  if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
 	    t = TYPE_TARGET_TYPE (t);
 
 	  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 377223a..5c71550 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -463,8 +463,7 @@ whatis_exp (char *exp, int show)
   get_user_print_options (&opts);
   if (opts.objectprint)
     {
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
         real_type = value_rtti_indirect_type (val, &full, &top, &using_enc);
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -581,6 +580,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_NAMESPACE:
       error (_("internal error: unhandled type in print_type_scalar"));
       break;
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 97145a1..fc6b7f4 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -239,11 +239,11 @@ binop_types_user_defined_p (enum exp_opcode op,
     return 0;
 
   type1 = check_typedef (type1);
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
   type2 = check_typedef (type2);
-  if (TYPE_CODE (type2) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
   return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
@@ -277,7 +277,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   if (op == UNOP_ADDR)
     return 0;
   type1 = check_typedef (value_type (arg1));
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
   return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
 }
diff --git a/gdb/valops.c b/gdb/valops.c
index 3a3e960..adf3636 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
     {
       struct value *v2;
 
-      if (TYPE_CODE (type2) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (type2))
 	v2 = coerce_ref (arg2);
       else
 	v2 = value_ind (arg2);
@@ -360,24 +360,20 @@ value_cast (struct type *type, struct value *arg2)
   if (value_type (arg2) == type)
     return arg2;
 
-  code1 = TYPE_CODE (check_typedef (type));
-
   /* Check if we are casting struct reference to struct reference.  */
-  if (code1 == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (check_typedef (type)))
     {
       /* We dereference type; then we recurse and finally
          we generate value of the given reference.  Nothing wrong with 
 	 that.  */
       struct type *t1 = check_typedef (type);
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
-      struct value *val =  value_cast (dereftype, arg2);
+      struct value *val = value_cast (dereftype, arg2);
 
       return value_ref (val, TYPE_CODE (t1));
     }
 
-  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
-
-  if (code2 == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (check_typedef (value_type (arg2))))
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
@@ -388,7 +384,7 @@ value_cast (struct type *type, struct value *arg2)
 
   /* You can't cast to a reference type.  See value_cast_pointers
      instead.  */
-  gdb_assert (code1 != TYPE_CODE_REF);
+  gdb_assert (!TYPE_REFERENCE (type));
 
   /* A cast to an undetermined-length array_type, such as 
      (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
@@ -591,8 +587,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
   dest_type = type;
 
   /* If we are casting to a reference type, transform
-     reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V).  */
-  if (TYPE_CODE (real_type) == TYPE_CODE_REF)
+     reinterpret_cast<T&[&]>(V) to *reinterpret_cast<T*>(&V).  */
+  if (TYPE_REFERENCE (real_type))
     {
       is_ref = 1;
       arg = value_addr (arg);
@@ -730,10 +726,10 @@ value_dynamic_cast (struct type *type, struct value *arg)
   struct type *class_type, *rtti_type;
   struct value *result, *tem, *original_arg = arg;
   CORE_ADDR addr;
-  int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
+  int is_ref = TYPE_REFERENCE (resolved_type);
 
   if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
-      && TYPE_CODE (resolved_type) != TYPE_CODE_REF)
+      && !TYPE_REFERENCE (resolved_type))
     error (_("Argument to dynamic_cast must be a pointer or reference type"));
   if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
       && TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
@@ -1461,9 +1457,9 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     {
-      /* Copy the value, but change the type from (T&) to (T*).  We
+      /* Copy the value, but change the type from (T&[&]) to (T*).  We
          keep the same location information, which is efficient, and
          allows &(&X) to get the location containing the reference.  */
       arg2 = value_copy (arg1);
@@ -1711,7 +1707,7 @@ typecmp (int staticp, int varargs, int nargs,
       tt1 = check_typedef (t1[i].type);
       tt2 = check_typedef (value_type (t2[i]));
 
-      if (TYPE_CODE (tt1) == TYPE_CODE_REF
+      if ((TYPE_REFERENCE (tt1))
 	  /* We should be doing hairy argument matching, as below.  */
 	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
 	      == TYPE_CODE (tt2)))
@@ -1729,14 +1725,12 @@ typecmp (int staticp, int varargs, int nargs,
 	 char *>, and properly access map["hello"], because the
 	 argument to [] will be a reference to a pointer to a char,
 	 and the argument will be a pointer to a char.  */
-      while (TYPE_CODE(tt1) == TYPE_CODE_REF
-	     || TYPE_CODE (tt1) == TYPE_CODE_PTR)
-	{
+      while (TYPE_REFERENCE(tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR) {
 	  tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
 	}
       while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
 	     || TYPE_CODE(tt2) == TYPE_CODE_PTR
-	     || TYPE_CODE(tt2) == TYPE_CODE_REF)
+	     || TYPE_REFERENCE(tt2))
 	{
 	  tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
 	}
@@ -2128,7 +2122,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
   /* Follow pointers until we get to a non-pointer.  */
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2217,7 +2211,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
 
   t = check_typedef (value_type (*argp));
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
@@ -2378,7 +2372,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
   t = check_typedef (value_type (*argp));
 
   /* Code snarfed from value_struct_elt.  */
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2789,7 +2783,7 @@ find_overload_match (struct value **args, int nargs,
 
       if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
 	  && (TYPE_CODE (objtype) == TYPE_CODE_PTR
-	      || TYPE_CODE (objtype) == TYPE_CODE_REF))
+	      || TYPE_REFERENCE (objtype)))
 	{
 	  temp = value_addr (temp);
 	}
@@ -3586,7 +3580,7 @@ value_rtti_indirect_type (struct value *v, int *full,
 
   type = value_type (v);
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     target = coerce_ref (v);
   else if (TYPE_CODE (type) == TYPE_CODE_PTR)
     {
@@ -3619,8 +3613,8 @@ value_rtti_indirect_type (struct value *v, int *full,
       target_type = value_type (target);
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_lvalue_reference_type (real_type);
+      if (TYPE_REFERENCE (type))
+        real_type = lookup_reference_type (real_type, TYPE_CODE (type));
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 753c2a1..7951d0c 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -276,7 +276,7 @@ int
 val_print_scalar_type_p (struct type *type)
 {
   type = check_typedef (type);
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_REFERENCE (type))
     {
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
@@ -478,7 +478,7 @@ generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
 			      original_value, options, 0, stream);
 }
 
-/* generic_val_print helper for TYPE_CODE_REF.  */
+/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */
 
 static void
 generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
@@ -849,6 +849,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
 			     original_value, options);
       break;
diff --git a/gdb/value.c b/gdb/value.c
index 91bf49e..e719ce6 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1129,8 +1129,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
     {
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
 	 fetch its rtti type.  */
-      if ((TYPE_CODE (result) == TYPE_CODE_PTR
-	  || TYPE_CODE (result) == TYPE_CODE_REF)
+      if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_REFERENCE (result))
 	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
 	     == TYPE_CODE_STRUCT)
         {
@@ -2782,7 +2781,7 @@ value_as_address (struct value *val)
      ABI-specific code is a more reasonable place to handle it.  */
 
   if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && !TYPE_REFERENCE (value_type (val))
       && gdbarch_integer_to_address_p (gdbarch))
     return gdbarch_integer_to_address (gdbarch, value_type (val),
 				       value_contents (val));
@@ -2839,6 +2838,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
          whether we want this to be true eventually.  */
       return extract_typed_address (valaddr, type);
@@ -3425,6 +3425,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3461,6 +3462,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3668,7 +3670,7 @@ coerce_ref_if_computed (const struct value *arg)
 {
   const struct lval_funcs *funcs;
 
-  if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+  if (!TYPE_REFERENCE (check_typedef (value_type (arg))))
     return NULL;
 
   if (value_lval_const (arg) != lval_computed)
@@ -3710,7 +3712,7 @@ coerce_ref (struct value *arg)
   if (retval)
     return retval;
 
-  if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+  if (!TYPE_REFERENCE (value_type_arg_tmp))
     return arg;
 
   enc_type = check_typedef (value_enclosing_type (arg));
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 0b19d84..5c6dd81 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2229,7 +2229,7 @@ varobj_get_value_type (const struct varobj *var)
 
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     type = get_target_type (type);
 
   type = check_typedef (type);
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

Parameterize lookup_reference_type() and make_reference_type() by the kind of
reference type we want to look up. Create two wrapper functions
lookup_{lvalue,rvalue}_reference_type() for lookup_reference_type() to simplify
the API. Change all callers to use the new API.

./Changelog:

2015-12-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/dwarf2read.c (read_tag_reference_type): Use
        lookup_lvalue_reference_type() instead of lookup_reference_type().
        * gdb/eval.c (evaluate_subexp_standard): Likewise.
        * gdb/f-exp.y: Likewise.
        * gdb/gdbtypes.c (make_reference_type): Generalize with rvalue
        reference types.
        (lookup_reference_type): Generalize with rvalue reference types.
        (lookup_lvalue_reference_type): New convenience wrapper for
        lookup_reference_type().
        (lookup_rvalue_reference_type): Likewise.
        * gdb/gdbtypes.h: Change interface for
        {make,lookup}_{rvalue,}_reference_type().
        * gdb/guile/scm-type.c (gdbscm_type_reference): Use
        lookup_lvalue_reference_type() instead of lookup_reference_type().
        * gdb/guile/scm-value.c (gdbscm_value_dynamic_type): Likewise.
        * gdb/parse.c (follow_types): Likewise.
        * gdb/python/py-type.c (typy_reference): Likewise.
        (typy_lookup_type): Likewise.
        * gdb/python/py-value.c (valpy_get_dynamic_type): Likewise.
        (valpy_getitem): Likewise.
        * gdb/python/py-xmethods.c (gdbpy_get_xmethod_result_type):
        Likewise.
        (gdbpy_invoke_xmethod): Likewise.
        * gdb/stabsread.c: Provide extra argument to make_reference_type()
        call.
        * gdb/valops.c (value_ref): Use lookup_lvalue_reference_type()
        instead of lookup_reference_type().
        (value_rtti_indirect_type): Likewise.
---
 gdb/dwarf2read.c         |  2 +-
 gdb/eval.c               |  2 +-
 gdb/f-exp.y              |  2 +-
 gdb/gdbtypes.c           | 45 ++++++++++++++++++++++++++++++++++-----------
 gdb/gdbtypes.h           |  8 ++++++--
 gdb/guile/scm-type.c     |  2 +-
 gdb/guile/scm-value.c    |  2 +-
 gdb/parse.c              |  2 +-
 gdb/python/py-type.c     |  4 ++--
 gdb/python/py-value.c    |  4 ++--
 gdb/python/py-xmethods.c |  4 ++--
 gdb/stabsread.c          |  2 +-
 gdb/valops.c             |  4 ++--
 13 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4881d72..5c3d42c 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14337,7 +14337,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_reference_type (target_type);
+  type = lookup_lvalue_reference_type (target_type);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
diff --git a/gdb/eval.c b/gdb/eval.c
index 84e2e34..3d408e4 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2789,7 +2789,7 @@ evaluate_subexp_standard (struct type *expect_type,
 
 	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
 		{
-		  type = lookup_reference_type (type);
+                 type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 56629dc..c57aec1 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -567,7 +567,7 @@ ptype	:	typebase
 			follow_type = lookup_pointer_type (follow_type);
 			break;
 		      case tp_reference:
-			follow_type = lookup_reference_type (follow_type);
+                       follow_type = lookup_lvalue_reference_type (follow_type);
 			break;
 		      case tp_array:
 			array_size = pop_type_int ();
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index b9850cf..49e5bf2 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -382,17 +382,23 @@ 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.  */
+   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.
+   REFCODE denotes the kind of reference type to lookup (lvalue or rvalue
+   reference). We allocate new memory if needed.  */
 
 struct type *
-make_reference_type (struct type *type, struct type **typeptr)
+make_reference_type (struct type *type, struct type **typeptr,
+                      enum type_code refcode)
 {
   struct type *ntype;	/* New type */
+  struct type **reftype;
   struct type *chain;
 
-  ntype = TYPE_REFERENCE_TYPE (type);
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
+           : TYPE_RVALUE_REFERENCE_TYPE (type));
 
   if (ntype)
     {
@@ -421,7 +427,11 @@ make_reference_type (struct type *type, struct type **typeptr)
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
-  TYPE_REFERENCE_TYPE (type) = ntype;
+  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
+             : &TYPE_RVALUE_REFERENCE_TYPE (type));
+
+  if(!*reftype)
+    *reftype = ntype;
 
   /* FIXME!  Assume the machine has only one representation for
      references, and that it matches the (only) representation for
@@ -429,10 +439,9 @@ make_reference_type (struct type *type, struct type **typeptr)
 
   TYPE_LENGTH (ntype) =
     gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
-  TYPE_CODE (ntype) = TYPE_CODE_REF;
+  TYPE_CODE (ntype) = refcode;
 
-  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
-    TYPE_REFERENCE_TYPE (type) = ntype;
+  *reftype = ntype;
 
   /* Update the length of all the other variants of this type.  */
   chain = TYPE_CHAIN (ntype);
@@ -449,9 +458,23 @@ make_reference_type (struct type *type, struct type **typeptr)
    details.  */
 
 struct type *
-lookup_reference_type (struct type *type)
+lookup_reference_type (struct type *type, enum type_code refcode)
+{
+  return make_reference_type (type, (struct type **) 0, refcode);
+}
+
+/* Separate convenience functions for lvalue and rvalue references. */
+
+struct type *
+lookup_lvalue_reference_type (struct type *type)
+{
+  return lookup_reference_type (type, TYPE_CODE_REF);
+}
+
+struct type *
+lookup_rvalue_reference_type (struct type *type)
 {
-  return make_reference_type (type, (struct type **) 0);
+  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
 }
 
 /* Lookup a function type that returns type TYPE.  TYPEPTR, if
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 2ef38ca..993cceb 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1725,9 +1725,13 @@ 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);
 
-extern struct type *lookup_reference_type (struct type *);
+extern struct type *lookup_reference_type (struct type *, enum type_code);
+extern struct type *lookup_lvalue_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_reference_type (struct type *, struct type **,
+                                         enum type_code);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 642ce15..0d4aa63 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -854,7 +854,7 @@ gdbscm_type_reference (SCM self)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 851d8a7..638876f 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -601,7 +601,7 @@ gdbscm_value_dynamic_type (SCM self)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+               type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
diff --git a/gdb/parse.c b/gdb/parse.c
index a24c52a..ef45fac 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1695,7 +1695,7 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_reference_type (follow_type);
+	follow_type = lookup_lvalue_reference_type (follow_type);
 	if (make_const)
 	  follow_type = make_cv_type (make_const, 
 				      TYPE_VOLATILE (follow_type), 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index ef4e719..676ab63 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -667,7 +667,7 @@ typy_reference (PyObject *self, PyObject *args)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -827,7 +827,7 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-	      rtype =  lookup_reference_type (type);
+             rtype = lookup_lvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 140aaf5..5d30a0f 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -376,7 +376,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+               type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -766,7 +766,7 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
-	    res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+           res_val = value_cast (lookup_lvalue_reference_type (base_class_type), tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index f927fe9..0cda83d 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -550,7 +550,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
@@ -636,7 +636,7 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index bc43566..285394f 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -1772,7 +1772,7 @@ again:
 
     case '&':			/* Reference to another type */
       type1 = read_type (pp, objfile);
-      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile));
+      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile), TYPE_CODE_REF);
       break;
 
     case 'f':			/* Function returning another type */
diff --git a/gdb/valops.c b/gdb/valops.c
index 5e5f685..1bf1d3d 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1508,7 +1508,7 @@ value_ref (struct value *arg1)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
   return arg2;
 }
 
@@ -3616,7 +3616,7 @@ value_rtti_indirect_type (struct value *v, int *full,
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
       if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_reference_type (real_type);
+        real_type = lookup_lvalue_reference_type (real_type);
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (2 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch adds the ability to inspect rvalue reference types and values using
the gdb python module. Changes include the RvalueReferenceExplorer method
providing mechanism to get a type and a referenced value for an rvalue
reference object, and the valpy_rvalue_reference_value() function used
to create an rvalue reference to an object of any type.

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/python/lib/gdb/command/explore.py: Add
        RvalueReferenceExplorer class.
        * gdb/python/lib/gdb/types.py: Implement get_basic_type() for
        rvalue reference types.
        * gdb/python/py-type.c: Add TYPE_CODE_RVALUE_REF to pyty_codes.
        * gdb/python/py-value.c (valpy_rvalue_reference_value): Add value
        getter function.
---
 gdb/python/lib/gdb/command/explore.py | 21 +++++++++++++++++++++
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 | 26 ++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
index 88f3e9a..2f6f692 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : RvalueReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,6 +319,26 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
+class RvalueReferenceExplorer(object):
+    """Internal class used to explore rvalue reference (TYPE_CODE_RVALUE_REF) values."""
+
+    @staticmethod
+    def explore_expr(expr, value, is_child):
+        """Function to explore array values.
+        See Explorer.explore_expr for more information.
+        """
+        referenced_value = value.referenced_value()
+        Explorer.explore_expr(expr, referenced_value, is_child)
+        return False
+
+    @staticmethod
+    def explore_type(name, datatype, is_child):
+        """Function to explore pointer types.
+        See Explorer.explore_type for more information.
+        """
+        target_type = datatype.target()
+        Explorer.explore_type(name, target_type, is_child)
+        return False
 
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index 5c9f5a9..f7055a7 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 2c071cc..a251d57 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index e97a040..0e049f9 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -263,6 +263,30 @@ valpy_reference_value (PyObject *self, PyObject *args)
   return result;
 }
 
+/* Return a value which is an rvalue reference to the value.  */
+
+static PyObject *
+valpy_rvalue_reference_value (PyObject *self, PyObject *args)
+{
+  PyObject *result = NULL;
+
+  TRY
+    {
+      struct value *self_val;
+      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+
+      self_val = ((value_object *) self)->value;
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_RVALUE_REF)); 
+      do_cleanups (cleanup);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  return result;
+}
 /* Return a "const" qualified version of the value.  */
 
 static PyObject *
@@ -1778,6 +1802,8 @@ reinterpret_cast operator."
     "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
   { "reference_value", valpy_reference_value, METH_NOARGS,
     "Return a value of type TYPE_CODE_REF referencing this value." },
+  { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
+    "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
   { "const_value", valpy_const_value, METH_NOARGS,
     "Return a 'const' qualied version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

Parameterize value_ref() by the kind of reference type the value of which
is requested. Change all callers to use the new API.

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/ada-lang.c (ada_evaluate_subexp): Adhere to the new
        value_ref() interface.
        * gdb/c-valprint.c (c_value_print): Likewise.
        * gdb/infcall.c (value_arg_coerce): Likewise.
        * gdb/python/py-value.c (valpy_reference_value): Likewise.
        * gdb/valops.c (value_cast): Likewise.
        (value_reinterpret_cast): Likewise.
        (value_dynamic_cast): Likewise.
        (value_ref): Parameterize by kind of return value reference type.
        (typecmp): Likewise.
        * gdb/value.h: New interface.
---
 gdb/ada-lang.c        |  2 +-
 gdb/c-valprint.c      |  9 ++++++---
 gdb/infcall.c         |  2 +-
 gdb/python/py-value.c |  2 +-
 gdb/valops.c          | 20 ++++++++++++--------
 gdb/value.h           |  2 +-
 6 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3fe7f9a..de0daa4 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10724,7 +10724,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 		     should return a ref as it should be valid to ask
 		     for its address; so rebuild a ref after coerce.  */
 		  arg1 = ada_coerce_ref (arg1);
-		  return value_ref (arg1);
+		  return value_ref (arg1, TYPE_CODE_REF);
 		}
 	    }
 
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 9c96df2..473147a 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -602,10 +602,13 @@ c_value_print (struct value *val, struct ui_file *stream,
       else if (options->objectprint
 	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
-	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+         int is_ref = TYPE_REFERENCE (type);
+         enum type_code refcode = TYPE_CODE_UNDEF;
 
-	  if (is_ref)
+	  if (is_ref) {
 	    val = value_addr (val);
+           refcode = TYPE_CODE (type);
+         }
 
 	  /* Pointer to class, check real type of object.  */
 	  fprintf_filtered (stream, "(");
@@ -625,7 +628,7 @@ c_value_print (struct value *val, struct ui_file *stream,
 
 		  if (is_ref)
 		    {
-		      val = value_ref (value_ind (val));
+		      val = value_ref (value_ind (val), refcode);
 		      type = value_type (val);
 		    }
 
diff --git a/gdb/infcall.c b/gdb/infcall.c
index efb389f..eafd812 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -169,7 +169,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
 	   if the value was not previously in memory - in some cases
 	   we should clearly be allowing this, but how?  */
 	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
-	new_value = value_ref (new_value);
+	new_value = value_ref (new_value, TYPE_CODE (type));
 	return new_value;
       }
     case TYPE_CODE_INT:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 5d30a0f..f9231fb 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -249,7 +249,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val));
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF));
 
       do_cleanups (cleanup);
     }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1bf1d3d..3a3e960 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -372,7 +372,7 @@ value_cast (struct type *type, struct value *arg2)
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
       struct value *val =  value_cast (dereftype, arg2);
 
-      return value_ref (val); 
+      return value_ref (val, TYPE_CODE (t1));
     }
 
   code2 = TYPE_CODE (check_typedef (value_type (arg2)));
@@ -622,7 +622,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
     error (_("Invalid reinterpret_cast"));
 
   if (is_ref)
-    result = value_cast (type, value_ref (value_ind (result)));
+    result = value_cast (type, value_ref (value_ind (result),
+                                          TYPE_CODE (type)));
 
   return result;
 }
@@ -816,7 +817,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
 				arg_type,
 				&result) == 1)
 	return value_cast (type,
-			   is_ref ? value_ref (result) : value_addr (result));
+			   is_ref ? value_ref (result, TYPE_CODE (resolved_type)) : value_addr (result));
     }
 
   /* The second dynamic check specified in 5.2.7.  */
@@ -828,7 +829,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
 			       value_address (tem), tem,
 			       rtti_type, &result) == 1)
     return value_cast (type,
-		       is_ref ? value_ref (result) : value_addr (result));
+		       is_ref ? value_ref (result, TYPE_CODE (resolved_type)) : value_addr (result));
 
   if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
     return value_zero (type, not_lval);
@@ -1499,16 +1500,19 @@ value_addr (struct value *arg1)
    contents.  */
 
 struct value *
-value_ref (struct value *arg1)
+value_ref (struct value *arg1, enum type_code refcode)
 {
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  if ((TYPE_CODE (type) == TYPE_CODE_REF || TYPE_CODE (type) == TYPE_CODE_RVALUE_REF)
+      && TYPE_CODE (type) == refcode)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_reference_type (type, refcode));
   return arg2;
 }
 
@@ -1715,7 +1719,7 @@ typecmp (int staticp, int varargs, int nargs,
 	  if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
 	    t2[i] = value_coerce_array (t2[i]);
 	  else
-	    t2[i] = value_ref (t2[i]);
+	    t2[i] = value_ref (t2[i], TYPE_CODE (tt1));
 	  continue;
 	}
 
diff --git a/gdb/value.h b/gdb/value.h
index eea0e59..cc0618c 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -725,7 +725,7 @@ extern struct value *value_ind (struct value *arg1);
 
 extern struct value *value_addr (struct value *arg1);
 
-extern struct value *value_ref (struct value *arg1);
+extern struct value *value_ref (struct value *arg1, enum type_code refcode);
 
 extern struct value *value_assign (struct value *toval,
 				   struct value *fromval);
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch adds tests for the initial rvalue reference support patchset.
Files to change were selected among the most important files which test
regular C++ references and the added tests are practically mirrored regular
references tests. Tested are printing of rvalue reference types and values,
rvalue reference parameters in function overloading, demangling of function
names containing rvalue reference parameters, casts to rvalue reference types,
and application of the sizeof operator to rvalue reference types and values.

All the changed files have been obviously set to compile with -std=c++11,
and in some cases this required altering function names which coincided
with keywords introduced in the new standard.

testsuite/ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb.cp/casts.cc (main): Change decltype() function name. Add
        rvalue reference type variables.
        * gdb.cp/casts.exp: Compile with -std=c++11. Add rvalue reference
        cast tests.
        * gdb.cp/cpsizeof.cc: Add rvalue reference type variables.
        * gdb.cp/cpsizeof.exp: Compile with -std=c++11. Add rvalue
        reference sizeof tests.
        * gdb.cp/demangle.exp: Add rvalue reference demangle tests.
        * gdb.cp/overload.cc (int main): Add a ctor and some methods
        with rvalue reference parameters.
        * gdb.cp/overload.exp: Compile with -std=c++11. Add rvalue
        reference overloading tests.
        * gdb.cp/ref-params.cc (int f1): New function taking rvalue
        reference parameter.
        (int f2): Likewise.
        (int mf1): Likewise.
        (int mf2): Likewise.
        * gdb.cp/ref-params.exp: Compile with -std=c++11. Add rvalue
        reference parameter printing tests.
        * gdb.cp/ref-types.cc (int main2): Add rvalue reference type
        variables.
        * gdb.cp/ref-types.exp: Compile with -std=c++11. Add rvalue
        reference type printing tests.
---
 gdb/testsuite/gdb.cp/casts.cc       |   8 +-
 gdb/testsuite/gdb.cp/casts.exp      |  34 ++++++-
 gdb/testsuite/gdb.cp/cpsizeof.cc    |   4 +
 gdb/testsuite/gdb.cp/cpsizeof.exp   |   2 +-
 gdb/testsuite/gdb.cp/demangle.exp   | 172 +++++++++++++++++++++++++++++++++++-
 gdb/testsuite/gdb.cp/overload.cc    |   9 ++
 gdb/testsuite/gdb.cp/overload.exp   |  14 ++-
 gdb/testsuite/gdb.cp/ref-params.cc  |  29 +++++-
 gdb/testsuite/gdb.cp/ref-params.exp |  20 ++++-
 gdb/testsuite/gdb.cp/ref-types.cc   |  24 +++++
 gdb/testsuite/gdb.cp/ref-types.exp  | 136 +++++++++++++++++++++++++++-
 11 files changed, 439 insertions(+), 13 deletions(-)

diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc
index 43f112f..d15fed1 100644
--- a/gdb/testsuite/gdb.cp/casts.cc
+++ b/gdb/testsuite/gdb.cp/casts.cc
@@ -1,3 +1,5 @@
+#include <utility>
+
 struct A
 {
   int a;
@@ -37,7 +39,7 @@ struct DoublyDerived : public VirtuallyDerived,
 // Confuse a simpler approach.
 
 double
-decltype(int x)
+decl_type(int x)
 {
   return x + 2.0;
 }
@@ -49,6 +51,8 @@ main (int argc, char **argv)
   B *b = (B *) a;
   A &ar = *b;
   B &br = (B&)ar;
+  A &&arr = std::move(A(42));
+  B &&brr = std::move(B(42, 1729));
 
   Derived derived;
   DoublyDerived doublyderived;
@@ -56,7 +60,7 @@ main (int argc, char **argv)
   Alpha *ad = &derived;
   Alpha *add = &doublyderived;
 
-  double y = decltype(2);
+  double y = decl_type(2);
 
   return 0;  /* breakpoint spot: casts.exp: 1 */
 }
diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp
index c202cb2..556b7c0 100644
--- a/gdb/testsuite/gdb.cp/casts.exp
+++ b/gdb/testsuite/gdb.cp/casts.exp
@@ -33,7 +33,7 @@ if [get_compiler_info "c++"] {
     return -1
 }
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -86,6 +86,18 @@ gdb_test "print (B &) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
 gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
     "let compiler cast base class reference to derived class reference"
 
+# Casting Rvalue References.
+# Check upcasting.
+gdb_test "print (A &&) br" ".* = .A &&.* {a = 42}" \
+    "cast derived class rvalue reference to base class rvalue reference"
+
+# Check downcasting.
+gdb_test "print (B &&) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "cast base class rvalue reference to derived class rvalue reference"
+
+# Check compiler casting
+gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "let compiler cast base class rvalue reference to derived class rvalue reference"
 
 # A few basic tests of "new" casts.
 
@@ -101,6 +113,9 @@ gdb_test "print static_cast<A *> (b)" " = \\(A \\*\\) $hex" \
 gdb_test "print static_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "static_cast to reference type"
 
+gdb_test "print static_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "static_cast to rvalue reference type"
+
 gdb_test "print reinterpret_cast<A *> (b)" " = \\(A \\*\\) $hex" \
     "basic test of reinterpret_cast"
 
@@ -110,13 +125,16 @@ gdb_test "print reinterpret_cast<void> (b)" "Invalid reinterpret_cast" \
 gdb_test "print reinterpret_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "reinterpret_cast to reference type"
 
+gdb_test "print reinterpret_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "reinterpret_cast to rvalue reference type"
+
 # Test that keyword shadowing works.
 
-gdb_test "whatis decltype(5)" " = double"
+gdb_test "whatis decl_type(5)" " = double"
 
 # Basic tests using typeof.
 
-foreach opname {__typeof__ __typeof __decltype} {
+foreach opname {__typeof__ __typeof decltype} {
     gdb_test "print (${opname}(a)) (b)" " = \\(A \\*\\) $hex" \
 	"old-style cast using $opname"
 
@@ -127,7 +145,7 @@ foreach opname {__typeof__ __typeof __decltype} {
 	"reinterpret_cast using $opname"
 }
 
-gdb_test "whatis __decltype(*a)" "type = A \\&"
+gdb_test "whatis decltype(*a)" "type = A \\&"
 
 # Tests of dynamic_cast.
 
@@ -153,6 +171,10 @@ gdb_test "print dynamic_cast<Alpha &> (derived)" \
     " = \\(Alpha \\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
     "dynamic_cast simple upcast to reference"
 
+gdb_test "print dynamic_cast<Alpha &&> (derived)" \
+    " = \\(Alpha \\&\\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
+    "dynamic_cast simple upcast to rvalue reference"
+
 gdb_test "print dynamic_cast<Derived *> (ad)" \
     " = \\(Derived \\*\\) ${nonzero_hex}( <vtable for Derived.*>)?" \
     "dynamic_cast simple downcast"
@@ -169,6 +191,10 @@ gdb_test "print dynamic_cast<VirtuallyDerived &> (*ad)" \
     "dynamic_cast failed" \
     "dynamic_cast to reference to non-existing base"
 
+gdb_test "print dynamic_cast<VirtuallyDerived &&> (*ad)" \
+    "dynamic_cast failed" \
+    "dynamic_cast to rvalue reference to non-existing base"
+
 gdb_test "print dynamic_cast<DoublyDerived *> (add)" \
     " = \\(DoublyDerived \\*\\) ${nonzero_hex}( <vtable for DoublyDerived.*>)?" \
     "dynamic_cast unique downcast"
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.cc b/gdb/testsuite/gdb.cp/cpsizeof.cc
index cac9397..d44d002 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.cc
+++ b/gdb/testsuite/gdb.cp/cpsizeof.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 struct Class
 {
   int a;
@@ -44,8 +46,10 @@ typedef Enum e12[12];
 #define T(N)					\
   N N ## obj;					\
   N& N ## _ref = N ## obj;			\
+  N&& N ## _rref = std::move(N ## obj);         \
   N* N ## p = &(N ## obj);			\
   N*& N ## p_ref = N ## p;			\
+  N*&& N ## p_rref = std::move(N ## p);         \
   int size_ ## N = sizeof (N ## _ref);		\
   int size_ ## N ## p = sizeof (N ## p_ref);	\
 
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.exp b/gdb/testsuite/gdb.cp/cpsizeof.exp
index 37bc440..ac0e5e1 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.exp
+++ b/gdb/testsuite/gdb.cp/cpsizeof.exp
@@ -18,7 +18,7 @@ standard_testfile .cc
 
 if {[skip_cplus_tests]} { continue }
 
-if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++}] } {
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}] } {
      return -1
 }
 
diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
index 078f4b4..8c0e1ba 100644
--- a/gdb/testsuite/gdb.cp/demangle.exp
+++ b/gdb/testsuite/gdb.cp/demangle.exp
@@ -123,20 +123,27 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: Append__15NameChooserViewPCc" \
 	"NameChooserView::Append\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadR6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)"
+    test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadO6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &&, Graphic *)"
     test_demangling_exact "gnu: AtEnd__13ivRubberGroup" "ivRubberGroup::AtEnd(void)"
     test_demangling_exact "gnu: BgFilter__9ivTSolverP12ivInteractor" "ivTSolver::BgFilter(ivInteractor *)"
     test_demangling "gnu: BitPatterntoa__FRC10BitPatternccc" \
 	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &, char, char, char\[)\]+"
+    test_demangling "gnu: BitPatterntoa__FOC10BitPatternccc" \
+	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &&, char, char, char\[)\]+"
     test_demangling_exact "gnu: Check__6UArrayi" "UArray::Check(int)"
     test_demangling_exact "gnu: CoreConstDecls__8TextCodeR7ostream" "TextCode::CoreConstDecls(ostream &)"
+    test_demangling_exact "gnu: CoreConstDecls__8TextCodeO7ostream" "TextCode::CoreConstDecls(ostream &&)"
     test_demangling_exact "gnu: Detach__8StateVarP12StateVarView" "StateVar::Detach(StateVarView *)"
     test_demangling_exact "gnu: Done__9ComponentG8Iterator" "Component::Done(Iterator)"
     test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCRC13ivTransformeriiii" \
 	"DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &, int, int, int, int\[)\]+"
+    test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCOC13ivTransformeriiii" \
+	"DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &&, int, int, int, int\[)\]+"
 
     test_demangling "gnu: Edit__12StringEditorPCcii" \
 	"StringEditor::Edit\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
     test_demangling_exact "gnu: Effect__11RelateManipR7ivEvent" "RelateManip::Effect(ivEvent &)"
+    test_demangling_exact "gnu: Effect__11RelateManipO7ivEvent" "RelateManip::Effect(ivEvent &&)"
     test_demangling "gnu: FilterName__FPCc" \
 	"FilterName\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling "gnu: Filter__6PSTextPCci" \
@@ -144,10 +151,13 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: FindColor__7CatalogPCciii" \
 	"Catalog::FindColor\[(\]+(const char|char const) \[*\]+, int, int, int\[)\]+"
     test_demangling_exact "gnu: FindFixed__FRP4CNetP4CNet" "FindFixed(CNet *&, CNet *)"
+    test_demangling_exact "gnu: FindFixed__FOP4CNetP4CNet" "FindFixed(CNet *&&, CNet *)"
     test_demangling "gnu: FindFont__7CatalogPCcN21" \
 	"Catalog::FindFont\[(\]+(const char|char const) \[*\]+, (const char|char const) \[*\]+, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: Fix48_abort__FR8twolongs" "Fix48_abort(twolongs &)"
+    test_demangling_exact "gnu: Fix48_abort__FO8twolongs" "Fix48_abort(twolongs &&)"
     test_demangling_exact "gnu: GetBarInfo__15iv2_6_VScrollerP13ivPerspectiveRiT2" "iv2_6_VScroller::GetBarInfo(ivPerspective *, int &, int &)"
+    test_demangling_exact "gnu: GetBarInfo__15iv2_6_VScrollerP13ivPerspectiveOiT2" "iv2_6_VScroller::GetBarInfo(ivPerspective *, int &&, int &&)"
     test_demangling_exact "gnu: GetBgColor__C9ivPainter" "ivPainter::GetBgColor(void) const"
 
     test_demangling "gnu: Iisdouble__FPC6IntRep" \
@@ -159,10 +169,13 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: InsertToplevel__7ivWorldP12ivInteractorT1iiUi" "ivWorld::InsertToplevel(ivInteractor *, ivInteractor *, int, int, unsigned int)"
     test_demangling "gnu: IsADirectory__FPCcR4stat" \
 	"IsADirectory\[(\]+(const char|char const) \[*\]+, stat &\[)\]+"
+    test_demangling "gnu: IsADirectory__FPCcO4stat" \
+	"IsADirectory\[(\]+(const char|char const) \[*\]+, stat &&\[)\]+"
     test_demangling_exact "gnu: IsAGroup__FP11GraphicViewP11GraphicComp" "IsAGroup(GraphicView *, GraphicComp *)"
     test_demangling_exact "gnu: IsA__10ButtonCodeUl" "ButtonCode::IsA(unsigned long)"
 
     test_demangling_exact "gnu: ReadName__FR7istreamPc" "ReadName(istream &, char *)"
+    test_demangling_exact "gnu: ReadName__FO7istreamPc" "ReadName(istream &&, char *)"
     test_demangling_exact "gnu: Redraw__13StringBrowseriiii" "StringBrowser::Redraw(int, int, int, int)"
     test_demangling_exact "gnu: Rotate__13ivTransformerf" "ivTransformer::Rotate(float)"
     test_demangling_exact "gnu: Rotated__C13ivTransformerf" "ivTransformer::Rotated(float) const"
@@ -173,10 +186,15 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: Set__5DFacePcii" "DFace::Set(char *, int, int)"
 
     test_demangling_exact "gnu: VConvert__9ivTSolverP12ivInteractorRP8TElementT2" "ivTSolver::VConvert(ivInteractor *, TElement *&, TElement *&)"
+    test_demangling_exact "gnu: VConvert__9ivTSolverP12ivInteractorOP8TElementT2" "ivTSolver::VConvert(ivInteractor *, TElement *&&, TElement *&&)"
     test_demangling_exact "gnu: VConvert__9ivTSolverP7ivTGlueRP8TElement" "ivTSolver::VConvert(ivTGlue *, TElement *&)"
+    test_demangling_exact "gnu: VConvert__9ivTSolverP7ivTGlueOP8TElement" "ivTSolver::VConvert(ivTGlue *, TElement *&&)"
     test_demangling_exact "gnu: VOrder__9ivTSolverUiRP12ivInteractorT2" "ivTSolver::VOrder(unsigned int, ivInteractor *&, ivInteractor *&)"
+    test_demangling_exact "gnu: VOrder__9ivTSolverUiOP12ivInteractorT2" "ivTSolver::VOrder(unsigned int, ivInteractor *&&, ivInteractor *&&)"
     test_demangling "gnu: Valid__7CatalogPCcRP4Tool" \
 	"Catalog::Valid\[(\]+(const char|char const) \[*\]+, Tool \[*\]+&\[)\]+"
+    test_demangling "gnu: Valid__7CatalogPCcOP4Tool" \
+	"Catalog::Valid\[(\]+(const char|char const) \[*\]+, Tool \[*\]+&&\[)\]+"
     test_demangling_exact "gnu: _10PageButton\$__both" "PageButton::__both"
     test_demangling_exact "gnu: _3RNG\$singleMantissa" "RNG::singleMantissa"
     test_demangling_exact "gnu: _5IComp\$_release" "IComp::_release"
@@ -206,16 +224,21 @@ proc test_gnu_style_demangling {} {
 	"iv2_6_MenuItem::iv2_6_MenuItem\[(\]+int, (const char|char const) \[*\]+, ivInteractor \[*\]+\[)\]+"
 
     test_demangling_exact "gnu: __20DisplayList_IteratorR11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &)"
+    test_demangling_exact "gnu: __20DisplayList_IteratorO11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &&)"
     test_demangling_exact "gnu: __3fooRT0" "foo::foo(foo &)"
+    test_demangling_exact "gnu: __3fooOT0" "foo::foo(foo &&)"
     test_demangling_exact "gnu: __3fooiN31" "foo::foo(int, int, int, int)"
     test_demangling "gnu: __3fooiPCc" \
 	"foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __3fooiRT0iT2iT2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "gnu: __3fooiOT0iT2iT2" "foo::foo(int, foo &&, int, foo &&, int, foo &&)"
     test_demangling "gnu: __6GetOptiPPcPCc" \
 	"GetOpt::GetOpt\[(\]+int, char \[*\]+\[*\]+, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __6KeyMapPT0" "KeyMap::KeyMap(KeyMap *)"
     test_demangling "gnu: __7ivWorldPCcRiPPcPC12ivOptionDescPC14ivPropertyData" \
 	"ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
+    test_demangling "gnu: __7ivWorldPCcOiPPcPC12ivOptionDescPC14ivPropertyData" \
+	"ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &&, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
     test_demangling "gnu: __7procbufPCci" \
 	"procbuf::procbuf\[(\]+(const char|char const) \[*\]+, int\[)\]+"
     test_demangling_exact "gnu: __8ArrowCmdP6EditorUiUi" "ArrowCmd::ArrowCmd(Editor *, unsigned int, unsigned int)"
@@ -265,10 +288,16 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: __ne__3fooRT0" "foo::operator!=(foo &)"
     test_demangling "gnu: __ne__FRC7ComplexT0" \
 	"operator!=\[(\]+(const Complex|Complex const) &, (const Complex|Complex const) &\[)\]+"
+    test_demangling "gnu: __ne__FOC7ComplexT0" \
+	"operator!=\[(\]+(const Complex|Complex const) &&, (const Complex|Complex const) &&\[)\]+"
     test_demangling "gnu: __ne__FRC7Complexd" \
 	"operator!=\[(\]+(const Complex|Complex const) &, double\[)\]+"
+    test_demangling "gnu: __ne__FOC7Complexd" \
+	"operator!=\[(\]+(const Complex|Complex const) &&, double\[)\]+"
     test_demangling "gnu: __ne__FRC9SubStringRC6String" \
 	"operator!=\[(\]+(const SubString|SubString const) &, (const String|String const) &\[)\]+"
+    test_demangling "gnu: __ne__FOC9SubStringOC6String" \
+	"operator!=\[(\]+(const SubString|SubString const) &&, (const String|String const) &&\[)\]+"
     test_demangling_exact "gnu: __nt__3foo" "foo::operator!(void)"
     test_demangling_exact "gnu: __nw__3fooi" "foo::operator new(int)"
     test_demangling_exact "gnu: __oo__3fooRT0" "foo::operator||(foo &)"
@@ -283,6 +312,8 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: __vc__3fooRT0" "foo::operator\\\[\\\]\\(foo &\\)"
     test_demangling "gnu: _gsub__6StringRC5RegexPCci" \
 	"String::_gsub\[(\]+(const Regex|Regex const) &, (const char|char const) \[*\]+, int\[)\]+"
+    test_demangling "gnu: _gsub__6StringOC5RegexPCci" \
+	"String::_gsub\[(\]+(const Regex|Regex const) &&, (const char|char const) \[*\]+, int\[)\]+"
     test_demangling_exact "gnu: _new_Fix__FUs" "_new_Fix(unsigned short)"
 
     # gcc 2.4.5 (and earlier) style virtual tables.  We want to continue to
@@ -295,6 +326,8 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: append__7ivGlyphPT0" "ivGlyph::append(ivGlyph *)"
     test_demangling "gnu: arg__FRC7Complex" \
 	"arg\[(\]+(const Complex|Complex const) &\[)\]+"
+    test_demangling "gnu: arg__FOC7Complex" \
+	"arg\[(\]+(const Complex|Complex const) &&\[)\]+"
     test_demangling_exact "gnu: clearok__FP7_win_sti" "clearok(_win_st *, int)"
 
     test_demangling_exact "gnu: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
@@ -305,35 +338,55 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
     test_demangling "gnu: contains__C9BitStringRC10BitPattern" \
 	"BitString::contains\[(\]+(const BitPattern|BitPattern const) &\[)\]+ const"
+    test_demangling "gnu: contains__C9BitStringOC10BitPattern" \
+	"BitString::contains\[(\]+(const BitPattern|BitPattern const) &&\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRC12BitSubStringi" \
 	"BitString::contains\[(\]+(const BitSubString|BitSubString const) &, int\[)\]+ const"
+    test_demangling "gnu: contains__C9BitStringOC12BitSubStringi" \
+	"BitString::contains\[(\]+(const BitSubString|BitSubString const) &&, int\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRT0" \
 	"BitString::contains\[(\]+(const BitString|BitString const) &\[)\]+ const"
+    test_demangling "gnu: contains__C9BitStringOT0" \
+	"BitString::contains\[(\]+(const BitString|BitString const) &&\[)\]+ const"
     test_demangling "gnu: div__FPC6IntRepT0P6IntRep" \
 	"div\[(\]+(const IntRep|IntRep const) \[*\]+, (const IntRep|IntRep const) \[*\]+, IntRep \[*\]+\[)\]+"
     test_demangling "gnu: div__FPC6IntReplP6IntRep" \
 	"div\[(\]+(const IntRep|IntRep const) \[*\]+, long, IntRep \[*\]+\[)\]+"
     test_demangling "gnu: div__FRC8RationalT0R8Rational" \
 	"div\[(\]+(const Rational|Rational const) &, (const Rational|Rational const) &, Rational &\[)\]+"
+    test_demangling "gnu: div__FOC8RationalT0O8Rational" \
+	"div\[(\]+(const Rational|Rational const) &&, (const Rational|Rational const) &&, Rational &&\[)\]+"
     test_demangling "gnu: divide__FRC7IntegerT0R7IntegerT2" \
 	"divide\[(\]+(const Integer|Integer const) &, (const Integer|Integer const) &, Integer &, Integer &\[)\]+"
+    test_demangling "gnu: divide__FOC7IntegerT0O7IntegerT2" \
+	"divide\[(\]+(const Integer|Integer const) &&, (const Integer|Integer const) &&, Integer &&, Integer &&\[)\]+"
     test_demangling "gnu: divide__FRC7IntegerlR7IntegerRl" \
 	"divide\[(\]+(const Integer|Integer const) &, long, Integer &, long &\[)\]+"
+    test_demangling "gnu: divide__FOC7IntegerlO7IntegerOl" \
+	"divide\[(\]+(const Integer|Integer const) &&, long, Integer &&, long &&\[)\]+"
     test_demangling "gnu: enable__14DocumentViewerPCcUi" \
 	"DocumentViewer::enable\[(\]+(const char|char const) \[*\]+, unsigned int\[)\]+"
 
     test_demangling_exact "gnu: foo__FiN30" "foo(int, int, int, int)"
     test_demangling_exact "gnu: foo__FiR3fooiT1iT1" "foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "gnu: foo__FiO3fooiT1iT1" "foo(int, foo &&, int, foo &&, int, foo &&)"
     test_demangling_exact "gnu: foo___3barl" "bar::foo_(long)"
     test_demangling_exact "gnu: insert__15ivClippingStacklRP8_XRegion" "ivClippingStack::insert(long, _XRegion *&)"
+    test_demangling_exact "gnu: insert__15ivClippingStacklOP8_XRegion" "ivClippingStack::insert(long, _XRegion *&&)"
     test_demangling_exact "gnu: insert__16ChooserInfo_ListlR11ChooserInfo" "ChooserInfo_List::insert(long, ChooserInfo &)"
+    test_demangling_exact "gnu: insert__16ChooserInfo_ListlO11ChooserInfo" "ChooserInfo_List::insert(long, ChooserInfo &&)"
     test_demangling_exact "gnu: insert__17FontFamilyRepListlRP15ivFontFamilyRep" "FontFamilyRepList::insert(long, ivFontFamilyRep *&)"
+    test_demangling_exact "gnu: insert__17FontFamilyRepListlOP15ivFontFamilyRep" "FontFamilyRepList::insert(long, ivFontFamilyRep *&&)"
     test_demangling_exact "gnu: leaveok__FP7_win_stc" "leaveok(_win_st *, char)"
     test_demangling_exact "gnu: left_mover__C7ivMFKitP12ivAdjustableP7ivStyle" "ivMFKit::left_mover(ivAdjustable *, ivStyle *) const"
     test_demangling "gnu: matches__C9BitStringRC10BitPatterni" \
 	"BitString::matches\[(\]+(const BitPattern|BitPattern const) &, int\[)\]+ const"
+    test_demangling "gnu: matches__C9BitStringOC10BitPatterni" \
+	"BitString::matches\[(\]+(const BitPattern|BitPattern const) &&, int\[)\]+ const"
     test_demangling "gnu: matches__C9SubStringRC5Regex" \
 	"SubString::matches\[(\]+(const Regex|Regex const) &\[)\]+ const"
+    test_demangling "gnu: matches__C9SubStringOC5Regex" \
+	"SubString::matches\[(\]+(const Regex|Regex const) &&\[)\]+ const"
 
     test_demangling_exact "gnu: overload1arg__FSc" "overload1arg(signed char)"
     test_demangling_exact "gnu: overload1arg__FUc" "overload1arg(unsigned char)"
@@ -361,12 +414,18 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: overloadargs__Fiiiiiiiiiii" "overloadargs(int, int, int, int, int, int, int, int, int, int, int)"
     test_demangling "gnu: pick__13ivCompositionP8ivCanvasRC12ivAllocationiR5ivHit" \
 	"ivComposition::pick\[(\]+ivCanvas \[*\]+, (const ivAllocation|ivAllocation const) &, int, ivHit &\[)\]+"
+    test_demangling "gnu: pick__13ivCompositionP8ivCanvasOC12ivAllocationiO5ivHit" \
+	"ivComposition::pick\[(\]+ivCanvas \[*\]+, (const ivAllocation|ivAllocation const) &&, int, ivHit &&\[)\]+"
     test_demangling "gnu: pointer__C11ivHScrollerRC7ivEventRC12ivAllocation" \
 	"ivHScroller::pointer\[(\]+(const ivEvent|ivEvent const) &, (const ivAllocation|ivAllocation const) &\[)\]+ const"
+    test_demangling "gnu: pointer__C11ivHScrollerOC7ivEventOC12ivAllocation" \
+	"ivHScroller::pointer\[(\]+(const ivEvent|ivEvent const) &&, (const ivAllocation|ivAllocation const) &&\[)\]+ const"
     test_demangling_exact "gnu: poke__8ivRasterUlUlffff" "ivRaster::poke(unsigned long, unsigned long, float, float, float, float)"
     test_demangling_exact "gnu: polar__Fdd" "polar(double, double)"
     test_demangling "gnu: read__10osStdInputRPCc" \
 	"osStdInput::read\[(\]+(const char|char const) \[*\]+&\[)\]+"
+    test_demangling "gnu: read__10osStdInputOPCc" \
+	"osStdInput::read\[(\]+(const char|char const) \[*\]+&&\[)\]+"
 
     test_demangling_exact "gnu: scale__13ivTransformerff" "ivTransformer::scale(float, float)"
     test_demangling "gnu: scanw__12CursesWindowPCce" \
@@ -379,6 +438,8 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: test__C6BitSetii" "BitSet::test(int, int) const"
     test_demangling "gnu: testbit__FRC7Integerl" \
 	"testbit\[(\]+(const Integer|Integer const) &, long\[)\]+"
+    test_demangling "gnu: testbit__FOC7Integerl" \
+	"testbit\[(\]+(const Integer|Integer const) &&, long\[)\]+"
     test_demangling_exact "gnu: text_source__8Documentl" "Document::text_source(long)"
     test_demangling_exact "gnu: variance__6Erlangd" "Erlang::variance(double)"
     test_demangling "gnu: vform__8iostreamPCcPc" \
@@ -436,27 +497,41 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)"
+    test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixOCQ2t4List1Z10VHDLEntity3Pix" \
+	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &&)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0" \
 	"List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)"
+    test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementOC10VHDLEntityPT0" \
+	"List<VHDLEntity>::element::element(VHDLEntity const &&, List<VHDLEntity>::element *)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element" \
 	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)"
+    test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementOCQ2t4List1Z10VHDLEntity7element" \
+	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const &&)"
 
     test_demangling_exact "gnu: __cl__C11VHDLLibraryGt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::operator()(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >) const"
 
     test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &) const"
+    test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityOCQ2t4List1Z10VHDLEntity3Pix" \
+	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &&) const"
 
     test_demangling_exact "gnu: __ne__FPvRCQ2t4List1Z10VHDLEntity3Pix" \
 	"operator!=(void *, List<VHDLEntity>::Pix const &)"
+    test_demangling_exact "gnu: __ne__FPvOCQ2t4List1Z10VHDLEntity3Pix" \
+	"operator!=(void *, List<VHDLEntity>::Pix const &&)"
 
     test_demangling_exact "gnu: __ne__FPvRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"operator!=(void *, PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+    test_demangling_exact "gnu: __ne__FPvOCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+	"operator!=(void *, PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &&)"
 
     test_demangling_exact "gnu: __t4List1Z10VHDLEntityRCt4List1Z10VHDLEntity" \
 	"List<VHDLEntity>::List(List<VHDLEntity> const &)"
+    test_demangling_exact "gnu: __t4List1Z10VHDLEntityOCt4List1Z10VHDLEntity" \
+	"List<VHDLEntity>::List(List<VHDLEntity> const &&)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(void)"
@@ -465,13 +540,19 @@ proc test_gnu_style_demangling {} {
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(VHDLLibraryRep *, List<VHDLEntity>::Pix)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
-	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+       "PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+    test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityOCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &&)"
 
     test_demangling_exact "gnu: nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const"
+    test_demangling_exact "gnu: nextE__C11VHDLLibraryOt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
+	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &&) const"
 
     test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityRQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::next(List<VHDLEntity>::Pix &) const"
+    test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityOQ2t4List1Z10VHDLEntity3Pix" \
+	"List<VHDLEntity>::next(List<VHDLEntity>::Pix &&) const"
 
     test_demangling_exact "gnu: _GLOBAL_\$D\$set" "global destructors keyed to set"
 
@@ -479,41 +560,67 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __as__t5ListS1ZUiRCt5ListS1ZUi" \
 	"ListS<unsigned int>::operator=(ListS<unsigned int> const &)"
+    test_demangling_exact "gnu: __as__t5ListS1ZUiOCt5ListS1ZUi" \
+	"ListS<unsigned int>::operator=(ListS<unsigned int> const &&)"
 
     test_demangling_exact "gnu: __cl__Ct5ListS1ZUiRCQ2t5ListS1ZUi3Vix" \
 	"ListS<unsigned int>::operator()(ListS<unsigned int>::Vix const &) const"
+    test_demangling_exact "gnu: __cl__Ct5ListS1ZUiOCQ2t5ListS1ZUi3Vix" \
+	"ListS<unsigned int>::operator()(ListS<unsigned int>::Vix const &&) const"
 
     test_demangling_exact "gnu: __cl__Ct5SetLS1ZUiRCQ2t5SetLS1ZUi3Vix" \
 	"SetLS<unsigned int>::operator()(SetLS<unsigned int>::Vix const &) const"
+    test_demangling_exact "gnu: __cl__Ct5SetLS1ZUiOCQ2t5SetLS1ZUi3Vix" \
+	"SetLS<unsigned int>::operator()(SetLS<unsigned int>::Vix const &&) const"
 
     test_demangling_exact "gnu: __t10ListS_link1ZUiRCUiPT0" \
 	"ListS_link<unsigned int>::ListS_link(unsigned int const &, ListS_link<unsigned int> *)"
+    test_demangling_exact "gnu: __t10ListS_link1ZUiOCUiPT0" \
+	"ListS_link<unsigned int>::ListS_link(unsigned int const &&, ListS_link<unsigned int> *)"
 
     test_demangling_exact "gnu: __t10ListS_link1ZUiRCt10ListS_link1ZUi" \
 	"ListS_link<unsigned int>::ListS_link(ListS_link<unsigned int> const &)"
+    test_demangling_exact "gnu: __t10ListS_link1ZUiOCt10ListS_link1ZUi" \
+	"ListS_link<unsigned int>::ListS_link(ListS_link<unsigned int> const &&)"
 
     test_demangling_exact "gnu: __t5ListS1ZUiRCt5ListS1ZUi" \
 	"ListS<unsigned int>::ListS(ListS<unsigned int> const &)"
+    test_demangling_exact "gnu: __t5ListS1ZUiOCt5ListS1ZUi" \
+	"ListS<unsigned int>::ListS(ListS<unsigned int> const &&)"
 
     test_demangling_exact "gnu: next__Ct5ListS1ZUiRQ2t5ListS1ZUi3Vix" \
 	"ListS<unsigned int>::next(ListS<unsigned int>::Vix &) const"
+    test_demangling_exact "gnu: next__Ct5ListS1ZUiOQ2t5ListS1ZUi3Vix" \
+	"ListS<unsigned int>::next(ListS<unsigned int>::Vix &&) const"
 
     test_demangling_exact "gnu: __ne__FPvRCQ2t5SetLS1ZUi3Vix" \
 	"operator!=(void *, SetLS<unsigned int>::Vix const &)"
+    test_demangling_exact "gnu: __ne__FPvOCQ2t5SetLS1ZUi3Vix" \
+	"operator!=(void *, SetLS<unsigned int>::Vix const &&)"
     test_demangling_exact "gnu: __t8ListElem1Z5LabelRt4List1Z5Label" \
 	"ListElem<Label>::ListElem(List<Label> &)"
+    test_demangling_exact "gnu: __t8ListElem1Z5LabelOt4List1Z5Label" \
+	"ListElem<Label>::ListElem(List<Label> &&)"
     test_demangling_exact "gnu: __t8BDDHookV1ZPcRCPc" \
 	"BDDHookV<char *>::BDDHookV(char *const &)"
+    test_demangling_exact "gnu: __t8BDDHookV1ZPcOCPc" \
+	"BDDHookV<char *>::BDDHookV(char *const &&)"
 
     test_demangling_exact "gnu: _vt\$t8BDDHookV1ZPc" "BDDHookV<char *> virtual table"
 
     test_demangling_exact "gnu: __ne__FPvRCQ211BDDFunction4VixB" \
 	"operator!=(void *, BDDFunction::VixB const &)"
+    test_demangling_exact "gnu: __ne__FPvOCQ211BDDFunction4VixB" \
+	"operator!=(void *, BDDFunction::VixB const &&)"
     test_demangling_exact "gnu: __eq__FPvRCQ211BDDFunction4VixB" \
 	"operator==(void *, BDDFunction::VixB const &)"
+    test_demangling_exact "gnu: __eq__FPvOCQ211BDDFunction4VixB" \
+	"operator==(void *, BDDFunction::VixB const &&)"
 
     test_demangling_exact "gnu: relativeId__CQ36T_phi210T_preserve8FPC_nextRCQ26T_phi210T_preserveRC10Parameters" \
 	 "T_phi2::T_preserve::FPC_next::relativeId(T_phi2::T_preserve const &, Parameters const &) const"
+    test_demangling_exact "gnu: relativeId__CQ36T_phi210T_preserve8FPC_nextOCQ26T_phi210T_preserveOC10Parameters" \
+	 "T_phi2::T_preserve::FPC_next::relativeId(T_phi2::T_preserve const &&, Parameters const &&) const"
 
     test_demangling_exact "gnu: _Utf390_1__1_9223372036854775807__9223372036854775" \
 	    "Can't demangle \"_Utf390_1__1_9223372036854775807__9223372036854775\""
@@ -535,6 +642,16 @@ proc test_gnu_style_demangling {} {
 	    pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
 	}
     }
+
+    gdb_test_multiple "demangle __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlOPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingOPQ29CosNaming15BindingIterator" "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlOPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingOPQ29CosNaming15BindingIterator" {
+	-re "virtual function thunk \\(delta:-64\\) for CosNaming::_proxy_NamingContext::_0RL__list\\(unsigned long, _CORBA_Unbounded_Sequence<CosNaming::Binding> \\*\\&\\&, CosNaming::BindingIterator \\*\\&\\&\\)\r\n$gdb_prompt $" {
+	    pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlOPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingOPQ29CosNaming15BindingIterator"
+	}
+	-re ".*Can't demangle \"__thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlOPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingOPQ29CosNaming15BindingIterator\"\r\n$gdb_prompt $" {
+	    pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlOPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingOPQ29CosNaming15BindingIterator"
+	}
+    }
+
 }
 
 #
@@ -570,12 +687,15 @@ proc test_lucid_style_demangling {} {
     test_demangling_exact "lucid: __ct__10ostrstreamFPciT2" "ostrstream::ostrstream(char *, int, int)"
     test_demangling_exact "lucid: __ct__10ostrstreamFv" "ostrstream::ostrstream(void)"
     test_demangling_exact "lucid: __ct__10smanip_intFPFR3iosi_R3iosi" "smanip_int::smanip_int(ios &(*)(ios &, int), int)"
+    test_demangling_exact "lucid: __ct__10smanip_intFPFO3iosi_O3iosi" "smanip_int::smanip_int(ios &&(*)(ios &&, int), int)"
     test_demangling "lucid: __ct__11c_exceptionFPcRC7complexT2" "c_exception::c_exception\[(\]+char \[*\]+, (const complex|complex const) &, (const complex|complex const) &\[)\]+"
+    test_demangling "lucid: __ct__11c_exceptionFPcOC7complexT2" "c_exception::c_exception\[(\]+char \[*\]+, (const complex|complex const) &&, (const complex|complex const) &&\[)\]+"
     test_demangling "lucid: __ct__11fstreambaseFPCciT2" "fstreambase::fstreambase\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
     test_demangling_exact "lucid: __ct__11fstreambaseFi" "fstreambase::fstreambase(int)"
     test_demangling_exact "lucid: __ct__11fstreambaseFiPcT1" "fstreambase::fstreambase(int, char *, int)"
     test_demangling_exact "lucid: __ct__11fstreambaseFv" "fstreambase::fstreambase(void)"
     test_demangling_exact "lucid: __ct__11smanip_longFPFR3iosl_R3iosl" "smanip_long::smanip_long(ios &(*)(ios &, long), long)"
+    test_demangling_exact "lucid: __ct__11smanip_longFPFO3iosl_O3iosl" "smanip_long::smanip_long(ios &&(*)(ios &&, long), long)"
     test_demangling_exact "lucid: __ct__11stdiostreamFP4FILE" "stdiostream::stdiostream(FILE *)"
     test_demangling_exact "lucid: __ct__12strstreambufFPFl_PvPFPv_v" "strstreambuf::strstreambuf(void *(*)(long), void (*)(void *))"
     test_demangling_exact "lucid: __ct__12strstreambufFPUciT1" "strstreambuf::strstreambuf(unsigned char *, int, unsigned char *)"
@@ -584,12 +704,14 @@ proc test_lucid_style_demangling {} {
     test_demangling_exact "lucid: __ct__12strstreambufFv" "strstreambuf::strstreambuf(void)"
     test_demangling_exact "lucid: __ct__13strstreambaseFPciT1" "strstreambase::strstreambase(char *, int, char *)"
     test_demangling_exact "lucid: __ct__3fooFR3foo" "foo::foo(foo &)"
+    test_demangling_exact "lucid: __ct__3fooFO3foo" "foo::foo(foo &&)"
 
     test_demangling_exact "lucid: __ct__3fooFi" "foo::foo(int)"
     test_demangling_exact "lucid: __ct__3fooFiN31" "foo::foo(int, int, int, int)"
     test_demangling "lucid: __ct__3fooFiPCc" \
 	"foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "lucid: __ct__3fooFiR3fooT1T2T1T2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "lucid: __ct__3fooFiO3fooT1T2T1T2" "foo::foo(int, foo &&, int, foo &&, int, foo &&)"
     test_demangling_exact "lucid: __ct__3iosFP9streambuf" "ios::ios(streambuf *)"
     test_demangling_exact "lucid: __ct__7filebufFiPcT1" "filebuf::filebuf(int, char *, int)"
     test_demangling "lucid: __ct__7fstreamFPCciT2" \
@@ -692,6 +814,7 @@ proc test_lucid_style_demangling {} {
     test_demangling_exact "lucid: bitalloc__3iosSFv" "ios::bitalloc(void) static"
     test_demangling_exact "lucid: chr__FiT1" "chr(int, int)"
     test_demangling_exact "lucid: complex_error__FR11c_exception" "complex_error(c_exception &)"
+    test_demangling_exact "lucid: complex_error__FO11c_exception" "complex_error(c_exception &&)"
     test_demangling_exact "lucid: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
     test_demangling_exact "lucid: complexfunc3__FPFPFPl_s_i" "complexfunc3(int (*)(short (*)(long *)))"
 
@@ -703,6 +826,7 @@ proc test_lucid_style_demangling {} {
     test_demangling_exact "lucid: conv10__FlPc" "conv10(long, char *)"
     test_demangling_exact "lucid: conv16__FUlPc" "conv16(unsigned long, char *)"
     test_demangling_exact "lucid: dec__FR3ios" "dec(ios &)"
+    test_demangling_exact "lucid: dec__FO3ios" "dec(ios &&)"
     test_demangling_exact "lucid: dec__Fli" "dec(long, int)"
     test_demangling_exact "lucid: dofield__FP7ostreamPciT2T3" "dofield(ostream *, char *, int, char *, int)"
 
@@ -710,12 +834,16 @@ proc test_lucid_style_demangling {} {
     test_demangling_exact "lucid: flags__3iosFv" "ios::flags(void)"
     test_demangling_exact "lucid: foo__FiN31" "foo(int, int, int, int)"
     test_demangling_exact "lucid: foo__FiR3fooT1T2T1T2" "foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "lucid: foo__FiO3fooT1T2T1T2" "foo(int, foo &&, int, foo &&, int, foo &&)"
     test_demangling_exact "lucid: foo___3barFl" "bar::foo_(long)"
     test_demangling "lucid: form__FPCce" "form\[(\]+(const char|char const) \[*\]+,...\[)\]+"
     test_demangling_exact "lucid: get__7istreamFPcic" "istream::get(char *, int, char)"
     test_demangling_exact "lucid: get__7istreamFR9streambufc" "istream::get(streambuf &, char)"
+    test_demangling_exact "lucid: get__7istreamFO9streambufc" "istream::get(streambuf &&, char)"
     test_demangling_exact "lucid: get_complicated__7istreamFRUc" "istream::get_complicated(unsigned char &)"
+    test_demangling_exact "lucid: get_complicated__7istreamFOUc" "istream::get_complicated(unsigned char &&)"
     test_demangling_exact "lucid: get_complicated__7istreamFRc" "istream::get_complicated(char &)"
+    test_demangling_exact "lucid: get_complicated__7istreamFOc" "istream::get_complicated(char &&)"
     test_demangling_exact "lucid: getline__7istreamFPUcic" "istream::getline(unsigned char *, int, char)"
     test_demangling_exact "lucid: getline__7istreamFPcic" "istream::getline(char *, int, char)"
 
@@ -764,9 +892,13 @@ proc test_lucid_style_demangling {} {
 
     test_demangling_exact "lucid: read__7istreamFPci" "istream::read(char *, int)"
     test_demangling_exact "lucid: resetiosflags__FR3iosl" "resetiosflags(ios &, long)"
+    test_demangling_exact "lucid: resetiosflags__FO3iosl" "resetiosflags(ios &&, long)"
     test_demangling_exact "lucid: restore_errno__FRi" "restore_errno(int &)"
+    test_demangling_exact "lucid: restore_errno__FOi" "restore_errno(int &&)"
     test_demangling_exact "lucid: rs_complicated__7istreamFRUc" "istream::rs_complicated(unsigned char &)"
+    test_demangling_exact "lucid: rs_complicated__7istreamFOUc" "istream::rs_complicated(unsigned char &&)"
     test_demangling_exact "lucid: rs_complicated__7istreamFRc" "istream::rs_complicated(char &)"
+    test_demangling_exact "lucid: rs_complicated__7istreamFOc" "istream::rs_complicated(char &&)"
     test_demangling_exact "lucid: seekg__7istreamFl8seek_dir" "istream::seekg(long, seek_dir)"
     test_demangling_exact "lucid: seekoff__12strstreambufFl8seek_diri" "strstreambuf::seekoff(long, seek_dir, int)"
     test_demangling_exact "lucid: seekoff__9streambufFlQ2_3ios12ios_seek_diri" "streambuf::seekoff(long, ios::ios_seek_dir, int)"
@@ -775,11 +907,13 @@ proc test_lucid_style_demangling {} {
     test_demangling_exact "lucid: setb__9streambufFPcT1i" "streambuf::setb(char *, char *, int)"
 
     test_demangling_exact "lucid: setb__FR3iosi" "setb(ios &, int)"
+    test_demangling_exact "lucid: setb__FO3iosi" "setb(ios &&, int)"
     test_demangling_exact "lucid: setbuf__11fstreambaseFPci" "fstreambase::setbuf(char *, int)"
     test_demangling_exact "lucid: setbuf__9streambufFPUci" "streambuf::setbuf(unsigned char *, int)"
     test_demangling_exact "lucid: setbuf__9streambufFPciT2" "streambuf::setbuf(char *, int, int)"
     test_demangling_exact "lucid: setf__3iosFlT1" "ios::setf(long, long)"
     test_demangling_exact "lucid: setfill__FR3iosi" "setfill(ios &, int)"
+    test_demangling_exact "lucid: setfill__FO3iosi" "setfill(ios &&, int)"
     test_demangling_exact "lucid: setg__9streambufFPcN21" "streambuf::setg(char *, char *, char *)"
     test_demangling_exact "lucid: setp__9streambufFPcT1" "streambuf::setp(char *, char *)"
 
@@ -835,34 +969,54 @@ proc test_arm_style_demangling {} {
 	"g\[(\]+T, long \[*\]+, (const long|long const) \[*\]+, long \[*\]+\[)\]+"
     test_demangling "arm: g__F1RRlRClT2" \
 	"g\[(\]+R, long &, (const long|long const) &, long &\[)\]+"
+    test_demangling "arm: g__F1ROlOClT2" \
+	"g\[(\]+R, long &&, (const long|long const) &&, long &&\[)\]+"
     test_demangling "arm: g__F1TPiPCiT2" \
 	"g\[(\]+T, int \[*\]+, (const int|int const) \[*\]+, int \[*\]+\[)\]+"
     test_demangling "arm: g__F1RRiRCiT2" \
 	"g\[(\]+R, int &, (const int|int const) &, int &\[)\]+"
+    test_demangling "arm: g__F1ROiOCiT2" \
+	"g\[(\]+R, int &&, (const int|int const) &&, int &&\[)\]+"
     test_demangling "arm: g__F1TPsPCsT2" \
 	"g\[(\]+T, short \[*\]+, (const short|short const) \[*\]+, short \[*\]+\[)\]+"
     test_demangling "arm: g__F1RRsRCsT2" \
 	"g\[(\]+R, short &, (const short|short const) &, short &\[)\]+"
+    test_demangling "arm: g__F1ROsOCsT2" \
+	"g\[(\]+R, short &&, (const short|short const) &&, short &&\[)\]+"
     test_demangling "arm: g__F1TPcPCcT2" \
 	"g\[(\]+T, char \[*\]+, (const char|char const) \[*\]+, char \[*\]+\[)\]+"
     test_demangling "arm: g__F1RRcRCcT2" \
 	"g\[(\]+R, char &, (const char|char const) &, char &\[)\]+"
+    test_demangling "arm: g__F1ROcOCcT2" \
+	"g\[(\]+R, char &&, (const char|char const) &&, char &&\[)\]+"
 
     test_demangling_exact "arm: __ct__21T5__pt__11_PFiPPdPv_iFi" "T5<int (*)(int, double **, void *)>::T5(int)"
 
     test_demangling "arm: __gt__FRC2T2c" \
 	"operator>\[(\]+(const T2|T2 const) &, char\[)\]+"
+    test_demangling "arm: __gt__FOC2T2c" \
+	"operator>\[(\]+(const T2|T2 const) &&, char\[)\]+"
     test_demangling "arm: __ge__FRC2T2c" \
 	"operator>=\[(\]+(const T2|T2 const) &, char\[)\]+"
+    test_demangling "arm: __ge__FOC2T2c" \
+	"operator>=\[(\]+(const T2|T2 const) &&, char\[)\]+"
     test_demangling "arm: __lt__FRC2T2c" \
 	"operator<\[(\]+(const T2|T2 const) &, char\[)\]+"
+    test_demangling "arm: __lt__FOC2T2c" \
+	"operator<\[(\]+(const T2|T2 const) &&, char\[)\]+"
 
     test_demangling "arm: __le__FRC2T2c" \
 	"operator<=\[(\]+(const T2|T2 const) &, char\[)\]+"
+    test_demangling "arm: __le__FOC2T2c" \
+	"operator<=\[(\]+(const T2|T2 const) &&, char\[)\]+"
     test_demangling "arm: __ne__FRC2T2c" \
 	"operator!=\[(\]+(const T2|T2 const) &, char\[)\]+"
+    test_demangling "arm: __ne__FOC2T2c" \
+	"operator!=\[(\]+(const T2|T2 const) &&, char\[)\]+"
     test_demangling "arm: __eq__FRC2T2c" \
 	"operator==\[(\]+(const T2|T2 const) &, char\[)\]+"
+    test_demangling "arm: __eq__FOC2T2c" \
+	"operator==\[(\]+(const T2|T2 const) &&, char\[)\]+"
     test_demangling_exact "arm: __amd__FR2T2i" "operator%=(T2 &, int)"
     test_demangling_exact "arm: __adv__FR2T2i" "operator/=(T2 &, int)"
     test_demangling_exact "arm: __amu__FR2T2i" "operator*=(T2 &, int)"
@@ -1127,6 +1281,8 @@ proc test_arm_style_demangling {} {
 
     test_demangling_exact "arm: __ct__25DListNode__pt__9_R6RLabelFR6RLabelP25DListNode__pt__9_R6RLabelT2" \
 	"DListNode<RLabel &>::DListNode(RLabel &, DListNode<RLabel &> *, DListNode<RLabel &> *)"
+    test_demangling_exact "arm: __ct__25DListNode__pt__9_O6RLabelFO6RLabelP25DListNode__pt__9_O6RLabelT2" \
+	"DListNode<RLabel &&>::DListNode(RLabel &&, DListNode<RLabel &&> *, DListNode<RLabel &&> *)"
 
     test_demangling_exact "arm: bar__3fooFiT16FooBar" "foo::bar(int, int, FooBar)"
 
@@ -1157,18 +1313,26 @@ proc test_hp_style_demangling {} {
 	"g\[(\]+T, long \[*\]+, (const long|long const) \[*\]+, long \[*\]+\[)\]+"
     test_demangling "hp: g__F1RRlRClT2" \
 	"g\[(\]+R, long &, (const long|long const) &, long &\[)\]+"
+    test_demangling "hp: g__F1ROlOClT2" \
+	"g\[(\]+R, long &&, (const long|long const) &&, long &&\[)\]+"
     test_demangling "hp: g__F1TPiPCiT2" \
 	"g\[(\]+T, int \[*\]+, (const int|int const) \[*\]+, int \[*\]+\[)\]+"
     test_demangling "hp: g__F1RRiRCiT2" \
 	"g\[(\]+R, int &, (const int|int const) &, int &\[)\]+"
+    test_demangling "hp: g__F1ROiOCiT2" \
+	"g\[(\]+R, int &&, (const int|int const) &&, int &&\[)\]+"
     test_demangling "hp: g__F1TPsPCsT2" \
 	"g\[(\]+T, short \[*\]+, (const short|short const) \[*\]+, short \[*\]+\[)\]+"
     test_demangling "hp: g__F1RRsRCsT2" \
 	"g\[(\]+R, short &, (const short|short const) &, short &\[)\]+"
+    test_demangling "hp: g__F1ROsOCsT2" \
+	"g\[(\]+R, short &&, (const short|short const) &&, short &&\[)\]+"
     test_demangling "hp: g__F1TPcPCcT2" \
 	"g\[(\]+T, char \[*\]+, (const char|char const) \[*\]+, char \[*\]+\[)\]+"
     test_demangling "hp: g__F1RRcRCcT2" \
 	"g\[(\]+R, char &, (const char|char const) &, char &\[)\]+"
+    test_demangling "hp: g__F1ROcOCcT2" \
+	"g\[(\]+R, char &&, (const char|char const) &&, char &&\[)\]+"
 
     test_demangling "hp: __gt__FRC2T2c" \
 	"operator>\[(\]+(const T2|T2 const) &, char\[)\]+"
@@ -1476,6 +1640,8 @@ proc test_hp_style_demangling {} {
 
     test_demangling_exact "hp: __ct__9DListNodeXTR6RLabel__FR6RLabelP9DListNodeXTR6RLabel_T2" \
 	"DListNode<RLabel &>::DListNode(RLabel &, DListNode<RLabel &> *, DListNode<RLabel &> *)"
+    test_demangling_exact "hp: __ct__9DListNodeXTO6RLabel__FO6RLabelP9DListNodeXTO6RLabel_T2" \
+	"DListNode<RLabel &&>::DListNode(RLabel &&, DListNode<RLabel &&> *, DListNode<RLabel &&> *)"
 
 
     # Absolute integer constants in template args
@@ -1486,8 +1652,12 @@ proc test_hp_style_demangling {} {
     test_demangling_exact "hp: elem__6vectorXTiSN67__Fi" "vector<int,-67>::elem(int)"
     test_demangling_exact "hp: elem__6vectorXTiSM__SCFPPd" "vector<int,-2147483648>::elem(double **) static const"
     test_demangling_exact "hp: elem__6vectorXTiSN67UP4000TRs__Fi" "vector<int,-67,4000U,short &>::elem(int)"
+    test_demangling_exact "hp: elem__6vectorXTiSN67UP4000TOs__Fi" "vector<int,-67,4000U,short &&>::elem(int)"
     test_demangling_exact "hp: elem__6vectorXTiSN67TRdTFPv_i__Fi" "vector<int,-67,double &,int (void *)>::elem(int)"
+    test_demangling_exact "hp: elem__6vectorXTiSN67TOdTFPv_i__Fi" "vector<int,-67,double &&,int (void *)>::elem(int)"
     test_demangling_exact "hp: X__6vectorXTiSN67TdTPvUP5TRs" "vector<int,-67,double,void *,5U,short &>::X"
+    test_demangling_exact "hp: X__6vectorXTiSN67TdTPvUP5TOs" "vector<int,-67,double,void *,5U,short &&>::X"
+
 
     # Named constants in template args
 
diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
index 5c782a4..a977c43 100644
--- a/gdb/testsuite/gdb.cp/overload.cc
+++ b/gdb/testsuite/gdb.cp/overload.cc
@@ -1,10 +1,12 @@
 #include <stddef.h>
+#include <utility>
 
 class foo {
 public:
   foo  (int);
   foo  (int, const char *);
   foo  (foo&);
+  foo  (foo&&);
   ~foo ();
   void foofunc (int);
   void foofunc (int, signed char *);
@@ -27,6 +29,9 @@ int overload1arg (double);
 int overload1arg (int*);
 int overload1arg (void*);
 
+int overload1arg (foo &);
+int overload1arg (foo &&);
+
 int overloadfnarg (void);
 int overloadfnarg (int);
 int overloadfnarg (int, int (*) (int));
@@ -114,6 +119,7 @@ int main ()
     double arg12 = 200.0;
     int arg13 = 200;
     char arg14 = 'a';
+    foo arg15(5);
 
     A a;
     B b;
@@ -153,6 +159,7 @@ int main ()
 foo::foo  (int i)                  { ifoo = i; ccpfoo = NULL; }
 foo::foo  (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
 foo::foo  (foo& afoo)              { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::foo  (foo&& afoo)             { ifoo = std::move(afoo.ifoo); ccpfoo = std::move (afoo.ccpfoo); }
 foo::~foo ()                       {}
 
 
@@ -172,6 +179,8 @@ int foo::overload1arg (float arg)           { arg = 0; return 11;}
 int foo::overload1arg (double arg)          { arg = 0; return 12;}
 int foo::overload1arg (int* arg)            { arg = 0; return 13;}
 int foo::overload1arg (void* arg)           { arg = 0; return 14;}
+int foo::overload1arg (foo &arg)            { return 15; }
+int foo::overload1arg (foo &&arg)           { return 16; }
 
 /* Test to see that we can explicitly request overloaded functions
    with function pointers in the prototype. */
diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
index bac6375..8fcfcca 100644
--- a/gdb/testsuite/gdb.cp/overload.exp
+++ b/gdb/testsuite/gdb.cp/overload.exp
@@ -28,7 +28,7 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -53,7 +53,7 @@ gdb_test "up" ".*main.*" "up from marker1"
 set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
 set re_fields	"int ifoo;${ws}const char ?\\* ?ccpfoo;"
 set XX_fields  	"int ifoo;${ws}char ?\\* ?ccpfoo;"
-set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);"
+set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);${ws}foo\\(foo ?&?&\\);"
 set re_dtor	"~foo\\((void|)\\);"
 set XX_dtor	"~foo\\(int\\);"
 set re_methods	                  "void foofunc\\(int\\);"
@@ -72,6 +72,8 @@ set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int \\*\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(void \\*\\);"
+set re_methods  "${re_methods}${ws}int overload1arg\\(foo &\\);"
+set re_methods  "${re_methods}${ws}int overload1arg\\(foo &&\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int, int ?\\(\\*\\) ?\\(int\\)\\);"
@@ -259,6 +261,14 @@ gdb_test "print foo_instance1.overload1arg(&arg14)" \
     "\\$\[0-9\]+ = 14" \
     "print call overloaded func char\\* arg"
 
+gdb_test "print foo_instance1.overload1arg(arg15)" \
+    "\\$\[0-9\]+ = 15" \
+    "print call overloaded func foo & arg"
+
+gdb_test "print foo_instance1.overload1arg(static_cast<foo&&>(arg15))" \
+    "\\$\[0-9\]+ = 16" \
+    "print call overloaded func foo && arg"
+
 gdb_test "print bar(a)" "= 11"
 gdb_test "print bar(b)" "= 22"
 gdb_test "print bar(c)" "= 22"
diff --git a/gdb/testsuite/gdb.cp/ref-params.cc b/gdb/testsuite/gdb.cp/ref-params.cc
index 12a5bb3..d0ef56b 100644
--- a/gdb/testsuite/gdb.cp/ref-params.cc
+++ b/gdb/testsuite/gdb.cp/ref-params.cc
@@ -17,6 +17,8 @@
 
 /* Author: Paul N. Hilfinger, AdaCore Inc. */
 
+#include <utility>
+
 struct Parent {
   Parent (int id0) : id(id0) { }
   int id;
@@ -28,7 +30,12 @@ struct Child : public Parent {
 
 int f1(Parent& R)
 {
-  return R.id;			/* Set breakpoint marker3 here.  */
+  return R.id;			/* Set breakpoint marker4 here.  */
+}
+
+int f1(Parent&& R)
+{
+  return R.id;			/* Set breakpoint marker5 here.  */
 }
 
 int f2(Child& C)
@@ -36,6 +43,11 @@ int f2(Child& C)
   return f1(C);			/* Set breakpoint marker2 here.  */
 }
 
+int f2(Child&& C)
+{
+  return f1(std::move(C));                 /* Set breakpoint marker3 here.  */
+}
+
 struct OtherParent {
   OtherParent (int other_id0) : other_id(other_id0) { }
   int other_id;
@@ -50,11 +62,21 @@ int mf1(OtherParent& R)
   return R.other_id;
 }
 
+int mf1(OtherParent&& R)
+{
+  return R.other_id;
+}
+
 int mf2(MultiChild& C)
 {
   return mf1(C);
 }
 
+int mf2(MultiChild&& C)
+{
+  return mf1(C);
+}
+
 int main(void) 
 {
   Child Q(42);
@@ -62,8 +84,13 @@ int main(void)
 
   /* Set breakpoint marker1 here.  */
 
+  f1(Q);
+  f1(QR);
+  f1(Child(42));
+
   f2(Q);
   f2(QR);
+  f2(Child(42));
 
   MultiChild MQ(53);
   MultiChild& MQR = MQ;
diff --git a/gdb/testsuite/gdb.cp/ref-params.exp b/gdb/testsuite/gdb.cp/ref-params.exp
index 7878907..b1feac4 100644
--- a/gdb/testsuite/gdb.cp/ref-params.exp
+++ b/gdb/testsuite/gdb.cp/ref-params.exp
@@ -24,7 +24,7 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[build_executable $testfile.exp $testfile $srcfile {debug c++}] == 1} {
+if {[build_executable $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}] == 1} {
     return -1
 }
 
@@ -48,15 +48,28 @@ gdb_start_again "marker1 here"
 gdb_test "print f1(QR)" ".* = 42.*" "print value of f1 on (Child&) in main"
 
 gdb_start_again "marker1 here"
+gdb_test "print f1(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f1 on (Child&&) in main"
+
+gdb_start_again "marker1 here"
 gdb_test "print f2(QR)" ".* = 42.*" "print value of f2 on (Child&) in main"
 
+gdb_start_again "marker1 here"
+gdb_test "print f2(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f2 on (Child&&) in main"
+
 gdb_start_again "marker2 here"
 gdb_test "print C" ".*id = 42.*" "print value of Child& in f2"
 gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child& in f2"
 
 gdb_start_again "marker3 here"
+gdb_test "print C" ".*id = 42.*" "print value of Child&& in f2"
+gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child&& in f2"
+
+gdb_start_again "marker4 here"
 gdb_test "print R" ".*id = 42.*" "print value of Parent& in f1"
 
+gdb_start_again "marker5 here"
+gdb_test "print R" ".*id = 42.*" "print value of Parent&& in f1"
+
 gdb_start_again "breakpoint MQ here"
 gdb_test "print f1(MQ)" ".* = 53"
 gdb_test "print mf1(MQ)" ".* = 106"
@@ -64,3 +77,8 @@ gdb_test "print mf2(MQ)" ".* = 106"
 gdb_test "print f1(MQR)" ".* = 53"
 gdb_test "print mf1(MQR)" ".* = 106"
 gdb_test "print mf2(MQR)" ".* = 106"
+gdb_test "print f1(static_cast<MultiChild&&>(MQ))" ".* = 53"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf1(static_cast<MultiChild&&>(MQ))" ".* = 106"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf2(static_cast<MultiChild&&>(MQ))" ".* = 106"
diff --git a/gdb/testsuite/gdb.cp/ref-types.cc b/gdb/testsuite/gdb.cp/ref-types.cc
index eb39370..3d5984d 100644
--- a/gdb/testsuite/gdb.cp/ref-types.cc
+++ b/gdb/testsuite/gdb.cp/ref-types.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 int main2(void);
 
 void marker1 (void)
@@ -39,6 +41,18 @@ int main(void)
     as[2] = 2;
     as[3] = 3;
 
+    short t = -1;
+    short *pt;
+    short &&rrt = std::move(t);
+    pt = &rrt;
+    short *&&rrpt = std::move(pt);
+    short at[4];
+    at[0] = 0;
+    at[1] = 1;
+    at[2] = 2;
+    at[3] = 3;
+    short (&&rrat)[4] = std::move(at);
+
     marker1();
 
     main2();
@@ -66,15 +80,25 @@ int main2(void)
     float F;
     double D;
     char &rC = C;
+    char &&rrC = 'A';
     unsigned char &rUC = UC;
+    unsigned char &&rrUC = 21;
     short &rS = S;
+    short &&rrS = -14;
     unsigned short &rUS = US;
+    unsigned short &&rrUS = 7;
     int &rI = I;
+    int &&rrI = 102;
     unsigned int &rUI = UI;
+    unsigned int &&rrUI = 1002;
     long &rL = L;
+    long &&rrL = -234;
     unsigned long &rUL = UL;
+    unsigned long &&rrUL = 234;
     float &rF = F;
+    float &&rrF = 1.25E10;
     double &rD = D;
+    double &&rrD = -1.375E-123;
     C = 'A';
     UC = 21;
     S = -14;
diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp
index 61827ab..1cb25ef 100644
--- a/gdb/testsuite/gdb.cp/ref-types.exp
+++ b/gdb/testsuite/gdb.cp/ref-types.exp
@@ -24,7 +24,7 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -127,6 +127,47 @@ gdb_test "print ras\[1\]" ".\[0-9\]* = 1" "print value of ras\[1\]"
 gdb_test "print ras\[2\]" ".\[0-9\]* = 2" "print value of ras\[2\]"
 gdb_test "print ras\[3\]" ".\[0-9\]* = 3" "print value of ras\[3\]"
 
+# rvalue reference tests
+
+gdb_test_multiple "print rrt" "print value of rrt" {
+    -re ".\[0-9\]* = \\(short &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    -re ".\[0-9\]* = \\(short int &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
+}
+
+gdb_test_multiple "ptype rrt" "ptype rrt" {
+    -re "type = short &&.*$gdb_prompt $"  { pass "ptype rrt" }
+    -re "type = short int &&.*$gdb_prompt $"  { pass "ptype rrt" }
+}
+
+gdb_test "print *rrpt" ".\[0-9\]* = -1" "print value of *rrpt"
+
+# gdb had a bug about dereferencing a pointer type
+# that would lead to wrong results
+# if we try to examine memory at pointer value.
+
+gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
+
+gdb_test_multiple "ptype rrpt" "ptype rrpt" {
+    -re "type = short \\*&&.*$gdb_prompt $"  { pass "ptype rrpt" }
+    -re "type = short int \\*&&.*$gdb_prompt $"  { pass "ptype rrpt" }
+}
+
+gdb_test "print rrat\[0\]" ".\[0-9\]* = 0" "print value of rrat\[0\]"
+
+gdb_test_multiple "ptype rrat" "ptype rrat" {
+    -re "type = short \\\(&&\\\)\\\[4\\\].*$gdb_prompt $"  { pass "ptype rrat" }
+    -re "type = short int \\\(&&\\\)\\\[4\\\].*$gdb_prompt $"  { pass "ptype rrat" }
+}
+
+gdb_test "print rrat\[1\]" ".\[0-9\]* = 1" "print value of rrat\[1\]"
+gdb_test "print rrat\[2\]" ".\[0-9\]* = 2" "print value of rrat\[2\]"
+gdb_test "print rrat\[3\]" ".\[0-9\]* = 3" "print value of rrat\[3\]"
+
 
 if ![runto 'f'] then {
     perror "couldn't run to f"
@@ -270,3 +311,96 @@ gdb_test "print rD" \
     ".\[0-9\]* = \\(double &\\) @$hex: -1.375e-123.*" \
     "print value of rD"
 
+#
+# test rvalue reference types
+#
+
+gdb_test "ptype rrC" "type = char &&"
+
+gdb_test "ptype rrUC" "type = unsigned char &&"
+
+gdb_test_multiple "ptype rrS" "ptype rrS" {
+    -re "type = short &&.*$gdb_prompt $"  { pass "ptype rrS" }
+    -re "type = short int &&.*$gdb_prompt $"  { pass "ptype rrS" }
+}
+
+gdb_test_multiple "ptype rrUS" "ptype rrUS" {
+    -re "type = unsigned short &&.*$gdb_prompt $"  { pass "ptype rrUS" }
+    -re "type = short unsigned int &&.*$gdb_prompt $"  { pass "ptype rrUS" }
+}
+
+gdb_test "ptype rrI" "type = int &&"
+
+gdb_test "ptype rrUI" "type = unsigned int &&"
+
+gdb_test_multiple "ptype rrL" "ptype rrL" {
+    -re "type = long &&.*$gdb_prompt $"  { pass "ptype rrL" }
+    -re "type = long int &&.*$gdb_prompt $"  { pass "ptype rrL" }
+}
+
+gdb_test_multiple "ptype rrUL" "ptype rrUL" {
+    -re "type = unsigned long &&.*$gdb_prompt $"  { pass "ptype rrUL" }
+    -re "type = long unsigned int &&.*$gdb_prompt $"  { pass "ptype rrUL" }
+}
+
+gdb_test "ptype rrF" "type = float &&"
+
+gdb_test "ptype rrD" "type = double &&"
+
+gdb_test "print rrC" ".\[0-9\]* = \\(char &&\\) @$hex: 65 \'A\'" \
+    "print value of rrC"
+
+gdb_test "print rrUC" \
+    ".\[0-9\]* = \\(unsigned char &&\\) @$hex: 21 \'.025\'" \
+    "print value of rrUC"
+
+gdb_test_multiple "print rrS" "print value of rrS" {
+    -re ".\[0-9\]* = \\(short &&\\) @$hex: -14.*$gdb_prompt $" {
+        pass "print value of rrS"
+    }
+    -re ".\[0-9\]* = \\(short int &&\\) @$hex: -14.*$gdb_prompt $" {
+        pass "print value of rrS"
+    }
+}
+
+gdb_test_multiple "print rrUS" "print value of rrUS" {
+    -re ".\[0-9\]* = \\(unsigned short &&\\) @$hex: 7.*$gdb_prompt $" {
+        pass "print value of rrUS"
+    }
+    -re ".\[0-9\]* = \\(short unsigned int &&\\) @$hex: 7.*$gdb_prompt $" {
+        pass "print value of rrUS"
+    }
+}
+
+gdb_test "print rrI" ".\[0-9\]* = \\(int &&\\) @$hex: 102" \
+	"print value of rrI"
+
+gdb_test "print rrUI" \
+    ".\[0-9\]* = \\(unsigned int &&\\) @$hex: 1002" \
+        "print value of UI"
+
+gdb_test_multiple "print rrL" "print value of rrL" {
+    -re ".\[0-9\]* = \\(long &&\\) @$hex: -234.*$gdb_prompt $" {
+        pass "print value of rrL"
+    }
+    -re ".\[0-9\]* = \\(long int &&\\) @$hex: -234.*$gdb_prompt $" {
+        pass "print value of rrL"
+    }
+}
+
+gdb_test_multiple "print rrUL" "print value of rrUL" {
+    -re ".\[0-9\]* = \\(unsigned long &&\\) @$hex: 234.*$gdb_prompt $" {
+        pass "print value of rrUL"
+    }
+    -re ".\[0-9\]* = \\(long unsigned int &&\\) @$hex: 234.*$gdb_prompt $" {
+        pass "print value of rrUL"
+    }
+}
+
+gdb_test "print rrF" \
+    ".\[0-9\]* = \\(float &&\\) @$hex: 1.2\[0-9\]*e\\+0?10.*" \
+    "print value of rrF"
+
+gdb_test "print rrD" \
+    ".\[0-9\]* = \\(double &&\\) @$hex: -1.375e-123.*" \
+    "print value of rrD"
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (8 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch provides the ability to print out names of rvalue reference types
and values of those types. This is done in full similarity to regular
references, and as with them, we don't print out "const" suffix because all
rvalue references are const.

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/c-typeprint.c (c_print_type): Support printing rvalue
        reference types.
        (c_type_print_varspec_prefix): Likewise.
        (c_type_print_modifier): Likewise.
        (c_type_print_varspec_suffix): Likewise.
        (c_type_print_base): Likewise.
        * gdb/c-valprint.c (c_val_print): Support printing rvalue
        reference values.
        (c_value_print): Likewise.
---
 gdb/c-typeprint.c | 10 ++++++----
 gdb/c-valprint.c  |  4 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 1af477c..1ed8cdc 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-		  || code == TYPE_CODE_REF)))
+                 || TYPE_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
@@ -341,9 +341,10 @@ c_type_print_varspec_prefix (struct type *type,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
 				   stream, show, 1, 0, flags);
-      fprintf_filtered (stream, "&");
+      fprintf_filtered (stream, TYPE_CODE(type) == TYPE_CODE_REF ? "&" : "&&");
       c_type_print_modifier (type, stream, 1, need_post_space);
       break;
 
@@ -409,8 +410,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
      every reference is `const'.  */
-  if (TYPE_CONST (type)
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CONST (type) && !TYPE_REFERENCE (type))
     {
       if (need_pre_space)
 	fprintf_filtered (stream, " ");
@@ -725,6 +725,7 @@ c_type_print_varspec_suffix (struct type *type,
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
 				   show, 1, 0, flags);
       break;
@@ -892,6 +893,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBERPTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_METHODPTR:
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 473147a..32f4d3f 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -538,6 +538,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_FLAGS:
     case TYPE_CODE_FUNC:
@@ -583,8 +584,7 @@ c_value_print (struct value *val, struct ui_file *stream,
   val_type = value_type (val);
   type = check_typedef (val_type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_PTR
-      || TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type))
     {
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway.
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (5 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

This patch implements correct parsing of C++0x rvalue reference typenames.
This is done in full similarity to the handling of regular references by adding
a '&&' token handling in c-exp.y, defining an rvalue reference type piece, and
implementing a follow type derivation in follow_types().

./ChangeLog:

2015-12-20  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/c-exp.y: Handle the '&&' token in the typename.
        * gdb/parse.c (insert_type): Change assert statement.
        (follow_types): Handle rvalue reference types.
        * gdb/parser-defs.h (enum type_pieces): Add tp_rvalue_reference
        constant.
---
 gdb/c-exp.y       |  6 +++++-
 gdb/parse.c       | 41 +++++++++++++++++++++++------------------
 gdb/parser-defs.h |  1 +
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 030e818..0922e22 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -799,7 +799,7 @@ exp	:	SIZEOF '(' type ')'	%prec UNARY
 			       says of sizeof:  "When applied to a reference
 			       or a reference type, the result is the size of
 			       the referenced type."  */
-			  if (TYPE_CODE (type) == TYPE_CODE_REF)
+                         if (TYPE_REFERENCE (type))
 			    type = check_typedef (TYPE_TARGET_TYPE (type));
 			  write_exp_elt_longcst (pstate,
 						 (LONGEST) TYPE_LENGTH (type));
@@ -1140,6 +1140,10 @@ ptr_operator:
 			{ insert_type (tp_reference); }
 	|	'&' ptr_operator
 			{ insert_type (tp_reference); }
+        |       ANDAND
+                       { insert_type (tp_rvalue_reference); }
+        |       ANDAND ptr_operator
+                       { insert_type (tp_rvalue_reference); }
 	;
 
 ptr_operator_ts: ptr_operator
diff --git a/gdb/parse.c b/gdb/parse.c
index ef45fac..99aec9b 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1470,10 +1470,10 @@ insert_into_type_stack (int slot, union type_stack_elt element)
 }
 
 /* Insert a new type, TP, at the bottom of the type stack.  If TP is
-   tp_pointer or tp_reference, it is inserted at the bottom.  If TP is
-   a qualifier, it is inserted at slot 1 (just above a previous
-   tp_pointer) if there is anything on the stack, or simply pushed if
-   the stack is empty.  Other values for TP are invalid.  */
+   tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the
+   bottom.  If TP is a qualifier, it is inserted at slot 1 (just above a
+   previous tp_pointer) if there is anything on the stack, or simply pushed
+   if the stack is empty.  Other values for TP are invalid.  */
 
 void
 insert_type (enum type_pieces tp)
@@ -1481,8 +1481,8 @@ insert_type (enum type_pieces tp)
   union type_stack_elt element;
   int slot;
 
-  gdb_assert (tp == tp_pointer || tp == tp_reference
-	      || tp == tp_const || tp == tp_volatile);
+  gdb_assert (tp == tp_pointer || tp == tp_reference ||
+             tp == tp_rvalue_reference || tp == tp_const || tp == tp_volatile);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
@@ -1695,21 +1695,26 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_lvalue_reference_type (follow_type);
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+        follow_type = lookup_lvalue_reference_type (follow_type);
+        goto process_reference;
+      case tp_rvalue_reference:
+        follow_type = lookup_rvalue_reference_type (follow_type);
+      process_reference:
+        if (make_const)
+          follow_type = make_cv_type (make_const,
+                                      TYPE_VOLATILE (follow_type),
+                                      follow_type, 0);
+        if (make_volatile)
+          follow_type = make_cv_type (TYPE_CONST (follow_type),
+                                      make_volatile,
+                                      follow_type, 0);
+        if (make_addr_space)
+          follow_type = make_type_with_address_space (follow_type,
+                                                      make_addr_space);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
 	break;
+
       case tp_array:
 	array_size = pop_type_int ();
 	/* FIXME-type-allocation: need a way to free this type when we are
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 25875d1..5387288 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -127,6 +127,7 @@ enum type_pieces
     tp_end = -1, 
     tp_pointer, 
     tp_reference, 
+    tp_rvalue_reference,
     tp_array, 
     tp_function,
     tp_function_with_arguments,
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (7 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2015-12-20 22:35 ` Artemiy Volkov
  2015-12-20 22:35 ` [PATCH 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-20 22:35 UTC (permalink / raw)
  To: gdb-patches; +Cc: Artemiy Volkov

Make gdb DWARF reader understand DW_AT_rvalue_reference type tag. Handling
of this tag is done in the existing read_tag_reference_type() function, to
which we add a new parameter representing the kind of reference type
(lvalue vs rvalue).

./ChangeLog:

2015-12-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/dwarf2read.c (process_die): Handle the
        DW_AT_rvalue_reference_type DIE.
        (read_tag_reference_type): Likewise.
        (read_type_die_1): Likewise.
---
 gdb/dwarf2read.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 5c3d42c..1735626 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8294,6 +8294,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;
 
@@ -14320,16 +14321,19 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
    the user defined type vector.  */
 
 static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+                          enum type_code refcode)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type, *target_type;
   struct attribute *attr;
 
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
   target_type = die_type (die, cu);
 
   /* The die_type call above may have already set the type for this DIE.  */
@@ -14337,7 +14341,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_lvalue_reference_type (target_type);
+  type = lookup_reference_type (target_type, refcode);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
@@ -19114,7 +19118,10 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
       this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      this_type = read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+      break;
+    case DW_TAG_rvalue_reference_type:
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
       break;
     case DW_TAG_const_type:
       this_type = read_tag_const_type (die, cu);
-- 
2.6.4

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (10 preceding siblings ...)
  2015-12-20 22:35 ` [PATCH 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2015-12-28 21:09 ` Artemiy Volkov
  2016-01-20  9:42   ` Yao Qi
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2015-12-28 21:09 UTC (permalink / raw)
  To: gdb-patches

On Mon, Dec 21, 2015 at 04:31:10AM +0300, Artemiy Volkov wrote:
> Hi all,
> 
> this is my take on fixing gdb/14441 which deals with C++0x rvalue references.
> 
> The approach is rather straightforward and the work for the most part consisted
> of mimicking the behavior for regular references. In gdbtypes.c, several helper
> functions were introduced and some parameterized by the reference kind to
> simplify the access to reference type objects API.
> 
> The only interesting part is the addition of overloading resolution rules
> with regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
> 13.3.3.2 were accounted for at the beginning of rank_one_type(). 
> 
> With this patch it is now also possible to fix the evaluation of decltype,
> which should return a plain type object, an lvalue reference or an rvalue
> reference depending on a type category of the type of its operand. However,
> this would require introduction of the type catyegory notion to gdb, which I
> think only needs adding a new constant to lval_type and propagating the type
> category through different parts of an expression in gdb/valops.c. I'm willing
> to do this if this patchset turns out to be OK.

Ping? Any comments on this patchset?

> 
> Artemiy Volkov (11):
>   gdb: gdbtypes: add definitions for rvalue reference type
>   gdb: gdbtypes: change {lookup,make}_reference_type() API
>   gdb: valops: add ability to return rvalue reference values from
>     value_ref()
>   gdb: parse: support rvalue reference type
>   gdb: demangle: implement demangling for rvalue reference typenames
>   gdb: print: implement correct printing of rvalue reference types and
>     values
>   gdb: dwarf2read: support DW_AT_rvalue_reference type
>   gdb: convert lvalue reference type check to general reference type
>     check
>   gdb: gdbtypes: add rvalue references to overloading resolution
>   gdb: python: support rvalue references in the gdb module
>   gdb: testsuite: add rvalue reference tests
> 
>  gdb/aarch64-tdep.c                    |   5 +-
>  gdb/ada-lang.c                        |   2 +-
>  gdb/amd64-tdep.c                      |   2 +-
>  gdb/amd64-windows-tdep.c              |   1 +
>  gdb/arm-tdep.c                        |   5 +-
>  gdb/ax-gdb.c                          |   2 +
>  gdb/c-exp.y                           |   6 +-
>  gdb/c-typeprint.c                     |  10 +-
>  gdb/c-valprint.c                      |  13 ++-
>  gdb/c-varobj.c                        |  10 +-
>  gdb/compile/compile-c-symbols.c       |   2 +-
>  gdb/completer.c                       |   3 +-
>  gdb/cp-name-parser.y                  |   4 +
>  gdb/cp-support.c                      |   3 +-
>  gdb/darwin-nat-info.c                 |   2 +-
>  gdb/dwarf2loc.c                       |   4 +-
>  gdb/dwarf2read.c                      |  15 ++-
>  gdb/eval.c                            |  16 ++--
>  gdb/f-exp.y                           |   2 +-
>  gdb/findvar.c                         |   6 +-
>  gdb/gdbtypes.c                        |  96 ++++++++++++++++---
>  gdb/gdbtypes.h                        |  21 ++++-
>  gdb/guile/scm-type.c                  |   2 +-
>  gdb/guile/scm-value.c                 |   2 +-
>  gdb/hppa-tdep.c                       |   1 +
>  gdb/infcall.c                         |   5 +-
>  gdb/language.c                        |   3 +-
>  gdb/m32c-tdep.c                       |   8 +-
>  gdb/m88k-tdep.c                       |   1 +
>  gdb/mn10300-tdep.c                    |   1 +
>  gdb/msp430-tdep.c                     |   2 +-
>  gdb/parse.c                           |  41 ++++----
>  gdb/parser-defs.h                     |   1 +
>  gdb/ppc-sysv-tdep.c                   |  10 +-
>  gdb/printcmd.c                        |   4 +-
>  gdb/python/lib/gdb/command/explore.py |  21 +++++
>  gdb/python/lib/gdb/types.py           |   4 +-
>  gdb/python/py-type.c                  |  14 ++-
>  gdb/python/py-value.c                 |  45 +++++++--
>  gdb/python/py-xmethods.c              |  19 +++-
>  gdb/s390-linux-tdep.c                 |   2 +-
>  gdb/sparc-tdep.c                      |   1 +
>  gdb/sparc64-tdep.c                    |   1 +
>  gdb/spu-tdep.c                        |   1 +
>  gdb/stabsread.c                       |   2 +-
>  gdb/symtab.c                          |   3 +-
>  gdb/testsuite/gdb.cp/casts.cc         |   8 +-
>  gdb/testsuite/gdb.cp/casts.exp        |  34 ++++++-
>  gdb/testsuite/gdb.cp/cpsizeof.cc      |   4 +
>  gdb/testsuite/gdb.cp/cpsizeof.exp     |   2 +-
>  gdb/testsuite/gdb.cp/demangle.exp     | 172 +++++++++++++++++++++++++++++++++-
>  gdb/testsuite/gdb.cp/overload.cc      |   9 ++
>  gdb/testsuite/gdb.cp/overload.exp     |  14 ++-
>  gdb/testsuite/gdb.cp/ref-params.cc    |  29 +++++-
>  gdb/testsuite/gdb.cp/ref-params.exp   |  20 +++-
>  gdb/testsuite/gdb.cp/ref-types.cc     |  24 +++++
>  gdb/testsuite/gdb.cp/ref-types.exp    | 136 ++++++++++++++++++++++++++-
>  gdb/typeprint.c                       |   4 +-
>  gdb/valarith.c                        |   6 +-
>  gdb/valops.c                          |  68 +++++++-------
>  gdb/valprint.c                        |   5 +-
>  gdb/value.c                           |  12 ++-
>  gdb/value.h                           |   2 +-
>  gdb/varobj.c                          |   2 +-
>  libiberty/cplus-dem.c                 |  14 ++-
>  65 files changed, 805 insertions(+), 184 deletions(-)
> 
> -- 
> 2.6.4
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2015-12-20 22:35 ` [PATCH 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2015-12-30 19:17   ` Pedro Alves
  0 siblings, 0 replies; 109+ messages in thread
From: Pedro Alves @ 2015-12-30 19:17 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

Hi Artemiy,

Thanks much for working on this.  Just a quick note below.

On 12/21/2015 01:31 AM, Artemiy Volkov wrote:

> libiberty/ChangeLog:
> 
> 2015-12-20  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * cplus-dem.c (enum type_kind_t): Add tk_rvalue_reference
>         constant.
>         (demangle_template_value_parm): Handle tk_rvalue_reference
>         type kind.
>         (do_type): Support 'O' type id (rvalue references).

It'd be nice to have a few tests in libiberty/testsuite/ to cover
this.

Note that libiberty is maintained by gcc.  You need to send this
to the gcc-patches list.  Once it is approved upstream, we can
merge it.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                   ` (11 preceding siblings ...)
  2015-12-28 21:09 ` [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
@ 2016-01-19 18:54 ` Artemiy Volkov
  2016-01-19 18:54   ` [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
                     ` (12 more replies)
  12 siblings, 13 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

Hi all,

this is my second take on fixing gdb/14441 which deals with C++0x rvalue
references.

The approach is rather straightforward and the work for the most part consisted
of mimicking the behavior for regular references. In gdbtypes.c, several helper
functions were introduced and some parameterized by the reference kind to
simplify the access to reference type objects API.

The only interesting part is the addition of overloading resolution rules with
regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
13.3.3.2 were accounted for at the beginning of rank_one_type().

With this patch it is now also possible to fix the evaluation of decltype,
which should return a plain type object, an lvalue reference or an rvalue
reference depending on a type category of the type of its operand. However,
this would require introduction of the type catyegory notion to gdb, which I
think only needs adding a new constant to lval_type and propagating the type
category through different parts of an expression in gdb/valops.c. I'm willing
to do this if this patchset turns out to be OK.

Changes from v1 consist of dropping the libiberty part of 05/11 and the
consequent testsuite changes. I have learned that introducing rvalue reference
support to the demangler in cplus-dem.c is completely unnecessary, since
virtually all contemporary compilers generate symbol names handled in
cp-demangle.c. Therefore I have removed some of the testcases in
gdb.cp/demangle.exp and switched the others to use the gnu-v3 demangling style.

Artemiy Volkov (11):
  gdb: gdbtypes: add definitions for rvalue reference type
  gdb: gdbtypes: change {lookup,make}_reference_type() API
  gdb: valops: add ability to return rvalue reference values from
    value_ref()
  gdb: parse: support rvalue reference type
  gdb: demangle: implement demangling for rvalue reference typenames
  gdb: print: implement correct printing of rvalue reference types and
    values
  gdb: dwarf2read: support DW_AT_rvalue_reference type
  gdb: convert lvalue reference type check to general reference type
    check
  gdb: gdbtypes: add rvalue references to overloading resolution
  gdb: python: support rvalue references in the gdb module
  gdb: testsuite: add rvalue reference tests

 gdb/aarch64-tdep.c                    |   5 +-
 gdb/ada-lang.c                        |   2 +-
 gdb/amd64-tdep.c                      |   2 +-
 gdb/amd64-windows-tdep.c              |   1 +
 gdb/arm-tdep.c                        |   5 +-
 gdb/ax-gdb.c                          |   2 +
 gdb/c-exp.y                           |   6 +-
 gdb/c-typeprint.c                     |  10 ++-
 gdb/c-valprint.c                      |  13 ++--
 gdb/c-varobj.c                        |  10 +--
 gdb/compile/compile-c-symbols.c       |   2 +-
 gdb/completer.c                       |   3 +-
 gdb/cp-name-parser.y                  |   4 +
 gdb/cp-support.c                      |   3 +-
 gdb/darwin-nat-info.c                 |   2 +-
 gdb/dwarf2loc.c                       |   4 +-
 gdb/dwarf2read.c                      |  15 +++-
 gdb/eval.c                            |  16 ++--
 gdb/f-exp.y                           |   2 +-
 gdb/findvar.c                         |   6 +-
 gdb/gdbtypes.c                        |  96 ++++++++++++++++++++----
 gdb/gdbtypes.h                        |  21 +++++-
 gdb/guile/scm-type.c                  |   2 +-
 gdb/guile/scm-value.c                 |   2 +-
 gdb/hppa-tdep.c                       |   1 +
 gdb/infcall.c                         |   5 +-
 gdb/language.c                        |   3 +-
 gdb/m32c-tdep.c                       |   8 +-
 gdb/m88k-tdep.c                       |   1 +
 gdb/mn10300-tdep.c                    |   1 +
 gdb/msp430-tdep.c                     |   2 +-
 gdb/parse.c                           |  41 +++++-----
 gdb/parser-defs.h                     |   1 +
 gdb/ppc-sysv-tdep.c                   |  10 +--
 gdb/printcmd.c                        |   4 +-
 gdb/python/lib/gdb/command/explore.py |  21 ++++++
 gdb/python/lib/gdb/types.py           |   4 +-
 gdb/python/py-type.c                  |  14 ++--
 gdb/python/py-value.c                 |  45 ++++++++---
 gdb/python/py-xmethods.c              |  19 ++++-
 gdb/s390-linux-tdep.c                 |   2 +-
 gdb/sparc-tdep.c                      |   1 +
 gdb/sparc64-tdep.c                    |   1 +
 gdb/spu-tdep.c                        |   1 +
 gdb/stabsread.c                       |   2 +-
 gdb/symtab.c                          |   3 +-
 gdb/testsuite/gdb.cp/casts.cc         |   8 +-
 gdb/testsuite/gdb.cp/casts.exp        |  34 ++++++++-
 gdb/testsuite/gdb.cp/cpsizeof.cc      |   4 +
 gdb/testsuite/gdb.cp/cpsizeof.exp     |   2 +-
 gdb/testsuite/gdb.cp/demangle.exp     |  41 +++++++++-
 gdb/testsuite/gdb.cp/overload.cc      |   9 +++
 gdb/testsuite/gdb.cp/overload.exp     |  14 +++-
 gdb/testsuite/gdb.cp/ref-params.cc    |  29 +++++++-
 gdb/testsuite/gdb.cp/ref-params.exp   |  20 ++++-
 gdb/testsuite/gdb.cp/ref-types.cc     |  24 ++++++
 gdb/testsuite/gdb.cp/ref-types.exp    | 136 +++++++++++++++++++++++++++++++++-
 gdb/typeprint.c                       |   4 +-
 gdb/valarith.c                        |   6 +-
 gdb/valops.c                          |  68 +++++++++--------
 gdb/valprint.c                        |   5 +-
 gdb/value.c                           |  12 +--
 gdb/value.h                           |   2 +-
 gdb/varobj.c                          |   2 +-
 64 files changed, 662 insertions(+), 182 deletions(-)

-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (4 preceding siblings ...)
  2016-01-19 18:54   ` [PATCH v2 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2016-01-19 18:54   ` Artemiy Volkov
  2016-02-19 18:49     ` Keith Seitz
  2016-01-19 18:55   ` [PATCH v2 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
                     ` (6 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch introduces preliminal definitions regarding C++0x rvalue references
to the gdb type system. In addition to an enum type_code entry, a field in
struct type and an accessor macro for that which are created similarly to the
lvalue references' counterparts, we also introduce a TYPE_REFERENCE convenience
macro used to check for both kinds of references simultaneously as they are
equivalent in many contexts.

./Changelog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/gdbtypes.h (enum type_code): Add TYPE_CODE_RVALUE_REF
        constant.
        (TYPE_REFERENCE): New macro.
        (struct type): Add rvalue_reference_type field.
        (TYPE_RVALUE_REFERENCE_TYPE): New macro.
---
 gdb/gdbtypes.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index e775a1d..52419b4 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -160,6 +160,8 @@ enum type_code
 
     TYPE_CODE_REF,		/**< C++ Reference types */
 
+    TYPE_CODE_RVALUE_REF,	/**< C++ rvalue reference types */
+
     TYPE_CODE_CHAR,		/**< *real* character type */
 
     /* * Boolean type.  0 is false, 1 is true, and other values are
@@ -362,6 +364,12 @@ enum type_instance_flag_value
 #define TYPE_ATOMIC(t) \
   (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
 
+/* * C++ lvalue and rvalue references are equivalent in many contexts,
+   thus create a convenience macro that checks if a type is either of them. */
+
+#define TYPE_REFERENCE(t) \
+  (TYPE_CODE(t) == TYPE_CODE_REF || TYPE_CODE(t) == TYPE_CODE_RVALUE_REF)
+
 /* * Instruction-space delimited type.  This is for Harvard architectures
    which have separate instruction and data address spaces (and perhaps
    others).
@@ -767,6 +775,10 @@ struct type
 
   struct type *reference_type;
 
+  /* * A C++ rvalue reference type added in C++0x. */
+
+  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 const, volatile, code-space, data-space, and
@@ -1229,6 +1241,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,
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (3 preceding siblings ...)
  2016-01-19 18:54   ` [PATCH v2 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2016-01-19 18:54   ` Artemiy Volkov
  2016-02-19 18:52     ` Keith Seitz
  2016-01-19 18:54   ` [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
                     ` (7 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

Parameterize value_ref() by the kind of reference type the value of which
is requested. Change all callers to use the new API.

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/ada-lang.c (ada_evaluate_subexp): Adhere to the new
        value_ref() interface.
        * gdb/c-valprint.c (c_value_print): Likewise.
        * gdb/infcall.c (value_arg_coerce): Likewise.
        * gdb/python/py-value.c (valpy_reference_value): Likewise.
        * gdb/valops.c (value_cast): Likewise.
        (value_reinterpret_cast): Likewise.
        (value_dynamic_cast): Likewise.
        (value_ref): Parameterize by kind of return value reference type.
        (typecmp): Likewise.
        * gdb/value.h: New interface.
---
 gdb/ada-lang.c        |  2 +-
 gdb/c-valprint.c      |  9 ++++++---
 gdb/infcall.c         |  2 +-
 gdb/python/py-value.c |  2 +-
 gdb/valops.c          | 20 ++++++++++++--------
 gdb/value.h           |  2 +-
 6 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 242e632..e42f66f 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10724,7 +10724,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 		     should return a ref as it should be valid to ask
 		     for its address; so rebuild a ref after coerce.  */
 		  arg1 = ada_coerce_ref (arg1);
-		  return value_ref (arg1);
+		  return value_ref (arg1, TYPE_CODE_REF);
 		}
 	    }
 
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 62552ec..e210e99 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -602,10 +602,13 @@ c_value_print (struct value *val, struct ui_file *stream,
       else if (options->objectprint
 	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
-	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+         int is_ref = TYPE_REFERENCE (type);
+         enum type_code refcode = TYPE_CODE_UNDEF;
 
-	  if (is_ref)
+	  if (is_ref) {
 	    val = value_addr (val);
+           refcode = TYPE_CODE (type);
+         }
 
 	  /* Pointer to class, check real type of object.  */
 	  fprintf_filtered (stream, "(");
@@ -625,7 +628,7 @@ c_value_print (struct value *val, struct ui_file *stream,
 
 		  if (is_ref)
 		    {
-		      val = value_ref (value_ind (val));
+		      val = value_ref (value_ind (val), refcode);
 		      type = value_type (val);
 		    }
 
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 77cd931..ad2512a 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -169,7 +169,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
 	   if the value was not previously in memory - in some cases
 	   we should clearly be allowing this, but how?  */
 	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
-	new_value = value_ref (new_value);
+	new_value = value_ref (new_value, TYPE_CODE (type));
 	return new_value;
       }
     case TYPE_CODE_INT:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 9d479ea..97ac91a 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -249,7 +249,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val));
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF));
 
       do_cleanups (cleanup);
     }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1aafb5a..cc01689 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -372,7 +372,7 @@ value_cast (struct type *type, struct value *arg2)
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
       struct value *val =  value_cast (dereftype, arg2);
 
-      return value_ref (val); 
+      return value_ref (val, TYPE_CODE (t1));
     }
 
   code2 = TYPE_CODE (check_typedef (value_type (arg2)));
@@ -622,7 +622,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
     error (_("Invalid reinterpret_cast"));
 
   if (is_ref)
-    result = value_cast (type, value_ref (value_ind (result)));
+    result = value_cast (type, value_ref (value_ind (result),
+                                          TYPE_CODE (type)));
 
   return result;
 }
@@ -816,7 +817,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
 				arg_type,
 				&result) == 1)
 	return value_cast (type,
-			   is_ref ? value_ref (result) : value_addr (result));
+			   is_ref ? value_ref (result, TYPE_CODE (resolved_type)) : value_addr (result));
     }
 
   /* The second dynamic check specified in 5.2.7.  */
@@ -828,7 +829,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
 			       value_address (tem), tem,
 			       rtti_type, &result) == 1)
     return value_cast (type,
-		       is_ref ? value_ref (result) : value_addr (result));
+		       is_ref ? value_ref (result, TYPE_CODE (resolved_type)) : value_addr (result));
 
   if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
     return value_zero (type, not_lval);
@@ -1499,16 +1500,19 @@ value_addr (struct value *arg1)
    contents.  */
 
 struct value *
-value_ref (struct value *arg1)
+value_ref (struct value *arg1, enum type_code refcode)
 {
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  if ((TYPE_CODE (type) == TYPE_CODE_REF || TYPE_CODE (type) == TYPE_CODE_RVALUE_REF)
+      && TYPE_CODE (type) == refcode)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_reference_type (type, refcode));
   return arg2;
 }
 
@@ -1715,7 +1719,7 @@ typecmp (int staticp, int varargs, int nargs,
 	  if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
 	    t2[i] = value_coerce_array (t2[i]);
 	  else
-	    t2[i] = value_ref (t2[i]);
+	    t2[i] = value_ref (t2[i], TYPE_CODE (tt1));
 	  continue;
 	}
 
diff --git a/gdb/value.h b/gdb/value.h
index 2eac5ef..db1b7bf 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -725,7 +725,7 @@ extern struct value *value_ind (struct value *arg1);
 
 extern struct value *value_addr (struct value *arg1);
 
-extern struct value *value_ref (struct value *arg1);
+extern struct value *value_ref (struct value *arg1, enum type_code refcode);
 
 extern struct value *value_assign (struct value *toval,
 				   struct value *fromval);
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
  2016-01-19 18:54   ` [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
  2016-01-19 18:54   ` [PATCH v2 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2016-01-19 18:54   ` Artemiy Volkov
  2016-02-19 18:54     ` Keith Seitz
  2016-01-19 18:54   ` [PATCH v2 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
                     ` (9 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch fixes demangling of names containing rvalue reference typenames by
handling DEMANGLE_COMPONENT_RVALUE_REFERENCE demangle component.

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/cp-name-parser.y: Handle the '&&' token in typename.
        * gdb/cp-support.c (replace_typedefs): Handle
        DEMANGLE_COMPONENT_RVALUE_REFERENCE.
        * gdb/python/py-type.c (typy_lookup_type): Likewise.
---
 gdb/cp-name-parser.y | 4 ++++
 gdb/cp-support.c     | 1 +
 gdb/python/py-type.c | 6 +++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index c6a5c34..33fdcea 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -769,6 +769,10 @@ ptr_operator	:	'*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
 			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
 			  $$.last = &d_left ($$.comp); }
+		|	ANDAND
+			{ $$.comp = make_empty (DEMANGLE_COMPONENT_RVALUE_REFERENCE);
+			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+			  $$.last = &d_left ($$.comp); }
 		|	nested_name '*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
 			  $$.comp->u.s_binary.left = $1.comp;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index df127c4..1dde382 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -520,6 +520,7 @@ replace_typedefs (struct demangle_parse_info *info,
 	case DEMANGLE_COMPONENT_RESTRICT_THIS:
 	case DEMANGLE_COMPONENT_POINTER:
 	case DEMANGLE_COMPONENT_REFERENCE:
+	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
 	  replace_typedefs (info, d_left (ret_comp), finder, data);
 	  break;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 385cb53..a66f7ba 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -811,6 +811,7 @@ typy_lookup_type (struct demangle_component *demangled,
 
   if (demangled_type == DEMANGLE_COMPONENT_POINTER
       || demangled_type == DEMANGLE_COMPONENT_REFERENCE
+      || demangled_type == DEMANGLE_COMPONENT_RVALUE_REFERENCE
       || demangled_type == DEMANGLE_COMPONENT_CONST
       || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
     {
@@ -827,7 +828,10 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-             rtype = lookup_lvalue_reference_type (type);
+              rtype = lookup_lvalue_reference_type (type);
+	      break;
+	    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+              rtype = lookup_rvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
  2016-01-19 18:54   ` [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2016-01-19 18:54   ` Artemiy Volkov
  2016-02-19 18:50     ` Keith Seitz
  2016-01-19 18:54   ` [PATCH v2 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
                     ` (10 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

Parameterize lookup_reference_type() and make_reference_type() by the kind of
reference type we want to look up. Create two wrapper functions
lookup_{lvalue,rvalue}_reference_type() for lookup_reference_type() to simplify
the API. Change all callers to use the new API.

./Changelog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/dwarf2read.c (read_tag_reference_type): Use
        lookup_lvalue_reference_type() instead of lookup_reference_type().
        * gdb/eval.c (evaluate_subexp_standard): Likewise.
        * gdb/f-exp.y: Likewise.
        * gdb/gdbtypes.c (make_reference_type): Generalize with rvalue
        reference types.
        (lookup_reference_type): Generalize with rvalue reference types.
        (lookup_lvalue_reference_type): New convenience wrapper for
        lookup_reference_type().
        (lookup_rvalue_reference_type): Likewise.
        * gdb/gdbtypes.h: Change interface for
        {make,lookup}_{rvalue,}_reference_type().
        * gdb/guile/scm-type.c (gdbscm_type_reference): Use
        lookup_lvalue_reference_type() instead of lookup_reference_type().
        * gdb/guile/scm-value.c (gdbscm_value_dynamic_type): Likewise.
        * gdb/parse.c (follow_types): Likewise.
        * gdb/python/py-type.c (typy_reference): Likewise.
        (typy_lookup_type): Likewise.
        * gdb/python/py-value.c (valpy_get_dynamic_type): Likewise.
        (valpy_getitem): Likewise.
        * gdb/python/py-xmethods.c (gdbpy_get_xmethod_result_type):
        Likewise.
        (gdbpy_invoke_xmethod): Likewise.
        * gdb/stabsread.c: Provide extra argument to make_reference_type()
        call.
        * gdb/valops.c (value_ref): Use lookup_lvalue_reference_type()
        instead of lookup_reference_type().
        (value_rtti_indirect_type): Likewise.
---
 gdb/dwarf2read.c         |  2 +-
 gdb/eval.c               |  2 +-
 gdb/f-exp.y              |  2 +-
 gdb/gdbtypes.c           | 45 ++++++++++++++++++++++++++++++++++-----------
 gdb/gdbtypes.h           |  8 ++++++--
 gdb/guile/scm-type.c     |  2 +-
 gdb/guile/scm-value.c    |  2 +-
 gdb/parse.c              |  2 +-
 gdb/python/py-type.c     |  4 ++--
 gdb/python/py-value.c    |  4 ++--
 gdb/python/py-xmethods.c |  4 ++--
 gdb/stabsread.c          |  2 +-
 gdb/valops.c             |  4 ++--
 13 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 1020c12..d2a3a50 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14337,7 +14337,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_reference_type (target_type);
+  type = lookup_lvalue_reference_type (target_type);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
diff --git a/gdb/eval.c b/gdb/eval.c
index 78ad946..729f473 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2789,7 +2789,7 @@ evaluate_subexp_standard (struct type *expect_type,
 
 	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
 		{
-		  type = lookup_reference_type (type);
+                 type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 4faac32..0aa8235 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -567,7 +567,7 @@ ptype	:	typebase
 			follow_type = lookup_pointer_type (follow_type);
 			break;
 		      case tp_reference:
-			follow_type = lookup_reference_type (follow_type);
+                       follow_type = lookup_lvalue_reference_type (follow_type);
 			break;
 		      case tp_array:
 			array_size = pop_type_int ();
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index f129b0e..058b77d 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -382,17 +382,23 @@ 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.  */
+   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.
+   REFCODE denotes the kind of reference type to lookup (lvalue or rvalue
+   reference). We allocate new memory if needed.  */
 
 struct type *
-make_reference_type (struct type *type, struct type **typeptr)
+make_reference_type (struct type *type, struct type **typeptr,
+                      enum type_code refcode)
 {
   struct type *ntype;	/* New type */
+  struct type **reftype;
   struct type *chain;
 
-  ntype = TYPE_REFERENCE_TYPE (type);
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
+           : TYPE_RVALUE_REFERENCE_TYPE (type));
 
   if (ntype)
     {
@@ -421,7 +427,11 @@ make_reference_type (struct type *type, struct type **typeptr)
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
-  TYPE_REFERENCE_TYPE (type) = ntype;
+  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
+             : &TYPE_RVALUE_REFERENCE_TYPE (type));
+
+  if(!*reftype)
+    *reftype = ntype;
 
   /* FIXME!  Assume the machine has only one representation for
      references, and that it matches the (only) representation for
@@ -429,10 +439,9 @@ make_reference_type (struct type *type, struct type **typeptr)
 
   TYPE_LENGTH (ntype) =
     gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
-  TYPE_CODE (ntype) = TYPE_CODE_REF;
+  TYPE_CODE (ntype) = refcode;
 
-  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
-    TYPE_REFERENCE_TYPE (type) = ntype;
+  *reftype = ntype;
 
   /* Update the length of all the other variants of this type.  */
   chain = TYPE_CHAIN (ntype);
@@ -449,9 +458,23 @@ make_reference_type (struct type *type, struct type **typeptr)
    details.  */
 
 struct type *
-lookup_reference_type (struct type *type)
+lookup_reference_type (struct type *type, enum type_code refcode)
+{
+  return make_reference_type (type, (struct type **) 0, refcode);
+}
+
+/* Separate convenience functions for lvalue and rvalue references. */
+
+struct type *
+lookup_lvalue_reference_type (struct type *type)
+{
+  return lookup_reference_type (type, TYPE_CODE_REF);
+}
+
+struct type *
+lookup_rvalue_reference_type (struct type *type)
 {
-  return make_reference_type (type, (struct type **) 0);
+  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
 }
 
 /* Lookup a function type that returns type TYPE.  TYPEPTR, if
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 52419b4..d9b6b9e 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1725,9 +1725,13 @@ 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);
 
-extern struct type *lookup_reference_type (struct type *);
+extern struct type *lookup_reference_type (struct type *, enum type_code);
+extern struct type *lookup_lvalue_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_reference_type (struct type *, struct type **,
+                                         enum type_code);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 2acdfad..888624d 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -854,7 +854,7 @@ gdbscm_type_reference (SCM self)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 1cdf953..1681a77 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -601,7 +601,7 @@ gdbscm_value_dynamic_type (SCM self)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+               type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
diff --git a/gdb/parse.c b/gdb/parse.c
index 4191fc6..06f7bcd 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1695,7 +1695,7 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_reference_type (follow_type);
+	follow_type = lookup_lvalue_reference_type (follow_type);
 	if (make_const)
 	  follow_type = make_cv_type (make_const, 
 				      TYPE_VOLATILE (follow_type), 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 03cc8d9..385cb53 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -667,7 +667,7 @@ typy_reference (PyObject *self, PyObject *args)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -827,7 +827,7 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-	      rtype =  lookup_reference_type (type);
+             rtype = lookup_lvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7dba0ad..9d479ea 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -376,7 +376,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+               type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -766,7 +766,7 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
-	    res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+           res_val = value_cast (lookup_lvalue_reference_type (base_class_type), tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 58bb783..d70cdd1 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -550,7 +550,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
@@ -636,7 +636,7 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 74260b7..8a50dbd 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -1772,7 +1772,7 @@ again:
 
     case '&':			/* Reference to another type */
       type1 = read_type (pp, objfile);
-      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile));
+      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile), TYPE_CODE_REF);
       break;
 
     case 'f':			/* Function returning another type */
diff --git a/gdb/valops.c b/gdb/valops.c
index 5a244a9..1aafb5a 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1508,7 +1508,7 @@ value_ref (struct value *arg1)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
   return arg2;
 }
 
@@ -3616,7 +3616,7 @@ value_rtti_indirect_type (struct value *v, int *full,
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
       if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_reference_type (real_type);
+        real_type = lookup_lvalue_reference_type (real_type);
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (2 preceding siblings ...)
  2016-01-19 18:54   ` [PATCH v2 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2016-01-19 18:54   ` Artemiy Volkov
  2016-02-19 18:56     ` Keith Seitz
  2016-01-19 18:54   ` [PATCH v2 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
                     ` (8 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch provides the ability to print out names of rvalue reference types
and values of those types. This is done in full similarity to regular
references, and as with them, we don't print out "const" suffix because all
rvalue references are const.

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/c-typeprint.c (c_print_type): Support printing rvalue
        reference types.
        (c_type_print_varspec_prefix): Likewise.
        (c_type_print_modifier): Likewise.
        (c_type_print_varspec_suffix): Likewise.
        (c_type_print_base): Likewise.
        * gdb/c-valprint.c (c_val_print): Support printing rvalue
        reference values.
        (c_value_print): Likewise.
---
 gdb/c-typeprint.c | 10 ++++++----
 gdb/c-valprint.c  |  4 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 762c027..67129ad 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-		  || code == TYPE_CODE_REF)))
+                 || TYPE_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
@@ -341,9 +341,10 @@ c_type_print_varspec_prefix (struct type *type,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
 				   stream, show, 1, 0, flags);
-      fprintf_filtered (stream, "&");
+      fprintf_filtered (stream, TYPE_CODE(type) == TYPE_CODE_REF ? "&" : "&&");
       c_type_print_modifier (type, stream, 1, need_post_space);
       break;
 
@@ -409,8 +410,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
      every reference is `const'.  */
-  if (TYPE_CONST (type)
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CONST (type) && !TYPE_REFERENCE (type))
     {
       if (need_pre_space)
 	fprintf_filtered (stream, " ");
@@ -725,6 +725,7 @@ c_type_print_varspec_suffix (struct type *type,
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
 				   show, 1, 0, flags);
       break;
@@ -892,6 +893,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBERPTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_METHODPTR:
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index e210e99..116686f 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -538,6 +538,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_FLAGS:
     case TYPE_CODE_FUNC:
@@ -583,8 +584,7 @@ c_value_print (struct value *val, struct ui_file *stream,
   val_type = value_type (val);
   type = check_typedef (val_type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_PTR
-      || TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type))
     {
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway.
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
@ 2016-01-19 18:54   ` Artemiy Volkov
  2016-02-19 18:53     ` Keith Seitz
  2016-01-19 18:54   ` [PATCH v2 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
                     ` (11 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch implements correct parsing of C++0x rvalue reference typenames.
This is done in full similarity to the handling of regular references by adding
a '&&' token handling in c-exp.y, defining an rvalue reference type piece, and
implementing a follow type derivation in follow_types().

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/c-exp.y: Handle the '&&' token in the typename.
        * gdb/parse.c (insert_type): Change assert statement.
        (follow_types): Handle rvalue reference types.
        * gdb/parser-defs.h (enum type_pieces): Add tp_rvalue_reference
        constant.
---
 gdb/c-exp.y       |  6 +++++-
 gdb/parse.c       | 41 +++++++++++++++++++++++------------------
 gdb/parser-defs.h |  1 +
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 9f2a229..d585bce 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -799,7 +799,7 @@ exp	:	SIZEOF '(' type ')'	%prec UNARY
 			       says of sizeof:  "When applied to a reference
 			       or a reference type, the result is the size of
 			       the referenced type."  */
-			  if (TYPE_CODE (type) == TYPE_CODE_REF)
+                         if (TYPE_REFERENCE (type))
 			    type = check_typedef (TYPE_TARGET_TYPE (type));
 			  write_exp_elt_longcst (pstate,
 						 (LONGEST) TYPE_LENGTH (type));
@@ -1140,6 +1140,10 @@ ptr_operator:
 			{ insert_type (tp_reference); }
 	|	'&' ptr_operator
 			{ insert_type (tp_reference); }
+        |       ANDAND
+                       { insert_type (tp_rvalue_reference); }
+        |       ANDAND ptr_operator
+                       { insert_type (tp_rvalue_reference); }
 	;
 
 ptr_operator_ts: ptr_operator
diff --git a/gdb/parse.c b/gdb/parse.c
index 06f7bcd..75627c5 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1470,10 +1470,10 @@ insert_into_type_stack (int slot, union type_stack_elt element)
 }
 
 /* Insert a new type, TP, at the bottom of the type stack.  If TP is
-   tp_pointer or tp_reference, it is inserted at the bottom.  If TP is
-   a qualifier, it is inserted at slot 1 (just above a previous
-   tp_pointer) if there is anything on the stack, or simply pushed if
-   the stack is empty.  Other values for TP are invalid.  */
+   tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the
+   bottom.  If TP is a qualifier, it is inserted at slot 1 (just above a
+   previous tp_pointer) if there is anything on the stack, or simply pushed
+   if the stack is empty.  Other values for TP are invalid.  */
 
 void
 insert_type (enum type_pieces tp)
@@ -1481,8 +1481,8 @@ insert_type (enum type_pieces tp)
   union type_stack_elt element;
   int slot;
 
-  gdb_assert (tp == tp_pointer || tp == tp_reference
-	      || tp == tp_const || tp == tp_volatile);
+  gdb_assert (tp == tp_pointer || tp == tp_reference ||
+             tp == tp_rvalue_reference || tp == tp_const || tp == tp_volatile);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
@@ -1695,21 +1695,26 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_lvalue_reference_type (follow_type);
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+        follow_type = lookup_lvalue_reference_type (follow_type);
+        goto process_reference;
+      case tp_rvalue_reference:
+        follow_type = lookup_rvalue_reference_type (follow_type);
+      process_reference:
+        if (make_const)
+          follow_type = make_cv_type (make_const,
+                                      TYPE_VOLATILE (follow_type),
+                                      follow_type, 0);
+        if (make_volatile)
+          follow_type = make_cv_type (TYPE_CONST (follow_type),
+                                      make_volatile,
+                                      follow_type, 0);
+        if (make_addr_space)
+          follow_type = make_type_with_address_space (follow_type,
+                                                      make_addr_space);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
 	break;
+
       case tp_array:
 	array_size = pop_type_int ();
 	/* FIXME-type-allocation: need a way to free this type when we are
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 1b1d3c3..c474150 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -127,6 +127,7 @@ enum type_pieces
     tp_end = -1, 
     tp_pointer, 
     tp_reference, 
+    tp_rvalue_reference,
     tp_array, 
     tp_function,
     tp_function_with_arguments,
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (6 preceding siblings ...)
  2016-01-19 18:55   ` [PATCH v2 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-01-19 18:55   ` Artemiy Volkov
  2016-02-19 20:05     ` Keith Seitz
  2016-01-19 18:55   ` [PATCH v2 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
                     ` (4 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:55 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch adds tests for the initial rvalue reference support patchset.  Files
to change were selected among the most important files which test regular C++
references and the added tests are practically mirrored regular references
tests. Tested are printing of rvalue reference types and values, rvalue
reference parameters in function overloading, demangling of function names
containing rvalue reference parameters (using the gnu-v3 demangling style since
only the gnu-v3 demangler supports rvalue references), casts to rvalue
reference types, and application of the sizeof operator to rvalue reference
types and values.

All the changed files have been obviously set to compile with -std=c++11,
and in some cases this required altering function names which coincided
with keywords introduced in the new standard.

testsuite/ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb.cp/casts.cc (main): Change decltype() function name. Add
        rvalue reference type variables.
        * gdb.cp/casts.exp: Compile with -std=c++11. Add rvalue reference
        cast tests.
        * gdb.cp/cpsizeof.cc: Add rvalue reference type variables.
        * gdb.cp/cpsizeof.exp: Compile with -std=c++11. Add rvalue
        reference sizeof tests.
        * gdb.cp/demangle.exp: Add rvalue reference demangle tests.
        * gdb.cp/overload.cc (int main): Add a ctor and some methods
        with rvalue reference parameters.
        * gdb.cp/overload.exp: Compile with -std=c++11. Add rvalue
        reference overloading tests.
        * gdb.cp/ref-params.cc (int f1): New function taking rvalue
        reference parameter.
        (int f2): Likewise.
        (int mf1): Likewise.
        (int mf2): Likewise.
        * gdb.cp/ref-params.exp: Compile with -std=c++11. Add rvalue
        reference parameter printing tests.
        * gdb.cp/ref-types.cc (int main2): Add rvalue reference type
        variables.
        * gdb.cp/ref-types.exp: Compile with -std=c++11. Add rvalue
        reference type printing tests.
---
 gdb/testsuite/gdb.cp/casts.cc       |   8 ++-
 gdb/testsuite/gdb.cp/casts.exp      |  34 +++++++--
 gdb/testsuite/gdb.cp/cpsizeof.cc    |   4 ++
 gdb/testsuite/gdb.cp/cpsizeof.exp   |   2 +-
 gdb/testsuite/gdb.cp/demangle.exp   |  41 ++++++++++-
 gdb/testsuite/gdb.cp/overload.cc    |   9 +++
 gdb/testsuite/gdb.cp/overload.exp   |  14 +++-
 gdb/testsuite/gdb.cp/ref-params.cc  |  29 +++++++-
 gdb/testsuite/gdb.cp/ref-params.exp |  20 +++++-
 gdb/testsuite/gdb.cp/ref-types.cc   |  24 +++++++
 gdb/testsuite/gdb.cp/ref-types.exp  | 136 +++++++++++++++++++++++++++++++++++-
 11 files changed, 307 insertions(+), 14 deletions(-)

diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc
index 43f112f..d15fed1 100644
--- a/gdb/testsuite/gdb.cp/casts.cc
+++ b/gdb/testsuite/gdb.cp/casts.cc
@@ -1,3 +1,5 @@
+#include <utility>
+
 struct A
 {
   int a;
@@ -37,7 +39,7 @@ struct DoublyDerived : public VirtuallyDerived,
 // Confuse a simpler approach.
 
 double
-decltype(int x)
+decl_type(int x)
 {
   return x + 2.0;
 }
@@ -49,6 +51,8 @@ main (int argc, char **argv)
   B *b = (B *) a;
   A &ar = *b;
   B &br = (B&)ar;
+  A &&arr = std::move(A(42));
+  B &&brr = std::move(B(42, 1729));
 
   Derived derived;
   DoublyDerived doublyderived;
@@ -56,7 +60,7 @@ main (int argc, char **argv)
   Alpha *ad = &derived;
   Alpha *add = &doublyderived;
 
-  double y = decltype(2);
+  double y = decl_type(2);
 
   return 0;  /* breakpoint spot: casts.exp: 1 */
 }
diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp
index 34a2492..086ad74 100644
--- a/gdb/testsuite/gdb.cp/casts.exp
+++ b/gdb/testsuite/gdb.cp/casts.exp
@@ -33,7 +33,7 @@ if [get_compiler_info "c++"] {
     return -1
 }
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -86,6 +86,18 @@ gdb_test "print (B &) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
 gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
     "let compiler cast base class reference to derived class reference"
 
+# Casting Rvalue References.
+# Check upcasting.
+gdb_test "print (A &&) br" ".* = .A &&.* {a = 42}" \
+    "cast derived class rvalue reference to base class rvalue reference"
+
+# Check downcasting.
+gdb_test "print (B &&) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "cast base class rvalue reference to derived class rvalue reference"
+
+# Check compiler casting
+gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "let compiler cast base class rvalue reference to derived class rvalue reference"
 
 # A few basic tests of "new" casts.
 
@@ -101,6 +113,9 @@ gdb_test "print static_cast<A *> (b)" " = \\(A \\*\\) $hex" \
 gdb_test "print static_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "static_cast to reference type"
 
+gdb_test "print static_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "static_cast to rvalue reference type"
+
 gdb_test "print reinterpret_cast<A *> (b)" " = \\(A \\*\\) $hex" \
     "basic test of reinterpret_cast"
 
@@ -110,13 +125,16 @@ gdb_test "print reinterpret_cast<void> (b)" "Invalid reinterpret_cast" \
 gdb_test "print reinterpret_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "reinterpret_cast to reference type"
 
+gdb_test "print reinterpret_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "reinterpret_cast to rvalue reference type"
+
 # Test that keyword shadowing works.
 
-gdb_test "whatis decltype(5)" " = double"
+gdb_test "whatis decl_type(5)" " = double"
 
 # Basic tests using typeof.
 
-foreach opname {__typeof__ __typeof __decltype} {
+foreach opname {__typeof__ __typeof decltype} {
     gdb_test "print (${opname}(a)) (b)" " = \\(A \\*\\) $hex" \
 	"old-style cast using $opname"
 
@@ -127,7 +145,7 @@ foreach opname {__typeof__ __typeof __decltype} {
 	"reinterpret_cast using $opname"
 }
 
-gdb_test "whatis __decltype(*a)" "type = A \\&"
+gdb_test "whatis decltype(*a)" "type = A \\&"
 
 # Tests of dynamic_cast.
 
@@ -153,6 +171,10 @@ gdb_test "print dynamic_cast<Alpha &> (derived)" \
     " = \\(Alpha \\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
     "dynamic_cast simple upcast to reference"
 
+gdb_test "print dynamic_cast<Alpha &&> (derived)" \
+    " = \\(Alpha \\&\\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
+    "dynamic_cast simple upcast to rvalue reference"
+
 gdb_test "print dynamic_cast<Derived *> (ad)" \
     " = \\(Derived \\*\\) ${nonzero_hex}( <vtable for Derived.*>)?" \
     "dynamic_cast simple downcast"
@@ -169,6 +191,10 @@ gdb_test "print dynamic_cast<VirtuallyDerived &> (*ad)" \
     "dynamic_cast failed" \
     "dynamic_cast to reference to non-existing base"
 
+gdb_test "print dynamic_cast<VirtuallyDerived &&> (*ad)" \
+    "dynamic_cast failed" \
+    "dynamic_cast to rvalue reference to non-existing base"
+
 gdb_test "print dynamic_cast<DoublyDerived *> (add)" \
     " = \\(DoublyDerived \\*\\) ${nonzero_hex}( <vtable for DoublyDerived.*>)?" \
     "dynamic_cast unique downcast"
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.cc b/gdb/testsuite/gdb.cp/cpsizeof.cc
index 2dcaea1..6a8de4a 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.cc
+++ b/gdb/testsuite/gdb.cp/cpsizeof.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 struct Class
 {
   int a;
@@ -44,8 +46,10 @@ typedef Enum e12[12];
 #define T(N)					\
   N N ## obj;					\
   N& N ## _ref = N ## obj;			\
+  N&& N ## _rref = std::move(N ## obj);         \
   N* N ## p = &(N ## obj);			\
   N*& N ## p_ref = N ## p;			\
+  N*&& N ## p_rref = std::move(N ## p);         \
   int size_ ## N = sizeof (N ## _ref);		\
   int size_ ## N ## p = sizeof (N ## p_ref);	\
 
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.exp b/gdb/testsuite/gdb.cp/cpsizeof.exp
index de95c49..18d4db8 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.exp
+++ b/gdb/testsuite/gdb.cp/cpsizeof.exp
@@ -18,7 +18,7 @@ standard_testfile .cc
 
 if {[skip_cplus_tests]} { continue }
 
-if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++}] } {
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}] } {
      return -1
 }
 
diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
index 96c90db..90d7be6 100644
--- a/gdb/testsuite/gdb.cp/demangle.exp
+++ b/gdb/testsuite/gdb.cp/demangle.exp
@@ -123,20 +123,27 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: Append__15NameChooserViewPCc" \
 	"NameChooserView::Append\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadR6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)"
+    test_demangling_exact "gnu-v3: _ZN9ArrowLine19ArrowheadIntersectsEP9ArrowheadO6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead*, BoxObj&&, Graphic*)"
     test_demangling_exact "gnu: AtEnd__13ivRubberGroup" "ivRubberGroup::AtEnd(void)"
     test_demangling_exact "gnu: BgFilter__9ivTSolverP12ivInteractor" "ivTSolver::BgFilter(ivInteractor *)"
     test_demangling "gnu: BitPatterntoa__FRC10BitPatternccc" \
 	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &, char, char, char\[)\]+"
+    test_demangling "gnu-v3: _Z13BitPatterntoaOK10BitPatternccc" \
+	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const)&&, char, char, char\[)\]+"
     test_demangling_exact "gnu: Check__6UArrayi" "UArray::Check(int)"
     test_demangling_exact "gnu: CoreConstDecls__8TextCodeR7ostream" "TextCode::CoreConstDecls(ostream &)"
+    test_demangling_exact "gnu-v3: _ZN8TextCode14CoreConstDeclsEO7ostream" "TextCode::CoreConstDecls(ostream&&)"
     test_demangling_exact "gnu: Detach__8StateVarP12StateVarView" "StateVar::Detach(StateVarView *)"
     test_demangling_exact "gnu: Done__9ComponentG8Iterator" "Component::Done(Iterator)"
     test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCRC13ivTransformeriiii" \
 	"DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &, int, int, int, int\[)\]+"
+    test_demangling "gnu-v3: _Z31DrawDestinationTransformedImageP7_XImageiiS0_iimjiijmmP4_XGCOK13ivTransformeriiii" \
+	"DrawDestinationTransformedImage\[(\]+_XImage\[*\]+, int, int, _XImage\[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC\[*\]+, (const ivTransformer|ivTransformer const)&&, int, int, int, int\[)\]+"
 
     test_demangling "gnu: Edit__12StringEditorPCcii" \
 	"StringEditor::Edit\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
     test_demangling_exact "gnu: Effect__11RelateManipR7ivEvent" "RelateManip::Effect(ivEvent &)"
+    test_demangling_exact "gnu-v3: _ZN11RelateManip6EffectEO7ivEvent" "RelateManip::Effect(ivEvent&&)"
     test_demangling "gnu: FilterName__FPCc" \
 	"FilterName\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling "gnu: Filter__6PSTextPCci" \
@@ -206,16 +213,21 @@ proc test_gnu_style_demangling {} {
 	"iv2_6_MenuItem::iv2_6_MenuItem\[(\]+int, (const char|char const) \[*\]+, ivInteractor \[*\]+\[)\]+"
 
     test_demangling_exact "gnu: __20DisplayList_IteratorR11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &)"
+    test_demangling_exact "gnu-v3: _ZN20DisplayList_IteratorC4EO11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList&&)"
     test_demangling_exact "gnu: __3fooRT0" "foo::foo(foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EOS_" "foo::foo(foo&&)"
     test_demangling_exact "gnu: __3fooiN31" "foo::foo(int, int, int, int)"
     test_demangling "gnu: __3fooiPCc" \
 	"foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __3fooiRT0iT2iT2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EiOS_iS0_iS0_" "foo::foo(int, foo&&, int, foo&&, int, foo&&)"
     test_demangling "gnu: __6GetOptiPPcPCc" \
 	"GetOpt::GetOpt\[(\]+int, char \[*\]+\[*\]+, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __6KeyMapPT0" "KeyMap::KeyMap(KeyMap *)"
     test_demangling "gnu: __7ivWorldPCcRiPPcPC12ivOptionDescPC14ivPropertyData" \
 	"ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
+    test_demangling "gnu-v3: _ZN7ivWorldC2EPKcOiPPcPK12ivOptionDescPK14ivPropertyData" \
+	"ivWorld::ivWorld\[(\]+(const char|char const)\[*\]+, int&&, char\[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const)\[*\]+, (const ivPropertyData|ivPropertyData const)\[*\]+\[)\]+"
     test_demangling "gnu: __7procbufPCci" \
 	"procbuf::procbuf\[(\]+(const char|char const) \[*\]+, int\[)\]+"
     test_demangling_exact "gnu: __8ArrowCmdP6EditorUiUi" "ArrowCmd::ArrowCmd(Editor *, unsigned int, unsigned int)"
@@ -295,6 +307,8 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: append__7ivGlyphPT0" "ivGlyph::append(ivGlyph *)"
     test_demangling "gnu: arg__FRC7Complex" \
 	"arg\[(\]+(const Complex|Complex const) &\[)\]+"
+    test_demangling "gnu-v3: _Z3argOK7Complex" \
+	"arg\[(\]+(const Complex|Complex const)&&\[)\]+"
     test_demangling_exact "gnu: clearok__FP7_win_sti" "clearok(_win_st *, int)"
 
     test_demangling_exact "gnu: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
@@ -305,10 +319,16 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
     test_demangling "gnu: contains__C9BitStringRC10BitPattern" \
 	"BitString::contains\[(\]+(const BitPattern|BitPattern const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK10BitPattern" \
+	"BitString::contains\[(\]+(const BitPattern|BitPattern const)&&\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRC12BitSubStringi" \
 	"BitString::contains\[(\]+(const BitSubString|BitSubString const) &, int\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK12BitSubStringi" \
+	"BitString::contains\[(\]+(const BitSubString|BitSubString const)&&, int\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRT0" \
 	"BitString::contains\[(\]+(const BitString|BitString const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOKS_" \
+	"BitString::contains\[(\]+(const BitString|BitString const)&&\[)\]+ const"
     test_demangling "gnu: div__FPC6IntRepT0P6IntRep" \
 	"div\[(\]+(const IntRep|IntRep const) \[*\]+, (const IntRep|IntRep const) \[*\]+, IntRep \[*\]+\[)\]+"
     test_demangling "gnu: div__FPC6IntReplP6IntRep" \
@@ -436,18 +456,26 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE3PixC4EOKS2_" \
+	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const&&)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0" \
 	"List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC2EOKS0_PS2_" \
+	"List<VHDLEntity>::element::element(VHDLEntity const&&, List<VHDLEntity>::element*)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element" \
 	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC4EOKS2_" \
+	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const&&)"
 
     test_demangling_exact "gnu: __cl__C11VHDLLibraryGt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::operator()(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >) const"
 
     test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityEclEOKNS1_3PixE" \
+	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const&&) const"
 
     test_demangling_exact "gnu: __ne__FPvRCQ2t4List1Z10VHDLEntity3Pix" \
 	"operator!=(void *, List<VHDLEntity>::Pix const &)"
@@ -457,6 +485,8 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4List1Z10VHDLEntityRCt4List1Z10VHDLEntity" \
 	"List<VHDLEntity>::List(List<VHDLEntity> const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityEC4EOKS1_" \
+	"List<VHDLEntity>::List(List<VHDLEntity> const&&)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(void)"
@@ -465,13 +495,19 @@ proc test_gnu_style_demangling {} {
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(VHDLLibraryRep *, List<VHDLEntity>::Pix)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
-	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+       "PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+    test_demangling_exact "gnu-v3: _ZN4PixXI11VHDLLibrary14VHDLLibraryRep4ListI10VHDLEntityEEC2EOKS5_" \
+	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const&&)"
 
     test_demangling_exact "gnu: nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const"
+    test_demangling_exact "gnu-v3: _ZNK11VHDLLibrary5nextEEO4PixXIS_14VHDLLibraryRep4ListI10VHDLEntityEE" \
+	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >&&) const"
 
     test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityRQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::next(List<VHDLEntity>::Pix &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityE4nextEONS1_3PixE" \
+	"List<VHDLEntity>::next(List<VHDLEntity>::Pix&&) const"
 
     test_demangling_exact "gnu: _GLOBAL_\$D\$set" "global destructors keyed to set"
 
@@ -511,7 +547,6 @@ proc test_gnu_style_demangling {} {
 	"operator!=(void *, BDDFunction::VixB const &)"
     test_demangling_exact "gnu: __eq__FPvRCQ211BDDFunction4VixB" \
 	"operator==(void *, BDDFunction::VixB const &)"
-
     test_demangling_exact "gnu: relativeId__CQ36T_phi210T_preserve8FPC_nextRCQ26T_phi210T_preserveRC10Parameters" \
 	 "T_phi2::T_preserve::FPC_next::relativeId(T_phi2::T_preserve const &, Parameters const &) const"
 
@@ -535,6 +570,7 @@ proc test_gnu_style_demangling {} {
 	    pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
 	}
     }
+
 }
 
 #
@@ -1489,6 +1525,7 @@ proc test_hp_style_demangling {} {
     test_demangling_exact "hp: elem__6vectorXTiSN67TRdTFPv_i__Fi" "vector<int,-67,double &,int (void *)>::elem(int)"
     test_demangling_exact "hp: X__6vectorXTiSN67TdTPvUP5TRs" "vector<int,-67,double,void *,5U,short &>::X"
 
+
     # Named constants in template args
 
     test_demangling_exact "hp: elem__6vectorXTiA3foo__Fi" "vector<int,&foo>::elem(int)"
diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
index 5c782a4..a977c43 100644
--- a/gdb/testsuite/gdb.cp/overload.cc
+++ b/gdb/testsuite/gdb.cp/overload.cc
@@ -1,10 +1,12 @@
 #include <stddef.h>
+#include <utility>
 
 class foo {
 public:
   foo  (int);
   foo  (int, const char *);
   foo  (foo&);
+  foo  (foo&&);
   ~foo ();
   void foofunc (int);
   void foofunc (int, signed char *);
@@ -27,6 +29,9 @@ int overload1arg (double);
 int overload1arg (int*);
 int overload1arg (void*);
 
+int overload1arg (foo &);
+int overload1arg (foo &&);
+
 int overloadfnarg (void);
 int overloadfnarg (int);
 int overloadfnarg (int, int (*) (int));
@@ -114,6 +119,7 @@ int main ()
     double arg12 = 200.0;
     int arg13 = 200;
     char arg14 = 'a';
+    foo arg15(5);
 
     A a;
     B b;
@@ -153,6 +159,7 @@ int main ()
 foo::foo  (int i)                  { ifoo = i; ccpfoo = NULL; }
 foo::foo  (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
 foo::foo  (foo& afoo)              { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::foo  (foo&& afoo)             { ifoo = std::move(afoo.ifoo); ccpfoo = std::move (afoo.ccpfoo); }
 foo::~foo ()                       {}
 
 
@@ -172,6 +179,8 @@ int foo::overload1arg (float arg)           { arg = 0; return 11;}
 int foo::overload1arg (double arg)          { arg = 0; return 12;}
 int foo::overload1arg (int* arg)            { arg = 0; return 13;}
 int foo::overload1arg (void* arg)           { arg = 0; return 14;}
+int foo::overload1arg (foo &arg)            { return 15; }
+int foo::overload1arg (foo &&arg)           { return 16; }
 
 /* Test to see that we can explicitly request overloaded functions
    with function pointers in the prototype. */
diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
index 0cfa638..cfe7f90 100644
--- a/gdb/testsuite/gdb.cp/overload.exp
+++ b/gdb/testsuite/gdb.cp/overload.exp
@@ -28,7 +28,7 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -53,7 +53,7 @@ gdb_test "up" ".*main.*" "up from marker1"
 set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
 set re_fields	"int ifoo;${ws}const char ?\\* ?ccpfoo;"
 set XX_fields  	"int ifoo;${ws}char ?\\* ?ccpfoo;"
-set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);"
+set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);${ws}foo\\(foo ?&?&\\);"
 set re_dtor	"~foo\\((void|)\\);"
 set XX_dtor	"~foo\\(int\\);"
 set re_methods	                  "void foofunc\\(int\\);"
@@ -72,6 +72,8 @@ set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int \\*\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(void \\*\\);"
+set re_methods  "${re_methods}${ws}int overload1arg\\(foo &\\);"
+set re_methods  "${re_methods}${ws}int overload1arg\\(foo &&\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int, int ?\\(\\*\\) ?\\(int\\)\\);"
@@ -254,6 +256,14 @@ gdb_test "print foo_instance1.overload1arg(&arg14)" \
     "\\$\[0-9\]+ = 14" \
     "print call overloaded func char\\* arg"
 
+gdb_test "print foo_instance1.overload1arg(arg15)" \
+    "\\$\[0-9\]+ = 15" \
+    "print call overloaded func foo & arg"
+
+gdb_test "print foo_instance1.overload1arg(static_cast<foo&&>(arg15))" \
+    "\\$\[0-9\]+ = 16" \
+    "print call overloaded func foo && arg"
+
 gdb_test "print bar(a)" "= 11"
 gdb_test "print bar(b)" "= 22"
 gdb_test "print bar(c)" "= 22"
diff --git a/gdb/testsuite/gdb.cp/ref-params.cc b/gdb/testsuite/gdb.cp/ref-params.cc
index 0f7e125..efced2e 100644
--- a/gdb/testsuite/gdb.cp/ref-params.cc
+++ b/gdb/testsuite/gdb.cp/ref-params.cc
@@ -17,6 +17,8 @@
 
 /* Author: Paul N. Hilfinger, AdaCore Inc. */
 
+#include <utility>
+
 struct Parent {
   Parent (int id0) : id(id0) { }
   int id;
@@ -28,7 +30,12 @@ struct Child : public Parent {
 
 int f1(Parent& R)
 {
-  return R.id;			/* Set breakpoint marker3 here.  */
+  return R.id;			/* Set breakpoint marker4 here.  */
+}
+
+int f1(Parent&& R)
+{
+  return R.id;			/* Set breakpoint marker5 here.  */
 }
 
 int f2(Child& C)
@@ -36,6 +43,11 @@ int f2(Child& C)
   return f1(C);			/* Set breakpoint marker2 here.  */
 }
 
+int f2(Child&& C)
+{
+  return f1(std::move(C));                 /* Set breakpoint marker3 here.  */
+}
+
 struct OtherParent {
   OtherParent (int other_id0) : other_id(other_id0) { }
   int other_id;
@@ -50,11 +62,21 @@ int mf1(OtherParent& R)
   return R.other_id;
 }
 
+int mf1(OtherParent&& R)
+{
+  return R.other_id;
+}
+
 int mf2(MultiChild& C)
 {
   return mf1(C);
 }
 
+int mf2(MultiChild&& C)
+{
+  return mf1(C);
+}
+
 int main(void) 
 {
   Child Q(42);
@@ -62,8 +84,13 @@ int main(void)
 
   /* Set breakpoint marker1 here.  */
 
+  f1(Q);
+  f1(QR);
+  f1(Child(42));
+
   f2(Q);
   f2(QR);
+  f2(Child(42));
 
   MultiChild MQ(53);
   MultiChild& MQR = MQ;
diff --git a/gdb/testsuite/gdb.cp/ref-params.exp b/gdb/testsuite/gdb.cp/ref-params.exp
index 4531602..8b8a7cf 100644
--- a/gdb/testsuite/gdb.cp/ref-params.exp
+++ b/gdb/testsuite/gdb.cp/ref-params.exp
@@ -24,7 +24,7 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[build_executable $testfile.exp $testfile $srcfile {debug c++}] == 1} {
+if {[build_executable $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}] == 1} {
     return -1
 }
 
@@ -48,15 +48,28 @@ gdb_start_again "marker1 here"
 gdb_test "print f1(QR)" ".* = 42.*" "print value of f1 on (Child&) in main"
 
 gdb_start_again "marker1 here"
+gdb_test "print f1(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f1 on (Child&&) in main"
+
+gdb_start_again "marker1 here"
 gdb_test "print f2(QR)" ".* = 42.*" "print value of f2 on (Child&) in main"
 
+gdb_start_again "marker1 here"
+gdb_test "print f2(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f2 on (Child&&) in main"
+
 gdb_start_again "marker2 here"
 gdb_test "print C" ".*id = 42.*" "print value of Child& in f2"
 gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child& in f2"
 
 gdb_start_again "marker3 here"
+gdb_test "print C" ".*id = 42.*" "print value of Child&& in f2"
+gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child&& in f2"
+
+gdb_start_again "marker4 here"
 gdb_test "print R" ".*id = 42.*" "print value of Parent& in f1"
 
+gdb_start_again "marker5 here"
+gdb_test "print R" ".*id = 42.*" "print value of Parent&& in f1"
+
 gdb_start_again "breakpoint MQ here"
 gdb_test "print f1(MQ)" ".* = 53"
 gdb_test "print mf1(MQ)" ".* = 106"
@@ -64,3 +77,8 @@ gdb_test "print mf2(MQ)" ".* = 106"
 gdb_test "print f1(MQR)" ".* = 53"
 gdb_test "print mf1(MQR)" ".* = 106"
 gdb_test "print mf2(MQR)" ".* = 106"
+gdb_test "print f1(static_cast<MultiChild&&>(MQ))" ".* = 53"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf1(static_cast<MultiChild&&>(MQ))" ".* = 106"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf2(static_cast<MultiChild&&>(MQ))" ".* = 106"
diff --git a/gdb/testsuite/gdb.cp/ref-types.cc b/gdb/testsuite/gdb.cp/ref-types.cc
index 2c124a9..dafec19 100644
--- a/gdb/testsuite/gdb.cp/ref-types.cc
+++ b/gdb/testsuite/gdb.cp/ref-types.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 int main2(void);
 
 void marker1 (void)
@@ -39,6 +41,18 @@ int main(void)
     as[2] = 2;
     as[3] = 3;
 
+    short t = -1;
+    short *pt;
+    short &&rrt = std::move(t);
+    pt = &rrt;
+    short *&&rrpt = std::move(pt);
+    short at[4];
+    at[0] = 0;
+    at[1] = 1;
+    at[2] = 2;
+    at[3] = 3;
+    short (&&rrat)[4] = std::move(at);
+
     marker1();
 
     main2();
@@ -66,15 +80,25 @@ int main2(void)
     float F;
     double D;
     char &rC = C;
+    char &&rrC = 'A';
     unsigned char &rUC = UC;
+    unsigned char &&rrUC = 21;
     short &rS = S;
+    short &&rrS = -14;
     unsigned short &rUS = US;
+    unsigned short &&rrUS = 7;
     int &rI = I;
+    int &&rrI = 102;
     unsigned int &rUI = UI;
+    unsigned int &&rrUI = 1002;
     long &rL = L;
+    long &&rrL = -234;
     unsigned long &rUL = UL;
+    unsigned long &&rrUL = 234;
     float &rF = F;
+    float &&rrF = 1.25E10;
     double &rD = D;
+    double &&rrD = -1.375E-123;
     C = 'A';
     UC = 21;
     S = -14;
diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp
index 3b557f9..5c7c0e5 100644
--- a/gdb/testsuite/gdb.cp/ref-types.exp
+++ b/gdb/testsuite/gdb.cp/ref-types.exp
@@ -24,7 +24,7 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -127,6 +127,47 @@ gdb_test "print ras\[1\]" ".\[0-9\]* = 1" "print value of ras\[1\]"
 gdb_test "print ras\[2\]" ".\[0-9\]* = 2" "print value of ras\[2\]"
 gdb_test "print ras\[3\]" ".\[0-9\]* = 3" "print value of ras\[3\]"
 
+# rvalue reference tests
+
+gdb_test_multiple "print rrt" "print value of rrt" {
+    -re ".\[0-9\]* = \\(short &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    -re ".\[0-9\]* = \\(short int &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
+}
+
+gdb_test_multiple "ptype rrt" "ptype rrt" {
+    -re "type = short &&.*$gdb_prompt $"  { pass "ptype rrt" }
+    -re "type = short int &&.*$gdb_prompt $"  { pass "ptype rrt" }
+}
+
+gdb_test "print *rrpt" ".\[0-9\]* = -1" "print value of *rrpt"
+
+# gdb had a bug about dereferencing a pointer type
+# that would lead to wrong results
+# if we try to examine memory at pointer value.
+
+gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
+
+gdb_test_multiple "ptype rrpt" "ptype rrpt" {
+    -re "type = short \\*&&.*$gdb_prompt $"  { pass "ptype rrpt" }
+    -re "type = short int \\*&&.*$gdb_prompt $"  { pass "ptype rrpt" }
+}
+
+gdb_test "print rrat\[0\]" ".\[0-9\]* = 0" "print value of rrat\[0\]"
+
+gdb_test_multiple "ptype rrat" "ptype rrat" {
+    -re "type = short \\\(&&\\\)\\\[4\\\].*$gdb_prompt $"  { pass "ptype rrat" }
+    -re "type = short int \\\(&&\\\)\\\[4\\\].*$gdb_prompt $"  { pass "ptype rrat" }
+}
+
+gdb_test "print rrat\[1\]" ".\[0-9\]* = 1" "print value of rrat\[1\]"
+gdb_test "print rrat\[2\]" ".\[0-9\]* = 2" "print value of rrat\[2\]"
+gdb_test "print rrat\[3\]" ".\[0-9\]* = 3" "print value of rrat\[3\]"
+
 
 if ![runto 'f'] then {
     perror "couldn't run to f"
@@ -270,3 +311,96 @@ gdb_test "print rD" \
     ".\[0-9\]* = \\(double &\\) @$hex: -1.375e-123.*" \
     "print value of rD"
 
+#
+# test rvalue reference types
+#
+
+gdb_test "ptype rrC" "type = char &&"
+
+gdb_test "ptype rrUC" "type = unsigned char &&"
+
+gdb_test_multiple "ptype rrS" "ptype rrS" {
+    -re "type = short &&.*$gdb_prompt $"  { pass "ptype rrS" }
+    -re "type = short int &&.*$gdb_prompt $"  { pass "ptype rrS" }
+}
+
+gdb_test_multiple "ptype rrUS" "ptype rrUS" {
+    -re "type = unsigned short &&.*$gdb_prompt $"  { pass "ptype rrUS" }
+    -re "type = short unsigned int &&.*$gdb_prompt $"  { pass "ptype rrUS" }
+}
+
+gdb_test "ptype rrI" "type = int &&"
+
+gdb_test "ptype rrUI" "type = unsigned int &&"
+
+gdb_test_multiple "ptype rrL" "ptype rrL" {
+    -re "type = long &&.*$gdb_prompt $"  { pass "ptype rrL" }
+    -re "type = long int &&.*$gdb_prompt $"  { pass "ptype rrL" }
+}
+
+gdb_test_multiple "ptype rrUL" "ptype rrUL" {
+    -re "type = unsigned long &&.*$gdb_prompt $"  { pass "ptype rrUL" }
+    -re "type = long unsigned int &&.*$gdb_prompt $"  { pass "ptype rrUL" }
+}
+
+gdb_test "ptype rrF" "type = float &&"
+
+gdb_test "ptype rrD" "type = double &&"
+
+gdb_test "print rrC" ".\[0-9\]* = \\(char &&\\) @$hex: 65 \'A\'" \
+    "print value of rrC"
+
+gdb_test "print rrUC" \
+    ".\[0-9\]* = \\(unsigned char &&\\) @$hex: 21 \'.025\'" \
+    "print value of rrUC"
+
+gdb_test_multiple "print rrS" "print value of rrS" {
+    -re ".\[0-9\]* = \\(short &&\\) @$hex: -14.*$gdb_prompt $" {
+        pass "print value of rrS"
+    }
+    -re ".\[0-9\]* = \\(short int &&\\) @$hex: -14.*$gdb_prompt $" {
+        pass "print value of rrS"
+    }
+}
+
+gdb_test_multiple "print rrUS" "print value of rrUS" {
+    -re ".\[0-9\]* = \\(unsigned short &&\\) @$hex: 7.*$gdb_prompt $" {
+        pass "print value of rrUS"
+    }
+    -re ".\[0-9\]* = \\(short unsigned int &&\\) @$hex: 7.*$gdb_prompt $" {
+        pass "print value of rrUS"
+    }
+}
+
+gdb_test "print rrI" ".\[0-9\]* = \\(int &&\\) @$hex: 102" \
+	"print value of rrI"
+
+gdb_test "print rrUI" \
+    ".\[0-9\]* = \\(unsigned int &&\\) @$hex: 1002" \
+        "print value of UI"
+
+gdb_test_multiple "print rrL" "print value of rrL" {
+    -re ".\[0-9\]* = \\(long &&\\) @$hex: -234.*$gdb_prompt $" {
+        pass "print value of rrL"
+    }
+    -re ".\[0-9\]* = \\(long int &&\\) @$hex: -234.*$gdb_prompt $" {
+        pass "print value of rrL"
+    }
+}
+
+gdb_test_multiple "print rrUL" "print value of rrUL" {
+    -re ".\[0-9\]* = \\(unsigned long &&\\) @$hex: 234.*$gdb_prompt $" {
+        pass "print value of rrUL"
+    }
+    -re ".\[0-9\]* = \\(long unsigned int &&\\) @$hex: 234.*$gdb_prompt $" {
+        pass "print value of rrUL"
+    }
+}
+
+gdb_test "print rrF" \
+    ".\[0-9\]* = \\(float &&\\) @$hex: 1.2\[0-9\]*e\\+0?10.*" \
+    "print value of rrF"
+
+gdb_test "print rrD" \
+    ".\[0-9\]* = \\(double &&\\) @$hex: -1.375e-123.*" \
+    "print value of rrD"
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (8 preceding siblings ...)
  2016-01-19 18:55   ` [PATCH v2 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
@ 2016-01-19 18:55   ` Artemiy Volkov
  2016-02-19 19:46     ` Keith Seitz
  2016-01-19 18:55   ` [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
                     ` (2 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:55 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch introduces changes to rank_one_type() dealing with ranking an rvalue
reference type when selecting a best viable function from a set of candidate
functions. The 3 new added rules for rvalue references are:

1) An rvalue argument cannot be bound to a non-const lvalue reference parameter
and an lvalue argument cannot be bound to an rvalue reference parameter.
[C++11 13.3.3.1.4p3]

2) If a conversion to one type of reference is an identity conversion, and a
conversion to the second type of reference is a non-identity conversion, choose
the first type. [C++11 13.3.3.2p3]

3) An rvalue should be first tried to bind to an rvalue reference, and then to
an lvalue reference. [C++11 13.3.3.2p3]

4) An lvalue reference to a function gets higher priority than an rvalue
reference to a function. [C++11 13.3.3.2p3]

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/gdbtypes.c (rank_one_type): Implement overloading
        resolution rules regarding rvalue references.
---
 gdb/gdbtypes.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index fd17d3c..4bb98c9 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -58,6 +58,8 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
 const struct rank BOOL_CONVERSION_BADNESS = {3,0};
 const struct rank BASE_CONVERSION_BADNESS = {2,0};
 const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0};
+const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0};
 const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
 const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
 const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
@@ -3464,6 +3466,20 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 {
   struct rank rank = {0,0};
 
+  /* Disallow an rvalue argument to bind to a non-const lvalue reference
+     parameter and an lvalue argument to bind to an rvalue reference
+     parameter. */
+
+  if ((value != NULL)
+      &&
+      ((TYPE_CODE (parm) == TYPE_CODE_REF
+       && !TYPE_CONST (parm->main_type->target_type)
+       && VALUE_LVAL (value) == not_lval)
+      ||
+       (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF
+       && VALUE_LVAL (value) != not_lval)))
+    return INCOMPATIBLE_TYPE_BADNESS;
+
   if (types_equal (parm, arg))
     return EXACT_MATCH_BADNESS;
 
@@ -3473,6 +3489,36 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
   if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
     arg = check_typedef (arg);
 
+  /* An lvalue reference to a function should get higher priority than an
+     rvalue reference to a function. */
+
+  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
+      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
+    return (sum_ranks (rank_one_type (parm,
+            lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
+            DIFFERENT_REFERENCE_TYPE_BADNESS));
+
+  /* If a conversion to one type of reference is an identity conversion, and a
+     conversion to the second type of reference is a non-identity conversion,
+     choose the first type. */
+
+  if (value != NULL && TYPE_REFERENCE (parm) && TYPE_REFERENCE (arg)
+     && TYPE_CODE (parm) != TYPE_CODE (arg))
+    return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
+            TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
+
+  /* An rvalue should be first tried to bind to an rvalue reference, and then to
+     an lvalue reference. */
+
+  if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
+      && VALUE_LVAL (value) == not_lval)
+    {
+      if (TYPE_REFERENCE (arg))
+	arg = TYPE_TARGET_TYPE (arg);
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
+			 LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
+    }
+
   /* See through references, since we can almost make non-references
      references.  */
 
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (9 preceding siblings ...)
  2016-01-19 18:55   ` [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2016-01-19 18:55   ` Artemiy Volkov
  2016-02-19 19:01     ` Keith Seitz
  2016-02-19 18:49   ` [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:55 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

In almost all contexts (except for overload resolution rules and expression
semantics), lvalue and rvalue references are equivalent. That means that in
all but these cases we can replace a TYPE_CODE_REF check to TYPE_REFERENCE
check. This patch does exactly that.

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/aarch64-tdep.c (aarch64_type_align): Change TYPE_CODE_REF
        check to TYPE_REFERENCE check.
        (aarch64_extract_return_value): Likewise.
        (aarch64_store_return_value): Likewise.
        * gdb/amd64-tdep.c (amd64_classify): Likewise.
        * gdb/amd64-windows-tdep.c (amd64_windows_passed_by_integer_register):
        Likewise.
        * gdb/arm-tdep.c (arm_type_align): Likewise.
        (arm_extract_return_value): Likewise.
        (arm_store_return_value): Likewise.
        * gdb/ax-gdb.c (gen_fetch): Likewise.
        (gen_cast): Likewise.
        * gdb/c-typeprint.c (c_print_type): Likewise.
        * gdb/c-varobj.c (adjust_value_for_child_access): Likewise.
        (c_value_of_variable): Likewise.
        (cplus_number_of_children): Likewise.
        (cplus_describe_child): Likewise.
        * gdb/compile/compile-c-symbols.c (generate_vla_size): Likewise.
        * gdb/completer.c (expression_completer): Likewise.
        * gdb/cp-support.c (make_symbol_overload_list_adl_namespace):
        Likewise.
        * gdb/darwin-nat-info.c (info_mach_region_command): Likewise.
        * gdb/dwarf2loc.c (entry_data_value_coerce_ref): Likewise.
        (value_of_dwarf_reg_entry): Likewise.
        * gdb/eval.c (ptrmath_type_p): Likewise.
        (evaluate_subexp_standard): Likewise.
        (evaluate_subexp_for_address): Likewise.
        (evaluate_subexp_for_sizeof): Likewise.
        * gdb/findvar.c (extract_typed_address): Likewise.
        (store_typed_address): Likewise.
        * gdb/gdbtypes.c (rank_one_type): Likewise.
        * gdb/hppa-tdep.c (hppa64_integral_or_pointer_p): Likewise.
        * gdb/infcall.c (value_arg_coerce): Likewise.
        * gdb/language.c (pointer_type): Likewise.
        * gdb/m32c-tdep.c (m32c_reg_arg_type): Likewise.
        (m32c_m16c_address_to_pointer): Likewise.
        (m32c_m16c_pointer_to_address): Likewise.
        * gdb/m88k-tdep.c (m88k_integral_or_pointer_p): Likewise.
        * gdb/mn10300-tdep.c (mn10300_type_align): Likewise.
        * gdb/msp430-tdep.c (msp430_push_dummy_call): Likewise.
        * gdb/ppc-sysv-tdep.c (do_ppc_sysv_return_value): Likewise.
        (ppc64_sysv_abi_push_param): Likewise.
        (ppc64_sysv_abi_return_value): Likewise.
        * gdb/printcmd.c (print_formatted): Likewise.
        (x_command): Likewise.
        * gdb/python/py-type.c (typy_get_composite): Likewise.
        (typy_template_argument): Likewise.
        * gdb/python/py-value.c (valpy_referenced_value): Likewise.
        (valpy_get_dynamic_type): Likewise.
        (value_has_field): Likewise.
        (valpy_getitem): Likewise.
        * gdb/python/py-xmethods.c (gdbpy_get_xmethod_result_type):
        Handle TYPE_CODE_VALUE_REF type.
        (gdbpy_invoke_xmethod): Likewise.
        * gdb/s390-linux-tdep.c (s390_function_arg_integer): Change
        TYPE_CODE_REF check to TYPE_REFERENCE check.
        * gdb/sparc-tdep.c (sparc_integral_or_pointer_p): Likewise.
        * gdb/sparc64-tdep.c (sparc64_integral_or_pointer_p): Likewise.
        * gdb/spu-tdep.c (spu_scalar_value_p): Likewise.
        * gdb/symtab.c (lookup_symbol_aux): Likewise.
        * gdb/typeprint.c (whatis_exp): Likewise.
        (print_type_scalar): Likewise.
        * gdb/valarith.c (binop_types_user_defined_p): Likewise.
        (unop_user_defined_p): Likewise.
        * gdb/valops.c (value_cast_pointers): Likewise.
        (value_cast): Likewise.
        (value_reinterpret_cast): Likewise.
        (value_dynamic_cast): Likewise.
        (value_addr): Likewise.
        (typecmp): Likewise.
        (value_struct_elt): Likewise.
        (value_struct_elt_bitpos): Likewise.
        (value_find_oload_method_list): Likewise.
        (find_overload_match): Likewise.
        (value_rtti_indirect_type): Likewise.
        * gdb/valprint.c (val_print_scalar_type_p): Likewise.
        (generic_val_print): Likewise.
        * gdb/value.c (value_actual_type): Likewise.
        (value_as_address): Likewise.
        (unpack_long): Likewise.
        (pack_long): Likewise.
        (pack_unsigned_long): Likewise.
        (coerce_ref_if_computed): Likewise.
        (coerce_ref): Likewise. Likewise.
        * gdb/varobj.c (varobj_get_value_type): Likewise.
---
 gdb/aarch64-tdep.c              |  5 +++--
 gdb/amd64-tdep.c                |  2 +-
 gdb/amd64-windows-tdep.c        |  1 +
 gdb/arm-tdep.c                  |  5 +++--
 gdb/ax-gdb.c                    |  2 ++
 gdb/c-typeprint.c               |  2 +-
 gdb/c-varobj.c                  | 10 ++++-----
 gdb/compile/compile-c-symbols.c |  2 +-
 gdb/completer.c                 |  3 +--
 gdb/cp-support.c                |  2 +-
 gdb/darwin-nat-info.c           |  2 +-
 gdb/dwarf2loc.c                 |  4 ++--
 gdb/eval.c                      | 16 +++++++-------
 gdb/findvar.c                   |  6 ++----
 gdb/gdbtypes.c                  |  5 +++--
 gdb/hppa-tdep.c                 |  1 +
 gdb/infcall.c                   |  3 ++-
 gdb/language.c                  |  3 +--
 gdb/m32c-tdep.c                 |  8 +++----
 gdb/m88k-tdep.c                 |  1 +
 gdb/mn10300-tdep.c              |  1 +
 gdb/msp430-tdep.c               |  2 +-
 gdb/ppc-sysv-tdep.c             | 10 ++++-----
 gdb/printcmd.c                  |  4 ++--
 gdb/python/py-type.c            |  5 ++---
 gdb/python/py-value.c           | 13 +++++------
 gdb/python/py-xmethods.c        | 15 +++++++++++++
 gdb/s390-linux-tdep.c           |  2 +-
 gdb/sparc-tdep.c                |  1 +
 gdb/sparc64-tdep.c              |  1 +
 gdb/spu-tdep.c                  |  1 +
 gdb/symtab.c                    |  3 +--
 gdb/typeprint.c                 |  4 ++--
 gdb/valarith.c                  |  6 +++---
 gdb/valops.c                    | 48 ++++++++++++++++++-----------------------
 gdb/valprint.c                  |  5 +++--
 gdb/value.c                     | 12 ++++++-----
 gdb/varobj.c                    |  2 +-
 38 files changed, 117 insertions(+), 101 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index c7da618..775fc03 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -890,6 +890,7 @@ aarch64_type_align (struct type *t)
     case TYPE_CODE_RANGE:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -1613,7 +1614,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the the type is a plain integer, then the access is
@@ -1754,7 +1755,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index fae92b2..405e483 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -643,7 +643,7 @@ amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_CHAR
-       || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
+       || code == TYPE_CODE_PTR || TYPE_REFERENCE (type))
       && (len == 1 || len == 2 || len == 4 || len == 8))
     theclass[0] = AMD64_INTEGER;
 
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index e05502e..6ae594d 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -55,6 +55,7 @@ amd64_windows_passed_by_integer_register (struct type *type)
       case TYPE_CODE_CHAR:
       case TYPE_CODE_PTR:
       case TYPE_CODE_REF:
+      case TYPE_CODE_RVALUE_REF:
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
 	return (TYPE_LENGTH (type) == 1
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index ccc2a03..01f77ba 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3245,6 +3245,7 @@ arm_type_align (struct type *t)
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -7826,7 +7827,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the type is a plain integer, then the access is
@@ -8031,7 +8032,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= 4)
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 7f250e9..23fe3d0 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -492,6 +492,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
@@ -1002,6 +1003,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* It's implementation-defined, and I'll bet this is what GCC
          does.  */
       break;
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 67129ad..47be804 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-                 || TYPE_REFERENCE (type))))
+		  || TYPE_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 48e16f9..75e8850 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -78,7 +78,7 @@ adjust_value_for_child_access (struct value **value,
      to us, is already supposed to be
      reference-stripped.  */
 
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+  gdb_assert (!TYPE_REFERENCE (*type));
 
   /* Pointers to structures are treated just like
      structures when accessing children.  Don't
@@ -489,7 +489,7 @@ c_value_of_variable (const struct varobj *var,
   struct type *type = get_type (var);
 
   /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
@@ -586,7 +586,7 @@ cplus_number_of_children (const struct varobj *var)
       if (opts.objectprint)
         {
           value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+          lookup_actual_type = (TYPE_REFERENCE (var->type)
 				|| TYPE_CODE (var->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -623,7 +623,7 @@ cplus_number_of_children (const struct varobj *var)
 	  const struct varobj *parent = var->parent;
 
 	  value = parent->value;
-	  lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+	  lookup_actual_type = (TYPE_REFERENCE (parent->type)
 				|| TYPE_CODE (parent->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -728,7 +728,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
   var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
   if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+    lookup_actual_type = (TYPE_REFERENCE (var->type)
 			  || TYPE_CODE (var->type) == TYPE_CODE_PTR);
   value = var->value;
   type = varobj_get_value_type (var);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index dcd530d..ab9e49e 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -593,7 +593,7 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
diff --git a/gdb/completer.c b/gdb/completer.c
index 5c3b3fc..9e564a4 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -610,8 +610,7 @@ expression_completer (struct cmd_list_element *ignore,
       for (;;)
 	{
 	  type = check_typedef (type);
-	  if (TYPE_CODE (type) != TYPE_CODE_PTR
-	      && TYPE_CODE (type) != TYPE_CODE_REF)
+	  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
 	    break;
 	  type = TYPE_TARGET_TYPE (type);
 	}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 1dde382..fb7e0dc 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1279,7 +1279,7 @@ make_symbol_overload_list_adl_namespace (struct type *type,
   int i, prefix_len;
 
   while (TYPE_CODE (type) == TYPE_CODE_PTR
-	 || TYPE_CODE (type) == TYPE_CODE_REF
+	 || TYPE_REFERENCE (type)
          || TYPE_CODE (type) == TYPE_CODE_ARRAY
          || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
     {
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 314d265..02fc7e6 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -732,7 +732,7 @@ info_mach_region_command (char *exp, int from_tty)
 
   expr = parse_expression (exp);
   val = evaluate_expression (expr);
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (value_type (val)))
     {
       val = value_ind (val);
     }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index ba6ed42..4630674 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1337,7 +1337,7 @@ entry_data_value_coerce_ref (const struct value *value)
   struct type *checked_type = check_typedef (value_type (value));
   struct value *target_val;
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+  if (!TYPE_REFERENCE (checked_type))
     return NULL;
 
   target_val = (struct value *) value_computed_closure (value);
@@ -1412,7 +1412,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      TYPE_CODE_REF with non-entry data value would give current value - not the
      entry value.  */
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+  if (!TYPE_REFERENCE (checked_type)
       || TYPE_TARGET_TYPE (checked_type) == NULL)
     return outer_val;
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 729f473..443a08c 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -640,7 +640,7 @@ static int
 ptrmath_type_p (const struct language_defn *lang, struct type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     type = TYPE_TARGET_TYPE (type);
 
   switch (TYPE_CODE (type))
@@ -2509,7 +2509,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	{
 	  type = check_typedef (value_type (arg1));
 	  if (TYPE_CODE (type) == TYPE_CODE_PTR
-	      || TYPE_CODE (type) == TYPE_CODE_REF
+	      || TYPE_REFERENCE (type)
 	  /* In C you can dereference an array to get the 1st elt.  */
 	      || TYPE_CODE (type) == TYPE_CODE_ARRAY
 	    )
@@ -2787,9 +2787,9 @@ evaluate_subexp_standard (struct type *expect_type,
 	    {
 	      struct type *type = value_type (result);
 
-	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+	      if (!TYPE_REFERENCE (type))
 		{
-                 type = lookup_lvalue_reference_type (type);
+		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
@@ -2890,7 +2890,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (SYMBOL_TYPE (var)))
 	goto default_case;
 
       (*pos) += 4;
@@ -2929,7 +2929,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 	{
 	  struct type *type = check_typedef (value_type (x));
 
-	  if (TYPE_CODE (type) == TYPE_CODE_REF)
+	  if (TYPE_REFERENCE (type))
 	    return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			       not_lval);
 	  else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
@@ -3019,7 +3019,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = check_typedef (value_type (val));
       if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF
+	  && !TYPE_REFERENCE (type)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
@@ -3091,7 +3091,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
      the size of the referenced type."  */
   type = check_typedef (type);
   if (exp->language_defn->la_language == language_cplus
-      && TYPE_CODE (type) == TYPE_CODE_REF)
+      && (TYPE_REFERENCE (type)))
     type = check_typedef (TYPE_TARGET_TYPE (type));
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a39d897..f0fd6cb 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -169,8 +169,7 @@ extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
 CORE_ADDR
 extract_typed_address (const gdb_byte *buf, struct type *type)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("extract_typed_address: "
 		    "type is not a pointer or reference"));
@@ -242,8 +241,7 @@ store_unsigned_integer (gdb_byte *addr, int len,
 void
 store_typed_address (gdb_byte *buf, struct type *type, CORE_ADDR addr)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("store_typed_address: "
 		    "type is not a pointer or reference"));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 058b77d..fd17d3c 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3475,10 +3475,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   /* See through references, since we can almost make non-references
      references.  */
-  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+  if (TYPE_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                        REFERENCE_CONVERSION_BADNESS));
-  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                        REFERENCE_CONVERSION_BADNESS));
   if (overload_debug)
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index ac507e7..afb3b5e 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -902,6 +902,7 @@ hppa64_integral_or_pointer_p (const struct type *type)
       }
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return (TYPE_LENGTH (type) == 8);
     default:
       break;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index ad2512a..5349156 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -158,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	struct value *new_value;
 
-	if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+	if (TYPE_REFERENCE (arg_type))
 	  return value_cast_pointers (type, arg, 0);
 
 	/* Cast the value to the reference's target type, and then
diff --git a/gdb/language.c b/gdb/language.c
index 78ec422..a9d88d6 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -410,8 +410,7 @@ language_info (int quietly)
 int
 pointer_type (struct type *type)
 {
-  return TYPE_CODE (type) == TYPE_CODE_PTR ||
-    TYPE_CODE (type) == TYPE_CODE_REF;
+  return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type);
 }
 
 \f
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 90bd732..0b035c7 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2031,7 +2031,7 @@ m32c_reg_arg_type (struct type *type)
   return (code == TYPE_CODE_INT
 	  || code == TYPE_CODE_ENUM
 	  || code == TYPE_CODE_PTR
-	  || code == TYPE_CODE_REF
+	  || TYPE_REFERENCE (type)
 	  || code == TYPE_CODE_BOOL
 	  || code == TYPE_CODE_CHAR);
 }
@@ -2453,8 +2453,7 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   enum type_code target_code;
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type));
 
   target_code = TYPE_CODE (TYPE_TARGET_TYPE (type));
 
@@ -2533,8 +2532,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR ptr;
   enum type_code target_code;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type));
 
   ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index 1a3c2cd..2a90a3a 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -165,6 +165,7 @@ m88k_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	/* Allow only 32-bit pointers.  */
 	return (TYPE_LENGTH (type) == 4);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 62d4ca1..79f5c85 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -96,6 +96,7 @@ mn10300_type_align (struct type *type)
     case TYPE_CODE_FLT:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type);
 
     case TYPE_CODE_COMPLEX:
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 4042ec3..1f8121a 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -769,7 +769,7 @@ msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 		  if (code_model == MSP_LARGE_CODE_MODEL
 		      && (TYPE_CODE (arg_type) == TYPE_CODE_PTR
-		          || TYPE_CODE (arg_type) == TYPE_CODE_REF
+		          || TYPE_REFERENCE (arg_type)
 			  || TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
 			  || TYPE_CODE (arg_type) == TYPE_CODE_UNION))
 		    {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 140d993..8a89b8e 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -805,7 +805,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF
+	    || TYPE_REFERENCE (type)
 	    || TYPE_CODE (type) == TYPE_CODE_ENUM)
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -1493,7 +1493,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF)
+	    || TYPE_REFERENCE (type))
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1505,8 +1505,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 
 	  /* Convert any function code addresses into descriptors.  */
 	  if (tdep->elf_abi == POWERPC_ELF_V1
-	      && (TYPE_CODE (type) == TYPE_CODE_PTR
-		  || TYPE_CODE (type) == TYPE_CODE_REF))
+	      && (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_REFERENCE (type)))
 	    {
 	      struct type *target_type
 		= check_typedef (TYPE_TARGET_TYPE (type));
@@ -1999,8 +1998,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 8acf441..c7d3459 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -306,7 +306,7 @@ print_formatted (struct value *val, int size,
     }
 
   if (options->format == 0 || options->format == 's'
-      || TYPE_CODE (type) == TYPE_CODE_REF
+      || TYPE_REFERENCE (type)
       || TYPE_CODE (type) == TYPE_CODE_ARRAY
       || TYPE_CODE (type) == TYPE_CODE_STRING
       || TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -1449,7 +1449,7 @@ x_command (char *exp, int from_tty)
 	*exp = 0;
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
-      if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index a66f7ba..dcdc20f 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -485,8 +485,7 @@ typy_get_composite (struct type *type)
 	}
       END_CATCH
 
-      if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF)
+      if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_REFERENCE (type))
 	break;
       type = TYPE_TARGET_TYPE (type);
     }
@@ -966,7 +965,7 @@ typy_template_argument (PyObject *self, PyObject *args)
   TRY
     {
       type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (type))
 	type = check_typedef (TYPE_TARGET_TYPE (type));
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 97ac91a..81d1225 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -217,6 +217,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -358,8 +359,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
 	  struct value *target;
@@ -598,9 +598,8 @@ value_has_field (struct value *v, PyObject *field)
     {
       val_type = value_type (v);
       val_type = check_typedef (val_type);
-      if (TYPE_CODE (val_type) == TYPE_CODE_REF
-	  || TYPE_CODE (val_type) == TYPE_CODE_PTR)
-      val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
+      if (TYPE_REFERENCE (val_type) || TYPE_CODE (val_type) == TYPE_CODE_PTR)
+        val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
 
       type_code = TYPE_CODE (val_type);
       if ((type_code == TYPE_CODE_STRUCT || type_code == TYPE_CODE_UNION)
@@ -767,6 +766,8 @@ valpy_getitem (PyObject *self, PyObject *key)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
            res_val = value_cast (lookup_lvalue_reference_type (base_class_type), tmp);
+	  else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+           res_val = value_cast (lookup_rvalue_reference_type (base_class_type), tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
@@ -1016,7 +1017,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index d70cdd1..8535bfc 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -555,6 +555,13 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
+  else if (TYPE_CODE (obj_type) == TYPE_CODE_RVALUE_REF)
+    {
+      struct type *this_ref = lookup_rvalue_reference_type (this_type);
+
+      if (!types_equal (obj_type, this_ref))
+	obj = value_cast (this_ref, obj);
+    }
   else
     {
       if (!types_equal (obj_type, this_type))
@@ -641,6 +648,14 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
+  else if (TYPE_CODE (obj_type) == TYPE_CODE_RVALUE_REF)
+    {
+      struct type *this_ref = lookup_rvalue_reference_type (this_type);
+
+      if (!types_equal (obj_type, this_ref))
+	obj = value_cast (this_ref, obj);
+    }
+
   else
     {
       if (!types_equal (obj_type, this_type))
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index e827684..57e508e 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3004,7 +3004,7 @@ s390_function_arg_integer (struct type *type)
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_BOOL
       || code == TYPE_CODE_PTR
-      || code == TYPE_CODE_REF)
+      || TYPE_REFERENCE (type))
     return 1;
 
   return ((code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index b85b15f..590b091 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -225,6 +225,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 5e8f17d..382fbc5 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -67,6 +67,7 @@ sparc64_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	int len = TYPE_LENGTH (type);
 	gdb_assert (len == 8);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index 95ca8ab..5f3c6d6 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1338,6 +1338,7 @@ spu_scalar_value_p (struct type *type)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type) <= 16;
 
     default:
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 95b3a11..98cd54d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2145,8 +2145,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
 	  /* I'm not really sure that type of this can ever
 	     be typedefed; just be safe.  */
 	  t = check_typedef (t);
-	  if (TYPE_CODE (t) == TYPE_CODE_PTR
-	      || TYPE_CODE (t) == TYPE_CODE_REF)
+	  if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
 	    t = TYPE_TARGET_TYPE (t);
 
 	  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 48a809b..5343a3c 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -463,8 +463,7 @@ whatis_exp (char *exp, int show)
   get_user_print_options (&opts);
   if (opts.objectprint)
     {
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
         real_type = value_rtti_indirect_type (val, &full, &top, &using_enc);
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -581,6 +580,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_NAMESPACE:
       error (_("internal error: unhandled type in print_type_scalar"));
       break;
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 7959f3b..2cf4939 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -239,11 +239,11 @@ binop_types_user_defined_p (enum exp_opcode op,
     return 0;
 
   type1 = check_typedef (type1);
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
   type2 = check_typedef (type2);
-  if (TYPE_CODE (type2) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
   return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
@@ -277,7 +277,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   if (op == UNOP_ADDR)
     return 0;
   type1 = check_typedef (value_type (arg1));
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
   return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
 }
diff --git a/gdb/valops.c b/gdb/valops.c
index cc01689..b4f9ba5 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
     {
       struct value *v2;
 
-      if (TYPE_CODE (type2) == TYPE_CODE_REF)
+      if (TYPE_REFERENCE (type2))
 	v2 = coerce_ref (arg2);
       else
 	v2 = value_ind (arg2);
@@ -360,24 +360,20 @@ value_cast (struct type *type, struct value *arg2)
   if (value_type (arg2) == type)
     return arg2;
 
-  code1 = TYPE_CODE (check_typedef (type));
-
   /* Check if we are casting struct reference to struct reference.  */
-  if (code1 == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (check_typedef (type)))
     {
       /* We dereference type; then we recurse and finally
          we generate value of the given reference.  Nothing wrong with 
 	 that.  */
       struct type *t1 = check_typedef (type);
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
-      struct value *val =  value_cast (dereftype, arg2);
+      struct value *val = value_cast (dereftype, arg2);
 
       return value_ref (val, TYPE_CODE (t1));
     }
 
-  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
-
-  if (code2 == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (check_typedef (value_type (arg2))))
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
@@ -388,7 +384,7 @@ value_cast (struct type *type, struct value *arg2)
 
   /* You can't cast to a reference type.  See value_cast_pointers
      instead.  */
-  gdb_assert (code1 != TYPE_CODE_REF);
+  gdb_assert (!TYPE_REFERENCE (type));
 
   /* A cast to an undetermined-length array_type, such as 
      (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
@@ -591,8 +587,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
   dest_type = type;
 
   /* If we are casting to a reference type, transform
-     reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V).  */
-  if (TYPE_CODE (real_type) == TYPE_CODE_REF)
+     reinterpret_cast<T&[&]>(V) to *reinterpret_cast<T*>(&V).  */
+  if (TYPE_REFERENCE (real_type))
     {
       is_ref = 1;
       arg = value_addr (arg);
@@ -730,10 +726,10 @@ value_dynamic_cast (struct type *type, struct value *arg)
   struct type *class_type, *rtti_type;
   struct value *result, *tem, *original_arg = arg;
   CORE_ADDR addr;
-  int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
+  int is_ref = TYPE_REFERENCE (resolved_type);
 
   if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
-      && TYPE_CODE (resolved_type) != TYPE_CODE_REF)
+      && !TYPE_REFERENCE (resolved_type))
     error (_("Argument to dynamic_cast must be a pointer or reference type"));
   if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
       && TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
@@ -1461,9 +1457,9 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     {
-      /* Copy the value, but change the type from (T&) to (T*).  We
+      /* Copy the value, but change the type from (T&[&]) to (T*).  We
          keep the same location information, which is efficient, and
          allows &(&X) to get the location containing the reference.  */
       arg2 = value_copy (arg1);
@@ -1711,7 +1707,7 @@ typecmp (int staticp, int varargs, int nargs,
       tt1 = check_typedef (t1[i].type);
       tt2 = check_typedef (value_type (t2[i]));
 
-      if (TYPE_CODE (tt1) == TYPE_CODE_REF
+      if ((TYPE_REFERENCE (tt1))
 	  /* We should be doing hairy argument matching, as below.  */
 	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
 	      == TYPE_CODE (tt2)))
@@ -1729,14 +1725,12 @@ typecmp (int staticp, int varargs, int nargs,
 	 char *>, and properly access map["hello"], because the
 	 argument to [] will be a reference to a pointer to a char,
 	 and the argument will be a pointer to a char.  */
-      while (TYPE_CODE(tt1) == TYPE_CODE_REF
-	     || TYPE_CODE (tt1) == TYPE_CODE_PTR)
-	{
+      while (TYPE_REFERENCE(tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR) {
 	  tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
 	}
       while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
 	     || TYPE_CODE(tt2) == TYPE_CODE_PTR
-	     || TYPE_CODE(tt2) == TYPE_CODE_REF)
+	     || TYPE_REFERENCE(tt2))
 	{
 	  tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
 	}
@@ -2128,7 +2122,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
   /* Follow pointers until we get to a non-pointer.  */
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2217,7 +2211,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
 
   t = check_typedef (value_type (*argp));
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
@@ -2378,7 +2372,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
   t = check_typedef (value_type (*argp));
 
   /* Code snarfed from value_struct_elt.  */
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2789,7 +2783,7 @@ find_overload_match (struct value **args, int nargs,
 
       if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
 	  && (TYPE_CODE (objtype) == TYPE_CODE_PTR
-	      || TYPE_CODE (objtype) == TYPE_CODE_REF))
+	      || TYPE_REFERENCE (objtype)))
 	{
 	  temp = value_addr (temp);
 	}
@@ -3586,7 +3580,7 @@ value_rtti_indirect_type (struct value *v, int *full,
 
   type = value_type (v);
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     target = coerce_ref (v);
   else if (TYPE_CODE (type) == TYPE_CODE_PTR)
     {
@@ -3619,8 +3613,8 @@ value_rtti_indirect_type (struct value *v, int *full,
       target_type = value_type (target);
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_lvalue_reference_type (real_type);
+      if (TYPE_REFERENCE (type))
+        real_type = lookup_reference_type (real_type, TYPE_CODE (type));
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
diff --git a/gdb/valprint.c b/gdb/valprint.c
index a9b03ec..d3929ee 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -276,7 +276,7 @@ int
 val_print_scalar_type_p (struct type *type)
 {
   type = check_typedef (type);
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_REFERENCE (type))
     {
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
@@ -478,7 +478,7 @@ generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
 			      original_value, options, 0, stream);
 }
 
-/* generic_val_print helper for TYPE_CODE_REF.  */
+/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */
 
 static void
 generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
@@ -849,6 +849,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
 			     original_value, options);
       break;
diff --git a/gdb/value.c b/gdb/value.c
index eeb2b7d..6d7b09e 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1129,8 +1129,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
     {
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
 	 fetch its rtti type.  */
-      if ((TYPE_CODE (result) == TYPE_CODE_PTR
-	  || TYPE_CODE (result) == TYPE_CODE_REF)
+      if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_REFERENCE (result))
 	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
 	     == TYPE_CODE_STRUCT)
         {
@@ -2782,7 +2781,7 @@ value_as_address (struct value *val)
      ABI-specific code is a more reasonable place to handle it.  */
 
   if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && !TYPE_REFERENCE (value_type (val))
       && gdbarch_integer_to_address_p (gdbarch))
     return gdbarch_integer_to_address (gdbarch, value_type (val),
 				       value_contents (val));
@@ -2839,6 +2838,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
          whether we want this to be true eventually.  */
       return extract_typed_address (valaddr, type);
@@ -3425,6 +3425,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3461,6 +3462,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3668,7 +3670,7 @@ coerce_ref_if_computed (const struct value *arg)
 {
   const struct lval_funcs *funcs;
 
-  if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+  if (!TYPE_REFERENCE (check_typedef (value_type (arg))))
     return NULL;
 
   if (value_lval_const (arg) != lval_computed)
@@ -3710,7 +3712,7 @@ coerce_ref (struct value *arg)
   if (retval)
     return retval;
 
-  if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+  if (!TYPE_REFERENCE (value_type_arg_tmp))
     return arg;
 
   enc_type = check_typedef (value_enclosing_type (arg));
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 8116a5b..b568c72 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2229,7 +2229,7 @@ varobj_get_value_type (const struct varobj *var)
 
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_REFERENCE (type))
     type = get_target_type (type);
 
   type = check_typedef (type);
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (7 preceding siblings ...)
  2016-01-19 18:55   ` [PATCH v2 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-01-19 18:55   ` Artemiy Volkov
  2016-02-19 18:57     ` Keith Seitz
  2016-01-19 18:55   ` [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
                     ` (3 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:55 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

Make gdb DWARF reader understand DW_AT_rvalue_reference type tag. Handling
of this tag is done in the existing read_tag_reference_type() function, to
which we add a new parameter representing the kind of reference type
(lvalue vs rvalue).

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/dwarf2read.c (process_die): Handle the
        DW_AT_rvalue_reference_type DIE.
        (read_tag_reference_type): Likewise.
        (read_type_die_1): Likewise.
---
 gdb/dwarf2read.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index d2a3a50..9f589b8 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8294,6 +8294,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;
 
@@ -14320,16 +14321,19 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
    the user defined type vector.  */
 
 static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+                          enum type_code refcode)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type, *target_type;
   struct attribute *attr;
 
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
   target_type = die_type (die, cu);
 
   /* The die_type call above may have already set the type for this DIE.  */
@@ -14337,7 +14341,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_lvalue_reference_type (target_type);
+  type = lookup_reference_type (target_type, refcode);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
@@ -19115,7 +19119,10 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
       this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      this_type = read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+      break;
+    case DW_TAG_rvalue_reference_type:
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
       break;
     case DW_TAG_const_type:
       this_type = read_tag_const_type (die, cu);
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v2 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (5 preceding siblings ...)
  2016-01-19 18:54   ` [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2016-01-19 18:55   ` Artemiy Volkov
  2016-02-19 19:48     ` Keith Seitz
  2016-01-19 18:55   ` [PATCH v2 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
                     ` (5 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-01-19 18:55 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, Artemiy Volkov

This patch adds the ability to inspect rvalue reference types and values using
the gdb python module. Changes include the RvalueReferenceExplorer method
providing mechanism to get a type and a referenced value for an rvalue
reference object, and the valpy_rvalue_reference_value() function used
to create an rvalue reference to an object of any type.

./ChangeLog:

2016-01-19  Artemiy Volkov  <artemiyv@acm.org>

        * gdb/python/lib/gdb/command/explore.py: Add
        RvalueReferenceExplorer class.
        * gdb/python/lib/gdb/types.py: Implement get_basic_type() for
        rvalue reference types.
        * gdb/python/py-type.c: Add TYPE_CODE_RVALUE_REF to pyty_codes.
        * gdb/python/py-value.c (valpy_rvalue_reference_value): Add value
        getter function.
---
 gdb/python/lib/gdb/command/explore.py | 21 +++++++++++++++++++++
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 | 26 ++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
index 6c9f17b..a980274 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : RvalueReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,6 +319,26 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
+class RvalueReferenceExplorer(object):
+    """Internal class used to explore rvalue reference (TYPE_CODE_RVALUE_REF) values."""
+
+    @staticmethod
+    def explore_expr(expr, value, is_child):
+        """Function to explore array values.
+        See Explorer.explore_expr for more information.
+        """
+        referenced_value = value.referenced_value()
+        Explorer.explore_expr(expr, referenced_value, is_child)
+        return False
+
+    @staticmethod
+    def explore_type(name, datatype, is_child):
+        """Function to explore pointer types.
+        See Explorer.explore_type for more information.
+        """
+        target_type = datatype.target()
+        Explorer.explore_type(name, target_type, is_child)
+        return False
 
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index c22e8a9..59b7df2 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index dcdc20f..313f003 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 81d1225..dcc0cf9 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -263,6 +263,30 @@ valpy_reference_value (PyObject *self, PyObject *args)
   return result;
 }
 
+/* Return a value which is an rvalue reference to the value.  */
+
+static PyObject *
+valpy_rvalue_reference_value (PyObject *self, PyObject *args)
+{
+  PyObject *result = NULL;
+
+  TRY
+    {
+      struct value *self_val;
+      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+
+      self_val = ((value_object *) self)->value;
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_RVALUE_REF));
+      do_cleanups (cleanup);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  return result;
+}
 /* Return a "const" qualified version of the value.  */
 
 static PyObject *
@@ -1778,6 +1802,8 @@ reinterpret_cast operator."
     "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
   { "reference_value", valpy_reference_value, METH_NOARGS,
     "Return a value of type TYPE_CODE_REF referencing this value." },
+  { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
+    "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
   { "const_value", valpy_const_value, METH_NOARGS,
     "Return a 'const' qualied version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
-- 
2.7.0

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2015-12-28 21:09 ` [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
@ 2016-01-20  9:42   ` Yao Qi
  0 siblings, 0 replies; 109+ messages in thread
From: Yao Qi @ 2016-01-20  9:42 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

Artemiy Volkov <artemiyv@acm.org> writes:

Hi Artemiyv,
Thanks for your patches, and they are definitely good improvement to GDB.

> Ping? Any comments on this patchset?

I intended to read these patches, but I am fixing some bugs these days
since GDB 7.11 will be released soon (on Feb).  I plan to revisit your
patches after all the bugs are fixed for the release, if nobody reviews
them by then.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (10 preceding siblings ...)
  2016-01-19 18:55   ` [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-02-19 18:49   ` Keith Seitz
  2016-02-23  6:04     ` Artemiy Volkov
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
  12 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:49 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches@sourceware.org ml

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:

> this is my second take on fixing gdb/14441 which deals with C++0x rvalue
> references.

Thank you for submitting this! I have been trying to find the time to do
this myself. I rather glad someone beat me to it! It's a lot more work
than I imagined.

> Artemiy Volkov (11):
>   gdb: gdbtypes: add definitions for rvalue reference type
>   gdb: gdbtypes: change {lookup,make}_reference_type() API
>   gdb: valops: add ability to return rvalue reference values from
>     value_ref()
>   gdb: parse: support rvalue reference type
>   gdb: demangle: implement demangling for rvalue reference typenames
>   gdb: print: implement correct printing of rvalue reference types and
>     values
>   gdb: dwarf2read: support DW_AT_rvalue_reference type
>   gdb: convert lvalue reference type check to general reference type
>     check
>   gdb: gdbtypes: add rvalue references to overloading resolution
>   gdb: python: support rvalue references in the gdb module
>   gdb: testsuite: add rvalue reference tests

I think this is important enough a new "feature" to have a mention in NEWS.

While I've attempted to add pointers to relevant submission
documentation, I encourage you to peruse the official GDB Contribution
Checklist on the GDB wiki:

https://sourceware.org/gdb/wiki/ContributionChecklist

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-01-19 18:54   ` [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2016-02-19 18:49     ` Keith Seitz
  2016-02-23  7:04       ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:49 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/gdbtypes.h (enum type_code): Add TYPE_CODE_RVALUE_REF
>         constant.

Nit: I believe the syntax for this would be:

  (enum type_code) <TYPE_CODE_RVALUE_REF>: New constant.

Also, remove the leading "gdb/" from all gdb/ChangeLog entries. [This
appears in all patches.]

>         (TYPE_REFERENCE): New macro.
>         (struct type): Add rvalue_reference_type field.
>         (TYPE_RVALUE_REFERENCE_TYPE): New macro.
> ---
>  gdb/gdbtypes.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index e775a1d..52419b4 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -362,6 +364,12 @@ enum type_instance_flag_value
>  #define TYPE_ATOMIC(t) \
>    (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
>  
> +/* * C++ lvalue and rvalue references are equivalent in many contexts,
> +   thus create a convenience macro that checks if a type is either of them. */
> +
> +#define TYPE_REFERENCE(t) \
> +  (TYPE_CODE(t) == TYPE_CODE_REF || TYPE_CODE(t) == TYPE_CODE_RVALUE_REF)
> +

Nit: a single whitespace between TYPE_CODE and '(', TYPE_CODE (t) ...
I think this macro could have a more helpful name. It's very close to
TYPE_REFERENCE_TYPE. How about TYPE_IS_REFERENCE (similarly named to
TYPE_IS_OPAQUE)? Then the comment becomes even clearer: "True if this
type represents either an lvalue or rvalue reference type."

>  /* * Instruction-space delimited type.  This is for Harvard architectures
>     which have separate instruction and data address spaces (and perhaps
>     others).
> @@ -767,6 +775,10 @@ struct type
>  
>    struct type *reference_type;
>  
> +  /* * A C++ rvalue reference type added in C++0x. */
> +
> +  struct type *rvalue_reference_type;
> +

Why is this new field necessary? AFAICT, it is used exactly the same way
as the reference_type field above it, and whether a reference type is an
rvalue type is encoded into the type code.

>    /* * Variant chain.  This points to a type that differs from this
>       one only in qualifiers and length.  Currently, the possible
>       qualifiers are const, volatile, code-space, data-space, and
> @@ -1229,6 +1241,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,

If struct type.rvalue_reference_type is superfluous, this is unneeded.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-01-19 18:54   ` [PATCH v2 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2016-02-19 18:50     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:50 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches; +Cc: palves

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 
> ./Changelog:
> 
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/dwarf2read.c (read_tag_reference_type): Use
>         lookup_lvalue_reference_type() instead of lookup_reference_type().
>         * gdb/eval.c (evaluate_subexp_standard): Likewise.
>         * gdb/f-exp.y: Likewise.

Nit: Instead of listing a bunch of functions and "Likewise" or "Ditto,"
I think we're using the shorthand: (func1, func1, func3): Use blah blah.
[Sadly does not extend to filenames.]

>         * gdb/gdbtypes.c (make_reference_type): Generalize with rvalue
>         reference types.
>         (lookup_reference_type): Generalize with rvalue reference types.
>         (lookup_lvalue_reference_type): New convenience wrapper for
>         lookup_reference_type().
>         (lookup_rvalue_reference_type): Likewise.
>         * gdb/gdbtypes.h: Change interface for
>         {make,lookup}_{rvalue,}_reference_type().

I would prefer that these function be listed explicitly -- it makes
searching through the changelogs a lot easier, but then I would prefer a
little better description of the change, too. The entry mentions
changing the interface, but it doesn't say how.

>         * gdb/guile/scm-type.c (gdbscm_type_reference): Use
>         lookup_lvalue_reference_type() instead of lookup_reference_type().
>         * gdb/guile/scm-value.c (gdbscm_value_dynamic_type): Likewise.
>         * gdb/parse.c (follow_types): Likewise.
>         * gdb/python/py-type.c (typy_reference): Likewise.
>         (typy_lookup_type): Likewise.
>         * gdb/python/py-value.c (valpy_get_dynamic_type): Likewise.
>         (valpy_getitem): Likewise.
>         * gdb/python/py-xmethods.c (gdbpy_get_xmethod_result_type):
>         Likewise.
>         (gdbpy_invoke_xmethod): Likewise.

Lotsa "likewise"s here! :-)

>         * gdb/stabsread.c: Provide extra argument to make_reference_type()
>         call.
>         * gdb/valops.c (value_ref): Use lookup_lvalue_reference_type()
>         instead of lookup_reference_type().
>         (value_rtti_indirect_type): Likewise.
> ---

> diff --git a/gdb/eval.c b/gdb/eval.c
> index 78ad946..729f473 100644
> --- a/gdb/eval.c
> +++ b/gdb/eval.c
> @@ -2789,7 +2789,7 @@ evaluate_subexp_standard (struct type *expect_type,
>  
>  	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
>  		{
> -		  type = lookup_reference_type (type);
> +                 type = lookup_lvalue_reference_type (type);

Indentation looks off. Please double-check.

>  		  result = allocate_value (type);
>  		}
>  	    }
> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index f129b0e..058b77d 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -382,17 +382,23 @@ 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.  */
> +   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.
> +   REFCODE denotes the kind of reference type to lookup (lvalue or rvalue
> +   reference). We allocate new memory if needed.  */

There's a lot less here that changed than this diff would indicate. It
is okay to tack on an extra sentence describing the new parameter,
leaving the rest unchanged.

>  struct type *
> -make_reference_type (struct type *type, struct type **typeptr)
> +make_reference_type (struct type *type, struct type **typeptr,
> +                      enum type_code refcode)
>  {
>    struct type *ntype;	/* New type */
> +  struct type **reftype;
>    struct type *chain;
>  
> -  ntype = TYPE_REFERENCE_TYPE (type);
> +  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
> +
> +  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
> +           : TYPE_RVALUE_REFERENCE_TYPE (type));

From comments in patch 1/11, I don't think this is necessary. We know
it's a reference type, and TYPE_REFERENCE_TYPE will get us the
reference's type, either rvalue or lvalue.

>    if (ntype)
>      {
> @@ -421,7 +427,11 @@ make_reference_type (struct type *type, struct type **typeptr)
>      }
>  
>    TYPE_TARGET_TYPE (ntype) = type;
> -  TYPE_REFERENCE_TYPE (type) = ntype;
> +  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
> +             : &TYPE_RVALUE_REFERENCE_TYPE (type));
> +
> +  if(!*reftype)
> +    *reftype = ntype;
>  
>    /* FIXME!  Assume the machine has only one representation for
>       references, and that it matches the (only) representation for
> @@ -429,10 +439,9 @@ make_reference_type (struct type *type, struct type **typeptr)
>  
>    TYPE_LENGTH (ntype) =
>      gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
> -  TYPE_CODE (ntype) = TYPE_CODE_REF;
> +  TYPE_CODE (ntype) = refcode;
>  
> -  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
> -    TYPE_REFERENCE_TYPE (type) = ntype;
> +  *reftype = ntype;
>  
>    /* Update the length of all the other variants of this type.  */
>    chain = TYPE_CHAIN (ntype);

This whole hunk is probably simplified or (largely) unnecessary if we've
agreed to remove struct type.rvalue_reference_type (from patch 1/11).

> @@ -449,9 +458,23 @@ make_reference_type (struct type *type, struct type **typeptr)
>     details.  */
>  
>  struct type *
> -lookup_reference_type (struct type *type)
> +lookup_reference_type (struct type *type, enum type_code refcode)
> +{
> +  return make_reference_type (type, (struct type **) 0, refcode);
> +}
> +
> +/* Separate convenience functions for lvalue and rvalue references. */
> +
> +struct type *
> +lookup_lvalue_reference_type (struct type *type)
> +{
> +  return lookup_reference_type (type, TYPE_CODE_REF);
> +}
> +
> +struct type *
> +lookup_rvalue_reference_type (struct type *type)
>  {
> -  return make_reference_type (type, (struct type **) 0);
> +  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
>  }
>  

Our coding standard requires a comment before each function, even
trivial ones. [Please don't shoot the messenger!] Additionally, if these
are exported, the comment explaining the purpose of the function should
be put in the header and "See description in foo.h." (or similar) should
be sufficient for the comment ahead of the implementation.

>  /* Lookup a function type that returns type TYPE.  TYPEPTR, if
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index 52419b4..d9b6b9e 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -1725,9 +1725,13 @@ 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);
>  
> -extern struct type *lookup_reference_type (struct type *);
> +extern struct type *lookup_reference_type (struct type *, enum type_code);
> +extern struct type *lookup_lvalue_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_reference_type (struct type *, struct type **,
> +                                         enum type_code);
>  
>  extern struct type *make_cv_type (int, int, struct type *, struct type **);
>  

See previous comment.

> diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
> index 1cdf953..1681a77 100644
> --- a/gdb/guile/scm-value.c
> +++ b/gdb/guile/scm-value.c
> @@ -601,7 +601,7 @@ gdbscm_value_dynamic_type (SCM self)
>  	      if (was_pointer)
>  		type = lookup_pointer_type (type);
>  	      else
> -		type = lookup_reference_type (type);
> +               type = lookup_lvalue_reference_type (type);

Indentation?
>  	    }
>  	}
>        else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
> diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
> index 03cc8d9..385cb53 100644
> --- a/gdb/python/py-type.c
> +++ b/gdb/python/py-type.c
> @@ -827,7 +827,7 @@ typy_lookup_type (struct demangle_component *demangled,
>  	  switch (demangled_type)
>  	    {
>  	    case DEMANGLE_COMPONENT_REFERENCE:
> -	      rtype =  lookup_reference_type (type);
> +             rtype = lookup_lvalue_reference_type (type);
>  	      break;

Indentation?

>  	    case DEMANGLE_COMPONENT_POINTER:
>  	      rtype = lookup_pointer_type (type);
> diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
> index 7dba0ad..9d479ea 100644
> --- a/gdb/python/py-value.c
> +++ b/gdb/python/py-value.c
> @@ -376,7 +376,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
>  	      if (was_pointer)
>  		type = lookup_pointer_type (type);
>  	      else
> -		type = lookup_reference_type (type);
> +               type = lookup_lvalue_reference_type (type);
>  	    }
>  	}

Indentation?

>        else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
> @@ -766,7 +766,7 @@ valpy_getitem (PyObject *self, PyObject *key)
>  	  if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
>  	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
>  	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
> -	    res_val = value_cast (lookup_reference_type (base_class_type), tmp);
> +           res_val = value_cast (lookup_lvalue_reference_type (base_class_type), tmp);
>  	  else
>  	    res_val = value_cast (base_class_type, tmp);
>  	}

Indentation? The line is also too long. See
https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards#Column_limits
.

> diff --git a/gdb/stabsread.c b/gdb/stabsread.c
> index 74260b7..8a50dbd 100644
> --- a/gdb/stabsread.c
> +++ b/gdb/stabsread.c
> @@ -1772,7 +1772,7 @@ again:
>  
>      case '&':                  /* Reference to another type */
>        type1 = read_type (pp, objfile);
> -      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile));
> +      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile), TYPE_CODE_REF);
>        break;
>  
>      case 'f':                  /* Function returning another type */

The changed line is too long.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2016-01-19 18:54   ` [PATCH v2 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2016-02-19 18:52     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:52 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

Just "nits" in this review.

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/ada-lang.c (ada_evaluate_subexp): Adhere to the new
>         value_ref() interface.
>         * gdb/c-valprint.c (c_value_print): Likewise.
>         * gdb/infcall.c (value_arg_coerce): Likewise.
>         * gdb/python/py-value.c (valpy_reference_value): Likewise.
>         * gdb/valops.c (value_cast): Likewise.
>         (value_reinterpret_cast): Likewise.
>         (value_dynamic_cast): Likewise.
>         (value_ref): Parameterize by kind of return value reference type.
>         (typecmp): Likewise.

Another place that could be simplified, removing "likewise."

>         * gdb/value.h: New interface.

This isn't a particularly useful comment. ChangeLogs explain what changed:

	* gdb/value.h (value_ref): Add new parameter "refcode".

> diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
> index 62552ec..e210e99 100644
> --- a/gdb/c-valprint.c
> +++ b/gdb/c-valprint.c
> @@ -602,10 +602,13 @@ c_value_print (struct value *val, struct ui_file *stream,
>        else if (options->objectprint
>  	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
>  	{
> -	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
> +         int is_ref = TYPE_REFERENCE (type);
> +         enum type_code refcode = TYPE_CODE_UNDEF;

Indentation?

>  
> -	  if (is_ref)
> +	  if (is_ref) {
>  	    val = value_addr (val);
> +           refcode = TYPE_CODE (type);
> +         }
>  
>  	  /* Pointer to class, check real type of object.  */
>  	  fprintf_filtered (stream, "(");
> diff --git a/gdb/valops.c b/gdb/valops.c
> index 1aafb5a..cc01689 100644
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
> @@ -828,7 +829,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
>  			       value_address (tem), tem,
>  			       rtti_type, &result) == 1)
>      return value_cast (type,
> -		       is_ref ? value_ref (result) : value_addr (result));
> +		       is_ref ? value_ref (result, TYPE_CODE (resolved_type)) : value_addr (result));
>  
>    if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
>      return value_zero (type, not_lval);

The two changed lines in the above hunk are too long.

> @@ -1499,16 +1500,19 @@ value_addr (struct value *arg1)
>     contents.  */
>  
>  struct value *
> -value_ref (struct value *arg1)
> +value_ref (struct value *arg1, enum type_code refcode)
>  {
>    struct value *arg2;
>    struct type *type = check_typedef (value_type (arg1));
>  
> -  if (TYPE_CODE (type) == TYPE_CODE_REF)
> +  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
> +
> +  if ((TYPE_CODE (type) == TYPE_CODE_REF || TYPE_CODE (type) == TYPE_CODE_RVALUE_REF)
> +      && TYPE_CODE (type) == refcode)
>      return arg1;
>  

The "if ((TYPE_CODE...)" line is too long.

>    arg2 = value_addr (arg1);
> -  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
> +  deprecated_set_value_type (arg2, lookup_reference_type (type, refcode));
>    return arg2;
>  }
>  

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2016-01-19 18:54   ` [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2016-02-19 18:53     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:53 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

Another patch of nothing but coding standard "nits."

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/c-exp.y: Handle the '&&' token in the typename.
>         * gdb/parse.c (insert_type): Change assert statement.
>         (follow_types): Handle rvalue reference types.
>         * gdb/parser-defs.h (enum type_pieces): Add tp_rvalue_reference
>         constant.

Nit: That last one should be

  * parser-defs.h (enum type_pieces) <tp_rvalue_reference>: New constant.

> diff --git a/gdb/parse.c b/gdb/parse.c
> index 06f7bcd..75627c5 100644
> --- a/gdb/parse.c
> +++ b/gdb/parse.c
> @@ -1695,21 +1695,26 @@ follow_types (struct type *follow_type)
>  	make_addr_space = 0;
>  	break;
>        case tp_reference:
> -	follow_type = lookup_lvalue_reference_type (follow_type);
> -	if (make_const)
> -	  follow_type = make_cv_type (make_const, 
> -				      TYPE_VOLATILE (follow_type), 
> -				      follow_type, 0);
> -	if (make_volatile)
> -	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
> -				      make_volatile, 
> -				      follow_type, 0);
> -	if (make_addr_space)
> -	  follow_type = make_type_with_address_space (follow_type, 
> -						      make_addr_space);
> +        follow_type = lookup_lvalue_reference_type (follow_type);
> +        goto process_reference;
> +      case tp_rvalue_reference:
> +        follow_type = lookup_rvalue_reference_type (follow_type);
> +      process_reference:
> +        if (make_const)
> +          follow_type = make_cv_type (make_const,
> +                                      TYPE_VOLATILE (follow_type),
> +                                      follow_type, 0);
> +        if (make_volatile)
> +          follow_type = make_cv_type (TYPE_CONST (follow_type),
> +                                      make_volatile,
> +                                      follow_type, 0);
> +        if (make_addr_space)
> +          follow_type = make_type_with_address_space (follow_type,
> +                                                      make_addr_space);
>  	make_const = make_volatile = 0;
>  	make_addr_space = 0;
>  	break;
> +

Just a comment -- nothing for you to do. This process_reference:
really is about dealing with qualifiers, and I see that this is
cut-n-pasted into several different cases. Yuck.

>        case tp_array:
>  	array_size = pop_type_int ();
>  	/* FIXME-type-allocation: need a way to free this type when we are

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2016-01-19 18:54   ` [PATCH v2 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2016-02-19 18:54     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:54 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

All nits here, too.

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/cp-name-parser.y: Handle the '&&' token in typename.

We normally put a production name in place of where one would normally
use a function name. In this case, "(ptr_operator)".

> @@ -827,7 +828,10 @@ typy_lookup_type (struct demangle_component *demangled,
>  	  switch (demangled_type)
>  	    {
>  	    case DEMANGLE_COMPONENT_REFERENCE:
> -             rtype = lookup_lvalue_reference_type (type);
> +              rtype = lookup_lvalue_reference_type (type);
> +	      break;
> +	    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
> +              rtype = lookup_rvalue_reference_type (type);
>  	      break;
>  	    case DEMANGLE_COMPONENT_POINTER:
>  	      rtype = lookup_pointer_type (type);

Indentation?

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2016-01-19 18:54   ` [PATCH v2 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2016-02-19 18:56     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:56 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/c-typeprint.c (c_print_type): Support printing rvalue
>         reference types.
>         (c_type_print_varspec_prefix): Likewise.
>         (c_type_print_modifier): Likewise.
>         (c_type_print_varspec_suffix): Likewise.
>         (c_type_print_base): Likewise.
>         * gdb/c-valprint.c (c_val_print): Support printing rvalue
>         reference values.
>         (c_value_print): Likewise.

More condensing of functions/changelogs:

	* c-typeprint.c (c_print_type, c_type_print_varspec)
	(c_type_print_modifier, c_type_print_varspec_suffix)
	(c_type_print_base): Suppport rvalue references.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type
  2016-01-19 18:55   ` [PATCH v2 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
@ 2016-02-19 18:57     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 18:57 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> Make gdb DWARF reader understand DW_AT_rvalue_reference type tag. Handling
> of this tag is done in the existing read_tag_reference_type() function, to
> which we add a new parameter representing the kind of reference type
> (lvalue vs rvalue).
> 
> ./ChangeLog:
> 
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/dwarf2read.c (process_die): Handle the
>         DW_AT_rvalue_reference_type DIE.
>         (read_tag_reference_type): Likewise.
>         (read_type_die_1): Likewise.

More "likewise," but otherwise, this looks okay to me.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-01-19 18:55   ` [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-02-19 19:01     ` Keith Seitz
  2016-02-26  5:08       ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 19:01 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> In almost all contexts (except for overload resolution rules and expression
> semantics), lvalue and rvalue references are equivalent. That means that in
> all but these cases we can replace a TYPE_CODE_REF check to TYPE_REFERENCE
> check. This patch does exactly that.
> 

This is largely a mechanical change, but I do have a few nits to point
out. See below.

May I also bring to your attention that any subsequent patch submissions
keep purely mechanical substitutions (like the majority of this patch)
separate from anything more substantial. This patch contains some
non-mechanical changes, such as cleanups (valops.c:value_cast) and
additional handling for TYPE_CODE_RVALUE_REF in a handful of places.

As a reviewer (and it may just be that I'm not very versed at it), I
find it easy to lose these in a sea of mechanical changes.

> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/aarch64-tdep.c (aarch64_type_align): Change TYPE_CODE_REF
>         check to TYPE_REFERENCE check.
>         (aarch64_extract_return_value): Likewise.
>         (aarch64_store_return_value): Likewise.
>         * gdb/amd64-tdep.c (amd64_classify): Likewise.
[big snip]

We are now encouraging/permitting developers to use the phrase "Update
all callers." or "All callers updated." with large, mechanical changes
like this.

> diff --git a/gdb/eval.c b/gdb/eval.c
> index 729f473..443a08c 100644
> --- a/gdb/eval.c
> +++ b/gdb/eval.c
> @@ -2509,7 +2509,7 @@ evaluate_subexp_standard (struct type *expect_type,
>  	{
>  	  type = check_typedef (value_type (arg1));
>  	  if (TYPE_CODE (type) == TYPE_CODE_PTR
> -	      || TYPE_CODE (type) == TYPE_CODE_REF
> +	      || TYPE_REFERENCE (type)
>  	  /* In C you can dereference an array to get the 1st elt.  */
>  	      || TYPE_CODE (type) == TYPE_CODE_ARRAY
>  	    )

Superfluous whitespace change?

> @@ -2787,9 +2787,9 @@ evaluate_subexp_standard (struct type *expect_type,
>  	    {
>  	      struct type *type = value_type (result);
>  
> -	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
> +	      if (!TYPE_REFERENCE (type))
>  		{
> -                 type = lookup_lvalue_reference_type (type);
> +		  type = lookup_lvalue_reference_type (type);
>  		  result = allocate_value (type);
>  		}
>  	    }

Same here?

> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index 058b77d..fd17d3c 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -3475,10 +3475,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
>  
>    /* See through references, since we can almost make non-references
>       references.  */
> -  if (TYPE_CODE (arg) == TYPE_CODE_REF)
> +

Superfluous whitespace.

> +  if (TYPE_REFERENCE (arg))
>      return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
>                         REFERENCE_CONVERSION_BADNESS));
> -  if (TYPE_CODE (parm) == TYPE_CODE_REF)
> +  if (TYPE_REFERENCE (parm))
>      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
>                         REFERENCE_CONVERSION_BADNESS));
>    if (overload_debug)
> diff --git a/gdb/valops.c b/gdb/valops.c
> index cc01689..b4f9ba5 100644
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
> @@ -360,24 +360,20 @@ value_cast (struct type *type, struct value *arg2)
>    if (value_type (arg2) == type)
>      return arg2;
>  
> -  code1 = TYPE_CODE (check_typedef (type));
> -
>    /* Check if we are casting struct reference to struct reference.  */
> -  if (code1 == TYPE_CODE_REF)
> +  if (TYPE_REFERENCE (check_typedef (type)))
>      {
>        /* We dereference type; then we recurse and finally
>           we generate value of the given reference.  Nothing wrong with 
>  	 that.  */
>        struct type *t1 = check_typedef (type);
>        struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
> -      struct value *val =  value_cast (dereftype, arg2);
> +      struct value *val = value_cast (dereftype, arg2);
>  
>        return value_ref (val, TYPE_CODE (t1));
>      }
>  
> -  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
> -
> -  if (code2 == TYPE_CODE_REF)
> +  if (TYPE_REFERENCE (check_typedef (value_type (arg2))))
>      /* We deref the value and then do the cast.  */
>      return value_cast (type, coerce_ref (arg2)); 
>  

A bunch of cleanups like this would normally be considered a separate
change. I'm not going to ask anything, but be aware that the final
reviewer may call this out.

> @@ -1729,14 +1725,12 @@ typecmp (int staticp, int varargs, int nargs,
>  	 char *>, and properly access map["hello"], because the
>  	 argument to [] will be a reference to a pointer to a char,
>  	 and the argument will be a pointer to a char.  */
> -      while (TYPE_CODE(tt1) == TYPE_CODE_REF
> -	     || TYPE_CODE (tt1) == TYPE_CODE_PTR)
> -	{
> +      while (TYPE_REFERENCE(tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR) {
>  	  tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
>  	}
>        while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
>  	     || TYPE_CODE(tt2) == TYPE_CODE_PTR
> -	     || TYPE_CODE(tt2) == TYPE_CODE_REF)
> +	     || TYPE_REFERENCE(tt2))
>  	{
>  	  tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
>  	}

Formatting errors. I realize you probably just did a text replace, but
since you've touched a handful of the places where there were errors,
please fix those instances. "TYPE_REFERENCE (". You do not need to fix
the other formatting errors here. Just the two lines you changed.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2016-01-19 18:55   ` [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2016-02-19 19:46     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 19:46 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index fd17d3c..4bb98c9 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -3464,6 +3466,20 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
>  {
>    struct rank rank = {0,0};
>  
> +  /* Disallow an rvalue argument to bind to a non-const lvalue reference
> +     parameter and an lvalue argument to bind to an rvalue reference
> +     parameter. */

Nit: two spaces after all sentences. ["parameter.  /*"]

> +
> +  if ((value != NULL)
> +      &&
> +      ((TYPE_CODE (parm) == TYPE_CODE_REF
> +       && !TYPE_CONST (parm->main_type->target_type)
> +       && VALUE_LVAL (value) == not_lval)
> +      ||
> +       (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF
> +       && VALUE_LVAL (value) != not_lval)))
> +    return INCOMPATIBLE_TYPE_BADNESS;
> +

I would probably split this up into two statements instead of using "||"
to combine, leading each statement with the appropriate comment/citation
from the spec.

if (value != NULL)
  {
    /* An rvalue argument cannot be bound to a non-const lvalue
       reference parameter...  */
    if (VALUE_LVAL (value) == not_lval
        && TYPE_CODE (parm) == TYPE_CODE_REF
        && !TYPE_CONST (TYPE_TARGET_TYPE (parm)))
      return INCOMPATIBLE_TYPE_BADNESS;

    /* ... and an lvalue argument cannot be bound to an rvalue
       reference parameter.  [C++ 13.3.3.1.4p3]  */
   if (VALUE_LVAL (value) != not_lval
       && TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
     return INCOMPATIBLE_TYPE_BADNESS;
  }

This is just so much easier to read IMO.

For the first test here, is using the target type of the reference
sufficient? Do we need to resolve typedefs? In many places, I see the
code looping over references (and pointers) to get to the underlying type:

  for (;;)
    {
      type = check_typedef (type);
      if (TYPE_CODE (type) != TYPE_CODE_PTR
          && TYPE_CODE (type) != TYPE_CODE_REF)
        break;
      type = TYPE_TARGET_TYPE (type);
    }

Maybe you have a test that covers this already (where a reference refers
to a typedef'd type)? [If not, please add.]

>    if (types_equal (parm, arg))
>      return EXACT_MATCH_BADNESS;
>  
> @@ -3473,6 +3489,36 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
>    if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
>      arg = check_typedef (arg);
>  
> +  /* An lvalue reference to a function should get higher priority than an
> +     rvalue reference to a function. */
> +
> +  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
> +      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
> +    return (sum_ranks (rank_one_type (parm,
> +            lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
> +            DIFFERENT_REFERENCE_TYPE_BADNESS));

Multi-line statements should be encapsulated in a block. [I know a *lot*
of patches have been committed where submitters (and maintainers)
haven't followed the rule, but it *is* in our internal coding style
wiki.
https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards#Whitespaces
]

This appears several times.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-01-19 18:55   ` [PATCH v2 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-02-19 19:48     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 19:48 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> This patch adds the ability to inspect rvalue reference types and values using
> the gdb python module. Changes include the RvalueReferenceExplorer method
> providing mechanism to get a type and a referenced value for an rvalue
> reference object, and the valpy_rvalue_reference_value() function used
> to create an rvalue reference to an object of any type.
> 
> ./ChangeLog:
> 
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb/python/lib/gdb/command/explore.py: Add
>         RvalueReferenceExplorer class.

The usual way to do this would be to mention the class first:

	* python/lib/gdb/command/explore.py
	(RvalueReferenceExplorer): New class.

But more on this later...

>         * gdb/python/lib/gdb/types.py: Implement get_basic_type() for
>         rvalue reference types.

Similarly,

	* python/lib/gdb/types.py (get_basic_type): Handle
	TYPE_CODE_RVALUE_REFERENCE.

>         * gdb/python/py-type.c: Add TYPE_CODE_RVALUE_REF to pyty_codes.

I would do the same here, too.

>         * gdb/python/py-value.c (valpy_rvalue_reference_value): Add value
>         getter function.
> ---
>  gdb/python/lib/gdb/command/explore.py | 21 +++++++++++++++++++++
>  gdb/python/lib/gdb/types.py           |  4 +++-
>  gdb/python/py-type.c                  |  1 +
>  gdb/python/py-value.c                 | 26 ++++++++++++++++++++++++++
>  4 files changed, 51 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
> index 6c9f17b..a980274 100644
> --- a/gdb/python/lib/gdb/command/explore.py
> +++ b/gdb/python/lib/gdb/command/explore.py
> @@ -318,6 +319,26 @@ class ReferenceExplorer(object):
>          Explorer.explore_type(name, target_type, is_child)
>          return False
>  
> +class RvalueReferenceExplorer(object):
> +    """Internal class used to explore rvalue reference (TYPE_CODE_RVALUE_REF) values."""
> +
> +    @staticmethod
> +    def explore_expr(expr, value, is_child):
> +        """Function to explore array values.
> +        See Explorer.explore_expr for more information.
> +        """
> +        referenced_value = value.referenced_value()
> +        Explorer.explore_expr(expr, referenced_value, is_child)
> +        return False
> +
> +    @staticmethod
> +    def explore_type(name, datatype, is_child):
> +        """Function to explore pointer types.
> +        See Explorer.explore_type for more information.
> +        """
> +        target_type = datatype.target()
> +        Explorer.explore_type(name, target_type, is_child)
> +        return False

I'm not all that familiar with python, but is there a reason for this to
be a new class? It looks identical to ReferenceExplorer?

>  class ArrayExplorer(object):
>      """Internal class used to explore arrays."""
> diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
> index 81d1225..dcc0cf9 100644
> --- a/gdb/python/py-value.c
> +++ b/gdb/python/py-value.c
> @@ -263,6 +263,30 @@ valpy_reference_value (PyObject *self, PyObject *args)
>    return result;
>  }
>  
> +/* Return a value which is an rvalue reference to the value.  */
> +
> +static PyObject *
> +valpy_rvalue_reference_value (PyObject *self, PyObject *args)
> +{
> +  PyObject *result = NULL;
> +
> +  TRY
> +    {
> +      struct value *self_val;
> +      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
> +
> +      self_val = ((value_object *) self)->value;
> +      result = value_to_value_object (value_ref (self_val, TYPE_CODE_RVALUE_REF));
> +      do_cleanups (cleanup);
> +    }
> +  CATCH (except, RETURN_MASK_ALL)
> +    {
> +      GDB_PY_HANDLE_EXCEPTION (except);
> +    }
> +  END_CATCH
> +
> +  return result;
> +}
>  /* Return a "const" qualified version of the value.  */
>  
>  static PyObject *
> @@ -1778,6 +1802,8 @@ reinterpret_cast operator."
>      "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
>    { "reference_value", valpy_reference_value, METH_NOARGS,
>      "Return a value of type TYPE_CODE_REF referencing this value." },
> +  { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
> +    "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
>    { "const_value", valpy_const_value, METH_NOARGS,
>      "Return a 'const' qualied version of the same value." },
>    { "lazy_string", (PyCFunction) valpy_lazy_string,

Same question here...

rvalue_reference_value/valpy_rvalue_reference_value have nearly
identical implementations as reference_value/valpy_reference_value.

Does TYPE_CODE (value_type (self_val)) not tell us which of the types we
are looking at? If so, I think it would be better to unify reference
handling into a common implementation, noting that the class handles
both types of references.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-01-19 18:55   ` [PATCH v2 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-02-19 20:05     ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-02-19 20:05 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches@sourceware.org ml

On 01/19/2016 10:53 AM, Artemiy Volkov wrote:

> testsuite/ChangeLog:
> 
> 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * gdb.cp/casts.cc (main): Change decltype() function name. Add
>         rvalue reference type variables.

This is better explained:

	* gdb.cp/casts.cc (decltype): Rename C++11 reserved keyword ...
	(decl_type): ... to this. All callers updated.

You can then omit the "Change decltype" bit in (main).

I would consider the above hunk a separate/obvious/trivial patch that
you could submit. AFAICT, HEAD is already broken on this. Not necessary,
though. [I'm easy!]

>         * gdb.cp/casts.exp: Compile with -std=c++11. Add rvalue reference
>         cast tests.

You also changed decltype -> decl_type in this file.

>         * gdb.cp/cpsizeof.cc: Add rvalue reference type variables.
>         * gdb.cp/cpsizeof.exp: Compile with -std=c++11. Add rvalue
>         reference sizeof tests.
>         * gdb.cp/demangle.exp: Add rvalue reference demangle tests.

The above occur in proc test_gnu_style_demangling:

	* gdb.cp/demangle.exp (test_gnu_style_demangling): ...

>         * gdb.cp/overload.cc (int main): Add a ctor and some methods
>         with rvalue reference parameters.

Changes need to be mentioned explicitly. "(main)"

>         * gdb.cp/overload.exp: Compile with -std=c++11. Add rvalue
>         reference overloading tests.
>         * gdb.cp/ref-params.cc (int f1): New function taking rvalue
>         reference parameter.
>         (int f2): Likewise.
>         (int mf1): Likewise.
>         (int mf2): Likewise.

"int" not necessary. Just list the the new functions:

	* gdb.cp/ref-params.cc (f1, f2, mf1, mf2): ...

>         * gdb.cp/ref-params.exp: Compile with -std=c++11. Add rvalue
>         reference parameter printing tests.
>         * gdb.cp/ref-types.cc (int main2): Add rvalue reference type
>         variables.

"int main2" -> "(main2)".

>         * gdb.cp/ref-types.exp: Compile with -std=c++11. Add rvalue
>         reference type printing tests.
> ---
> diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc
> index 43f112f..d15fed1 100644
> --- a/gdb/testsuite/gdb.cp/casts.cc
> +++ b/gdb/testsuite/gdb.cp/casts.cc
> @@ -1,3 +1,5 @@
> +#include <utility>
> +
>  struct A
>  {
>    int a;

This change is not mentioned in the ChangeLog.

> diff --git a/gdb/testsuite/gdb.cp/cpsizeof.cc b/gdb/testsuite/gdb.cp/cpsizeof.cc
> index 2dcaea1..6a8de4a 100644
> --- a/gdb/testsuite/gdb.cp/cpsizeof.cc
> +++ b/gdb/testsuite/gdb.cp/cpsizeof.cc
> @@ -15,6 +15,8 @@
>     You should have received a copy of the GNU General Public License
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>  
> +#include <utility>
> +

This isn't mentioned in the ChangeLog.

>  struct Class
>  {
>    int a;
> @@ -44,8 +46,10 @@ typedef Enum e12[12];
>  #define T(N)					\
>    N N ## obj;					\
>    N& N ## _ref = N ## obj;			\
> +  N&& N ## _rref = std::move(N ## obj);         \
>    N* N ## p = &(N ## obj);			\
>    N*& N ## p_ref = N ## p;			\
> +  N*&& N ## p_rref = std::move(N ## p);         \
>    int size_ ## N = sizeof (N ## _ref);		\
>    int size_ ## N ## p = sizeof (N ## p_ref);	\
>  
> diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
> index 96c90db..90d7be6 100644
> --- a/gdb/testsuite/gdb.cp/demangle.exp
> +++ b/gdb/testsuite/gdb.cp/demangle.exp
> @@ -511,7 +547,6 @@ proc test_gnu_style_demangling {} {
>  	"operator!=(void *, BDDFunction::VixB const &)"
>      test_demangling_exact "gnu: __eq__FPvRCQ211BDDFunction4VixB" \
>  	"operator==(void *, BDDFunction::VixB const &)"
> -
>      test_demangling_exact "gnu: relativeId__CQ36T_phi210T_preserve8FPC_nextRCQ26T_phi210T_preserveRC10Parameters" \
>  	 "T_phi2::T_preserve::FPC_next::relativeId(T_phi2::T_preserve const &, Parameters const &) const"
>  

Superfluous whitespace change?

> @@ -535,6 +570,7 @@ proc test_gnu_style_demangling {} {
>  	    pass "gnu: __thunk_64__0RL__list__Q29CosNaming20_proxy_NamingContextUlRPt25_CORBA_Unbounded_Sequence1ZQ29CosNaming7BindingRPQ29CosNaming15BindingIterator"
>  	}
>      }
> +
>  }
>  
>  #

Likewise.

> @@ -1489,6 +1525,7 @@ proc test_hp_style_demangling {} {
>      test_demangling_exact "hp: elem__6vectorXTiSN67TRdTFPv_i__Fi" "vector<int,-67,double &,int (void *)>::elem(int)"
>      test_demangling_exact "hp: X__6vectorXTiSN67TdTPvUP5TRs" "vector<int,-67,double,void *,5U,short &>::X"
>  
> +
>      # Named constants in template args
>  
>      test_demangling_exact "hp: elem__6vectorXTiA3foo__Fi" "vector<int,&foo>::elem(int)"

Here, too.

> diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
> index 5c782a4..a977c43 100644
> --- a/gdb/testsuite/gdb.cp/overload.cc
> +++ b/gdb/testsuite/gdb.cp/overload.cc
> @@ -1,10 +1,12 @@
>  #include <stddef.h>
> +#include <utility>

This include needs to be mentioned in the ChangeLog.

> diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
> index 0cfa638..cfe7f90 100644
> --- a/gdb/testsuite/gdb.cp/overload.exp
> +++ b/gdb/testsuite/gdb.cp/overload.exp
> @@ -28,7 +28,7 @@ if { [skip_cplus_tests] } { continue }
>  
>  standard_testfile .cc
>  
> -if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
> +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
>      return -1
>  }
>  

Line too long. Either assign the compile options to a variable and pass
the variable OR add a '\' to split this line.

> @@ -53,7 +53,7 @@ gdb_test "up" ".*main.*" "up from marker1"
>  set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
>  set re_fields	"int ifoo;${ws}const char ?\\* ?ccpfoo;"
>  set XX_fields  	"int ifoo;${ws}char ?\\* ?ccpfoo;"
> -set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);"
> +set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);${ws}foo\\(foo ?&?&\\);"
>  set re_dtor	"~foo\\((void|)\\);"
>  set XX_dtor	"~foo\\(int\\);"
>  set re_methods	                  "void foofunc\\(int\\);"
> @@ -72,6 +72,8 @@ set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
>  set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
>  set re_methods	"${re_methods}${ws}int overload1arg\\(int \\*\\);"
>  set re_methods	"${re_methods}${ws}int overload1arg\\(void \\*\\);"
> +set re_methods  "${re_methods}${ws}int overload1arg\\(foo &\\);"
> +set re_methods  "${re_methods}${ws}int overload1arg\\(foo &&\\);"
>  set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
>  set re_methods	"${re_methods}${ws}int overloadfnarg\\(int\\);"
>  set re_methods	"${re_methods}${ws}int overloadfnarg\\(int, int ?\\(\\*\\) ?\\(int\\)\\);"

I know that you're following suit, but I try to limit my line-lengths to
under 80 columns. It's not always possible/feasible, but it can be done.

 Please use "append" for appending to a string.  Let's try to nip this
inefficient shell-ism in the bud:

append re_methods "${ws}int overload1arg\\(foo &'\)"


> diff --git a/gdb/testsuite/gdb.cp/ref-params.cc b/gdb/testsuite/gdb.cp/ref-params.cc
> index 0f7e125..efced2e 100644
> --- a/gdb/testsuite/gdb.cp/ref-params.cc
> +++ b/gdb/testsuite/gdb.cp/ref-params.cc
> @@ -17,6 +17,8 @@
>  
>  /* Author: Paul N. Hilfinger, AdaCore Inc. */
>  
> +#include <utility>
> +
>  struct Parent {
>    Parent (int id0) : id(id0) { }
>    int id;

This isn't mentioned in the ChangeLog.

> @@ -28,7 +30,12 @@ struct Child : public Parent {
>  
>  int f1(Parent& R)
>  {
> -  return R.id;			/* Set breakpoint marker3 here.  */
> +  return R.id;			/* Set breakpoint marker4 here.  */
> +}
> +
> +int f1(Parent&& R)
> +{
> +  return R.id;			/* Set breakpoint marker5 here.  */
>  }
>  
>  int f2(Child& C)
> @@ -36,6 +43,11 @@ int f2(Child& C)
>    return f1(C);			/* Set breakpoint marker2 here.  */
>  }
>  
> +int f2(Child&& C)
> +{
> +  return f1(std::move(C));                 /* Set breakpoint marker3 here.  */
> +}
> +

I don't think there is any requirement that the comments for
gdb_get_line_number be in order. I would not change the comment for
f1(Parent&) and just make unique comment for f1(Parent&&).

>  struct OtherParent {
>    OtherParent (int other_id0) : other_id(other_id0) { }
>    int other_id;
> @@ -50,11 +62,21 @@ int mf1(OtherParent& R)
>    return R.other_id;
>  }
>  
> +int mf1(OtherParent&& R)
> +{
> +  return R.other_id;
> +}
> +
>  int mf2(MultiChild& C)
>  {
>    return mf1(C);
>  }
>  
> +int mf2(MultiChild&& C)
> +{
> +  return mf1(C);
> +}
> +
>  int main(void) 
>  {
>    Child Q(42);

We would like test cases to follow the coding standard, too. [See
https://sourceware.org/gdb/wiki/Internals%20GDB-Testsuite-Coding-Standards]

int
mf1 (OtherParent &&C)
{
  ...
}

and so on.

> @@ -62,8 +84,13 @@ int main(void)
>  
>    /* Set breakpoint marker1 here.  */
>  
> +  f1(Q);
> +  f1(QR);
> +  f1(Child(42));
> +
>    f2(Q);
>    f2(QR);
> +  f2(Child(42));
>  
>    MultiChild MQ(53);
>    MultiChild& MQR = MQ;

Likewise here: "f1 (Q)", "f1 (Child (42))", etc.

> diff --git a/gdb/testsuite/gdb.cp/ref-types.cc b/gdb/testsuite/gdb.cp/ref-types.cc
> index 2c124a9..dafec19 100644
> --- a/gdb/testsuite/gdb.cp/ref-types.cc
> +++ b/gdb/testsuite/gdb.cp/ref-types.cc
> @@ -15,6 +15,8 @@
>     You should have received a copy of the GNU General Public License
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>  
> +#include <utility>
> +
>  int main2(void);
>  
>  void marker1 (void)

Not mentioned in ChangeLog.

> @@ -39,6 +41,18 @@ int main(void)
>      as[2] = 2;
>      as[3] = 3;
>  
> +    short t = -1;
> +    short *pt;
> +    short &&rrt = std::move(t);
> +    pt = &rrt;
> +    short *&&rrpt = std::move(pt);
> +    short at[4];
> +    at[0] = 0;
> +    at[1] = 1;
> +    at[2] = 2;
> +    at[3] = 3;
> +    short (&&rrat)[4] = std::move(at);
> +
>      marker1();
>  
>      main2();

This hunk isn't mentioned in the ChangeLog at all.

> @@ -66,15 +80,25 @@ int main2(void)
>      float F;
>      double D;
>      char &rC = C;
> +    char &&rrC = 'A';
>      unsigned char &rUC = UC;
> +    unsigned char &&rrUC = 21;
>      short &rS = S;
> +    short &&rrS = -14;
>      unsigned short &rUS = US;
> +    unsigned short &&rrUS = 7;
>      int &rI = I;
> +    int &&rrI = 102;
>      unsigned int &rUI = UI;
> +    unsigned int &&rrUI = 1002;
>      long &rL = L;
> +    long &&rrL = -234;
>      unsigned long &rUL = UL;
> +    unsigned long &&rrUL = 234;
>      float &rF = F;
> +    float &&rrF = 1.25E10;
>      double &rD = D;
> +    double &&rrD = -1.375E-123;
>      C = 'A';
>      UC = 21;
>      S = -14;
> diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp
> index 3b557f9..5c7c0e5 100644
> --- a/gdb/testsuite/gdb.cp/ref-types.exp
> +++ b/gdb/testsuite/gdb.cp/ref-types.exp
> @@ -24,7 +24,7 @@ if { [skip_cplus_tests] } { continue }
>  
>  standard_testfile .cc
>  
> -if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
> +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++ additional_flags="-std=c++11"}]} {
>      return -1
>  }
>  

Line too long.

> @@ -127,6 +127,47 @@ gdb_test "print ras\[1\]" ".\[0-9\]* = 1" "print value of ras\[1\]"
>  gdb_test "print ras\[2\]" ".\[0-9\]* = 2" "print value of ras\[2\]"
>  gdb_test "print ras\[3\]" ".\[0-9\]* = 3" "print value of ras\[3\]"
>  
> +# rvalue reference tests
> +
> +gdb_test_multiple "print rrt" "print value of rrt" {
> +    -re ".\[0-9\]* = \\(short &&\\) @$hex: -1.*$gdb_prompt $" {
> +        pass "print value of rrt"
> +    }
> +    -re ".\[0-9\]* = \\(short int &&\\) @$hex: -1.*$gdb_prompt $" {
> +        pass "print value of rrt"
> +    }
> +    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
> +}
> +

You can use an atom for the int part and write this test using the
simpler gdb_test, i.e., "= \\(short( int)? &&\\)".

PS. I know a lot of the test doesn't do it, but you can use the global
variable "decimal", defined by dejagnu:

  set decimal "\[0-9\]+"

> +gdb_test_multiple "ptype rrt" "ptype rrt" {
> +    -re "type = short &&.*$gdb_prompt $"  { pass "ptype rrt" }
> +    -re "type = short int &&.*$gdb_prompt $"  { pass "ptype rrt" }
> +}
> +

Likewise.

> +gdb_test "print *rrpt" ".\[0-9\]* = -1" "print value of *rrpt"

$decimal or just start with "= ...". That's a common usage pattern in
the test suite.

> +
> +# gdb had a bug about dereferencing a pointer type
> +# that would lead to wrong results
> +# if we try to examine memory at pointer value.
> +
> +gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
> +
> +gdb_test_multiple "ptype rrpt" "ptype rrpt" {
> +    -re "type = short \\*&&.*$gdb_prompt $"  { pass "ptype rrpt" }
> +    -re "type = short int \\*&&.*$gdb_prompt $"  { pass "ptype rrpt" }
> +}
> +

"( int)?" and gdb_test

> +gdb_test "print rrat\[0\]" ".\[0-9\]* = 0" "print value of rrat\[0\]"
> +

$decimal or start with "= ..."

> +gdb_test_multiple "ptype rrat" "ptype rrat" {
> +    -re "type = short \\\(&&\\\)\\\[4\\\].*$gdb_prompt $"  { pass "ptype rrat" }
> +    -re "type = short int \\\(&&\\\)\\\[4\\\].*$gdb_prompt $"  { pass "ptype rrat" }
> +}
> +
> +gdb_test "print rrat\[1\]" ".\[0-9\]* = 1" "print value of rrat\[1\]"
> +gdb_test "print rrat\[2\]" ".\[0-9\]* = 2" "print value of rrat\[2\]"
> +gdb_test "print rrat\[3\]" ".\[0-9\]* = 3" "print value of rrat\[3\]"
> +

$decimal

>  if ![runto 'f'] then {
>      perror "couldn't run to f"
> @@ -270,3 +311,96 @@ gdb_test "print rD" \
>      ".\[0-9\]* = \\(double &\\) @$hex: -1.375e-123.*" \
>      "print value of rD"
>  
> +#
> +# test rvalue reference types
> +#
> +
> +gdb_test "ptype rrC" "type = char &&"
> +
> +gdb_test "ptype rrUC" "type = unsigned char &&"
> +
> +gdb_test_multiple "ptype rrS" "ptype rrS" {
> +    -re "type = short &&.*$gdb_prompt $"  { pass "ptype rrS" }
> +    -re "type = short int &&.*$gdb_prompt $"  { pass "ptype rrS" }
> +}
> +
> +gdb_test_multiple "ptype rrUS" "ptype rrUS" {
> +    -re "type = unsigned short &&.*$gdb_prompt $"  { pass "ptype rrUS" }
> +    -re "type = short unsigned int &&.*$gdb_prompt $"  { pass "ptype rrUS" }
> +}
> +

"( int)?" and gdb_test

> +gdb_test "ptype rrI" "type = int &&"
> +
> +gdb_test "ptype rrUI" "type = unsigned int &&"
> +
> +gdb_test_multiple "ptype rrL" "ptype rrL" {
> +    -re "type = long &&.*$gdb_prompt $"  { pass "ptype rrL" }
> +    -re "type = long int &&.*$gdb_prompt $"  { pass "ptype rrL" }
> +}
> +
> +gdb_test_multiple "ptype rrUL" "ptype rrUL" {
> +    -re "type = unsigned long &&.*$gdb_prompt $"  { pass "ptype rrUL" }
> +    -re "type = long unsigned int &&.*$gdb_prompt $"  { pass "ptype rrUL" }
> +}
> +

Can use an atom here, too.

> +gdb_test "ptype rrF" "type = float &&"
> +
> +gdb_test "ptype rrD" "type = double &&"
> +
> +gdb_test "print rrC" ".\[0-9\]* = \\(char &&\\) @$hex: 65 \'A\'" \
> +    "print value of rrC"
> +
> +gdb_test "print rrUC" \
> +    ".\[0-9\]* = \\(unsigned char &&\\) @$hex: 21 \'.025\'" \
> +    "print value of rrUC"
> +
> +gdb_test_multiple "print rrS" "print value of rrS" {
> +    -re ".\[0-9\]* = \\(short &&\\) @$hex: -14.*$gdb_prompt $" {
> +        pass "print value of rrS"
> +    }
> +    -re ".\[0-9\]* = \\(short int &&\\) @$hex: -14.*$gdb_prompt $" {
> +        pass "print value of rrS"
> +    }
> +}
> +
> +gdb_test_multiple "print rrUS" "print value of rrUS" {
> +    -re ".\[0-9\]* = \\(unsigned short &&\\) @$hex: 7.*$gdb_prompt $" {
> +        pass "print value of rrUS"
> +    }
> +    -re ".\[0-9\]* = \\(short unsigned int &&\\) @$hex: 7.*$gdb_prompt $" {
> +        pass "print value of rrUS"
> +    }
> +}
> +
> +gdb_test "print rrI" ".\[0-9\]* = \\(int &&\\) @$hex: 102" \
> +	"print value of rrI"
> +
> +gdb_test "print rrUI" \
> +    ".\[0-9\]* = \\(unsigned int &&\\) @$hex: 1002" \
> +        "print value of UI"
> +

There are already two tests named "print value of UI," and you've now
added a third. Please make the name of this test unique. See
https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#Make_sure_test_messages_are_unique
for more information. [You need not fix the other tests. Just don't
introduce another duplicate test name.]

> +gdb_test_multiple "print rrL" "print value of rrL" {
> +    -re ".\[0-9\]* = \\(long &&\\) @$hex: -234.*$gdb_prompt $" {
> +        pass "print value of rrL"
> +    }
> +    -re ".\[0-9\]* = \\(long int &&\\) @$hex: -234.*$gdb_prompt $" {
> +        pass "print value of rrL"
> +    }
> +}
> +
> +gdb_test_multiple "print rrUL" "print value of rrUL" {
> +    -re ".\[0-9\]* = \\(unsigned long &&\\) @$hex: 234.*$gdb_prompt $" {
> +        pass "print value of rrUL"
> +    }
> +    -re ".\[0-9\]* = \\(long unsigned int &&\\) @$hex: 234.*$gdb_prompt $" {
> +        pass "print value of rrUL"
> +    }
> +}
> +
> +gdb_test "print rrF" \
> +    ".\[0-9\]* = \\(float &&\\) @$hex: 1.2\[0-9\]*e\\+0?10.*" \
> +    "print value of rrF"
> +
> +gdb_test "print rrD" \
> +    ".\[0-9\]* = \\(double &&\\) @$hex: -1.375e-123.*" \
> +    "print value of rrD"

Atom and/or $decimal in all of the above.

IIRC, code was added to python, but I don't see any python tests?

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-02-19 18:49   ` [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
@ 2016-02-23  6:04     ` Artemiy Volkov
  0 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-02-23  6:04 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches@sourceware.org ml

On Fri, Feb 19, 2016 at 10:49:18AM -0800, Keith Seitz wrote:
> On 01/19/2016 10:53 AM, Artemiy Volkov wrote:
> 
> > this is my second take on fixing gdb/14441 which deals with C++0x rvalue
> > references.
> 
> Thank you for submitting this! I have been trying to find the time to do
> this myself. I rather glad someone beat me to it! It's a lot more work
> than I imagined.

Hi Keith,

thank you for such an extensive review. The errors are mostly trivial so
I'll try and send out v3 by the end of the week.

> 
> I think this is important enough a new "feature" to have a mention in NEWS.

Sure, I'll add an entry to it.

> 
> While I've attempted to add pointers to relevant submission
> documentation, I encourage you to peruse the official GDB Contribution
> Checklist on the GDB wiki:
> 
> https://sourceware.org/gdb/wiki/ContributionChecklist

OK, I'll make sure to double-check everything against this list next
time.

> 
> Keith
> 

Thanks,
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-02-19 18:49     ` Keith Seitz
@ 2016-02-23  7:04       ` Artemiy Volkov
  2016-02-25  1:22         ` Keith Seitz
  0 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-02-23  7:04 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Fri, Feb 19, 2016 at 10:49:38AM -0800, Keith Seitz wrote:

[snip]

> >  /* * Instruction-space delimited type.  This is for Harvard architectures
> >     which have separate instruction and data address spaces (and perhaps
> >     others).
> > @@ -767,6 +775,10 @@ struct type
> >  
> >    struct type *reference_type;
> >  
> > +  /* * A C++ rvalue reference type added in C++0x. */
> > +
> > +  struct type *rvalue_reference_type;
> > +
> 
> Why is this new field necessary? AFAICT, it is used exactly the same way
> as the reference_type field above it, and whether a reference type is an
> rvalue type is encoded into the type code.

Do you suggest keeping only the lvalue version of the reference type and
then adjust its type code from TYPE_CODE_REF to TYPE_CODE_RVALUE_REF on
lookup_rvalue_reference_type()? It seems somewhat hacky to me. E.g. how
would we be able to create a struct type for a complex type involving a
T&&, such as a typedef of it?

> 
> >    /* * Variant chain.  This points to a type that differs from this
> >       one only in qualifiers and length.  Currently, the possible
> >       qualifiers are const, volatile, code-space, data-space, and
> > @@ -1229,6 +1241,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,
> 
> If struct type.rvalue_reference_type is superfluous, this is unneeded.
> 
> Keith
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-02-23  7:04       ` Artemiy Volkov
@ 2016-02-25  1:22         ` Keith Seitz
  2016-02-25  1:32           ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-02-25  1:22 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

On 02/22/2016 11:03 PM, Artemiy Volkov wrote:
> On Fri, Feb 19, 2016 at 10:49:38AM -0800, Keith Seitz wrote:
> 
> Do you suggest keeping only the lvalue version of the reference type and
> then adjust its type code from TYPE_CODE_REF to TYPE_CODE_RVALUE_REF on
> lookup_rvalue_reference_type()? It seems somewhat hacky to me. E.g. how
> would we be able to create a struct type for a complex type involving a
> T&&, such as a typedef of it?

Bah. No, I am wrong. Please disregard this comment.

Sorry about the confusion.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-02-25  1:22         ` Keith Seitz
@ 2016-02-25  1:32           ` Artemiy Volkov
  2016-02-25  1:41             ` Keith Seitz
  0 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-02-25  1:32 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Wed, Feb 24, 2016 at 05:22:18PM -0800, Keith Seitz wrote:
> On 02/22/2016 11:03 PM, Artemiy Volkov wrote:
> > On Fri, Feb 19, 2016 at 10:49:38AM -0800, Keith Seitz wrote:
> > 
> > Do you suggest keeping only the lvalue version of the reference type and
> > then adjust its type code from TYPE_CODE_REF to TYPE_CODE_RVALUE_REF on
> > lookup_rvalue_reference_type()? It seems somewhat hacky to me. E.g. how
> > would we be able to create a struct type for a complex type involving a
> > T&&, such as a typedef of it?
> 
> Bah. No, I am wrong. Please disregard this comment.
> 
> Sorry about the confusion.

No problem at all. Correct me if I am wrong, but I think this
invalidates your remarks in 2/11 that refer to this change. Do those 2
hunks in 2/11 look OK now?

> 
> Keith

Thanks,
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-02-25  1:32           ` Artemiy Volkov
@ 2016-02-25  1:41             ` Keith Seitz
  2016-02-25  1:45               ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-02-25  1:41 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: gdb-patches

[bah -- forgot to "reply all"]

On 02/24/2016 05:31 PM, Artemiy Volkov wrote:
> On Wed, Feb 24, 2016 at 05:22:18PM -0800, Keith Seitz wrote:
>> On 02/22/2016 11:03 PM, Artemiy Volkov wrote:
>>> On Fri, Feb 19, 2016 at 10:49:38AM -0800, Keith Seitz wrote:
>>>
>>> Do you suggest keeping only the lvalue version of the reference type and
>>> then adjust its type code from TYPE_CODE_REF to TYPE_CODE_RVALUE_REF on
>>> lookup_rvalue_reference_type()? It seems somewhat hacky to me. E.g. how
>>> would we be able to create a struct type for a complex type involving a
>>> T&&, such as a typedef of it?
>>
>> Bah. No, I am wrong. Please disregard this comment.
>>
>> Sorry about the confusion.
> 
> No problem at all. Correct me if I am wrong, but I think this
> invalidates your remarks in 2/11 that refer to this change. Do those 2
> hunks in 2/11 look OK now?

Yes, ignore my comments in make_reference_type. The only thing of note
in there, then, is that we prefer the usage of explicit NULL checks:

  if (*reftype != NULL)
    ...

instead of

  if (!*reftype)
    ...

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-02-25  1:41             ` Keith Seitz
@ 2016-02-25  1:45               ` Artemiy Volkov
  0 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-02-25  1:45 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Wed, Feb 24, 2016 at 05:41:09PM -0800, Keith Seitz wrote:
> [bah -- forgot to "reply all"]
> 
> On 02/24/2016 05:31 PM, Artemiy Volkov wrote:
> > On Wed, Feb 24, 2016 at 05:22:18PM -0800, Keith Seitz wrote:
> >> On 02/22/2016 11:03 PM, Artemiy Volkov wrote:
> >>> On Fri, Feb 19, 2016 at 10:49:38AM -0800, Keith Seitz wrote:
> >>>
> >>> Do you suggest keeping only the lvalue version of the reference type and
> >>> then adjust its type code from TYPE_CODE_REF to TYPE_CODE_RVALUE_REF on
> >>> lookup_rvalue_reference_type()? It seems somewhat hacky to me. E.g. how
> >>> would we be able to create a struct type for a complex type involving a
> >>> T&&, such as a typedef of it?
> >>
> >> Bah. No, I am wrong. Please disregard this comment.
> >>
> >> Sorry about the confusion.
> > 
> > No problem at all. Correct me if I am wrong, but I think this
> > invalidates your remarks in 2/11 that refer to this change. Do those 2
> > hunks in 2/11 look OK now?
> 
> Yes, ignore my comments in make_reference_type. The only thing of note
> in there, then, is that we prefer the usage of explicit NULL checks:
> 
>   if (*reftype != NULL)
>     ...
> 
> instead of
> 
>   if (!*reftype)
>     ...

Gotcha. I'll make sure to fix that.

> 
> Keith

Thanks,
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-02-19 19:01     ` Keith Seitz
@ 2016-02-26  5:08       ` Artemiy Volkov
  0 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-02-26  5:08 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Fri, Feb 19, 2016 at 11:01:01AM -0800, Keith Seitz wrote:

[snip]

> > 2016-01-19  Artemiy Volkov  <artemiyv@acm.org>
> > 
> >         * gdb/aarch64-tdep.c (aarch64_type_align): Change TYPE_CODE_REF
> >         check to TYPE_REFERENCE check.
> >         (aarch64_extract_return_value): Likewise.
> >         (aarch64_store_return_value): Likewise.
> >         * gdb/amd64-tdep.c (amd64_classify): Likewise.
> [big snip]
> 
> We are now encouraging/permitting developers to use the phrase "Update
> all callers." or "All callers updated." with large, mechanical changes
> like this.
> 

This phrase doesn't fit here, does it? There's no function signature
changes, thus no callers really get updated. Maybe I should leave the
"likewise"s as they were or rephrase it in some other way?

Thanks,
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
                     ` (11 preceding siblings ...)
  2016-02-19 18:49   ` [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
@ 2016-03-05  3:20   ` Artemiy Volkov
  2016-03-05  3:20     ` [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
                       ` (11 more replies)
  12 siblings, 12 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Hi all,

this is my third take on fixing gdb/14441 which deals with C++0x rvalue
references.

The approach is rather straightforward and the work for the most part consisted
of mimicking the behavior for regular references. In gdbtypes.c, several helper
functions were introduced and some parameterized by the reference kind to
simplify the access to reference type objects API.

The only interesting part is the addition of overloading resolution rules
with regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
13.3.3.2 were accounted for at the beginning of rank_one_type().

With this patch it is now also possible to fix the evaluation of decltype,
which should return a plain type object, an lvalue reference or an rvalue
reference depending on a type category of the type of its operand. However,
this would require introduction of the type catyegory notion to gdb, which I
think only needs adding a new constant to lval_type and propagating the type
category through different parts of an expression in gdb/valops.c. I'm willing
to do this if this patchset turns out to be OK.

Changes from v1 consist of dropping the libiberty part of 05/11 and the
consequent testsuite changes. I have learned that introducing rvalue reference
support to the demangler in cplus-dem.c is completely unnecessary, since
virtually all contemporary compilers generate symbol names handled in
cp-demangle.c. Therefore I have removed some of the testcases in
gdb.cp/demangle.exp and switched the others to use the gnu-v3 demangling style.

Changes from v2 are numerous coding style fixes, improvements and
simplifications of the changelog, reorganization and reordering of the
patchset, removal of redundant code in gdb/python/*, addition of a couple of
python tests, and a few bugfixes.

Artemiy Volkov (11):
  gdb: gdbtypes: add definitions for rvalue reference type
  gdb: gdbtypes: change {lookup,make}_reference_type() API
  gdb: valops: add ability to return rvalue reference values from
    value_ref()
  gdb: parse: support rvalue reference type
  gdb: demangle: implement demangling for rvalue reference typenames
  gdb: print: implement correct printing of rvalue reference types and
    values
  gdb: dwarf2read: support DW_AT_rvalue_reference type
  gdb: python: support rvalue references in the gdb module
  gdb: convert lvalue reference type check to general reference type
    check
  gdb: gdbtypes: add rvalue references to overloading resolution
  gdb: testsuite: add rvalue reference tests

 gdb/aarch64-tdep.c                       |   5 +-
 gdb/ada-lang.c                           |   2 +-
 gdb/amd64-tdep.c                         |   2 +-
 gdb/amd64-windows-tdep.c                 |   1 +
 gdb/arm-tdep.c                           |   5 +-
 gdb/ax-gdb.c                             |   2 +
 gdb/c-exp.y                              |   6 +-
 gdb/c-typeprint.c                        |  10 +--
 gdb/c-valprint.c                         |  13 ++--
 gdb/c-varobj.c                           |  10 +--
 gdb/compile/compile-c-symbols.c          |   2 +-
 gdb/completer.c                          |   3 +-
 gdb/cp-name-parser.y                     |   4 ++
 gdb/cp-support.c                         |   3 +-
 gdb/darwin-nat-info.c                    |   2 +-
 gdb/dwarf2loc.c                          |   4 +-
 gdb/dwarf2read.c                         |  15 +++--
 gdb/eval.c                               |  16 ++---
 gdb/f-exp.y                              |   2 +-
 gdb/findvar.c                            |   6 +-
 gdb/gdbtypes.c                           | 106 +++++++++++++++++++++++++++----
 gdb/gdbtypes.h                           |  20 +++++-
 gdb/guile/scm-type.c                     |   2 +-
 gdb/guile/scm-value.c                    |   2 +-
 gdb/hppa-tdep.c                          |   1 +
 gdb/infcall.c                            |   5 +-
 gdb/language.c                           |   3 +-
 gdb/m32c-tdep.c                          |   8 +--
 gdb/m88k-tdep.c                          |   1 +
 gdb/mn10300-tdep.c                       |   1 +
 gdb/msp430-tdep.c                        |   2 +-
 gdb/parse.c                              |  40 ++++++------
 gdb/parser-defs.h                        |   1 +
 gdb/ppc-sysv-tdep.c                      |   7 +-
 gdb/printcmd.c                           |   2 +-
 gdb/python/lib/gdb/command/explore.py    |   2 +-
 gdb/python/lib/gdb/types.py              |   4 +-
 gdb/python/py-type.c                     |  14 ++--
 gdb/python/py-value.c                    |  16 +++--
 gdb/python/py-xmethods.c                 |  14 ++--
 gdb/s390-linux-tdep.c                    |   2 +-
 gdb/sparc-tdep.c                         |   1 +
 gdb/sparc64-tdep.c                       |   1 +
 gdb/spu-tdep.c                           |   1 +
 gdb/stabsread.c                          |   3 +-
 gdb/symtab.c                             |   3 +-
 gdb/testsuite/gdb.cp/casts.cc            |   8 ++-
 gdb/testsuite/gdb.cp/casts.exp           |  35 ++++++++--
 gdb/testsuite/gdb.cp/cpsizeof.cc         |   4 ++
 gdb/testsuite/gdb.cp/cpsizeof.exp        |   3 +-
 gdb/testsuite/gdb.cp/demangle.exp        |  36 +++++++++++
 gdb/testsuite/gdb.cp/overload.cc         |  14 ++++
 gdb/testsuite/gdb.cp/overload.exp        |  16 ++++-
 gdb/testsuite/gdb.cp/ref-params.cc       |  27 ++++++++
 gdb/testsuite/gdb.cp/ref-params.exp      |  21 +++++-
 gdb/testsuite/gdb.cp/ref-types.cc        |  24 +++++++
 gdb/testsuite/gdb.cp/ref-types.exp       |  92 ++++++++++++++++++++++++++-
 gdb/testsuite/gdb.python/py-value-cc.cc  |   4 ++
 gdb/testsuite/gdb.python/py-value-cc.exp |  10 ++-
 gdb/typeprint.c                          |   4 +-
 gdb/valarith.c                           |   6 +-
 gdb/valops.c                             |  68 +++++++++++---------
 gdb/valprint.c                           |   5 +-
 gdb/value.c                              |  12 ++--
 gdb/value.h                              |   2 +-
 gdb/varobj.c                             |   2 +-
 66 files changed, 593 insertions(+), 175 deletions(-)

-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (8 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:19       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Parameterize lookup_reference_type() and make_reference_type() by the kind of
reference type we want to look up. Create two wrapper functions
lookup_{lvalue,rvalue}_reference_type() for lookup_reference_type() to simplify
the API. Change all callers to use the new API.

gdb/Changelog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * dwarf2read.c (read_tag_reference_type): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
    * eval.c (evaluate_subexp_standard): Likewise.
    * f-exp.y: Likewise.
    * gdbtypes.c (make_reference_type, lookup_reference_type):
    Generalize with rvalue reference types.
    (lookup_lvalue_reference_type, lookup_rvalue_reference_type): New
    convenience wrappers for lookup_reference_type().
    * gdbtypes.h (make_reference_type, lookup_reference_type): Add a
    reference kind parameter.
    (lookup_lvalue_reference_type, lookup_rvalue_reference_type): Add
    wrappers for lookup_reference_type().
    * guile/scm-type.c (gdbscm_type_reference): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
    * guile/scm-value.c (gdbscm_value_dynamic_type): Likewise.
    * parse.c (follow_types): Likewise.
    * python/py-type.c (typy_reference, typy_lookup_type): Likewise.
    * python/py-value.c (valpy_get_dynamic_type, valpy_getitem):
    Likewise.
    * python/py-xmethods.c (gdbpy_get_xmethod_result_type)
    (gdbpy_invoke_xmethod): Likewise.
    * stabsread.c: Provide extra argument to make_reference_type()
    call.
    * valops.c (value_ref, value_rtti_indirect_type): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
---
 gdb/dwarf2read.c         |  2 +-
 gdb/eval.c               |  2 +-
 gdb/f-exp.y              |  2 +-
 gdb/gdbtypes.c           | 43 ++++++++++++++++++++++++++++++++++---------
 gdb/gdbtypes.h           |  8 ++++++--
 gdb/guile/scm-type.c     |  2 +-
 gdb/guile/scm-value.c    |  2 +-
 gdb/parse.c              |  2 +-
 gdb/python/py-type.c     |  4 ++--
 gdb/python/py-value.c    |  5 +++--
 gdb/python/py-xmethods.c |  4 ++--
 gdb/stabsread.c          |  3 ++-
 gdb/valops.c             |  4 ++--
 13 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index dcd49e3..cf8ce53 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14337,7 +14337,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_reference_type (target_type);
+  type = lookup_lvalue_reference_type (target_type);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
diff --git a/gdb/eval.c b/gdb/eval.c
index 78ad946..8969f49 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2789,7 +2789,7 @@ evaluate_subexp_standard (struct type *expect_type,
 
 	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
 		{
-		  type = lookup_reference_type (type);
+		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 4faac32..8948578 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -567,7 +567,7 @@ ptype	:	typebase
 			follow_type = lookup_pointer_type (follow_type);
 			break;
 		      case tp_reference:
-			follow_type = lookup_reference_type (follow_type);
+			follow_type = lookup_lvalue_reference_type (follow_type);
 			break;
 		      case tp_array:
 			array_size = pop_type_int ();
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index f129b0e..a99e878 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -384,15 +384,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. REFCODE denotes
+   the kind of reference type to lookup (lvalue or rvalue reference).  */
 
 struct type *
-make_reference_type (struct type *type, struct type **typeptr)
+make_reference_type (struct type *type, struct type **typeptr,
+                      enum type_code refcode)
 {
   struct type *ntype;	/* New type */
+  struct type **reftype;
   struct type *chain;
 
-  ntype = TYPE_REFERENCE_TYPE (type);
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
+           : TYPE_RVALUE_REFERENCE_TYPE (type));
 
   if (ntype)
     {
@@ -421,7 +427,11 @@ make_reference_type (struct type *type, struct type **typeptr)
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
-  TYPE_REFERENCE_TYPE (type) = ntype;
+  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
+             : &TYPE_RVALUE_REFERENCE_TYPE (type));
+
+  if(*reftype != NULL)
+    *reftype = ntype;
 
   /* FIXME!  Assume the machine has only one representation for
      references, and that it matches the (only) representation for
@@ -429,10 +439,9 @@ make_reference_type (struct type *type, struct type **typeptr)
 
   TYPE_LENGTH (ntype) =
     gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
-  TYPE_CODE (ntype) = TYPE_CODE_REF;
+  TYPE_CODE (ntype) = refcode;
 
-  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
-    TYPE_REFERENCE_TYPE (type) = ntype;
+  *reftype = ntype;
 
   /* Update the length of all the other variants of this type.  */
   chain = TYPE_CHAIN (ntype);
@@ -449,9 +458,25 @@ make_reference_type (struct type *type, struct type **typeptr)
    details.  */
 
 struct type *
-lookup_reference_type (struct type *type)
+lookup_reference_type (struct type *type, enum type_code refcode)
+{
+  return make_reference_type (type, (struct type **) 0, refcode);
+}
+
+/* Lookup the lvalue reference type for the type TYPE.  */
+
+struct type *
+lookup_lvalue_reference_type (struct type *type)
+{
+  return lookup_reference_type (type, TYPE_CODE_REF);
+}
+
+/* Lookup the rvalue reference type for the type TYPE.  */
+
+struct type *
+lookup_rvalue_reference_type (struct type *type)
 {
-  return make_reference_type (type, (struct type **) 0);
+  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
 }
 
 /* Lookup a function type that returns type TYPE.  TYPEPTR, if
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 3bdbcd9..620bf66 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1724,9 +1724,13 @@ 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);
 
-extern struct type *lookup_reference_type (struct type *);
+extern struct type *lookup_reference_type (struct type *, enum type_code);
+extern struct type *lookup_lvalue_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_reference_type (struct type *, struct type **,
+                                         enum type_code);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 2acdfad..888624d 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -854,7 +854,7 @@ gdbscm_type_reference (SCM self)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 1cdf953..fff3817 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -601,7 +601,7 @@ gdbscm_value_dynamic_type (SCM self)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+		type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
diff --git a/gdb/parse.c b/gdb/parse.c
index 4191fc6..06f7bcd 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1695,7 +1695,7 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_reference_type (follow_type);
+	follow_type = lookup_lvalue_reference_type (follow_type);
 	if (make_const)
 	  follow_type = make_cv_type (make_const, 
 				      TYPE_VOLATILE (follow_type), 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 03cc8d9..6103a2b 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -667,7 +667,7 @@ typy_reference (PyObject *self, PyObject *args)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -827,7 +827,7 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-	      rtype =  lookup_reference_type (type);
+	      rtype = lookup_lvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7dba0ad..be08231 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -376,7 +376,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+		type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -766,7 +766,8 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
-	    res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
+	                          tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 58bb783..d70cdd1 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -550,7 +550,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
@@ -636,7 +636,7 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 74260b7..60691a1 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -1772,7 +1772,8 @@ again:
 
     case '&':			/* Reference to another type */
       type1 = read_type (pp, objfile);
-      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile));
+      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile),
+                                  TYPE_CODE_REF);
       break;
 
     case 'f':			/* Function returning another type */
diff --git a/gdb/valops.c b/gdb/valops.c
index 5a244a9..1aafb5a 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1508,7 +1508,7 @@ value_ref (struct value *arg1)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
   return arg2;
 }
 
@@ -3616,7 +3616,7 @@ value_rtti_indirect_type (struct value *v, int *full,
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
       if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_reference_type (real_type);
+        real_type = lookup_lvalue_reference_type (real_type);
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (4 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:22       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
                       ` (5 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Parameterize value_ref() by the kind of reference type the value of which
is requested. Change all callers to use the new API.

gdb/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * ada-lang.c (ada_evaluate_subexp): Adhere to the new
    value_ref() interface.
    * c-valprint.c (c_value_print): Likewise.
    * infcall.c (value_arg_coerce): Likewise.
    * python/py-value.c (valpy_reference_value): Likewise.
    * valops.c (value_cast, value_reinterpret_cast)
    (value_dynamic_cast, typecmp): Likewise.
    (value_ref): Parameterize by kind of return value reference type.
    * value.h (value_ref): Add new parameter "refcode".
---
 gdb/ada-lang.c        |  2 +-
 gdb/c-valprint.c      |  9 ++++++---
 gdb/infcall.c         |  2 +-
 gdb/python/py-value.c |  2 +-
 gdb/valops.c          | 25 +++++++++++++++++--------
 gdb/value.h           |  2 +-
 6 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d874129..585d729 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10724,7 +10724,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 		     should return a ref as it should be valid to ask
 		     for its address; so rebuild a ref after coerce.  */
 		  arg1 = ada_coerce_ref (arg1);
-		  return value_ref (arg1);
+		  return value_ref (arg1, TYPE_CODE_REF);
 		}
 	    }
 
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 62552ec..a1f5db6 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -602,10 +602,13 @@ c_value_print (struct value *val, struct ui_file *stream,
       else if (options->objectprint
 	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
-	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+	  int is_ref = TYPE_IS_REFERENCE (type);
+	  enum type_code refcode = TYPE_CODE_UNDEF;
 
-	  if (is_ref)
+	  if (is_ref) {
 	    val = value_addr (val);
+	    refcode = TYPE_CODE (type);
+	  }
 
 	  /* Pointer to class, check real type of object.  */
 	  fprintf_filtered (stream, "(");
@@ -625,7 +628,7 @@ c_value_print (struct value *val, struct ui_file *stream,
 
 		  if (is_ref)
 		    {
-		      val = value_ref (value_ind (val));
+		      val = value_ref (value_ind (val), refcode);
 		      type = value_type (val);
 		    }
 
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 77cd931..ad2512a 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -169,7 +169,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
 	   if the value was not previously in memory - in some cases
 	   we should clearly be allowing this, but how?  */
 	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
-	new_value = value_ref (new_value);
+	new_value = value_ref (new_value, TYPE_CODE (type));
 	return new_value;
       }
     case TYPE_CODE_INT:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index be08231..141f180 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -249,7 +249,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val));
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF));
 
       do_cleanups (cleanup);
     }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1aafb5a..1f423a0 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -372,7 +372,7 @@ value_cast (struct type *type, struct value *arg2)
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
       struct value *val =  value_cast (dereftype, arg2);
 
-      return value_ref (val); 
+      return value_ref (val, TYPE_CODE (t1));
     }
 
   code2 = TYPE_CODE (check_typedef (value_type (arg2)));
@@ -622,7 +622,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
     error (_("Invalid reinterpret_cast"));
 
   if (is_ref)
-    result = value_cast (type, value_ref (value_ind (result)));
+    result = value_cast (type, value_ref (value_ind (result),
+                                          TYPE_CODE (type)));
 
   return result;
 }
@@ -816,7 +817,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
 				arg_type,
 				&result) == 1)
 	return value_cast (type,
-			   is_ref ? value_ref (result) : value_addr (result));
+			   is_ref
+			   ? value_ref (result, TYPE_CODE (resolved_type))
+			   : value_addr (result));
     }
 
   /* The second dynamic check specified in 5.2.7.  */
@@ -828,7 +831,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
 			       value_address (tem), tem,
 			       rtti_type, &result) == 1)
     return value_cast (type,
-		       is_ref ? value_ref (result) : value_addr (result));
+		       is_ref
+		       ? value_ref (result, TYPE_CODE (resolved_type))
+		       : value_addr (result));
 
   if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
     return value_zero (type, not_lval);
@@ -1499,16 +1504,20 @@ value_addr (struct value *arg1)
    contents.  */
 
 struct value *
-value_ref (struct value *arg1)
+value_ref (struct value *arg1, enum type_code refcode)
 {
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  if ((TYPE_CODE (type) == TYPE_CODE_REF
+       || TYPE_CODE (type) == TYPE_CODE_RVALUE_REF)
+      && TYPE_CODE (type) == refcode)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_reference_type (type, refcode));
   return arg2;
 }
 
@@ -1715,7 +1724,7 @@ typecmp (int staticp, int varargs, int nargs,
 	  if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
 	    t2[i] = value_coerce_array (t2[i]);
 	  else
-	    t2[i] = value_ref (t2[i]);
+	    t2[i] = value_ref (t2[i], TYPE_CODE (tt1));
 	  continue;
 	}
 
diff --git a/gdb/value.h b/gdb/value.h
index 2eac5ef..db1b7bf 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -725,7 +725,7 @@ extern struct value *value_ind (struct value *arg1);
 
 extern struct value *value_addr (struct value *arg1);
 
-extern struct value *value_ref (struct value *arg1);
+extern struct value *value_ref (struct value *arg1, enum type_code refcode);
 
 extern struct value *value_assign (struct value *toval,
 				   struct value *fromval);
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (3 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:08       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
                       ` (6 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch introduces preliminal definitions regarding C++0x rvalue references
to the gdb type system. In addition to an enum type_code entry, a field in
struct type and an accessor macro for that which are created similarly to the
lvalue references' counterparts, we also introduce a TYPE_REFERENCE convenience
macro used to check for both kinds of references simultaneously as they are
equivalent in many contexts.

gdb/Changelog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * gdbtypes.h (enum type_code) <TYPE_CODE_RVALUE_REF>: New constant.
    (TYPE_IS_REFERENCE): New macro.
    (struct type): Add rvalue_reference_type field.
    (TYPE_RVALUE_REFERENCE_TYPE): New macro.
---
 gdb/gdbtypes.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index e775a1d..3bdbcd9 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -160,6 +160,8 @@ enum type_code
 
     TYPE_CODE_REF,		/**< C++ Reference types */
 
+    TYPE_CODE_RVALUE_REF,	/**< C++ rvalue reference types */
+
     TYPE_CODE_CHAR,		/**< *real* character type */
 
     /* * Boolean type.  0 is false, 1 is true, and other values are
@@ -362,6 +364,11 @@ enum type_instance_flag_value
 #define TYPE_ATOMIC(t) \
   (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
 
+/* True if this type represents either an lvalue or lvalue reference type.  */
+
+#define TYPE_IS_REFERENCE(t) \
+  (TYPE_CODE (t) == TYPE_CODE_REF || TYPE_CODE (t) == TYPE_CODE_RVALUE_REF)
+
 /* * Instruction-space delimited type.  This is for Harvard architectures
    which have separate instruction and data address spaces (and perhaps
    others).
@@ -767,6 +774,10 @@ struct type
 
   struct type *reference_type;
 
+  /* * A C++ rvalue reference type added in C++0x. */
+
+  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 const, volatile, code-space, data-space, and
@@ -1229,6 +1240,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,
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
  2016-03-05  3:20     ` [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
  2016-03-05  3:20     ` [PATCH v3 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:45       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
                       ` (8 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch introduces changes to rank_one_type() dealing with ranking an rvalue
reference type when selecting a best viable function from a set of candidate
functions. The 4 new added rules for rvalue references are:

1) An rvalue argument cannot be bound to a non-const lvalue reference parameter
and an lvalue argument cannot be bound to an rvalue reference parameter.
[C++11 13.3.3.1.4p3]

2) If a conversion to one type of reference is an identity conversion, and a
conversion to the second type of reference is a non-identity conversion, choose
the first type. [C++11 13.3.3.2p3]

3) An rvalue should be first tried to bind to an rvalue reference, and then to
an lvalue reference. [C++11 13.3.3.2p3]

4) An lvalue reference to a function gets higher priority than an rvalue
reference to a function. [C++11 13.3.3.2p3]

gdb/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * gdbtypes.c (rank_one_type): Implement overloading
    resolution rules regarding rvalue references.
---
 gdb/gdbtypes.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ce4b9be..c5b8ab5 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -58,6 +58,8 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
 const struct rank BOOL_CONVERSION_BADNESS = {3,0};
 const struct rank BASE_CONVERSION_BADNESS = {2,0};
 const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0};
+const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0};
 const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
 const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
 const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
@@ -3466,15 +3468,65 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 {
   struct rank rank = {0,0};
 
-  if (types_equal (parm, arg))
-    return EXACT_MATCH_BADNESS;
-
   /* Resolve typedefs */
   if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
     parm = check_typedef (parm);
   if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
     arg = check_typedef (arg);
 
+  if (value != NULL)
+    {
+      /* An rvalue argument cannot be bound to a non-const lvalue
+         reference parameter...  */
+      if (VALUE_LVAL (value) == not_lval
+          && TYPE_CODE (parm) == TYPE_CODE_REF
+          && !TYPE_CONST (parm->main_type->target_type))
+        return INCOMPATIBLE_TYPE_BADNESS;
+
+      /* ... and an lvalue argument cannot be bound to an rvalue
+         reference parameter.  [C++ 13.3.3.1.4p3]  */
+      if (VALUE_LVAL (value) != not_lval
+          && TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
+        return INCOMPATIBLE_TYPE_BADNESS;
+    }
+
+  if (types_equal (parm, arg))
+    return EXACT_MATCH_BADNESS;
+
+  /* An lvalue reference to a function should get higher priority than an
+     rvalue reference to a function. */
+
+  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
+      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
+    {
+      return (sum_ranks (rank_one_type (parm,
+              lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
+              DIFFERENT_REFERENCE_TYPE_BADNESS));
+    }
+
+  /* If a conversion to one type of reference is an identity conversion, and a
+     conversion to the second type of reference is a non-identity conversion,
+     choose the first type. */
+
+  if (value != NULL && TYPE_IS_REFERENCE (parm) && TYPE_IS_REFERENCE (arg)
+     && TYPE_CODE (parm) != TYPE_CODE (arg))
+    {
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
+              TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
+    }
+
+  /* An rvalue should be first tried to bind to an rvalue reference, and then to
+     an lvalue reference. */
+
+  if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
+      && VALUE_LVAL (value) == not_lval)
+    {
+      if (TYPE_IS_REFERENCE (arg))
+	arg = TYPE_TARGET_TYPE (arg);
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
+			 LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
+    }
+
   /* See through references, since we can almost make non-references
      references.  */
 
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (2 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:32       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
                       ` (7 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch adds the ability to inspect rvalue reference types and values using
the gdb python module. This is achieved by simply using the ReferenceExplorer
class to handle the objects of rvalue reference types and placing necessary
checks for a TYPE_CODE_RVALUE_REF type code next to the checks for a
TYPE_CODE_REF type code.

gdb/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

        * python/lib/gdb/command/explore.py: Support exploring values
        of rvalue reference types.
        * python/lib/gdb/types.py: Implement get_basic_type() for
        rvalue reference types.
        * python/py-type.c (pyty_codes) <TYPE_CODE_RVALUE_REF>: New
        constant.
        * python/py-value.c (valpy_getitem): Add an rvalue reference
        check.
        * python/py-xmethods.c (gdbpy_get_xmethod_result_type)
        (gdbpy_invoke_xmethod): Likewise.
---
 gdb/python/lib/gdb/command/explore.py |  2 +-
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 |  3 +++
 gdb/python/py-xmethods.c              | 14 ++++++++------
 5 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
index 6c9f17b..ed25fa6 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,7 +319,6 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
-
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
 
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index c22e8a9..59b7df2 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 4ec920e..259bb70 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 141f180..7802ae0 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -768,6 +768,9 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
 	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
 	                          tmp);
+	  else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+	    res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
+	                          tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index d70cdd1..859e346 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -548,10 +548,11 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
 	obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
-
+      struct type *this_ref = TYPE_CODE (obj_type) == TYPE_CODE_REF
+                                ? lookup_lvalue_reference_type (this_type)
+                                : lookup_rvalue_reference_type (this_type);
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
@@ -634,10 +635,11 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
 	obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
-
+      struct type *this_ref = TYPE_CODE (obj_type) == TYPE_CODE_REF 
+                                ? lookup_lvalue_reference_type (this_type)
+                                : lookup_rvalue_reference_type (this_type);
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (7 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:28       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
                       ` (2 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Make gdb DWARF reader understand the DW_AT_rvalue_reference type tag. Handling
of this tag is done in the existing read_tag_reference_type() function, to
which we add a new parameter representing the kind of reference type
(lvalue vs rvalue).

gdb/ChangeLog:

2016-03-03  Artemiy Volkov  <artemiyv@acm.org>

    * dwarf2read.c (process_die, read_type_die_1): Handle the
    DW_AT_rvalue_reference_type DIE.
    (read_tag_reference_type): Add new parameter "refcode".
---
 gdb/dwarf2read.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index cf8ce53..df6491a 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8294,6 +8294,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;
 
@@ -14320,16 +14321,19 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
    the user defined type vector.  */
 
 static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+                          enum type_code refcode)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type, *target_type;
   struct attribute *attr;
 
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
   target_type = die_type (die, cu);
 
   /* The die_type call above may have already set the type for this DIE.  */
@@ -14337,7 +14341,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_lvalue_reference_type (target_type);
+  type = lookup_reference_type (target_type, refcode);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
@@ -19115,7 +19119,10 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
       this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      this_type = read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+      break;
+    case DW_TAG_rvalue_reference_type:
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
       break;
     case DW_TAG_const_type:
       this_type = read_tag_const_type (die, cu);
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (6 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:25       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
                       ` (3 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch fixes demangling of names containing rvalue reference typenames by
handling DEMANGLE_COMPONENT_RVALUE_REFERENCE demangle component.

gdb/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * cp-name-parser.y (ptr_operator): Handle the '&&' token in
    typename.
    * cp-support.c (replace_typedefs): Handle
    DEMANGLE_COMPONENT_RVALUE_REFERENCE.
    * python/py-type.c (typy_lookup_type): Likewise.
---
 gdb/cp-name-parser.y | 4 ++++
 gdb/cp-support.c     | 1 +
 gdb/python/py-type.c | 4 ++++
 3 files changed, 9 insertions(+)

diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index c6a5c34..33fdcea 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -769,6 +769,10 @@ ptr_operator	:	'*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
 			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
 			  $$.last = &d_left ($$.comp); }
+		|	ANDAND
+			{ $$.comp = make_empty (DEMANGLE_COMPONENT_RVALUE_REFERENCE);
+			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+			  $$.last = &d_left ($$.comp); }
 		|	nested_name '*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
 			  $$.comp->u.s_binary.left = $1.comp;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index df127c4..1dde382 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -520,6 +520,7 @@ replace_typedefs (struct demangle_parse_info *info,
 	case DEMANGLE_COMPONENT_RESTRICT_THIS:
 	case DEMANGLE_COMPONENT_POINTER:
 	case DEMANGLE_COMPONENT_REFERENCE:
+	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
 	  replace_typedefs (info, d_left (ret_comp), finder, data);
 	  break;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 6103a2b..4ec920e 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -811,6 +811,7 @@ typy_lookup_type (struct demangle_component *demangled,
 
   if (demangled_type == DEMANGLE_COMPONENT_POINTER
       || demangled_type == DEMANGLE_COMPONENT_REFERENCE
+      || demangled_type == DEMANGLE_COMPONENT_RVALUE_REFERENCE
       || demangled_type == DEMANGLE_COMPONENT_CONST
       || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
     {
@@ -829,6 +830,9 @@ typy_lookup_type (struct demangle_component *demangled,
 	    case DEMANGLE_COMPONENT_REFERENCE:
 	      rtype = lookup_lvalue_reference_type (type);
 	      break;
+	    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+	      rtype = lookup_rvalue_reference_type (type);
+	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
 	      break;
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (9 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:23       ` Keith Seitz
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch implements correct parsing of C++0x rvalue reference typenames.
This is done in full similarity to the handling of regular references by adding
a '&&' token handling in c-exp.y, defining an rvalue reference type piece, and
implementing a follow type derivation in follow_types().

gdb/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * c-exp.y (ptr_operator): Handle the '&&' token in the typename.
    * parse.c (insert_type): Change assert statement.
    (follow_types): Handle rvalue reference types.
    * parser-defs.h (enum type_pieces) <tp_rvalue_reference>: New
    constant.
---
 gdb/c-exp.y       |  6 +++++-
 gdb/parse.c       | 40 ++++++++++++++++++++++------------------
 gdb/parser-defs.h |  1 +
 3 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 9f2a229..f83047b 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -799,7 +799,7 @@ exp	:	SIZEOF '(' type ')'	%prec UNARY
 			       says of sizeof:  "When applied to a reference
 			       or a reference type, the result is the size of
 			       the referenced type."  */
-			  if (TYPE_CODE (type) == TYPE_CODE_REF)
+			  if (TYPE_IS_REFERENCE (type))
 			    type = check_typedef (TYPE_TARGET_TYPE (type));
 			  write_exp_elt_longcst (pstate,
 						 (LONGEST) TYPE_LENGTH (type));
@@ -1140,6 +1140,10 @@ ptr_operator:
 			{ insert_type (tp_reference); }
 	|	'&' ptr_operator
 			{ insert_type (tp_reference); }
+	|       ANDAND
+			{ insert_type (tp_rvalue_reference); }
+	|       ANDAND ptr_operator
+			{ insert_type (tp_rvalue_reference); }
 	;
 
 ptr_operator_ts: ptr_operator
diff --git a/gdb/parse.c b/gdb/parse.c
index 06f7bcd..b67d1f0 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1470,10 +1470,10 @@ insert_into_type_stack (int slot, union type_stack_elt element)
 }
 
 /* Insert a new type, TP, at the bottom of the type stack.  If TP is
-   tp_pointer or tp_reference, it is inserted at the bottom.  If TP is
-   a qualifier, it is inserted at slot 1 (just above a previous
-   tp_pointer) if there is anything on the stack, or simply pushed if
-   the stack is empty.  Other values for TP are invalid.  */
+   tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the
+   bottom.  If TP is a qualifier, it is inserted at slot 1 (just above a
+   previous tp_pointer) if there is anything on the stack, or simply pushed
+   if the stack is empty.  Other values for TP are invalid.  */
 
 void
 insert_type (enum type_pieces tp)
@@ -1481,8 +1481,8 @@ insert_type (enum type_pieces tp)
   union type_stack_elt element;
   int slot;
 
-  gdb_assert (tp == tp_pointer || tp == tp_reference
-	      || tp == tp_const || tp == tp_volatile);
+  gdb_assert (tp == tp_pointer || tp == tp_reference ||
+	      tp == tp_rvalue_reference || tp == tp_const || tp == tp_volatile);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
@@ -1695,18 +1695,22 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_lvalue_reference_type (follow_type);
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+	 follow_type = lookup_lvalue_reference_type (follow_type);
+	 goto process_reference;
+	case tp_rvalue_reference:
+	 follow_type = lookup_rvalue_reference_type (follow_type);
+	process_reference:
+	 if (make_const)
+	   follow_type = make_cv_type (make_const,
+				       TYPE_VOLATILE (follow_type),
+				       follow_type, 0);
+	 if (make_volatile)
+	   follow_type = make_cv_type (TYPE_CONST (follow_type),
+				       make_volatile,
+				       follow_type, 0);
+	 if (make_addr_space)
+	   follow_type = make_type_with_address_space (follow_type,
+						       make_addr_space);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
 	break;
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 1b1d3c3..c474150 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -127,6 +127,7 @@ enum type_pieces
     tp_end = -1, 
     tp_pointer, 
     tp_reference, 
+    tp_rvalue_reference,
     tp_array, 
     tp_function,
     tp_function_with_arguments,
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (5 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:26       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
                       ` (4 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch provides the ability to print out names of rvalue reference types
and values of those types. This is done in full similarity to regular
references, and as with them, we don't print out "const" suffix because all
rvalue references are const.

gdb/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

    * c-typeprint.c (c_print_type, c_type_print_varspec_prefix)
    (c_type_print_modifier, c_type_print_varspec_suffix)
    (c_type_print_base): Support printing rvalue reference types.
    * c-valprint.c (c_val_print, c_value_print): Support printing
    rvalue reference values.
---
 gdb/c-typeprint.c | 10 ++++++----
 gdb/c-valprint.c  |  4 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 6b9e6b3..fbfbac7 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-		  || code == TYPE_CODE_REF)))
+		  || TYPE_IS_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
@@ -341,9 +341,10 @@ c_type_print_varspec_prefix (struct type *type,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
 				   stream, show, 1, 0, flags);
-      fprintf_filtered (stream, "&");
+      fprintf_filtered (stream, TYPE_CODE(type) == TYPE_CODE_REF ? "&" : "&&");
       c_type_print_modifier (type, stream, 1, need_post_space);
       break;
 
@@ -409,8 +410,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
      every reference is `const'.  */
-  if (TYPE_CONST (type)
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CONST (type) && !TYPE_IS_REFERENCE (type))
     {
       if (need_pre_space)
 	fprintf_filtered (stream, " ");
@@ -725,6 +725,7 @@ c_type_print_varspec_suffix (struct type *type,
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
 				   show, 1, 0, flags);
       break;
@@ -892,6 +893,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBERPTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_METHODPTR:
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index a1f5db6..e43783f 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -538,6 +538,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_FLAGS:
     case TYPE_CODE_FUNC:
@@ -583,8 +584,7 @@ c_value_print (struct value *val, struct ui_file *stream,
   val_type = value_type (val);
   type = check_typedef (val_type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_PTR
-      || TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
     {
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway.
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:41       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
                       ` (10 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

In almost all contexts (except for overload resolution rules and expression
semantics), lvalue and rvalue references are equivalent. That means that in all
but these cases we can replace a TYPE_CODE_REF check to a TYPE_IS_REFERENCE
check and, for switch statements, add a case label for a rvalue reference type
next to a case label for an lvalue reference type. This patch does exactly
that.

gdb/ChangeLog:

2016-03-03  Artemiy Volkov  <artemiyv@acm.org>

    * aarch64-tdep.c (aarch64_type_align)
    (aarch64_extract_return_value, aarch64_store_return_value): Change
    lvalue reference type checks to general reference type checks.
    * amd64-tdep.c (amd64_classify): Likewise.
    * amd64-windows-tdep.c (amd64_windows_passed_by_integer_register):
    Likewise.
    * arm-tdep.c (arm_type_align, arm_extract_return_value)
    (arm_store_return_value): Likewise.
    * ax-gdb.c (gen_fetch, gen_cast): Likewise.
    * c-typeprint.c (c_print_type): Likewise.
    * c-varobj.c (adjust_value_for_child_access, c_value_of_variable)
    (cplus_number_of_children, cplus_describe_child): Likewise.
    * compile/compile-c-symbols.c (generate_vla_size): Likewise.
    * completer.c (expression_completer): Likewise.
    * cp-support.c (make_symbol_overload_list_adl_namespace):
    Likewise.
    * darwin-nat-info.c (info_mach_region_command): Likewise.
    * dwarf2loc.c (entry_data_value_coerce_ref)
    (value_of_dwarf_reg_entry): Likewise.
    * eval.c (ptrmath_type_p, evaluate_subexp_standard)
    (evaluate_subexp_for_address, evaluate_subexp_for_sizeof):
    Likewise.
    * findvar.c (extract_typed_address, store_typed_address):
    Likewise.
    * gdbtypes.c (rank_one_type): Likewise.
    * hppa-tdep.c (hppa64_integral_or_pointer_p): Likewise.
    * infcall.c (value_arg_coerce): Likewise.
    * language.c (pointer_type): Likewise.
    * m32c-tdep.c (m32c_reg_arg_type, m32c_m16c_address_to_pointer):
    Likewise.
    * m88k-tdep.c (m88k_integral_or_pointer_p): Likewise.
    * mn10300-tdep.c (mn10300_type_align): Likewise.
    * msp430-tdep.c (msp430_push_dummy_call): Likewise.
    * ppc-sysv-tdep.c (do_ppc_sysv_return_value)
    (ppc64_sysv_abi_push_param, ppc64_sysv_abi_return_value):
    Likewise.
    * printcmd.c (print_formatted, x_command): Likewise.
    * python/py-type.c (typy_get_composite, typy_template_argument):
    Likewise.
    * python/py-value.c (valpy_referenced_value)
    (valpy_get_dynamic_type, value_has_field): Likewise.
    * s390-linux-tdep.c (s390_function_arg_integer): Likewise.
    * sparc-tdep.c (sparc_integral_or_pointer_p): Likewise.
    * sparc64-tdep.c (sparc64_integral_or_pointer_p): Likewise.
    * spu-tdep.c (spu_scalar_value_p): Likewise.
    * symtab.c (lookup_symbol_aux): Likewise.
    * typeprint.c (whatis_exp, print_type_scalar): Likewise.
    * valarith.c (binop_types_user_defined_p, unop_user_defined_p):
    Likewise.
    * valops.c (value_cast_pointers, value_cast)
    (value_reinterpret_cast, value_dynamic_cast, value_addr, typecmp)
    (value_struct_elt, value_struct_elt_bitpos)
    (value_find_oload_method_list, find_overload_match)
    (value_rtti_indirect_type): Likewise.
    * valprint.c (val_print_scalar_type_p, generic_val_print):
    Likewise.
    * value.c (value_actual_type, value_as_address, unpack_long)
    (pack_long, pack_unsigned_long, coerce_ref_if_computed)
    (coerce_ref): Likewise.
    * varobj.c (varobj_get_value_type): Likewise.
---
 gdb/aarch64-tdep.c              |  5 +++--
 gdb/amd64-tdep.c                |  2 +-
 gdb/amd64-windows-tdep.c        |  1 +
 gdb/arm-tdep.c                  |  5 +++--
 gdb/ax-gdb.c                    |  2 ++
 gdb/c-varobj.c                  | 10 +++++-----
 gdb/compile/compile-c-symbols.c |  2 +-
 gdb/completer.c                 |  3 +--
 gdb/cp-support.c                |  2 +-
 gdb/darwin-nat-info.c           |  2 +-
 gdb/dwarf2loc.c                 |  4 ++--
 gdb/eval.c                      | 14 +++++++-------
 gdb/findvar.c                   |  6 ++----
 gdb/gdbtypes.c                  |  5 +++--
 gdb/hppa-tdep.c                 |  1 +
 gdb/infcall.c                   |  3 ++-
 gdb/language.c                  |  3 +--
 gdb/m32c-tdep.c                 |  8 +++-----
 gdb/m88k-tdep.c                 |  1 +
 gdb/mn10300-tdep.c              |  1 +
 gdb/msp430-tdep.c               |  2 +-
 gdb/ppc-sysv-tdep.c             |  7 +++----
 gdb/printcmd.c                  |  2 +-
 gdb/python/py-type.c            |  5 ++---
 gdb/python/py-value.c           |  6 +++---
 gdb/s390-linux-tdep.c           |  2 +-
 gdb/sparc-tdep.c                |  1 +
 gdb/sparc64-tdep.c              |  1 +
 gdb/spu-tdep.c                  |  1 +
 gdb/symtab.c                    |  3 +--
 gdb/typeprint.c                 |  4 ++--
 gdb/valarith.c                  |  6 +++---
 gdb/valops.c                    | 43 ++++++++++++++++++++---------------------
 gdb/valprint.c                  |  5 +++--
 gdb/value.c                     | 12 +++++++-----
 gdb/varobj.c                    |  2 +-
 36 files changed, 94 insertions(+), 88 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 77155ef..b54f14e 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -890,6 +890,7 @@ aarch64_type_align (struct type *t)
     case TYPE_CODE_RANGE:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -1613,7 +1614,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the the type is a plain integer, then the access is
@@ -1754,7 +1755,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index a62efde..4b56202 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -672,7 +672,7 @@ amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_CHAR
-       || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
+       || code == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
       && (len == 1 || len == 2 || len == 4 || len == 8))
     theclass[0] = AMD64_INTEGER;
 
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index e05502e..6ae594d 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -55,6 +55,7 @@ amd64_windows_passed_by_integer_register (struct type *type)
       case TYPE_CODE_CHAR:
       case TYPE_CODE_PTR:
       case TYPE_CODE_REF:
+      case TYPE_CODE_RVALUE_REF:
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
 	return (TYPE_LENGTH (type) == 1
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 2eb7bb1..4afc247 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3236,6 +3236,7 @@ arm_type_align (struct type *t)
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -7792,7 +7793,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the type is a plain integer, then the access is
@@ -7997,7 +7998,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= 4)
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 7c6cb64..7ec01e7 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -491,6 +491,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
@@ -1001,6 +1002,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* It's implementation-defined, and I'll bet this is what GCC
          does.  */
       break;
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 48e16f9..f7bdee0 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -78,7 +78,7 @@ adjust_value_for_child_access (struct value **value,
      to us, is already supposed to be
      reference-stripped.  */
 
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (*type));
 
   /* Pointers to structures are treated just like
      structures when accessing children.  Don't
@@ -489,7 +489,7 @@ c_value_of_variable (const struct varobj *var,
   struct type *type = get_type (var);
 
   /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
@@ -586,7 +586,7 @@ cplus_number_of_children (const struct varobj *var)
       if (opts.objectprint)
         {
           value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+          lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
 				|| TYPE_CODE (var->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -623,7 +623,7 @@ cplus_number_of_children (const struct varobj *var)
 	  const struct varobj *parent = var->parent;
 
 	  value = parent->value;
-	  lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+	  lookup_actual_type = (TYPE_IS_REFERENCE (parent->type)
 				|| TYPE_CODE (parent->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -728,7 +728,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
   var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
   if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+    lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
 			  || TYPE_CODE (var->type) == TYPE_CODE_PTR);
   value = var->value;
   type = varobj_get_value_type (var);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index dcd530d..c06687f 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -593,7 +593,7 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
diff --git a/gdb/completer.c b/gdb/completer.c
index 5c3b3fc..ec0f65d 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -610,8 +610,7 @@ expression_completer (struct cmd_list_element *ignore,
       for (;;)
 	{
 	  type = check_typedef (type);
-	  if (TYPE_CODE (type) != TYPE_CODE_PTR
-	      && TYPE_CODE (type) != TYPE_CODE_REF)
+	  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
 	    break;
 	  type = TYPE_TARGET_TYPE (type);
 	}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 1dde382..b008ecf 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1279,7 +1279,7 @@ make_symbol_overload_list_adl_namespace (struct type *type,
   int i, prefix_len;
 
   while (TYPE_CODE (type) == TYPE_CODE_PTR
-	 || TYPE_CODE (type) == TYPE_CODE_REF
+	 || TYPE_IS_REFERENCE (type)
          || TYPE_CODE (type) == TYPE_CODE_ARRAY
          || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
     {
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 314d265..4b4059a 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -732,7 +732,7 @@ info_mach_region_command (char *exp, int from_tty)
 
   expr = parse_expression (exp);
   val = evaluate_expression (expr);
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (value_type (val)))
     {
       val = value_ind (val);
     }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index ba6ed42..202a8c8 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1337,7 +1337,7 @@ entry_data_value_coerce_ref (const struct value *value)
   struct type *checked_type = check_typedef (value_type (value));
   struct value *target_val;
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (checked_type))
     return NULL;
 
   target_val = (struct value *) value_computed_closure (value);
@@ -1412,7 +1412,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      TYPE_CODE_REF with non-entry data value would give current value - not the
      entry value.  */
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+  if (!TYPE_IS_REFERENCE (checked_type)
       || TYPE_TARGET_TYPE (checked_type) == NULL)
     return outer_val;
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 8969f49..a69c69c 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -640,7 +640,7 @@ static int
 ptrmath_type_p (const struct language_defn *lang, struct type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = TYPE_TARGET_TYPE (type);
 
   switch (TYPE_CODE (type))
@@ -2509,7 +2509,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	{
 	  type = check_typedef (value_type (arg1));
 	  if (TYPE_CODE (type) == TYPE_CODE_PTR
-	      || TYPE_CODE (type) == TYPE_CODE_REF
+	      || TYPE_IS_REFERENCE (type)
 	  /* In C you can dereference an array to get the 1st elt.  */
 	      || TYPE_CODE (type) == TYPE_CODE_ARRAY
 	    )
@@ -2787,7 +2787,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	    {
 	      struct type *type = value_type (result);
 
-	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+	      if (!TYPE_IS_REFERENCE (type))
 		{
 		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
@@ -2890,7 +2890,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var)))
 	goto default_case;
 
       (*pos) += 4;
@@ -2929,7 +2929,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 	{
 	  struct type *type = check_typedef (value_type (x));
 
-	  if (TYPE_CODE (type) == TYPE_CODE_REF)
+	  if (TYPE_IS_REFERENCE (type))
 	    return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			       not_lval);
 	  else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
@@ -3019,7 +3019,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = check_typedef (value_type (val));
       if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF
+	  && !TYPE_IS_REFERENCE (type)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
@@ -3091,7 +3091,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
      the size of the referenced type."  */
   type = check_typedef (type);
   if (exp->language_defn->la_language == language_cplus
-      && TYPE_CODE (type) == TYPE_CODE_REF)
+      && (TYPE_IS_REFERENCE (type)))
     type = check_typedef (TYPE_TARGET_TYPE (type));
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a39d897..b9b8d05 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -169,8 +169,7 @@ extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
 CORE_ADDR
 extract_typed_address (const gdb_byte *buf, struct type *type)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("extract_typed_address: "
 		    "type is not a pointer or reference"));
@@ -242,8 +241,7 @@ store_unsigned_integer (gdb_byte *addr, int len,
 void
 store_typed_address (gdb_byte *buf, struct type *type, CORE_ADDR addr)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("store_typed_address: "
 		    "type is not a pointer or reference"));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index a99e878..ce4b9be 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3477,10 +3477,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   /* See through references, since we can almost make non-references
      references.  */
-  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+  if (TYPE_IS_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                        REFERENCE_CONVERSION_BADNESS));
-  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                        REFERENCE_CONVERSION_BADNESS));
   if (overload_debug)
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index ac507e7..afb3b5e 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -902,6 +902,7 @@ hppa64_integral_or_pointer_p (const struct type *type)
       }
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return (TYPE_LENGTH (type) == 8);
     default:
       break;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index ad2512a..5a2a4a7 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -158,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	struct value *new_value;
 
-	if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+	if (TYPE_IS_REFERENCE (arg_type))
 	  return value_cast_pointers (type, arg, 0);
 
 	/* Cast the value to the reference's target type, and then
diff --git a/gdb/language.c b/gdb/language.c
index 78ec422..c1b0526 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -410,8 +410,7 @@ language_info (int quietly)
 int
 pointer_type (struct type *type)
 {
-  return TYPE_CODE (type) == TYPE_CODE_PTR ||
-    TYPE_CODE (type) == TYPE_CODE_REF;
+  return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type);
 }
 
 \f
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 90bd732..49aa3f5 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2031,7 +2031,7 @@ m32c_reg_arg_type (struct type *type)
   return (code == TYPE_CODE_INT
 	  || code == TYPE_CODE_ENUM
 	  || code == TYPE_CODE_PTR
-	  || code == TYPE_CODE_REF
+	  || TYPE_IS_REFERENCE (type)
 	  || code == TYPE_CODE_BOOL
 	  || code == TYPE_CODE_CHAR);
 }
@@ -2453,8 +2453,7 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   enum type_code target_code;
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   target_code = TYPE_CODE (TYPE_TARGET_TYPE (type));
 
@@ -2533,8 +2532,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR ptr;
   enum type_code target_code;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index 1a3c2cd..2a90a3a 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -165,6 +165,7 @@ m88k_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	/* Allow only 32-bit pointers.  */
 	return (TYPE_LENGTH (type) == 4);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 62d4ca1..79f5c85 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -96,6 +96,7 @@ mn10300_type_align (struct type *type)
     case TYPE_CODE_FLT:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type);
 
     case TYPE_CODE_COMPLEX:
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 4042ec3..1b25339 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -769,7 +769,7 @@ msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 		  if (code_model == MSP_LARGE_CODE_MODEL
 		      && (TYPE_CODE (arg_type) == TYPE_CODE_PTR
-		          || TYPE_CODE (arg_type) == TYPE_CODE_REF
+		          || TYPE_IS_REFERENCE (arg_type)
 			  || TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
 			  || TYPE_CODE (arg_type) == TYPE_CODE_UNION))
 		    {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 140d993..20e2a40 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -805,7 +805,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF
+	    || TYPE_IS_REFERENCE (type)
 	    || TYPE_CODE (type) == TYPE_CODE_ENUM)
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -1493,7 +1493,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF)
+	    || TYPE_IS_REFERENCE (type))
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1999,8 +1999,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index f5c4211..8e6a1d8 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1449,7 +1449,7 @@ x_command (char *exp, int from_tty)
 	*exp = 0;
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
-      if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 259bb70..835f1e4 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -486,8 +486,7 @@ typy_get_composite (struct type *type)
 	}
       END_CATCH
 
-      if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF)
+      if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
 	break;
       type = TYPE_TARGET_TYPE (type);
     }
@@ -967,7 +966,7 @@ typy_template_argument (PyObject *self, PyObject *args)
   TRY
     {
       type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type))
 	type = check_typedef (TYPE_TARGET_TYPE (type));
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7802ae0..7a25984 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -217,6 +217,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -358,8 +359,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
 	  struct value *target;
@@ -1020,7 +1020,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 7f860b6..3877bf6 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3040,7 +3040,7 @@ s390_function_arg_integer (struct type *type)
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_BOOL
       || code == TYPE_CODE_PTR
-      || code == TYPE_CODE_REF)
+      || TYPE_IS_REFERENCE (type))
     return 1;
 
   return ((code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index b85b15f..590b091 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -225,6 +225,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 5e8f17d..382fbc5 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -67,6 +67,7 @@ sparc64_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	int len = TYPE_LENGTH (type);
 	gdb_assert (len == 8);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index bf3b289..5ca6fa1 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1338,6 +1338,7 @@ spu_scalar_value_p (struct type *type)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type) <= 16;
 
     default:
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e06104b..7da136e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2179,8 +2179,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
 	  /* I'm not really sure that type of this can ever
 	     be typedefed; just be safe.  */
 	  t = check_typedef (t);
-	  if (TYPE_CODE (t) == TYPE_CODE_PTR
-	      || TYPE_CODE (t) == TYPE_CODE_REF)
+	  if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
 	    t = TYPE_TARGET_TYPE (t);
 
 	  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 48a809b..366654e 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -463,8 +463,7 @@ whatis_exp (char *exp, int show)
   get_user_print_options (&opts);
   if (opts.objectprint)
     {
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
         real_type = value_rtti_indirect_type (val, &full, &top, &using_enc);
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -581,6 +580,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_NAMESPACE:
       error (_("internal error: unhandled type in print_type_scalar"));
       break;
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 7959f3b..5ffa659 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -239,11 +239,11 @@ binop_types_user_defined_p (enum exp_opcode op,
     return 0;
 
   type1 = check_typedef (type1);
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
   type2 = check_typedef (type2);
-  if (TYPE_CODE (type2) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
   return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
@@ -277,7 +277,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   if (op == UNOP_ADDR)
     return 0;
   type1 = check_typedef (value_type (arg1));
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
   return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
 }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1f423a0..30e1c59 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
     {
       struct value *v2;
 
-      if (TYPE_CODE (type2) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type2))
 	v2 = coerce_ref (arg2);
       else
 	v2 = value_ind (arg2);
@@ -363,21 +363,21 @@ value_cast (struct type *type, struct value *arg2)
   code1 = TYPE_CODE (check_typedef (type));
 
   /* Check if we are casting struct reference to struct reference.  */
-  if (code1 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (type)))
     {
       /* We dereference type; then we recurse and finally
          we generate value of the given reference.  Nothing wrong with 
 	 that.  */
       struct type *t1 = check_typedef (type);
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
-      struct value *val =  value_cast (dereftype, arg2);
+      struct value *val = value_cast (dereftype, arg2);
 
       return value_ref (val, TYPE_CODE (t1));
     }
 
   code2 = TYPE_CODE (check_typedef (value_type (arg2)));
 
-  if (code2 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (value_type (arg2))))
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
@@ -388,7 +388,7 @@ value_cast (struct type *type, struct value *arg2)
 
   /* You can't cast to a reference type.  See value_cast_pointers
      instead.  */
-  gdb_assert (code1 != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (type));
 
   /* A cast to an undetermined-length array_type, such as 
      (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
@@ -591,8 +591,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
   dest_type = type;
 
   /* If we are casting to a reference type, transform
-     reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V).  */
-  if (TYPE_CODE (real_type) == TYPE_CODE_REF)
+     reinterpret_cast<T&[&]>(V) to *reinterpret_cast<T*>(&V).  */
+  if (TYPE_IS_REFERENCE (real_type))
     {
       is_ref = 1;
       arg = value_addr (arg);
@@ -730,10 +730,10 @@ value_dynamic_cast (struct type *type, struct value *arg)
   struct type *class_type, *rtti_type;
   struct value *result, *tem, *original_arg = arg;
   CORE_ADDR addr;
-  int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
+  int is_ref = TYPE_IS_REFERENCE (resolved_type);
 
   if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
-      && TYPE_CODE (resolved_type) != TYPE_CODE_REF)
+      && !TYPE_IS_REFERENCE (resolved_type))
     error (_("Argument to dynamic_cast must be a pointer or reference type"));
   if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
       && TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
@@ -1465,9 +1465,9 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     {
-      /* Copy the value, but change the type from (T&) to (T*).  We
+      /* Copy the value, but change the type from (T&[&]) to (T*).  We
          keep the same location information, which is efficient, and
          allows &(&X) to get the location containing the reference.  */
       arg2 = value_copy (arg1);
@@ -1716,7 +1716,7 @@ typecmp (int staticp, int varargs, int nargs,
       tt1 = check_typedef (t1[i].type);
       tt2 = check_typedef (value_type (t2[i]));
 
-      if (TYPE_CODE (tt1) == TYPE_CODE_REF
+      if ((TYPE_IS_REFERENCE (tt1))
 	  /* We should be doing hairy argument matching, as below.  */
 	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
 	      == TYPE_CODE (tt2)))
@@ -1734,14 +1734,13 @@ typecmp (int staticp, int varargs, int nargs,
 	 char *>, and properly access map["hello"], because the
 	 argument to [] will be a reference to a pointer to a char,
 	 and the argument will be a pointer to a char.  */
-      while (TYPE_CODE(tt1) == TYPE_CODE_REF
-	     || TYPE_CODE (tt1) == TYPE_CODE_PTR)
+      while (TYPE_IS_REFERENCE (tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR)
 	{
 	  tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
 	}
       while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
 	     || TYPE_CODE(tt2) == TYPE_CODE_PTR
-	     || TYPE_CODE(tt2) == TYPE_CODE_REF)
+	     || TYPE_IS_REFERENCE (tt2))
 	{
 	  tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
 	}
@@ -2133,7 +2132,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
   /* Follow pointers until we get to a non-pointer.  */
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2222,7 +2221,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
 
   t = check_typedef (value_type (*argp));
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
@@ -2383,7 +2382,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
   t = check_typedef (value_type (*argp));
 
   /* Code snarfed from value_struct_elt.  */
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2794,7 +2793,7 @@ find_overload_match (struct value **args, int nargs,
 
       if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
 	  && (TYPE_CODE (objtype) == TYPE_CODE_PTR
-	      || TYPE_CODE (objtype) == TYPE_CODE_REF))
+	      || TYPE_IS_REFERENCE (objtype)))
 	{
 	  temp = value_addr (temp);
 	}
@@ -3591,7 +3590,7 @@ value_rtti_indirect_type (struct value *v, int *full,
 
   type = value_type (v);
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     target = coerce_ref (v);
   else if (TYPE_CODE (type) == TYPE_CODE_PTR)
     {
@@ -3624,8 +3623,8 @@ value_rtti_indirect_type (struct value *v, int *full,
       target_type = value_type (target);
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_lvalue_reference_type (real_type);
+      if (TYPE_IS_REFERENCE (type))
+        real_type = lookup_reference_type (real_type, TYPE_CODE (type));
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
diff --git a/gdb/valprint.c b/gdb/valprint.c
index a9b03ec..2e18514 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -276,7 +276,7 @@ int
 val_print_scalar_type_p (struct type *type)
 {
   type = check_typedef (type);
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     {
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
@@ -478,7 +478,7 @@ generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
 			      original_value, options, 0, stream);
 }
 
-/* generic_val_print helper for TYPE_CODE_REF.  */
+/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */
 
 static void
 generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
@@ -849,6 +849,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
 			     original_value, options);
       break;
diff --git a/gdb/value.c b/gdb/value.c
index 738b2b2..1307a37 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1202,8 +1202,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
     {
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
 	 fetch its rtti type.  */
-      if ((TYPE_CODE (result) == TYPE_CODE_PTR
-	  || TYPE_CODE (result) == TYPE_CODE_REF)
+      if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result))
 	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
 	     == TYPE_CODE_STRUCT)
         {
@@ -2855,7 +2854,7 @@ value_as_address (struct value *val)
      ABI-specific code is a more reasonable place to handle it.  */
 
   if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && !TYPE_IS_REFERENCE (value_type (val))
       && gdbarch_integer_to_address_p (gdbarch))
     return gdbarch_integer_to_address (gdbarch, value_type (val),
 				       value_contents (val));
@@ -2912,6 +2911,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
          whether we want this to be true eventually.  */
       return extract_typed_address (valaddr, type);
@@ -3501,6 +3501,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3537,6 +3538,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3744,7 +3746,7 @@ coerce_ref_if_computed (const struct value *arg)
 {
   const struct lval_funcs *funcs;
 
-  if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (check_typedef (value_type (arg))))
     return NULL;
 
   if (value_lval_const (arg) != lval_computed)
@@ -3786,7 +3788,7 @@ coerce_ref (struct value *arg)
   if (retval)
     return retval;
 
-  if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (value_type_arg_tmp))
     return arg;
 
   enc_type = check_typedef (value_enclosing_type (arg));
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 6f56cba..2917432 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2176,7 +2176,7 @@ varobj_get_value_type (const struct varobj *var)
 
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = get_target_type (type);
 
   type = check_typedef (type);
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v3 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
  2016-03-05  3:20     ` [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-03-05  3:20     ` Artemiy Volkov
  2016-03-16 22:48       ` Keith Seitz
  2016-03-05  3:20     ` [PATCH v3 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
                       ` (9 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-05  3:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch adds tests for the initial rvalue reference support patchset.
Files to change were selected among the most important files which test
regular C++ references and the added tests are practically mirrored regular
references tests. Tested are printing of rvalue reference types and values,
rvalue reference parameters in function overloading, demangling of function
names containing rvalue reference parameters, casts to rvalue reference types,
and application of the sizeof operator to rvalue reference types and values,
support for rvalue references within the gdb python module.

All the changed files have been obviously set to compile with -std=c++11,
and in some cases this required altering function names which coincided
with keywords introduced in the new standard.

gdb/testsuite/ChangeLog:

2016-03-04  Artemiy Volkov  <artemiyv@acm.org>

        * gdb.cp/casts.cc (main): Add rvalue reference type variables.
        Include the stdlib header "utility".
        (decltype) Rename C++11 reserved keyword ...
        (decl_type) ... to this. All callers updated.
        * gdb.cp/casts.exp: Compile with -std=c++11. Add rvalue reference
        cast tests.
        * gdb.cp/cpsizeof.cc: Add rvalue reference type variables.
        Include the stdlib header "utility".
        * gdb.cp/cpsizeof.exp: Compile with -std=c++11. Add rvalue
        reference sizeof tests.
        * gdb.cp/demangle.exp (test_gnu_style_demangling): Add rvalue
        reference demangle tests.
        * gdb.cp/overload.cc (main): Add a ctor and some methods
        with rvalue reference parameters.
        * gdb.cp/overload.exp: Compile with -std=c++11. Add rvalue
        reference overloading tests.
        * gdb.cp/ref-params.cc (f1, f2, mf1, mf2): New function taking
        rvalue reference parameter.
        * gdb.cp/ref-params.exp: Compile with -std=c++11. Add rvalue
        reference parameter printing tests.
        * gdb.cp/ref-types.cc (main2): Add rvalue reference type
        tests. Include the stdlib header "utility".
        * gdb.cp/ref-types.exp: Compile with -std=c++11. Add rvalue
        reference type printing tests.
        * gdb.python/py-value.cc: (func) Add rvalue reference variables.
        Include the stdlib header "utility".
        * gdb.python/py-value.exp: Compile with -std=c++11. Add rvalue
        reference tests.
---
 gdb/testsuite/gdb.cp/casts.cc            |  8 ++-
 gdb/testsuite/gdb.cp/casts.exp           | 35 ++++++++++--
 gdb/testsuite/gdb.cp/cpsizeof.cc         |  4 ++
 gdb/testsuite/gdb.cp/cpsizeof.exp        |  3 +-
 gdb/testsuite/gdb.cp/demangle.exp        | 36 +++++++++++++
 gdb/testsuite/gdb.cp/overload.cc         | 14 +++++
 gdb/testsuite/gdb.cp/overload.exp        | 16 +++++-
 gdb/testsuite/gdb.cp/ref-params.cc       | 27 ++++++++++
 gdb/testsuite/gdb.cp/ref-params.exp      | 21 +++++++-
 gdb/testsuite/gdb.cp/ref-types.cc        | 24 +++++++++
 gdb/testsuite/gdb.cp/ref-types.exp       | 92 +++++++++++++++++++++++++++++++-
 gdb/testsuite/gdb.python/py-value-cc.cc  |  4 ++
 gdb/testsuite/gdb.python/py-value-cc.exp | 10 +++-
 13 files changed, 282 insertions(+), 12 deletions(-)

diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc
index 43f112f..d15fed1 100644
--- a/gdb/testsuite/gdb.cp/casts.cc
+++ b/gdb/testsuite/gdb.cp/casts.cc
@@ -1,3 +1,5 @@
+#include <utility>
+
 struct A
 {
   int a;
@@ -37,7 +39,7 @@ struct DoublyDerived : public VirtuallyDerived,
 // Confuse a simpler approach.
 
 double
-decltype(int x)
+decl_type(int x)
 {
   return x + 2.0;
 }
@@ -49,6 +51,8 @@ main (int argc, char **argv)
   B *b = (B *) a;
   A &ar = *b;
   B &br = (B&)ar;
+  A &&arr = std::move(A(42));
+  B &&brr = std::move(B(42, 1729));
 
   Derived derived;
   DoublyDerived doublyderived;
@@ -56,7 +60,7 @@ main (int argc, char **argv)
   Alpha *ad = &derived;
   Alpha *add = &doublyderived;
 
-  double y = decltype(2);
+  double y = decl_type(2);
 
   return 0;  /* breakpoint spot: casts.exp: 1 */
 }
diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp
index 34a2492..2000b77 100644
--- a/gdb/testsuite/gdb.cp/casts.exp
+++ b/gdb/testsuite/gdb.cp/casts.exp
@@ -33,7 +33,8 @@ if [get_compiler_info "c++"] {
     return -1
 }
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -86,6 +87,18 @@ gdb_test "print (B &) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
 gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
     "let compiler cast base class reference to derived class reference"
 
+# Casting Rvalue References.
+# Check upcasting.
+gdb_test "print (A &&) br" ".* = .A &&.* {a = 42}" \
+    "cast derived class rvalue reference to base class rvalue reference"
+
+# Check downcasting.
+gdb_test "print (B &&) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "cast base class rvalue reference to derived class rvalue reference"
+
+# Check compiler casting
+gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "let compiler cast base class rvalue reference to derived class rvalue reference"
 
 # A few basic tests of "new" casts.
 
@@ -101,6 +114,9 @@ gdb_test "print static_cast<A *> (b)" " = \\(A \\*\\) $hex" \
 gdb_test "print static_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "static_cast to reference type"
 
+gdb_test "print static_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "static_cast to rvalue reference type"
+
 gdb_test "print reinterpret_cast<A *> (b)" " = \\(A \\*\\) $hex" \
     "basic test of reinterpret_cast"
 
@@ -110,13 +126,16 @@ gdb_test "print reinterpret_cast<void> (b)" "Invalid reinterpret_cast" \
 gdb_test "print reinterpret_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "reinterpret_cast to reference type"
 
+gdb_test "print reinterpret_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "reinterpret_cast to rvalue reference type"
+
 # Test that keyword shadowing works.
 
-gdb_test "whatis decltype(5)" " = double"
+gdb_test "whatis decl_type(5)" " = double"
 
 # Basic tests using typeof.
 
-foreach opname {__typeof__ __typeof __decltype} {
+foreach opname {__typeof__ __typeof decltype} {
     gdb_test "print (${opname}(a)) (b)" " = \\(A \\*\\) $hex" \
 	"old-style cast using $opname"
 
@@ -127,7 +146,7 @@ foreach opname {__typeof__ __typeof __decltype} {
 	"reinterpret_cast using $opname"
 }
 
-gdb_test "whatis __decltype(*a)" "type = A \\&"
+gdb_test "whatis decltype(*a)" "type = A \\&"
 
 # Tests of dynamic_cast.
 
@@ -153,6 +172,10 @@ gdb_test "print dynamic_cast<Alpha &> (derived)" \
     " = \\(Alpha \\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
     "dynamic_cast simple upcast to reference"
 
+gdb_test "print dynamic_cast<Alpha &&> (derived)" \
+    " = \\(Alpha \\&\\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
+    "dynamic_cast simple upcast to rvalue reference"
+
 gdb_test "print dynamic_cast<Derived *> (ad)" \
     " = \\(Derived \\*\\) ${nonzero_hex}( <vtable for Derived.*>)?" \
     "dynamic_cast simple downcast"
@@ -169,6 +192,10 @@ gdb_test "print dynamic_cast<VirtuallyDerived &> (*ad)" \
     "dynamic_cast failed" \
     "dynamic_cast to reference to non-existing base"
 
+gdb_test "print dynamic_cast<VirtuallyDerived &&> (*ad)" \
+    "dynamic_cast failed" \
+    "dynamic_cast to rvalue reference to non-existing base"
+
 gdb_test "print dynamic_cast<DoublyDerived *> (add)" \
     " = \\(DoublyDerived \\*\\) ${nonzero_hex}( <vtable for DoublyDerived.*>)?" \
     "dynamic_cast unique downcast"
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.cc b/gdb/testsuite/gdb.cp/cpsizeof.cc
index 2dcaea1..6a8de4a 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.cc
+++ b/gdb/testsuite/gdb.cp/cpsizeof.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 struct Class
 {
   int a;
@@ -44,8 +46,10 @@ typedef Enum e12[12];
 #define T(N)					\
   N N ## obj;					\
   N& N ## _ref = N ## obj;			\
+  N&& N ## _rref = std::move(N ## obj);         \
   N* N ## p = &(N ## obj);			\
   N*& N ## p_ref = N ## p;			\
+  N*&& N ## p_rref = std::move(N ## p);         \
   int size_ ## N = sizeof (N ## _ref);		\
   int size_ ## N ## p = sizeof (N ## p_ref);	\
 
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.exp b/gdb/testsuite/gdb.cp/cpsizeof.exp
index de95c49..47c841e 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.exp
+++ b/gdb/testsuite/gdb.cp/cpsizeof.exp
@@ -18,7 +18,8 @@ standard_testfile .cc
 
 if {[skip_cplus_tests]} { continue }
 
-if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++}] } {
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}] } {
      return -1
 }
 
diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
index 96c90db..c007097 100644
--- a/gdb/testsuite/gdb.cp/demangle.exp
+++ b/gdb/testsuite/gdb.cp/demangle.exp
@@ -123,20 +123,27 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: Append__15NameChooserViewPCc" \
 	"NameChooserView::Append\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadR6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)"
+    test_demangling_exact "gnu-v3: _ZN9ArrowLine19ArrowheadIntersectsEP9ArrowheadO6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead*, BoxObj&&, Graphic*)"
     test_demangling_exact "gnu: AtEnd__13ivRubberGroup" "ivRubberGroup::AtEnd(void)"
     test_demangling_exact "gnu: BgFilter__9ivTSolverP12ivInteractor" "ivTSolver::BgFilter(ivInteractor *)"
     test_demangling "gnu: BitPatterntoa__FRC10BitPatternccc" \
 	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &, char, char, char\[)\]+"
+    test_demangling "gnu-v3: _Z13BitPatterntoaOK10BitPatternccc" \
+	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const)&&, char, char, char\[)\]+"
     test_demangling_exact "gnu: Check__6UArrayi" "UArray::Check(int)"
     test_demangling_exact "gnu: CoreConstDecls__8TextCodeR7ostream" "TextCode::CoreConstDecls(ostream &)"
+    test_demangling_exact "gnu-v3: _ZN8TextCode14CoreConstDeclsEO7ostream" "TextCode::CoreConstDecls(ostream&&)"
     test_demangling_exact "gnu: Detach__8StateVarP12StateVarView" "StateVar::Detach(StateVarView *)"
     test_demangling_exact "gnu: Done__9ComponentG8Iterator" "Component::Done(Iterator)"
     test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCRC13ivTransformeriiii" \
 	"DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &, int, int, int, int\[)\]+"
+    test_demangling "gnu-v3: _Z31DrawDestinationTransformedImageP7_XImageiiS0_iimjiijmmP4_XGCOK13ivTransformeriiii" \
+	"DrawDestinationTransformedImage\[(\]+_XImage\[*\]+, int, int, _XImage\[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC\[*\]+, (const ivTransformer|ivTransformer const)&&, int, int, int, int\[)\]+"
 
     test_demangling "gnu: Edit__12StringEditorPCcii" \
 	"StringEditor::Edit\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
     test_demangling_exact "gnu: Effect__11RelateManipR7ivEvent" "RelateManip::Effect(ivEvent &)"
+    test_demangling_exact "gnu-v3: _ZN11RelateManip6EffectEO7ivEvent" "RelateManip::Effect(ivEvent&&)"
     test_demangling "gnu: FilterName__FPCc" \
 	"FilterName\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling "gnu: Filter__6PSTextPCci" \
@@ -206,16 +213,21 @@ proc test_gnu_style_demangling {} {
 	"iv2_6_MenuItem::iv2_6_MenuItem\[(\]+int, (const char|char const) \[*\]+, ivInteractor \[*\]+\[)\]+"
 
     test_demangling_exact "gnu: __20DisplayList_IteratorR11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &)"
+    test_demangling_exact "gnu-v3: _ZN20DisplayList_IteratorC4EO11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList&&)"
     test_demangling_exact "gnu: __3fooRT0" "foo::foo(foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EOS_" "foo::foo(foo&&)"
     test_demangling_exact "gnu: __3fooiN31" "foo::foo(int, int, int, int)"
     test_demangling "gnu: __3fooiPCc" \
 	"foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __3fooiRT0iT2iT2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EiOS_iS0_iS0_" "foo::foo(int, foo&&, int, foo&&, int, foo&&)"
     test_demangling "gnu: __6GetOptiPPcPCc" \
 	"GetOpt::GetOpt\[(\]+int, char \[*\]+\[*\]+, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __6KeyMapPT0" "KeyMap::KeyMap(KeyMap *)"
     test_demangling "gnu: __7ivWorldPCcRiPPcPC12ivOptionDescPC14ivPropertyData" \
 	"ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
+    test_demangling "gnu-v3: _ZN7ivWorldC2EPKcOiPPcPK12ivOptionDescPK14ivPropertyData" \
+	"ivWorld::ivWorld\[(\]+(const char|char const)\[*\]+, int&&, char\[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const)\[*\]+, (const ivPropertyData|ivPropertyData const)\[*\]+\[)\]+"
     test_demangling "gnu: __7procbufPCci" \
 	"procbuf::procbuf\[(\]+(const char|char const) \[*\]+, int\[)\]+"
     test_demangling_exact "gnu: __8ArrowCmdP6EditorUiUi" "ArrowCmd::ArrowCmd(Editor *, unsigned int, unsigned int)"
@@ -295,6 +307,8 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: append__7ivGlyphPT0" "ivGlyph::append(ivGlyph *)"
     test_demangling "gnu: arg__FRC7Complex" \
 	"arg\[(\]+(const Complex|Complex const) &\[)\]+"
+    test_demangling "gnu-v3: _Z3argOK7Complex" \
+	"arg\[(\]+(const Complex|Complex const)&&\[)\]+"
     test_demangling_exact "gnu: clearok__FP7_win_sti" "clearok(_win_st *, int)"
 
     test_demangling_exact "gnu: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
@@ -305,10 +319,16 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
     test_demangling "gnu: contains__C9BitStringRC10BitPattern" \
 	"BitString::contains\[(\]+(const BitPattern|BitPattern const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK10BitPattern" \
+	"BitString::contains\[(\]+(const BitPattern|BitPattern const)&&\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRC12BitSubStringi" \
 	"BitString::contains\[(\]+(const BitSubString|BitSubString const) &, int\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK12BitSubStringi" \
+	"BitString::contains\[(\]+(const BitSubString|BitSubString const)&&, int\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRT0" \
 	"BitString::contains\[(\]+(const BitString|BitString const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOKS_" \
+	"BitString::contains\[(\]+(const BitString|BitString const)&&\[)\]+ const"
     test_demangling "gnu: div__FPC6IntRepT0P6IntRep" \
 	"div\[(\]+(const IntRep|IntRep const) \[*\]+, (const IntRep|IntRep const) \[*\]+, IntRep \[*\]+\[)\]+"
     test_demangling "gnu: div__FPC6IntReplP6IntRep" \
@@ -436,18 +456,26 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE3PixC4EOKS2_" \
+	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const&&)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0" \
 	"List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC2EOKS0_PS2_" \
+	"List<VHDLEntity>::element::element(VHDLEntity const&&, List<VHDLEntity>::element*)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element" \
 	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC4EOKS2_" \
+	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const&&)"
 
     test_demangling_exact "gnu: __cl__C11VHDLLibraryGt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::operator()(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >) const"
 
     test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityEclEOKNS1_3PixE" \
+	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const&&) const"
 
     test_demangling_exact "gnu: __ne__FPvRCQ2t4List1Z10VHDLEntity3Pix" \
 	"operator!=(void *, List<VHDLEntity>::Pix const &)"
@@ -457,6 +485,8 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4List1Z10VHDLEntityRCt4List1Z10VHDLEntity" \
 	"List<VHDLEntity>::List(List<VHDLEntity> const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityEC4EOKS1_" \
+	"List<VHDLEntity>::List(List<VHDLEntity> const&&)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(void)"
@@ -466,12 +496,18 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+    test_demangling_exact "gnu-v3: _ZN4PixXI11VHDLLibrary14VHDLLibraryRep4ListI10VHDLEntityEEC2EOKS5_" \
+	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const&&)"
 
     test_demangling_exact "gnu: nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const"
+    test_demangling_exact "gnu-v3: _ZNK11VHDLLibrary5nextEEO4PixXIS_14VHDLLibraryRep4ListI10VHDLEntityEE" \
+	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >&&) const"
 
     test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityRQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::next(List<VHDLEntity>::Pix &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityE4nextEONS1_3PixE" \
+	"List<VHDLEntity>::next(List<VHDLEntity>::Pix&&) const"
 
     test_demangling_exact "gnu: _GLOBAL_\$D\$set" "global destructors keyed to set"
 
diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
index 5c782a4..05cbded 100644
--- a/gdb/testsuite/gdb.cp/overload.cc
+++ b/gdb/testsuite/gdb.cp/overload.cc
@@ -1,10 +1,12 @@
 #include <stddef.h>
+#include <utility>
 
 class foo {
 public:
   foo  (int);
   foo  (int, const char *);
   foo  (foo&);
+  foo  (foo&&);
   ~foo ();
   void foofunc (int);
   void foofunc (int, signed char *);
@@ -27,6 +29,14 @@ int overload1arg (double);
 int overload1arg (int*);
 int overload1arg (void*);
 
+typedef foo &foo_lval_ref;
+typedef foo &&foo_rval_ref;
+
+int overload1arg (foo &);
+int overload1arg (foo &&);
+int overload1arg (foo_lval_ref);
+int overload1arg (foo_rval_ref);
+
 int overloadfnarg (void);
 int overloadfnarg (int);
 int overloadfnarg (int, int (*) (int));
@@ -114,6 +124,7 @@ int main ()
     double arg12 = 200.0;
     int arg13 = 200;
     char arg14 = 'a';
+    foo arg15(5);
 
     A a;
     B b;
@@ -153,6 +164,7 @@ int main ()
 foo::foo  (int i)                  { ifoo = i; ccpfoo = NULL; }
 foo::foo  (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
 foo::foo  (foo& afoo)              { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::foo  (foo&& afoo)             { ifoo = std::move(afoo.ifoo); ccpfoo = std::move (afoo.ccpfoo); }
 foo::~foo ()                       {}
 
 
@@ -172,6 +184,8 @@ int foo::overload1arg (float arg)           { arg = 0; return 11;}
 int foo::overload1arg (double arg)          { arg = 0; return 12;}
 int foo::overload1arg (int* arg)            { arg = 0; return 13;}
 int foo::overload1arg (void* arg)           { arg = 0; return 14;}
+int foo::overload1arg (foo &arg)            { return 15; }
+int foo::overload1arg (foo &&arg)           { return 16; }
 
 /* Test to see that we can explicitly request overloaded functions
    with function pointers in the prototype. */
diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
index 0cfa638..a1fa4ef 100644
--- a/gdb/testsuite/gdb.cp/overload.exp
+++ b/gdb/testsuite/gdb.cp/overload.exp
@@ -28,7 +28,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -53,7 +54,8 @@ gdb_test "up" ".*main.*" "up from marker1"
 set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
 set re_fields	"int ifoo;${ws}const char ?\\* ?ccpfoo;"
 set XX_fields  	"int ifoo;${ws}char ?\\* ?ccpfoo;"
-set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);"
+set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);\
+                 ${ws}foo\\(foo ?&\\);${ws}foo\\(foo ?&?&\\);"
 set re_dtor	"~foo\\((void|)\\);"
 set XX_dtor	"~foo\\(int\\);"
 set re_methods	                  "void foofunc\\(int\\);"
@@ -72,6 +74,8 @@ set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int \\*\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(void \\*\\);"
+append re_methods "${ws}int overload1arg\\(foo &\\);"
+append re_methods "${ws}int overload1arg\\(foo &&\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int, int ?\\(\\*\\) ?\\(int\\)\\);"
@@ -254,6 +258,14 @@ gdb_test "print foo_instance1.overload1arg(&arg14)" \
     "\\$\[0-9\]+ = 14" \
     "print call overloaded func char\\* arg"
 
+gdb_test "print foo_instance1.overload1arg(arg15)" \
+    "\\$\[0-9\]+ = 15" \
+    "print call overloaded func foo & arg"
+
+gdb_test "print foo_instance1.overload1arg(static_cast<foo&&>(arg15))" \
+    "\\$\[0-9\]+ = 16" \
+    "print call overloaded func foo && arg"
+
 gdb_test "print bar(a)" "= 11"
 gdb_test "print bar(b)" "= 22"
 gdb_test "print bar(c)" "= 22"
diff --git a/gdb/testsuite/gdb.cp/ref-params.cc b/gdb/testsuite/gdb.cp/ref-params.cc
index 0f7e125..eb46a99 100644
--- a/gdb/testsuite/gdb.cp/ref-params.cc
+++ b/gdb/testsuite/gdb.cp/ref-params.cc
@@ -17,6 +17,8 @@
 
 /* Author: Paul N. Hilfinger, AdaCore Inc. */
 
+#include <utility>
+
 struct Parent {
   Parent (int id0) : id(id0) { }
   int id;
@@ -31,11 +33,21 @@ int f1(Parent& R)
   return R.id;			/* Set breakpoint marker3 here.  */
 }
 
+int f1(Parent&& R)
+{
+  return R.id;			/* Set breakpoint marker5 here.  */
+}
+
 int f2(Child& C)
 {
   return f1(C);			/* Set breakpoint marker2 here.  */
 }
 
+int f2(Child&& C)
+{
+  return f1(std::move(C));                 /* Set breakpoint marker4 here.  */
+}
+
 struct OtherParent {
   OtherParent (int other_id0) : other_id(other_id0) { }
   int other_id;
@@ -50,11 +62,21 @@ int mf1(OtherParent& R)
   return R.other_id;
 }
 
+int mf1(OtherParent&& R)
+{
+  return R.other_id;
+}
+
 int mf2(MultiChild& C)
 {
   return mf1(C);
 }
 
+int mf2(MultiChild&& C)
+{
+  return mf1(C);
+}
+
 int main(void) 
 {
   Child Q(42);
@@ -62,8 +84,13 @@ int main(void)
 
   /* Set breakpoint marker1 here.  */
 
+  f1(Q);
+  f1(QR);
+  f1(Child(42));
+
   f2(Q);
   f2(QR);
+  f2(Child(42));
 
   MultiChild MQ(53);
   MultiChild& MQR = MQ;
diff --git a/gdb/testsuite/gdb.cp/ref-params.exp b/gdb/testsuite/gdb.cp/ref-params.exp
index 4531602..ce943b8 100644
--- a/gdb/testsuite/gdb.cp/ref-params.exp
+++ b/gdb/testsuite/gdb.cp/ref-params.exp
@@ -24,7 +24,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[build_executable $testfile.exp $testfile $srcfile {debug c++}] == 1} {
+if {[build_executable $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}] == 1} {
     return -1
 }
 
@@ -48,15 +49,28 @@ gdb_start_again "marker1 here"
 gdb_test "print f1(QR)" ".* = 42.*" "print value of f1 on (Child&) in main"
 
 gdb_start_again "marker1 here"
+gdb_test "print f1(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f1 on (Child&&) in main"
+
+gdb_start_again "marker1 here"
 gdb_test "print f2(QR)" ".* = 42.*" "print value of f2 on (Child&) in main"
 
+gdb_start_again "marker1 here"
+gdb_test "print f2(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f2 on (Child&&) in main"
+
 gdb_start_again "marker2 here"
 gdb_test "print C" ".*id = 42.*" "print value of Child& in f2"
 gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child& in f2"
 
+gdb_start_again "marker4 here"
+gdb_test "print C" ".*id = 42.*" "print value of Child&& in f2"
+gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child&& in f2"
+
 gdb_start_again "marker3 here"
 gdb_test "print R" ".*id = 42.*" "print value of Parent& in f1"
 
+gdb_start_again "marker5 here"
+gdb_test "print R" ".*id = 42.*" "print value of Parent&& in f1"
+
 gdb_start_again "breakpoint MQ here"
 gdb_test "print f1(MQ)" ".* = 53"
 gdb_test "print mf1(MQ)" ".* = 106"
@@ -64,3 +78,8 @@ gdb_test "print mf2(MQ)" ".* = 106"
 gdb_test "print f1(MQR)" ".* = 53"
 gdb_test "print mf1(MQR)" ".* = 106"
 gdb_test "print mf2(MQR)" ".* = 106"
+gdb_test "print f1(static_cast<MultiChild&&>(MQ))" ".* = 53"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf1(static_cast<MultiChild&&>(MQ))" ".* = 106"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf2(static_cast<MultiChild&&>(MQ))" ".* = 106"
diff --git a/gdb/testsuite/gdb.cp/ref-types.cc b/gdb/testsuite/gdb.cp/ref-types.cc
index 2c124a9..dafec19 100644
--- a/gdb/testsuite/gdb.cp/ref-types.cc
+++ b/gdb/testsuite/gdb.cp/ref-types.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 int main2(void);
 
 void marker1 (void)
@@ -39,6 +41,18 @@ int main(void)
     as[2] = 2;
     as[3] = 3;
 
+    short t = -1;
+    short *pt;
+    short &&rrt = std::move(t);
+    pt = &rrt;
+    short *&&rrpt = std::move(pt);
+    short at[4];
+    at[0] = 0;
+    at[1] = 1;
+    at[2] = 2;
+    at[3] = 3;
+    short (&&rrat)[4] = std::move(at);
+
     marker1();
 
     main2();
@@ -66,15 +80,25 @@ int main2(void)
     float F;
     double D;
     char &rC = C;
+    char &&rrC = 'A';
     unsigned char &rUC = UC;
+    unsigned char &&rrUC = 21;
     short &rS = S;
+    short &&rrS = -14;
     unsigned short &rUS = US;
+    unsigned short &&rrUS = 7;
     int &rI = I;
+    int &&rrI = 102;
     unsigned int &rUI = UI;
+    unsigned int &&rrUI = 1002;
     long &rL = L;
+    long &&rrL = -234;
     unsigned long &rUL = UL;
+    unsigned long &&rrUL = 234;
     float &rF = F;
+    float &&rrF = 1.25E10;
     double &rD = D;
+    double &&rrD = -1.375E-123;
     C = 'A';
     UC = 21;
     S = -14;
diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp
index 3b557f9..fbaafc1 100644
--- a/gdb/testsuite/gdb.cp/ref-types.exp
+++ b/gdb/testsuite/gdb.cp/ref-types.exp
@@ -24,7 +24,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -127,6 +128,35 @@ gdb_test "print ras\[1\]" ".\[0-9\]* = 1" "print value of ras\[1\]"
 gdb_test "print ras\[2\]" ".\[0-9\]* = 2" "print value of ras\[2\]"
 gdb_test "print ras\[3\]" ".\[0-9\]* = 3" "print value of ras\[3\]"
 
+# rvalue reference tests
+
+gdb_test_multiple "print rrt" "print value of rrt" {
+    -re ".\[0-9\]* = \\(short( int)? &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
+}
+
+gdb_test "ptype rrt" "type = short( int)? &&.*$gdb_prompt $" "ptype rrt"
+
+gdb_test "print *rrpt" ".$decimal = -1" "print value of *rrpt"
+
+# gdb had a bug about dereferencing a pointer type
+# that would lead to wrong results
+# if we try to examine memory at pointer value.
+
+gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
+
+gdb_test "ptype rrpt" "type = short( int)? \\*&&.*$gdb_prompt $" "ptype rrpt"
+
+gdb_test "print rrat\[0\]" ".$decimal = 0" "print value of rrat\[0\]"
+
+gdb_test "ptype rrat" "type = short( int)? \\\(&&\\\)\\\[4\\\].*$gdb_prompt $" "ptype rrat" {
+
+gdb_test "print rrat\[1\]" ".$decimal = 1" "print value of rrat\[1\]"
+gdb_test "print rrat\[2\]" ".$decimal = 2" "print value of rrat\[2\]"
+gdb_test "print rrat\[3\]" ".$decimal = 3" "print value of rrat\[3\]"
+
 
 if ![runto 'f'] then {
     perror "couldn't run to f"
@@ -270,3 +300,63 @@ gdb_test "print rD" \
     ".\[0-9\]* = \\(double &\\) @$hex: -1.375e-123.*" \
     "print value of rD"
 
+#
+# test rvalue reference types
+#
+
+gdb_test "ptype rrC" "type = char &&"
+
+gdb_test "ptype rrUC" "type = unsigned char &&"
+
+gdb_test "ptype rrS" "type = short( int)? &&" "ptype rrS"
+
+gdb_test "ptype rrUS" "type = unsigned short( int)? &&" "ptype rrUS"
+
+gdb_test "ptype rrI" "type = int &&"
+
+gdb_test "ptype rrUI" "type = unsigned int &&"
+
+gdb_test "ptype rrL" "type = long( int)? &&" "ptype rrL"
+
+gdb_test "ptype rrUL" "type = unsigned long( int)? &&" "ptype rrUL"
+
+gdb_test "ptype rrF" "type = float &&"
+
+gdb_test "ptype rrD" "type = double &&"
+
+gdb_test "print rrC" "$decimal = \\(char &&\\) @$hex: 65 \'A\'" \
+    "print value of rrC"
+
+gdb_test "print rrUC" \
+    "$decimal = \\(unsigned char &&\\) @$hex: 21 \'.025\'" \
+    "print value of rrUC"
+
+gdb_test "print rrS" "$decimal = \\(short( int)? &&\\) @$hex: -14" \
+                  "print value of rrS"
+
+gdb_test "print rrUS" \
+         "$decimal = \\(unsigned short( int)? &&\\) @$hex: 7" \
+         "print value of rrUS"
+
+gdb_test "print rrI" "$decimal = \\(int &&\\) @$hex: 102" \
+       "print value of rrI"
+
+gdb_test "print rrUI" \
+    "$decimal = \\(unsigned int &&\\) @$hex: 1002" \
+        "print value of rrUI"
+
+gdb_test "print rrL" \
+       "$decimal = \\(long( int)? &&\\) @$hex: -234" \
+         "print value of rrL"
+
+gdb_test "print rrUL" \
+    "$decimal = \\((unsigned long|long unsigned int)? &&\\) @$hex: 234" \
+    "print value of rrUL"
+
+gdb_test "print rrF" \
+    "$decimal = \\(float &&\\) @$hex: 1.2${decimal}e\\+0?10.*" \
+    "print value of rrF"
+
+gdb_test "print rrD" \
+    "$decimal = \\(double &&\\) @$hex: -1.375e-123.*" \
+    "print value of rrD"
diff --git a/gdb/testsuite/gdb.python/py-value-cc.cc b/gdb/testsuite/gdb.python/py-value-cc.cc
index de819d7..188c4fa 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.cc
+++ b/gdb/testsuite/gdb.python/py-value-cc.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 class A {
  public:
   int operator+ (const int a1);
@@ -60,8 +62,10 @@ func (const A &a)
 {
   int val = 10;
   int &int_ref = val;
+  int &&int_rref = std::move(val);
   int_ptr ptr = &val;
   int_ptr &int_ptr_ref = ptr;
+  int_ptr &&int_ptr_rref = std::move(ptr);
 
   B b;
   B b1;
diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp
index d7c5e0b..1e48ab6 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.exp
+++ b/gdb/testsuite/gdb.python/py-value-cc.exp
@@ -20,7 +20,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -39,11 +40,18 @@ gdb_test "python print (str(gdb.parse_and_eval(\"a\").referenced_value().type))"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ref\").type))" "int &"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ref\").referenced_value().type))" "int"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ref\").referenced_value()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").type))" "int &&"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").referenced_value().type))" "int"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").referenced_value()))" "10"
 
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").dereference().type))" "int"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().type))" "int_ptr"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().dereference()))" "10"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().referenced_value()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").dereference().type))" "int"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().type))" "int_ptr"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().dereference()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().referenced_value()))" "10"
 
 # Tests for gdb.Value[gdb.Field]
 gdb_test_no_output "python b = gdb.parse_and_eval('b')" "init b"
-- 
2.7.2

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-03-05  3:20     ` [PATCH v3 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2016-03-16 22:08       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:08 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index e775a1d..3bdbcd9 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -362,6 +364,11 @@ enum type_instance_flag_value
>  #define TYPE_ATOMIC(t) \
>    (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
>  
> +/* True if this type represents either an lvalue or lvalue reference type.  */
> +

I think there's a missing '*' docbook marker on this comment. [Arguably,
that whole thing appears to have fallen by the wayside...]

> +#define TYPE_IS_REFERENCE(t) \
> +  (TYPE_CODE (t) == TYPE_CODE_REF || TYPE_CODE (t) == TYPE_CODE_RVALUE_REF)
> +
>  /* * Instruction-space delimited type.  This is for Harvard architectures
>     which have separate instruction and data address spaces (and perhaps
>     others).

Otherwise looks good.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-03-05  3:20     ` [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2016-03-16 22:19       ` Keith Seitz
  2016-03-20 12:10         ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:19 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> Parameterize lookup_reference_type() and make_reference_type() by the kind of
> reference type we want to look up. Create two wrapper functions
> lookup_{lvalue,rvalue}_reference_type() for lookup_reference_type() to simplify
> the API. Change all callers to use the new API.

Just an FYI: When the time comes to commit this, GIT will require a
single-line description/summary of the patch, followed by a blank line.

> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index f129b0e..a99e878 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -384,15 +384,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. REFCODE denotes

Need two spaces after "if needed."

> +   the kind of reference type to lookup (lvalue or rvalue reference).  */
>  
>  struct type *
> -make_reference_type (struct type *type, struct type **typeptr)
> +make_reference_type (struct type *type, struct type **typeptr,
> +                      enum type_code refcode)
>  {
>    struct type *ntype;	/* New type */
> +  struct type **reftype;
>    struct type *chain;
>  
> -  ntype = TYPE_REFERENCE_TYPE (type);
> +  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
> +
> +  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
> +           : TYPE_RVALUE_REFERENCE_TYPE (type));
>  
>    if (ntype)
>      {
> @@ -421,7 +427,11 @@ make_reference_type (struct type *type, struct type **typeptr)
>      }
>  
>    TYPE_TARGET_TYPE (ntype) = type;
> -  TYPE_REFERENCE_TYPE (type) = ntype;
> +  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
> +             : &TYPE_RVALUE_REFERENCE_TYPE (type));
> +
> +  if(*reftype != NULL)
> +    *reftype = ntype;
>  
>    /* FIXME!  Assume the machine has only one representation for
>       references, and that it matches the (only) representation for

I would prefer to do:

  if (refcode == TYPE_CODE_REF)
    TYPE_REFERENCE_TYPE (type) = ntype;
  else
    TYPE_RVALUE_REFERENCE_TYPE (type) = ntype;

It's cleaner/smaller/easier to read (at least for me). [Otherwise, a
space is missing between "if" and "(".] See next comment, though.


> @@ -429,10 +439,9 @@ make_reference_type (struct type *type, struct type **typeptr)
>  
>    TYPE_LENGTH (ntype) =
>      gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
> -  TYPE_CODE (ntype) = TYPE_CODE_REF;
> +  TYPE_CODE (ntype) = refcode;
>  
> -  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
> -    TYPE_REFERENCE_TYPE (type) = ntype;
> +  *reftype = ntype;
>  

This is slightly different from the original, which only set the new
type if it was unset in the type. Your revised version will
unconditionally do it every time. I have no idea if it makes a
difference or not. Do you?

>    /* Update the length of all the other variants of this type.  */
>    chain = TYPE_CHAIN (ntype);

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2016-03-05  3:20     ` [PATCH v3 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2016-03-16 22:22       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:22 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
> index 62552ec..a1f5db6 100644
> --- a/gdb/c-valprint.c
> +++ b/gdb/c-valprint.c
> @@ -602,10 +602,13 @@ c_value_print (struct value *val, struct ui_file *stream,
>        else if (options->objectprint
>  	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
>  	{
> -	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
> +	  int is_ref = TYPE_IS_REFERENCE (type);
> +	  enum type_code refcode = TYPE_CODE_UNDEF;
>  
> -	  if (is_ref)
> +	  if (is_ref) {
>  	    val = value_addr (val);
> +	    refcode = TYPE_CODE (type);
> +	  }
>  

Open braces go on new line.

>  	  /* Pointer to class, check real type of object.  */
>  	  fprintf_filtered (stream, "(");

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2016-03-05  3:20     ` [PATCH v3 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2016-03-16 22:23       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:23 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> diff --git a/gdb/parse.c b/gdb/parse.c
> index 06f7bcd..b67d1f0 100644
> --- a/gdb/parse.c
> +++ b/gdb/parse.c
> @@ -1481,8 +1481,8 @@ insert_type (enum type_pieces tp)
>    union type_stack_elt element;
>    int slot;
>  
> -  gdb_assert (tp == tp_pointer || tp == tp_reference
> -	      || tp == tp_const || tp == tp_volatile);
> +  gdb_assert (tp == tp_pointer || tp == tp_reference ||
> +	      tp == tp_rvalue_reference || tp == tp_const || tp == tp_volatile);

The coding standard specifies that operators should not end a line. [Our
ARI script (ari/gdb_ari.sh) will flag this, too.]

>  
>    /* If there is anything on the stack (we know it will be a
>       tp_pointer), insert the qualifier above it.  Otherwise, simply

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2016-03-05  3:20     ` [PATCH v3 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2016-03-16 22:25       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:25 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> This patch fixes demangling of names containing rvalue reference typenames by
> handling DEMANGLE_COMPONENT_RVALUE_REFERENCE demangle component.
> 
> gdb/ChangeLog:
> 
> 2016-03-04  Artemiy Volkov  <artemiyv@acm.org>
> 
>     * cp-name-parser.y (ptr_operator): Handle the '&&' token in
>     typename.
>     * cp-support.c (replace_typedefs): Handle
>     DEMANGLE_COMPONENT_RVALUE_REFERENCE.
>     * python/py-type.c (typy_lookup_type): Likewise.
> ---
>  gdb/cp-name-parser.y | 4 ++++
>  gdb/cp-support.c     | 1 +
>  gdb/python/py-type.c | 4 ++++
>  3 files changed, 9 insertions(+)
> 

This all looks okay to me.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2016-03-05  3:20     ` [PATCH v3 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2016-03-16 22:26       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:26 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> This patch provides the ability to print out names of rvalue reference types
> and values of those types. This is done in full similarity to regular
> references, and as with them, we don't print out "const" suffix because all
> rvalue references are const.
> 
> gdb/ChangeLog:
> 
> 2016-03-04  Artemiy Volkov  <artemiyv@acm.org>
> 
>     * c-typeprint.c (c_print_type, c_type_print_varspec_prefix)
>     (c_type_print_modifier, c_type_print_varspec_suffix)
>     (c_type_print_base): Support printing rvalue reference types.
>     * c-valprint.c (c_val_print, c_value_print): Support printing
>     rvalue reference values.
> ---
>  gdb/c-typeprint.c | 10 ++++++----
>  gdb/c-valprint.c  |  4 ++--
>  2 files changed, 8 insertions(+), 6 deletions(-)

This looks okay, too.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type
  2016-03-05  3:20     ` [PATCH v3 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
@ 2016-03-16 22:28       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:28 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> Make gdb DWARF reader understand the DW_AT_rvalue_reference type tag. Handling
> of this tag is done in the existing read_tag_reference_type() function, to
> which we add a new parameter representing the kind of reference type
> (lvalue vs rvalue).
> 
> gdb/ChangeLog:
> 
> 2016-03-03  Artemiy Volkov  <artemiyv@acm.org>
> 
>     * dwarf2read.c (process_die, read_type_die_1): Handle the
>     DW_AT_rvalue_reference_type DIE.
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>     (read_tag_reference_type): Add new parameter "refcode".

DW_TAG_rvalue_reference_type?

> ---
>  gdb/dwarf2read.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)

Otherwise this looks good to me.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-03-05  3:20     ` [PATCH v3 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-03-16 22:32       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:32 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> This patch adds the ability to inspect rvalue reference types and values using
> the gdb python module. This is achieved by simply using the ReferenceExplorer
> class to handle the objects of rvalue reference types and placing necessary
> checks for a TYPE_CODE_RVALUE_REF type code next to the checks for a
> TYPE_CODE_REF type code.
> 
> gdb/ChangeLog:
> 
> 2016-03-04  Artemiy Volkov  <artemiyv@acm.org>
> 
>         * python/lib/gdb/command/explore.py: Support exploring values
>         of rvalue reference types.
>         * python/lib/gdb/types.py: Implement get_basic_type() for
>         rvalue reference types.
>         * python/py-type.c (pyty_codes) <TYPE_CODE_RVALUE_REF>: New
>         constant.
>         * python/py-value.c (valpy_getitem): Add an rvalue reference
>         check.
>         * python/py-xmethods.c (gdbpy_get_xmethod_result_type)
>         (gdbpy_invoke_xmethod): Likewise.
> ---
>  gdb/python/lib/gdb/command/explore.py |  2 +-
>  gdb/python/lib/gdb/types.py           |  4 +++-
>  gdb/python/py-type.c                  |  1 +
>  gdb/python/py-value.c                 |  3 +++
>  gdb/python/py-xmethods.c              | 14 ++++++++------
>  5 files changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
> index d70cdd1..859e346 100644
> --- a/gdb/python/py-xmethods.c
> +++ b/gdb/python/py-xmethods.c
> @@ -548,10 +548,11 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
>        if (!types_equal (obj_type, this_ptr))
>  	obj = value_cast (this_ptr, obj);
>      }
> -  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
> +  else if (TYPE_IS_REFERENCE (obj_type))
>      {
> -      struct type *this_ref = lookup_lvalue_reference_type (this_type);
> -
> +      struct type *this_ref = TYPE_CODE (obj_type) == TYPE_CODE_REF
> +                                ? lookup_lvalue_reference_type (this_type)
> +                                : lookup_rvalue_reference_type (this_type);
>        if (!types_equal (obj_type, this_ref))
>  	obj = value_cast (this_ref, obj);
>      }

I see this same paradigm repeated in a handful of places...  In other
places, I've seen

  struct type *this_ref
    = lookup_reference_type (this_type, TYPE_CODE (obj_type);

Those are equivalent, right? If so, let's use the above. It's a lot
easier/quicker to read than the ternary conditional.

> @@ -634,10 +635,11 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
>        if (!types_equal (obj_type, this_ptr))
>  	obj = value_cast (this_ptr, obj);
>      }
> -  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
> +  else if (TYPE_IS_REFERENCE (obj_type))
>      {
> -      struct type *this_ref = lookup_lvalue_reference_type (this_type);
> -
> +      struct type *this_ref = TYPE_CODE (obj_type) == TYPE_CODE_REF 
> +                                ? lookup_lvalue_reference_type (this_type)
> +                                : lookup_rvalue_reference_type (this_type);
>        if (!types_equal (obj_type, this_ref))
>  	obj = value_cast (this_ref, obj);
>      }
> 

Likewise?

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-03-05  3:20     ` [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-03-16 22:41       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:41 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches@sourceware.org ml

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:
> In almost all contexts (except for overload resolution rules and expression
> semantics), lvalue and rvalue references are equivalent. That means that in all
> but these cases we can replace a TYPE_CODE_REF check to a TYPE_IS_REFERENCE
> check and, for switch statements, add a case label for a rvalue reference type
> next to a case label for an lvalue reference type. This patch does exactly
> that.

> diff --git a/gdb/valops.c b/gdb/valops.c
> index 1f423a0..30e1c59 100644
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
> @@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
>      {
>        struct value *v2;
>  
> -      if (TYPE_CODE (type2) == TYPE_CODE_REF)
> +      if (TYPE_IS_REFERENCE (type2))
>  	v2 = coerce_ref (arg2);
>        else
>  	v2 = value_ind (arg2);
> @@ -363,21 +363,21 @@ value_cast (struct type *type, struct value *arg2)
>    code1 = TYPE_CODE (check_typedef (type));
>  

code1 isn't used anymore in this early part of the function. It is later
unconditionally assigned a new value, so I would just remove this
assignment.

>    /* Check if we are casting struct reference to struct reference.  */
> -  if (code1 == TYPE_CODE_REF)
> +  if (TYPE_IS_REFERENCE (check_typedef (type)))
>      {
>        /* We dereference type; then we recurse and finally
>           we generate value of the given reference.  Nothing wrong with 
>  	 that.  */
>        struct type *t1 = check_typedef (type);
>        struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
> -      struct value *val =  value_cast (dereftype, arg2);
> +      struct value *val = value_cast (dereftype, arg2);
>  
>        return value_ref (val, TYPE_CODE (t1));
>      }
>  
>    code2 = TYPE_CODE (check_typedef (value_type (arg2)));

And I believe the same with code2. It isn't used until later, and by
that time, it has been assigned a new value.
>  
> -  if (code2 == TYPE_CODE_REF)
> +  if (TYPE_IS_REFERENCE (check_typedef (value_type (arg2))))
>      /* We deref the value and then do the cast.  */
>      return value_cast (type, coerce_ref (arg2)); 
>  

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2016-03-05  3:20     ` [PATCH v3 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2016-03-16 22:45       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:45 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:

> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index ce4b9be..c5b8ab5 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -3466,15 +3468,65 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
>  {
>    struct rank rank = {0,0};
>  
> -  if (types_equal (parm, arg))
> -    return EXACT_MATCH_BADNESS;
> -
>    /* Resolve typedefs */
>    if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
>      parm = check_typedef (parm);
>    if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
>      arg = check_typedef (arg);
>  
> +  if (value != NULL)
> +    {
> +      /* An rvalue argument cannot be bound to a non-const lvalue
> +         reference parameter...  */
> +      if (VALUE_LVAL (value) == not_lval
> +          && TYPE_CODE (parm) == TYPE_CODE_REF
> +          && !TYPE_CONST (parm->main_type->target_type))
> +        return INCOMPATIBLE_TYPE_BADNESS;
> +
> +      /* ... and an lvalue argument cannot be bound to an rvalue
> +         reference parameter.  [C++ 13.3.3.1.4p3]  */
> +      if (VALUE_LVAL (value) != not_lval
> +          && TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
> +        return INCOMPATIBLE_TYPE_BADNESS;
> +    }
> +
> +  if (types_equal (parm, arg))
> +    return EXACT_MATCH_BADNESS;
> +
> +  /* An lvalue reference to a function should get higher priority than an
> +     rvalue reference to a function. */
> +

Two spaces after "."

> +  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
> +      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
> +    {
> +      return (sum_ranks (rank_one_type (parm,
> +              lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
> +              DIFFERENT_REFERENCE_TYPE_BADNESS));
> +    }
> +
> +  /* If a conversion to one type of reference is an identity conversion, and a
> +     conversion to the second type of reference is a non-identity conversion,
> +     choose the first type. */
> +

Same here.

> +  if (value != NULL && TYPE_IS_REFERENCE (parm) && TYPE_IS_REFERENCE (arg)
> +     && TYPE_CODE (parm) != TYPE_CODE (arg))
> +    {
> +      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
> +              TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
> +    }
> +
> +  /* An rvalue should be first tried to bind to an rvalue reference, and then to
> +     an lvalue reference. */
> +

And here.

> +  if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
> +      && VALUE_LVAL (value) == not_lval)
> +    {
> +      if (TYPE_IS_REFERENCE (arg))
> +	arg = TYPE_TARGET_TYPE (arg);
> +      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
> +			 LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
> +    }
> +
>    /* See through references, since we can almost make non-references
>       references.  */
>  
> 

Other than that, this looks good to me.

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-03-05  3:20     ` [PATCH v3 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-03-16 22:48       ` Keith Seitz
  0 siblings, 0 replies; 109+ messages in thread
From: Keith Seitz @ 2016-03-16 22:48 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/04/2016 07:19 PM, Artemiy Volkov wrote:

> diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
> index 5c782a4..05cbded 100644
> --- a/gdb/testsuite/gdb.cp/overload.cc
> +++ b/gdb/testsuite/gdb.cp/overload.cc
> @@ -1,10 +1,12 @@
>  #include <stddef.h>
> +#include <utility>
>  
>  class foo {
>  public:
>    foo  (int);
>    foo  (int, const char *);
>    foo  (foo&);
> +  foo  (foo&&);
>    ~foo ();
>    void foofunc (int);
>    void foofunc (int, signed char *);
> @@ -27,6 +29,14 @@ int overload1arg (double);
>  int overload1arg (int*);
>  int overload1arg (void*);
>  
> +typedef foo &foo_lval_ref;
> +typedef foo &&foo_rval_ref;
> +
> +int overload1arg (foo &);
> +int overload1arg (foo &&);
> +int overload1arg (foo_lval_ref);
> +int overload1arg (foo_rval_ref);
> +

With GCC6, I am getting the build error "cannot overload `int
overload1arg(foo &)' with `int overload1arg(foo_lval_ref)'". Likewise
with foo &&/foo_rval_ref.

>  int overloadfnarg (void);
>  int overloadfnarg (int);
>  int overloadfnarg (int, int (*) (int));

> diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp
> index 3b557f9..fbaafc1 100644
> --- a/gdb/testsuite/gdb.cp/ref-types.exp
> +++ b/gdb/testsuite/gdb.cp/ref-types.exp
> @@ -127,6 +128,35 @@ gdb_test "print ras\[1\]" ".\[0-9\]* = 1" "print value of ras\[1\]"
>  gdb_test "print ras\[2\]" ".\[0-9\]* = 2" "print value of ras\[2\]"
>  gdb_test "print ras\[3\]" ".\[0-9\]* = 3" "print value of ras\[3\]"
>  
> +# rvalue reference tests
> +
> +gdb_test_multiple "print rrt" "print value of rrt" {
> +    -re ".\[0-9\]* = \\(short( int)? &&\\) @$hex: -1.*$gdb_prompt $" {
> +        pass "print value of rrt"
> +    }
> +    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
> +}
> +
> +gdb_test "ptype rrt" "type = short( int)? &&.*$gdb_prompt $" "ptype rrt"
> +

This test doesn't pass -- the expected result is incorrect. Remove
".*$gdb_prompt $". gdb_test will automatically append this.

> +gdb_test "print *rrpt" ".$decimal = -1" "print value of *rrpt"
> +
> +# gdb had a bug about dereferencing a pointer type
> +# that would lead to wrong results
> +# if we try to examine memory at pointer value.
> +
> +gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
> +
> +gdb_test "ptype rrpt" "type = short( int)? \\*&&.*$gdb_prompt $" "ptype rrpt"
> +

Same here.

> +gdb_test "print rrat\[0\]" ".$decimal = 0" "print value of rrat\[0\]"
> +
> +gdb_test "ptype rrat" "type = short( int)? \\\(&&\\\)\\\[4\\\].*$gdb_prompt $" "ptype rrat" {
> +

and here. There's also a stray '{' at the end here.

> +gdb_test "print rrat\[1\]" ".$decimal = 1" "print value of rrat\[1\]"
> +gdb_test "print rrat\[2\]" ".$decimal = 2" "print value of rrat\[2\]"
> +gdb_test "print rrat\[3\]" ".$decimal = 3" "print value of rrat\[3\]"
> +
>  
>  if ![runto 'f'] then {
>      perror "couldn't run to f"

Thank you!

Keith

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-03-16 22:19       ` Keith Seitz
@ 2016-03-20 12:10         ` Artemiy Volkov
  0 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-20 12:10 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Wed, Mar 16, 2016 at 03:19:13PM -0700, Keith Seitz wrote:

[snip]

> > +   the kind of reference type to lookup (lvalue or rvalue reference).  */
> >  
> >  struct type *
> > -make_reference_type (struct type *type, struct type **typeptr)
> > +make_reference_type (struct type *type, struct type **typeptr,
> > +                      enum type_code refcode)
> >  {
> >    struct type *ntype;	/* New type */
> > +  struct type **reftype;
> >    struct type *chain;
> >  
> > -  ntype = TYPE_REFERENCE_TYPE (type);
> > +  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
> > +
> > +  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
> > +           : TYPE_RVALUE_REFERENCE_TYPE (type));
> >  
> >    if (ntype)
> >      {
> > @@ -421,7 +427,11 @@ make_reference_type (struct type *type, struct type **typeptr)
> >      }
> >  
> >    TYPE_TARGET_TYPE (ntype) = type;
> > -  TYPE_REFERENCE_TYPE (type) = ntype;
> > +  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
> > +             : &TYPE_RVALUE_REFERENCE_TYPE (type));
> > +
> > +  if(*reftype != NULL)
> > +    *reftype = ntype;
> >  
> >    /* FIXME!  Assume the machine has only one representation for
> >       references, and that it matches the (only) representation for
> 
> I would prefer to do:
> 
>   if (refcode == TYPE_CODE_REF)
>     TYPE_REFERENCE_TYPE (type) = ntype;
>   else
>     TYPE_RVALUE_REFERENCE_TYPE (type) = ntype;
> 
> It's cleaner/smaller/easier to read (at least for me). [Otherwise, a
> space is missing between "if" and "(".] See next comment, though.

My idea was to create a new variable 'reftype' and use it as a
pointer to the member of struct main_type that we're dealing with here.
Without it, we would have to paste your fragment (more readable,
granted) two times rather than just do "*reftype = ntype" two times. I
think the latter is better since it's several lines shorter in total and
reduces the amount of copy-paste code.

> 
> 
> > @@ -429,10 +439,9 @@ make_reference_type (struct type *type, struct type **typeptr)
> >  
> >    TYPE_LENGTH (ntype) =
> >      gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
> > -  TYPE_CODE (ntype) = TYPE_CODE_REF;
> > +  TYPE_CODE (ntype) = refcode;
> >  
> > -  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
> > -    TYPE_REFERENCE_TYPE (type) = ntype;
> > +  *reftype = ntype;
> >  
> 
> This is slightly different from the original, which only set the new
> type if it was unset in the type. Your revised version will
> unconditionally do it every time. I have no idea if it makes a
> difference or not. Do you?

AFAICT *reftype is provably unequal to 0 here, because it was set to
ntype by the previous assignment, and ntype was unequal to 0 itself. I
went ahead and simplified this a little bit. Is this kind of code
change justified here?

> 
> >    /* Update the length of all the other variants of this type.  */
> >    chain = TYPE_CHAIN (ntype);

Thanks!
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (3 preceding siblings ...)
  2016-03-21 21:02       ` [PATCH v4 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
                         ` (7 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Make gdb DWARF reader understand the DW_TAG_rvalue_reference type tag. Handling
of this tag is done in the existing read_tag_reference_type() function, to
which we add a new parameter representing the kind of reference type
(lvalue vs rvalue).

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * dwarf2read.c (process_die, read_type_die_1): Handle the
    DW_TAG_rvalue_reference_type DIE.
    (read_tag_reference_type): Add new parameter "refcode".
---
 gdb/dwarf2read.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index cf8ce53..df6491a 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8294,6 +8294,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;
 
@@ -14320,16 +14321,19 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
    the user defined type vector.  */
 
 static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+                          enum type_code refcode)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type, *target_type;
   struct attribute *attr;
 
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
   target_type = die_type (die, cu);
 
   /* The die_type call above may have already set the type for this DIE.  */
@@ -14337,7 +14341,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_lvalue_reference_type (target_type);
+  type = lookup_reference_type (target_type, refcode);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
@@ -19115,7 +19119,10 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
       this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      this_type = read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+      break;
+    case DW_TAG_rvalue_reference_type:
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
       break;
     case DW_TAG_const_type:
       this_type = read_tag_const_type (die, cu);
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
                         ` (11 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Parameterize lookup_reference_type() and make_reference_type() by the kind of
reference type we want to look up. Create two wrapper functions
lookup_{lvalue,rvalue}_reference_type() for lookup_reference_type() to simplify
the API. Change all callers to use the new API.

gdb/Changelog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * dwarf2read.c (read_tag_reference_type): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
    * eval.c (evaluate_subexp_standard): Likewise.
    * f-exp.y: Likewise.
    * gdbtypes.c (make_reference_type, lookup_reference_type):
    Generalize with rvalue reference types.
    (lookup_lvalue_reference_type, lookup_rvalue_reference_type): New
    convenience wrappers for lookup_reference_type().
    * gdbtypes.h (make_reference_type, lookup_reference_type): Add a
    reference kind parameter.
    (lookup_lvalue_reference_type, lookup_rvalue_reference_type): Add
    wrappers for lookup_reference_type().
    * guile/scm-type.c (gdbscm_type_reference): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
    * guile/scm-value.c (gdbscm_value_dynamic_type): Likewise.
    * parse.c (follow_types): Likewise.
    * python/py-type.c (typy_reference, typy_lookup_type): Likewise.
    * python/py-value.c (valpy_get_dynamic_type, valpy_getitem):
    Likewise.
    * python/py-xmethods.c (gdbpy_get_xmethod_result_type)
    (gdbpy_invoke_xmethod): Likewise.
    * stabsread.c: Provide extra argument to make_reference_type()
    call.
    * valops.c (value_ref, value_rtti_indirect_type): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
---
 gdb/dwarf2read.c         |  2 +-
 gdb/eval.c               |  2 +-
 gdb/f-exp.y              |  2 +-
 gdb/gdbtypes.c           | 42 +++++++++++++++++++++++++++++++++---------
 gdb/gdbtypes.h           |  8 ++++++--
 gdb/guile/scm-type.c     |  2 +-
 gdb/guile/scm-value.c    |  2 +-
 gdb/parse.c              |  2 +-
 gdb/python/py-type.c     |  4 ++--
 gdb/python/py-value.c    |  5 +++--
 gdb/python/py-xmethods.c |  4 ++--
 gdb/stabsread.c          |  3 ++-
 gdb/valops.c             |  4 ++--
 13 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index dcd49e3..cf8ce53 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14337,7 +14337,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_reference_type (target_type);
+  type = lookup_lvalue_reference_type (target_type);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
diff --git a/gdb/eval.c b/gdb/eval.c
index 78ad946..8969f49 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2789,7 +2789,7 @@ evaluate_subexp_standard (struct type *expect_type,
 
 	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
 		{
-		  type = lookup_reference_type (type);
+		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 4faac32..8948578 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -567,7 +567,7 @@ ptype	:	typebase
 			follow_type = lookup_pointer_type (follow_type);
 			break;
 		      case tp_reference:
-			follow_type = lookup_reference_type (follow_type);
+			follow_type = lookup_lvalue_reference_type (follow_type);
 			break;
 		      case tp_array:
 			array_size = pop_type_int ();
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 65758bf..391fd28 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -384,15 +384,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. REFCODE denotes
+   the kind of reference type to lookup (lvalue or rvalue reference).  */
 
 struct type *
-make_reference_type (struct type *type, struct type **typeptr)
+make_reference_type (struct type *type, struct type **typeptr,
+                      enum type_code refcode)
 {
   struct type *ntype;	/* New type */
+  struct type **reftype;
   struct type *chain;
 
-  ntype = TYPE_REFERENCE_TYPE (type);
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
+           : TYPE_RVALUE_REFERENCE_TYPE (type));
 
   if (ntype)
     {
@@ -421,7 +427,10 @@ make_reference_type (struct type *type, struct type **typeptr)
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
-  TYPE_REFERENCE_TYPE (type) = ntype;
+  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
+             : &TYPE_RVALUE_REFERENCE_TYPE (type));
+
+  *reftype = ntype;
 
   /* FIXME!  Assume the machine has only one representation for
      references, and that it matches the (only) representation for
@@ -429,10 +438,9 @@ make_reference_type (struct type *type, struct type **typeptr)
 
   TYPE_LENGTH (ntype) =
     gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
-  TYPE_CODE (ntype) = TYPE_CODE_REF;
+  TYPE_CODE (ntype) = refcode;
 
-  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
-    TYPE_REFERENCE_TYPE (type) = ntype;
+  *reftype = ntype;
 
   /* Update the length of all the other variants of this type.  */
   chain = TYPE_CHAIN (ntype);
@@ -449,9 +457,25 @@ make_reference_type (struct type *type, struct type **typeptr)
    details.  */
 
 struct type *
-lookup_reference_type (struct type *type)
+lookup_reference_type (struct type *type, enum type_code refcode)
+{
+  return make_reference_type (type, (struct type **) 0, refcode);
+}
+
+/* Lookup the lvalue reference type for the type TYPE.  */
+
+struct type *
+lookup_lvalue_reference_type (struct type *type)
+{
+  return lookup_reference_type (type, TYPE_CODE_REF);
+}
+
+/* Lookup the rvalue reference type for the type TYPE.  */
+
+struct type *
+lookup_rvalue_reference_type (struct type *type)
 {
-  return make_reference_type (type, (struct type **) 0);
+  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
 }
 
 /* Lookup a function type that returns type TYPE.  TYPEPTR, if
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 6842052..1614d16 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1727,9 +1727,13 @@ 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);
 
-extern struct type *lookup_reference_type (struct type *);
+extern struct type *lookup_reference_type (struct type *, enum type_code);
+extern struct type *lookup_lvalue_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_reference_type (struct type *, struct type **,
+                                         enum type_code);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 2acdfad..888624d 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -854,7 +854,7 @@ gdbscm_type_reference (SCM self)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 1cdf953..fff3817 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -601,7 +601,7 @@ gdbscm_value_dynamic_type (SCM self)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+		type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
diff --git a/gdb/parse.c b/gdb/parse.c
index 4191fc6..06f7bcd 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1695,7 +1695,7 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_reference_type (follow_type);
+	follow_type = lookup_lvalue_reference_type (follow_type);
 	if (make_const)
 	  follow_type = make_cv_type (make_const, 
 				      TYPE_VOLATILE (follow_type), 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 03cc8d9..6103a2b 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -667,7 +667,7 @@ typy_reference (PyObject *self, PyObject *args)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -827,7 +827,7 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-	      rtype =  lookup_reference_type (type);
+	      rtype = lookup_lvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7dba0ad..be08231 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -376,7 +376,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+		type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -766,7 +766,8 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
-	    res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
+	                          tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 58bb783..d70cdd1 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -550,7 +550,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
@@ -636,7 +636,7 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 74260b7..60691a1 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -1772,7 +1772,8 @@ again:
 
     case '&':			/* Reference to another type */
       type1 = read_type (pp, objfile);
-      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile));
+      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile),
+                                  TYPE_CODE_REF);
       break;
 
     case 'f':			/* Function returning another type */
diff --git a/gdb/valops.c b/gdb/valops.c
index 5a244a9..1aafb5a 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1508,7 +1508,7 @@ value_ref (struct value *arg1)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
   return arg2;
 }
 
@@ -3616,7 +3616,7 @@ value_rtti_indirect_type (struct value *v, int *full,
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
       if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_reference_type (real_type);
+        real_type = lookup_lvalue_reference_type (real_type);
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
                       ` (10 preceding siblings ...)
  2016-03-05  3:20     ` [PATCH v3 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2016-03-21 21:02     ` Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
                         ` (12 more replies)
  11 siblings, 13 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Hi all,

this is my fourth take on fixing gdb/14441 which deals with C++0x rvalue
references.

The approach is rather straightforward and the work for the most part consisted
of mimicking the behavior for regular references. In gdbtypes.c, several helper
functions were introduced and some parameterized by the reference kind to
simplify the access to reference type objects API.

The only interesting part is the addition of overloading resolution rules
with regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
13.3.3.2 were accounted for at the beginning of rank_one_type().

With this patch it is now also possible to fix the evaluation of decltype,
which should return a plain type object, an lvalue reference or an rvalue
reference depending on a type category of the type of its operand. However,
this would require introduction of the type category notion to gdb, which I
think only needs adding a new constant to lval_type and propagating the type
category through different parts of an expression in gdb/valops.c. I'm willing
to do this if this patchset turns out to be OK.

Changes from v1 consist of dropping the libiberty part of 05/11 and the
consequent testsuite changes. I have learned that introducing rvalue reference
support to the demangler in cplus-dem.c is completely unnecessary, since
virtually all contemporary compilers generate symbol names handled in
cp-demangle.c. Therefore I have removed some of the testcases in
gdb.cp/demangle.exp and switched the others to use the gnu-v3 demangling style.

Changes from v2 are numerous coding style fixes, improvements and
simplifications of the changelog, reorganization and reordering of the
patchset, removal of redundant code in gdb/python/*, addition of a couple of
python tests, and a few bugfixes.

Changes from v3 are a few more coding style / English grammar fixes and code
simplifications left over from v2.

Artemiy Volkov (11):
  gdb: gdbtypes: add definitions for rvalue reference type
  gdb: gdbtypes: change {lookup,make}_reference_type() API
  gdb: valops: add ability to return rvalue reference values from
    value_ref()
  gdb: parse: support rvalue reference type
  gdb: demangle: implement demangling for rvalue reference typenames
  gdb: print: implement correct printing of rvalue reference types and
    values
  gdb: dwarf2read: support DW_TAG_rvalue_reference type
  gdb: python: support rvalue references in the gdb module
  gdb: convert lvalue reference type check to general reference type
    check
  gdb: gdbtypes: add rvalue references to overloading resolution
  gdb: testsuite: add rvalue reference tests

 gdb/aarch64-tdep.c                       |   5 +-
 gdb/ada-lang.c                           |   2 +-
 gdb/amd64-tdep.c                         |   2 +-
 gdb/amd64-windows-tdep.c                 |   1 +
 gdb/arm-tdep.c                           |   5 +-
 gdb/ax-gdb.c                             |   2 +
 gdb/c-exp.y                              |   6 +-
 gdb/c-typeprint.c                        |  10 +--
 gdb/c-valprint.c                         |  14 +++--
 gdb/c-varobj.c                           |  10 +--
 gdb/compile/compile-c-symbols.c          |   2 +-
 gdb/completer.c                          |   3 +-
 gdb/cp-name-parser.y                     |   4 ++
 gdb/cp-support.c                         |   3 +-
 gdb/darwin-nat-info.c                    |   2 +-
 gdb/dwarf2loc.c                          |   4 +-
 gdb/dwarf2read.c                         |  15 +++--
 gdb/eval.c                               |  16 ++---
 gdb/f-exp.y                              |   2 +-
 gdb/findvar.c                            |   6 +-
 gdb/gdbtypes.c                           | 105 ++++++++++++++++++++++++++-----
 gdb/gdbtypes.h                           |  20 +++++-
 gdb/guile/scm-type.c                     |   2 +-
 gdb/guile/scm-value.c                    |   2 +-
 gdb/hppa-tdep.c                          |   1 +
 gdb/infcall.c                            |   5 +-
 gdb/language.c                           |   3 +-
 gdb/m32c-tdep.c                          |   8 +--
 gdb/m88k-tdep.c                          |   1 +
 gdb/mn10300-tdep.c                       |   1 +
 gdb/msp430-tdep.c                        |   2 +-
 gdb/parse.c                              |  39 +++++++-----
 gdb/parser-defs.h                        |   1 +
 gdb/ppc-sysv-tdep.c                      |   7 +--
 gdb/printcmd.c                           |   2 +-
 gdb/python/lib/gdb/command/explore.py    |   2 +-
 gdb/python/lib/gdb/types.py              |   4 +-
 gdb/python/py-type.c                     |  14 +++--
 gdb/python/py-value.c                    |  16 +++--
 gdb/python/py-xmethods.c                 |  12 ++--
 gdb/s390-linux-tdep.c                    |   2 +-
 gdb/sparc-tdep.c                         |   1 +
 gdb/sparc64-tdep.c                       |   1 +
 gdb/spu-tdep.c                           |   1 +
 gdb/stabsread.c                          |   3 +-
 gdb/symtab.c                             |   3 +-
 gdb/testsuite/gdb.cp/casts.cc            |   8 ++-
 gdb/testsuite/gdb.cp/casts.exp           |  35 +++++++++--
 gdb/testsuite/gdb.cp/cpsizeof.cc         |   4 ++
 gdb/testsuite/gdb.cp/cpsizeof.exp        |   3 +-
 gdb/testsuite/gdb.cp/demangle.exp        |  36 +++++++++++
 gdb/testsuite/gdb.cp/overload.cc         |  18 +++++-
 gdb/testsuite/gdb.cp/overload.exp        |  16 ++++-
 gdb/testsuite/gdb.cp/ref-params.cc       |  27 ++++++++
 gdb/testsuite/gdb.cp/ref-params.exp      |  21 ++++++-
 gdb/testsuite/gdb.cp/ref-types.cc        |  24 +++++++
 gdb/testsuite/gdb.cp/ref-types.exp       |  92 ++++++++++++++++++++++++++-
 gdb/testsuite/gdb.python/py-value-cc.cc  |   4 ++
 gdb/testsuite/gdb.python/py-value-cc.exp |  10 ++-
 gdb/typeprint.c                          |   4 +-
 gdb/valarith.c                           |   6 +-
 gdb/valops.c                             |  72 +++++++++++----------
 gdb/valprint.c                           |   5 +-
 gdb/value.c                              |  12 ++--
 gdb/value.h                              |   2 +-
 gdb/varobj.c                             |   2 +-
 66 files changed, 593 insertions(+), 180 deletions(-)

-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
                         ` (10 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch introduces preliminal definitions regarding C++0x rvalue references
to the gdb type system. In addition to an enum type_code entry, a field in
struct type and an accessor macro for that which are created similarly to the
lvalue references' counterparts, we also introduce a TYPE_IS_REFERENCE
convenience macro used to check for both kinds of references simultaneously as
they are equivalent in many contexts.

gdb/Changelog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * gdbtypes.h (enum type_code) <TYPE_CODE_RVALUE_REF>: New constant.
    (TYPE_IS_REFERENCE): New macro.
    (struct type): Add rvalue_reference_type field.
    (TYPE_RVALUE_REFERENCE_TYPE): New macro.
---
 gdb/gdbtypes.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 1518a7a..6842052 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -160,6 +160,8 @@ enum type_code
 
     TYPE_CODE_REF,		/**< C++ Reference types */
 
+    TYPE_CODE_RVALUE_REF,	/**< C++ rvalue reference types */
+
     TYPE_CODE_CHAR,		/**< *real* character type */
 
     /* * Boolean type.  0 is false, 1 is true, and other values are
@@ -362,6 +364,11 @@ enum type_instance_flag_value
 #define TYPE_ATOMIC(t) \
   (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
 
+/* * True if this type represents either an lvalue or lvalue reference type.  */
+
+#define TYPE_IS_REFERENCE(t) \
+  (TYPE_CODE (t) == TYPE_CODE_REF || TYPE_CODE (t) == TYPE_CODE_RVALUE_REF)
+
 /* * Instruction-space delimited type.  This is for Harvard architectures
    which have separate instruction and data address spaces (and perhaps
    others).
@@ -767,6 +774,10 @@ struct type
 
   struct type *reference_type;
 
+  /* * A C++ rvalue reference type added in C++0x. */
+
+  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 const, volatile, code-space, data-space, and
@@ -1229,6 +1240,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,
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (5 preceding siblings ...)
  2016-03-21 21:02       ` [PATCH v4 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-21 21:03       ` [PATCH v4 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
                         ` (5 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch provides the ability to print out names of rvalue reference types
and values of those types. This is done in full similarity to regular
references, and as with them, we don't print out "const" suffix because all
rvalue references are const.

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * c-typeprint.c (c_print_type, c_type_print_varspec_prefix)
    (c_type_print_modifier, c_type_print_varspec_suffix)
    (c_type_print_base): Support printing rvalue reference types.
    * c-valprint.c (c_val_print, c_value_print): Support printing
    rvalue reference values.
---
 gdb/c-typeprint.c | 10 ++++++----
 gdb/c-valprint.c  |  4 ++--
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index ed16fc3..569a803 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-		  || code == TYPE_CODE_REF)))
+		  || TYPE_IS_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
@@ -341,9 +341,10 @@ c_type_print_varspec_prefix (struct type *type,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
 				   stream, show, 1, 0, flags);
-      fprintf_filtered (stream, "&");
+      fprintf_filtered (stream, TYPE_CODE(type) == TYPE_CODE_REF ? "&" : "&&");
       c_type_print_modifier (type, stream, 1, need_post_space);
       break;
 
@@ -410,8 +411,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
      every reference is `const'.  */
-  if (TYPE_CONST (type)
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CONST (type) && !TYPE_IS_REFERENCE (type))
     {
       if (need_pre_space)
 	fprintf_filtered (stream, " ");
@@ -726,6 +726,7 @@ c_type_print_varspec_suffix (struct type *type,
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
 				   show, 1, 0, flags);
       break;
@@ -894,6 +895,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBERPTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_METHODPTR:
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 7c8d9be..2b8aaf0 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -538,6 +538,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_FLAGS:
     case TYPE_CODE_FUNC:
@@ -583,8 +584,7 @@ c_value_print (struct value *val, struct ui_file *stream,
   val_type = value_type (val);
   type = check_typedef (val_type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_PTR
-      || TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
     {
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway.
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (4 preceding siblings ...)
  2016-03-21 21:02       ` [PATCH v4 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
                         ` (6 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch implements correct parsing of C++0x rvalue reference typenames.
This is done in full similarity to the handling of regular references by adding
a '&&' token handling in c-exp.y, defining an rvalue reference type piece, and
implementing a follow type derivation in follow_types().

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * c-exp.y (ptr_operator): Handle the '&&' token in the typename.
    * parse.c (insert_type): Change assert statement.
    (follow_types): Handle rvalue reference types.
    * parser-defs.h (enum type_pieces) <tp_rvalue_reference>: New
    constant.
---
 gdb/c-exp.y       |  6 +++++-
 gdb/parse.c       | 39 ++++++++++++++++++++++-----------------
 gdb/parser-defs.h |  1 +
 3 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 9f2a229..f83047b 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -799,7 +799,7 @@ exp	:	SIZEOF '(' type ')'	%prec UNARY
 			       says of sizeof:  "When applied to a reference
 			       or a reference type, the result is the size of
 			       the referenced type."  */
-			  if (TYPE_CODE (type) == TYPE_CODE_REF)
+			  if (TYPE_IS_REFERENCE (type))
 			    type = check_typedef (TYPE_TARGET_TYPE (type));
 			  write_exp_elt_longcst (pstate,
 						 (LONGEST) TYPE_LENGTH (type));
@@ -1140,6 +1140,10 @@ ptr_operator:
 			{ insert_type (tp_reference); }
 	|	'&' ptr_operator
 			{ insert_type (tp_reference); }
+	|       ANDAND
+			{ insert_type (tp_rvalue_reference); }
+	|       ANDAND ptr_operator
+			{ insert_type (tp_rvalue_reference); }
 	;
 
 ptr_operator_ts: ptr_operator
diff --git a/gdb/parse.c b/gdb/parse.c
index 06f7bcd..eb8e475 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1470,10 +1470,10 @@ insert_into_type_stack (int slot, union type_stack_elt element)
 }
 
 /* Insert a new type, TP, at the bottom of the type stack.  If TP is
-   tp_pointer or tp_reference, it is inserted at the bottom.  If TP is
-   a qualifier, it is inserted at slot 1 (just above a previous
-   tp_pointer) if there is anything on the stack, or simply pushed if
-   the stack is empty.  Other values for TP are invalid.  */
+   tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the
+   bottom.  If TP is a qualifier, it is inserted at slot 1 (just above a
+   previous tp_pointer) if there is anything on the stack, or simply pushed
+   if the stack is empty.  Other values for TP are invalid.  */
 
 void
 insert_type (enum type_pieces tp)
@@ -1482,7 +1482,8 @@ insert_type (enum type_pieces tp)
   int slot;
 
   gdb_assert (tp == tp_pointer || tp == tp_reference
-	      || tp == tp_const || tp == tp_volatile);
+	      || tp == tp_rvalue_reference || tp == tp_const
+	      || tp == tp_volatile);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
@@ -1695,18 +1696,22 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_lvalue_reference_type (follow_type);
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+	 follow_type = lookup_lvalue_reference_type (follow_type);
+	 goto process_reference;
+	case tp_rvalue_reference:
+	 follow_type = lookup_rvalue_reference_type (follow_type);
+	process_reference:
+	 if (make_const)
+	   follow_type = make_cv_type (make_const,
+				       TYPE_VOLATILE (follow_type),
+				       follow_type, 0);
+	 if (make_volatile)
+	   follow_type = make_cv_type (TYPE_CONST (follow_type),
+				       make_volatile,
+				       follow_type, 0);
+	 if (make_addr_space)
+	   follow_type = make_type_with_address_space (follow_type,
+						       make_addr_space);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
 	break;
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 1b1d3c3..c474150 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -127,6 +127,7 @@ enum type_pieces
     tp_end = -1, 
     tp_pointer, 
     tp_reference, 
+    tp_rvalue_reference,
     tp_array, 
     tp_function,
     tp_function_with_arguments,
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-31 20:35         ` Keith Seitz
  2016-03-21 21:02       ` [PATCH v4 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
                         ` (9 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch adds the ability to inspect rvalue reference types and values using
the gdb python module. This is achieved by simply using the ReferenceExplorer
class to handle the objects of rvalue reference types and placing necessary
checks for a TYPE_CODE_RVALUE_REF type code next to the checks for a
TYPE_CODE_REF type code.

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

	* python/lib/gdb/command/explore.py: Support exploring values
	of rvalue reference types.
	* python/lib/gdb/types.py: Implement get_basic_type() for
	rvalue reference types.
	* python/py-type.c (pyty_codes) <TYPE_CODE_RVALUE_REF>: New
	constant.
	* python/py-value.c (valpy_getitem): Add an rvalue reference
	check.
	* python/py-xmethods.c (gdbpy_get_xmethod_result_type)
	(gdbpy_invoke_xmethod): Likewise.
---
 gdb/python/lib/gdb/command/explore.py |  2 +-
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 |  3 +++
 gdb/python/py-xmethods.c              | 12 ++++++------
 5 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
index 6c9f17b..ed25fa6 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,7 +319,6 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
-
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
 
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index c22e8a9..59b7df2 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 4ec920e..259bb70 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 141f180..7802ae0 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -768,6 +768,9 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
 	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
 	                          tmp);
+	  else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+	    res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
+	                          tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index d70cdd1..17fdfb2 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -548,10 +548,10 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
 	obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
-
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
@@ -634,10 +634,10 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
 	obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
-
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
     }
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (2 preceding siblings ...)
  2016-03-21 21:02       ` [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-03-21 21:02       ` Artemiy Volkov
  2016-03-21 21:02       ` [PATCH v4 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type Artemiy Volkov
                         ` (8 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

Parameterize value_ref() by the kind of reference type the value of which
is requested. Change all callers to use the new API.

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * ada-lang.c (ada_evaluate_subexp): Adhere to the new
    value_ref() interface.
    * c-valprint.c (c_value_print): Likewise.
    * infcall.c (value_arg_coerce): Likewise.
    * python/py-value.c (valpy_reference_value): Likewise.
    * valops.c (value_cast, value_reinterpret_cast)
    (value_dynamic_cast, typecmp): Likewise.
    (value_ref): Parameterize by kind of return value reference type.
    * value.h (value_ref): Add new parameter "refcode".
---
 gdb/ada-lang.c        |  2 +-
 gdb/c-valprint.c      | 10 +++++++---
 gdb/infcall.c         |  2 +-
 gdb/python/py-value.c |  2 +-
 gdb/valops.c          | 25 +++++++++++++++++--------
 gdb/value.h           |  2 +-
 6 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d874129..585d729 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10724,7 +10724,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 		     should return a ref as it should be valid to ask
 		     for its address; so rebuild a ref after coerce.  */
 		  arg1 = ada_coerce_ref (arg1);
-		  return value_ref (arg1);
+		  return value_ref (arg1, TYPE_CODE_REF);
 		}
 	    }
 
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 62552ec..7c8d9be 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -602,10 +602,14 @@ c_value_print (struct value *val, struct ui_file *stream,
       else if (options->objectprint
 	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
-	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+	  int is_ref = TYPE_IS_REFERENCE (type);
+	  enum type_code refcode = TYPE_CODE_UNDEF;
 
 	  if (is_ref)
-	    val = value_addr (val);
+	    {
+	      val = value_addr (val);
+	      refcode = TYPE_CODE (type);
+	    }
 
 	  /* Pointer to class, check real type of object.  */
 	  fprintf_filtered (stream, "(");
@@ -625,7 +629,7 @@ c_value_print (struct value *val, struct ui_file *stream,
 
 		  if (is_ref)
 		    {
-		      val = value_ref (value_ind (val));
+		      val = value_ref (value_ind (val), refcode);
 		      type = value_type (val);
 		    }
 
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 77cd931..ad2512a 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -169,7 +169,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
 	   if the value was not previously in memory - in some cases
 	   we should clearly be allowing this, but how?  */
 	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
-	new_value = value_ref (new_value);
+	new_value = value_ref (new_value, TYPE_CODE (type));
 	return new_value;
       }
     case TYPE_CODE_INT:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index be08231..141f180 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -249,7 +249,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val));
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF));
 
       do_cleanups (cleanup);
     }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1aafb5a..1f423a0 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -372,7 +372,7 @@ value_cast (struct type *type, struct value *arg2)
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
       struct value *val =  value_cast (dereftype, arg2);
 
-      return value_ref (val); 
+      return value_ref (val, TYPE_CODE (t1));
     }
 
   code2 = TYPE_CODE (check_typedef (value_type (arg2)));
@@ -622,7 +622,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
     error (_("Invalid reinterpret_cast"));
 
   if (is_ref)
-    result = value_cast (type, value_ref (value_ind (result)));
+    result = value_cast (type, value_ref (value_ind (result),
+                                          TYPE_CODE (type)));
 
   return result;
 }
@@ -816,7 +817,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
 				arg_type,
 				&result) == 1)
 	return value_cast (type,
-			   is_ref ? value_ref (result) : value_addr (result));
+			   is_ref
+			   ? value_ref (result, TYPE_CODE (resolved_type))
+			   : value_addr (result));
     }
 
   /* The second dynamic check specified in 5.2.7.  */
@@ -828,7 +831,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
 			       value_address (tem), tem,
 			       rtti_type, &result) == 1)
     return value_cast (type,
-		       is_ref ? value_ref (result) : value_addr (result));
+		       is_ref
+		       ? value_ref (result, TYPE_CODE (resolved_type))
+		       : value_addr (result));
 
   if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
     return value_zero (type, not_lval);
@@ -1499,16 +1504,20 @@ value_addr (struct value *arg1)
    contents.  */
 
 struct value *
-value_ref (struct value *arg1)
+value_ref (struct value *arg1, enum type_code refcode)
 {
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  if ((TYPE_CODE (type) == TYPE_CODE_REF
+       || TYPE_CODE (type) == TYPE_CODE_RVALUE_REF)
+      && TYPE_CODE (type) == refcode)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_reference_type (type, refcode));
   return arg2;
 }
 
@@ -1715,7 +1724,7 @@ typecmp (int staticp, int varargs, int nargs,
 	  if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
 	    t2[i] = value_coerce_array (t2[i]);
 	  else
-	    t2[i] = value_ref (t2[i]);
+	    t2[i] = value_ref (t2[i], TYPE_CODE (tt1));
 	  continue;
 	}
 
diff --git a/gdb/value.h b/gdb/value.h
index 2eac5ef..db1b7bf 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -725,7 +725,7 @@ extern struct value *value_ind (struct value *arg1);
 
 extern struct value *value_addr (struct value *arg1);
 
-extern struct value *value_ref (struct value *arg1);
+extern struct value *value_ref (struct value *arg1, enum type_code refcode);
 
 extern struct value *value_assign (struct value *toval,
 				   struct value *fromval);
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (6 preceding siblings ...)
  2016-03-21 21:02       ` [PATCH v4 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2016-03-21 21:03       ` Artemiy Volkov
  2016-03-21 21:03       ` [PATCH v4 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
                         ` (4 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:03 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch adds tests for the initial rvalue reference support patchset.
Files to change were selected among the most important files which test
regular C++ references and the added tests are practically mirrored regular
references tests. Tested are printing of rvalue reference types and values,
rvalue reference parameters in function overloading, demangling of function
names containing rvalue reference parameters, casts to rvalue reference types,
and application of the sizeof operator to rvalue reference types and values,
support for rvalue references within the gdb python module.

All the changed files have been obviously set to compile with -std=c++11,
and in some cases this required altering function names which coincided
with keywords introduced in the new standard.

gdb/testsuite/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

	* gdb.cp/casts.cc (main): Add rvalue reference type variables.
	Include the stdlib header "utility".
	(decltype) Rename C++11 reserved keyword ...
	(decl_type) ... to this. All callers updated.
	* gdb.cp/casts.exp: Compile with -std=c++11. Add rvalue reference
	cast tests.
	* gdb.cp/cpsizeof.cc: Add rvalue reference type variables.
	Include the stdlib header "utility".
	* gdb.cp/cpsizeof.exp: Compile with -std=c++11. Add rvalue
	reference sizeof tests.
	* gdb.cp/demangle.exp (test_gnu_style_demangling): Add rvalue
	reference demangle tests.
	* gdb.cp/overload.cc (main): Add typedefs for lvalue and rvalue
	reference types. Add a ctor and some methods with rvalue reference
	parameters.
	* gdb.cp/overload.exp: Compile with -std=c++11. Add rvalue
	reference overloading tests.
	* gdb.cp/ref-params.cc (f1, f2, mf1, mf2): New function taking
	rvalue reference parameter.
	* gdb.cp/ref-params.exp: Compile with -std=c++11. Add rvalue
	reference parameter printing tests.
	* gdb.cp/ref-types.cc (main2): Add rvalue reference type
	tests. Include the stdlib header "utility".
	* gdb.cp/ref-types.exp: Compile with -std=c++11. Add rvalue
	reference type printing tests.
	* gdb.python/py-value.cc: (func) Add rvalue reference variables.
	Include the stdlib header "utility".
	* gdb.python/py-value.exp: Compile with -std=c++11. Add rvalue
	reference tests.
---
 gdb/testsuite/gdb.cp/casts.cc            |  8 ++-
 gdb/testsuite/gdb.cp/casts.exp           | 35 ++++++++++--
 gdb/testsuite/gdb.cp/cpsizeof.cc         |  4 ++
 gdb/testsuite/gdb.cp/cpsizeof.exp        |  3 +-
 gdb/testsuite/gdb.cp/demangle.exp        | 36 +++++++++++++
 gdb/testsuite/gdb.cp/overload.cc         | 18 ++++++-
 gdb/testsuite/gdb.cp/overload.exp        | 16 +++++-
 gdb/testsuite/gdb.cp/ref-params.cc       | 27 ++++++++++
 gdb/testsuite/gdb.cp/ref-params.exp      | 21 +++++++-
 gdb/testsuite/gdb.cp/ref-types.cc        | 24 +++++++++
 gdb/testsuite/gdb.cp/ref-types.exp       | 92 +++++++++++++++++++++++++++++++-
 gdb/testsuite/gdb.python/py-value-cc.cc  |  4 ++
 gdb/testsuite/gdb.python/py-value-cc.exp | 10 +++-
 13 files changed, 284 insertions(+), 14 deletions(-)

diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc
index 43f112f..d15fed1 100644
--- a/gdb/testsuite/gdb.cp/casts.cc
+++ b/gdb/testsuite/gdb.cp/casts.cc
@@ -1,3 +1,5 @@
+#include <utility>
+
 struct A
 {
   int a;
@@ -37,7 +39,7 @@ struct DoublyDerived : public VirtuallyDerived,
 // Confuse a simpler approach.
 
 double
-decltype(int x)
+decl_type(int x)
 {
   return x + 2.0;
 }
@@ -49,6 +51,8 @@ main (int argc, char **argv)
   B *b = (B *) a;
   A &ar = *b;
   B &br = (B&)ar;
+  A &&arr = std::move(A(42));
+  B &&brr = std::move(B(42, 1729));
 
   Derived derived;
   DoublyDerived doublyderived;
@@ -56,7 +60,7 @@ main (int argc, char **argv)
   Alpha *ad = &derived;
   Alpha *add = &doublyderived;
 
-  double y = decltype(2);
+  double y = decl_type(2);
 
   return 0;  /* breakpoint spot: casts.exp: 1 */
 }
diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp
index 34a2492..2000b77 100644
--- a/gdb/testsuite/gdb.cp/casts.exp
+++ b/gdb/testsuite/gdb.cp/casts.exp
@@ -33,7 +33,8 @@ if [get_compiler_info "c++"] {
     return -1
 }
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -86,6 +87,18 @@ gdb_test "print (B &) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
 gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
     "let compiler cast base class reference to derived class reference"
 
+# Casting Rvalue References.
+# Check upcasting.
+gdb_test "print (A &&) br" ".* = .A &&.* {a = 42}" \
+    "cast derived class rvalue reference to base class rvalue reference"
+
+# Check downcasting.
+gdb_test "print (B &&) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "cast base class rvalue reference to derived class rvalue reference"
+
+# Check compiler casting
+gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "let compiler cast base class rvalue reference to derived class rvalue reference"
 
 # A few basic tests of "new" casts.
 
@@ -101,6 +114,9 @@ gdb_test "print static_cast<A *> (b)" " = \\(A \\*\\) $hex" \
 gdb_test "print static_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "static_cast to reference type"
 
+gdb_test "print static_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "static_cast to rvalue reference type"
+
 gdb_test "print reinterpret_cast<A *> (b)" " = \\(A \\*\\) $hex" \
     "basic test of reinterpret_cast"
 
@@ -110,13 +126,16 @@ gdb_test "print reinterpret_cast<void> (b)" "Invalid reinterpret_cast" \
 gdb_test "print reinterpret_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
     "reinterpret_cast to reference type"
 
+gdb_test "print reinterpret_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "reinterpret_cast to rvalue reference type"
+
 # Test that keyword shadowing works.
 
-gdb_test "whatis decltype(5)" " = double"
+gdb_test "whatis decl_type(5)" " = double"
 
 # Basic tests using typeof.
 
-foreach opname {__typeof__ __typeof __decltype} {
+foreach opname {__typeof__ __typeof decltype} {
     gdb_test "print (${opname}(a)) (b)" " = \\(A \\*\\) $hex" \
 	"old-style cast using $opname"
 
@@ -127,7 +146,7 @@ foreach opname {__typeof__ __typeof __decltype} {
 	"reinterpret_cast using $opname"
 }
 
-gdb_test "whatis __decltype(*a)" "type = A \\&"
+gdb_test "whatis decltype(*a)" "type = A \\&"
 
 # Tests of dynamic_cast.
 
@@ -153,6 +172,10 @@ gdb_test "print dynamic_cast<Alpha &> (derived)" \
     " = \\(Alpha \\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
     "dynamic_cast simple upcast to reference"
 
+gdb_test "print dynamic_cast<Alpha &&> (derived)" \
+    " = \\(Alpha \\&\\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
+    "dynamic_cast simple upcast to rvalue reference"
+
 gdb_test "print dynamic_cast<Derived *> (ad)" \
     " = \\(Derived \\*\\) ${nonzero_hex}( <vtable for Derived.*>)?" \
     "dynamic_cast simple downcast"
@@ -169,6 +192,10 @@ gdb_test "print dynamic_cast<VirtuallyDerived &> (*ad)" \
     "dynamic_cast failed" \
     "dynamic_cast to reference to non-existing base"
 
+gdb_test "print dynamic_cast<VirtuallyDerived &&> (*ad)" \
+    "dynamic_cast failed" \
+    "dynamic_cast to rvalue reference to non-existing base"
+
 gdb_test "print dynamic_cast<DoublyDerived *> (add)" \
     " = \\(DoublyDerived \\*\\) ${nonzero_hex}( <vtable for DoublyDerived.*>)?" \
     "dynamic_cast unique downcast"
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.cc b/gdb/testsuite/gdb.cp/cpsizeof.cc
index 2dcaea1..6a8de4a 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.cc
+++ b/gdb/testsuite/gdb.cp/cpsizeof.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 struct Class
 {
   int a;
@@ -44,8 +46,10 @@ typedef Enum e12[12];
 #define T(N)					\
   N N ## obj;					\
   N& N ## _ref = N ## obj;			\
+  N&& N ## _rref = std::move(N ## obj);         \
   N* N ## p = &(N ## obj);			\
   N*& N ## p_ref = N ## p;			\
+  N*&& N ## p_rref = std::move(N ## p);         \
   int size_ ## N = sizeof (N ## _ref);		\
   int size_ ## N ## p = sizeof (N ## p_ref);	\
 
diff --git a/gdb/testsuite/gdb.cp/cpsizeof.exp b/gdb/testsuite/gdb.cp/cpsizeof.exp
index de95c49..47c841e 100644
--- a/gdb/testsuite/gdb.cp/cpsizeof.exp
+++ b/gdb/testsuite/gdb.cp/cpsizeof.exp
@@ -18,7 +18,8 @@ standard_testfile .cc
 
 if {[skip_cplus_tests]} { continue }
 
-if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++}] } {
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}] } {
      return -1
 }
 
diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
index 96c90db..c007097 100644
--- a/gdb/testsuite/gdb.cp/demangle.exp
+++ b/gdb/testsuite/gdb.cp/demangle.exp
@@ -123,20 +123,27 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: Append__15NameChooserViewPCc" \
 	"NameChooserView::Append\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadR6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)"
+    test_demangling_exact "gnu-v3: _ZN9ArrowLine19ArrowheadIntersectsEP9ArrowheadO6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead*, BoxObj&&, Graphic*)"
     test_demangling_exact "gnu: AtEnd__13ivRubberGroup" "ivRubberGroup::AtEnd(void)"
     test_demangling_exact "gnu: BgFilter__9ivTSolverP12ivInteractor" "ivTSolver::BgFilter(ivInteractor *)"
     test_demangling "gnu: BitPatterntoa__FRC10BitPatternccc" \
 	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &, char, char, char\[)\]+"
+    test_demangling "gnu-v3: _Z13BitPatterntoaOK10BitPatternccc" \
+	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const)&&, char, char, char\[)\]+"
     test_demangling_exact "gnu: Check__6UArrayi" "UArray::Check(int)"
     test_demangling_exact "gnu: CoreConstDecls__8TextCodeR7ostream" "TextCode::CoreConstDecls(ostream &)"
+    test_demangling_exact "gnu-v3: _ZN8TextCode14CoreConstDeclsEO7ostream" "TextCode::CoreConstDecls(ostream&&)"
     test_demangling_exact "gnu: Detach__8StateVarP12StateVarView" "StateVar::Detach(StateVarView *)"
     test_demangling_exact "gnu: Done__9ComponentG8Iterator" "Component::Done(Iterator)"
     test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCRC13ivTransformeriiii" \
 	"DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &, int, int, int, int\[)\]+"
+    test_demangling "gnu-v3: _Z31DrawDestinationTransformedImageP7_XImageiiS0_iimjiijmmP4_XGCOK13ivTransformeriiii" \
+	"DrawDestinationTransformedImage\[(\]+_XImage\[*\]+, int, int, _XImage\[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC\[*\]+, (const ivTransformer|ivTransformer const)&&, int, int, int, int\[)\]+"
 
     test_demangling "gnu: Edit__12StringEditorPCcii" \
 	"StringEditor::Edit\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
     test_demangling_exact "gnu: Effect__11RelateManipR7ivEvent" "RelateManip::Effect(ivEvent &)"
+    test_demangling_exact "gnu-v3: _ZN11RelateManip6EffectEO7ivEvent" "RelateManip::Effect(ivEvent&&)"
     test_demangling "gnu: FilterName__FPCc" \
 	"FilterName\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling "gnu: Filter__6PSTextPCci" \
@@ -206,16 +213,21 @@ proc test_gnu_style_demangling {} {
 	"iv2_6_MenuItem::iv2_6_MenuItem\[(\]+int, (const char|char const) \[*\]+, ivInteractor \[*\]+\[)\]+"
 
     test_demangling_exact "gnu: __20DisplayList_IteratorR11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &)"
+    test_demangling_exact "gnu-v3: _ZN20DisplayList_IteratorC4EO11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList&&)"
     test_demangling_exact "gnu: __3fooRT0" "foo::foo(foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EOS_" "foo::foo(foo&&)"
     test_demangling_exact "gnu: __3fooiN31" "foo::foo(int, int, int, int)"
     test_demangling "gnu: __3fooiPCc" \
 	"foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __3fooiRT0iT2iT2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EiOS_iS0_iS0_" "foo::foo(int, foo&&, int, foo&&, int, foo&&)"
     test_demangling "gnu: __6GetOptiPPcPCc" \
 	"GetOpt::GetOpt\[(\]+int, char \[*\]+\[*\]+, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __6KeyMapPT0" "KeyMap::KeyMap(KeyMap *)"
     test_demangling "gnu: __7ivWorldPCcRiPPcPC12ivOptionDescPC14ivPropertyData" \
 	"ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
+    test_demangling "gnu-v3: _ZN7ivWorldC2EPKcOiPPcPK12ivOptionDescPK14ivPropertyData" \
+	"ivWorld::ivWorld\[(\]+(const char|char const)\[*\]+, int&&, char\[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const)\[*\]+, (const ivPropertyData|ivPropertyData const)\[*\]+\[)\]+"
     test_demangling "gnu: __7procbufPCci" \
 	"procbuf::procbuf\[(\]+(const char|char const) \[*\]+, int\[)\]+"
     test_demangling_exact "gnu: __8ArrowCmdP6EditorUiUi" "ArrowCmd::ArrowCmd(Editor *, unsigned int, unsigned int)"
@@ -295,6 +307,8 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: append__7ivGlyphPT0" "ivGlyph::append(ivGlyph *)"
     test_demangling "gnu: arg__FRC7Complex" \
 	"arg\[(\]+(const Complex|Complex const) &\[)\]+"
+    test_demangling "gnu-v3: _Z3argOK7Complex" \
+	"arg\[(\]+(const Complex|Complex const)&&\[)\]+"
     test_demangling_exact "gnu: clearok__FP7_win_sti" "clearok(_win_st *, int)"
 
     test_demangling_exact "gnu: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
@@ -305,10 +319,16 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
     test_demangling "gnu: contains__C9BitStringRC10BitPattern" \
 	"BitString::contains\[(\]+(const BitPattern|BitPattern const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK10BitPattern" \
+	"BitString::contains\[(\]+(const BitPattern|BitPattern const)&&\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRC12BitSubStringi" \
 	"BitString::contains\[(\]+(const BitSubString|BitSubString const) &, int\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK12BitSubStringi" \
+	"BitString::contains\[(\]+(const BitSubString|BitSubString const)&&, int\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRT0" \
 	"BitString::contains\[(\]+(const BitString|BitString const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOKS_" \
+	"BitString::contains\[(\]+(const BitString|BitString const)&&\[)\]+ const"
     test_demangling "gnu: div__FPC6IntRepT0P6IntRep" \
 	"div\[(\]+(const IntRep|IntRep const) \[*\]+, (const IntRep|IntRep const) \[*\]+, IntRep \[*\]+\[)\]+"
     test_demangling "gnu: div__FPC6IntReplP6IntRep" \
@@ -436,18 +456,26 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE3PixC4EOKS2_" \
+	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const&&)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0" \
 	"List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC2EOKS0_PS2_" \
+	"List<VHDLEntity>::element::element(VHDLEntity const&&, List<VHDLEntity>::element*)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element" \
 	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC4EOKS2_" \
+	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const&&)"
 
     test_demangling_exact "gnu: __cl__C11VHDLLibraryGt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::operator()(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >) const"
 
     test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityEclEOKNS1_3PixE" \
+	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const&&) const"
 
     test_demangling_exact "gnu: __ne__FPvRCQ2t4List1Z10VHDLEntity3Pix" \
 	"operator!=(void *, List<VHDLEntity>::Pix const &)"
@@ -457,6 +485,8 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4List1Z10VHDLEntityRCt4List1Z10VHDLEntity" \
 	"List<VHDLEntity>::List(List<VHDLEntity> const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityEC4EOKS1_" \
+	"List<VHDLEntity>::List(List<VHDLEntity> const&&)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(void)"
@@ -466,12 +496,18 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+    test_demangling_exact "gnu-v3: _ZN4PixXI11VHDLLibrary14VHDLLibraryRep4ListI10VHDLEntityEEC2EOKS5_" \
+	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const&&)"
 
     test_demangling_exact "gnu: nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const"
+    test_demangling_exact "gnu-v3: _ZNK11VHDLLibrary5nextEEO4PixXIS_14VHDLLibraryRep4ListI10VHDLEntityEE" \
+	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >&&) const"
 
     test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityRQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::next(List<VHDLEntity>::Pix &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityE4nextEONS1_3PixE" \
+	"List<VHDLEntity>::next(List<VHDLEntity>::Pix&&) const"
 
     test_demangling_exact "gnu: _GLOBAL_\$D\$set" "global destructors keyed to set"
 
diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
index 5c782a4..f9519ff 100644
--- a/gdb/testsuite/gdb.cp/overload.cc
+++ b/gdb/testsuite/gdb.cp/overload.cc
@@ -1,10 +1,17 @@
 #include <stddef.h>
+#include <utility>
+
+class foo;
+
+typedef foo &foo_lval_ref;
+typedef foo &&foo_rval_ref;
 
 class foo {
 public:
   foo  (int);
   foo  (int, const char *);
-  foo  (foo&);
+  foo  (foo_lval_ref);
+  foo  (foo_rval_ref);
   ~foo ();
   void foofunc (int);
   void foofunc (int, signed char *);
@@ -27,6 +34,9 @@ int overload1arg (double);
 int overload1arg (int*);
 int overload1arg (void*);
 
+int overload1arg (foo_lval_ref);
+int overload1arg (foo_rval_ref);
+
 int overloadfnarg (void);
 int overloadfnarg (int);
 int overloadfnarg (int, int (*) (int));
@@ -114,6 +124,7 @@ int main ()
     double arg12 = 200.0;
     int arg13 = 200;
     char arg14 = 'a';
+    foo arg15(5);
 
     A a;
     B b;
@@ -152,7 +163,8 @@ int main ()
 
 foo::foo  (int i)                  { ifoo = i; ccpfoo = NULL; }
 foo::foo  (int i, const char *ccp) { ifoo = i; ccpfoo = ccp; }
-foo::foo  (foo& afoo)              { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::foo  (foo_lval_ref afoo)      { ifoo = afoo.ifoo; ccpfoo = afoo.ccpfoo;}
+foo::foo  (foo_rval_ref afoo)      { ifoo = std::move(afoo.ifoo); ccpfoo = std::move (afoo.ccpfoo); }
 foo::~foo ()                       {}
 
 
@@ -172,6 +184,8 @@ int foo::overload1arg (float arg)           { arg = 0; return 11;}
 int foo::overload1arg (double arg)          { arg = 0; return 12;}
 int foo::overload1arg (int* arg)            { arg = 0; return 13;}
 int foo::overload1arg (void* arg)           { arg = 0; return 14;}
+int foo::overload1arg (foo_lval_ref arg)           { return 15; }
+int foo::overload1arg (foo_rval_ref arg)           { return 16; }
 
 /* Test to see that we can explicitly request overloaded functions
    with function pointers in the prototype. */
diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
index 0cfa638..aefac18 100644
--- a/gdb/testsuite/gdb.cp/overload.exp
+++ b/gdb/testsuite/gdb.cp/overload.exp
@@ -28,7 +28,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -53,7 +54,8 @@ gdb_test "up" ".*main.*" "up from marker1"
 set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
 set re_fields	"int ifoo;${ws}const char ?\\* ?ccpfoo;"
 set XX_fields  	"int ifoo;${ws}char ?\\* ?ccpfoo;"
-set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo ?&\\);"
+set re_ctor	"foo\\(int\\);${ws}foo\\(int, (char const|const char) ?\\*\\);${ws}foo\\(foo_lval_ref\\);"
+append re_ctor  "${ws}foo\\(foo_rval_ref\\);"
 set re_dtor	"~foo\\((void|)\\);"
 set XX_dtor	"~foo\\(int\\);"
 set re_methods	                  "void foofunc\\(int\\);"
@@ -72,6 +74,8 @@ set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int \\*\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(void \\*\\);"
+append re_methods "${ws}int overload1arg\\(foo_lval_ref\\);"
+append re_methods "${ws}int overload1arg\\(foo_rval_ref\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\(int, int ?\\(\\*\\) ?\\(int\\)\\);"
@@ -254,6 +258,14 @@ gdb_test "print foo_instance1.overload1arg(&arg14)" \
     "\\$\[0-9\]+ = 14" \
     "print call overloaded func char\\* arg"
 
+gdb_test "print foo_instance1.overload1arg(arg15)" \
+    "\\$\[0-9\]+ = 15" \
+    "print call overloaded func foo & arg"
+
+gdb_test "print foo_instance1.overload1arg(static_cast<foo&&>(arg15))" \
+    "\\$\[0-9\]+ = 16" \
+    "print call overloaded func foo && arg"
+
 gdb_test "print bar(a)" "= 11"
 gdb_test "print bar(b)" "= 22"
 gdb_test "print bar(c)" "= 22"
diff --git a/gdb/testsuite/gdb.cp/ref-params.cc b/gdb/testsuite/gdb.cp/ref-params.cc
index 0f7e125..eb46a99 100644
--- a/gdb/testsuite/gdb.cp/ref-params.cc
+++ b/gdb/testsuite/gdb.cp/ref-params.cc
@@ -17,6 +17,8 @@
 
 /* Author: Paul N. Hilfinger, AdaCore Inc. */
 
+#include <utility>
+
 struct Parent {
   Parent (int id0) : id(id0) { }
   int id;
@@ -31,11 +33,21 @@ int f1(Parent& R)
   return R.id;			/* Set breakpoint marker3 here.  */
 }
 
+int f1(Parent&& R)
+{
+  return R.id;			/* Set breakpoint marker5 here.  */
+}
+
 int f2(Child& C)
 {
   return f1(C);			/* Set breakpoint marker2 here.  */
 }
 
+int f2(Child&& C)
+{
+  return f1(std::move(C));                 /* Set breakpoint marker4 here.  */
+}
+
 struct OtherParent {
   OtherParent (int other_id0) : other_id(other_id0) { }
   int other_id;
@@ -50,11 +62,21 @@ int mf1(OtherParent& R)
   return R.other_id;
 }
 
+int mf1(OtherParent&& R)
+{
+  return R.other_id;
+}
+
 int mf2(MultiChild& C)
 {
   return mf1(C);
 }
 
+int mf2(MultiChild&& C)
+{
+  return mf1(C);
+}
+
 int main(void) 
 {
   Child Q(42);
@@ -62,8 +84,13 @@ int main(void)
 
   /* Set breakpoint marker1 here.  */
 
+  f1(Q);
+  f1(QR);
+  f1(Child(42));
+
   f2(Q);
   f2(QR);
+  f2(Child(42));
 
   MultiChild MQ(53);
   MultiChild& MQR = MQ;
diff --git a/gdb/testsuite/gdb.cp/ref-params.exp b/gdb/testsuite/gdb.cp/ref-params.exp
index 4531602..ce943b8 100644
--- a/gdb/testsuite/gdb.cp/ref-params.exp
+++ b/gdb/testsuite/gdb.cp/ref-params.exp
@@ -24,7 +24,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[build_executable $testfile.exp $testfile $srcfile {debug c++}] == 1} {
+if {[build_executable $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}] == 1} {
     return -1
 }
 
@@ -48,15 +49,28 @@ gdb_start_again "marker1 here"
 gdb_test "print f1(QR)" ".* = 42.*" "print value of f1 on (Child&) in main"
 
 gdb_start_again "marker1 here"
+gdb_test "print f1(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f1 on (Child&&) in main"
+
+gdb_start_again "marker1 here"
 gdb_test "print f2(QR)" ".* = 42.*" "print value of f2 on (Child&) in main"
 
+gdb_start_again "marker1 here"
+gdb_test "print f2(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f2 on (Child&&) in main"
+
 gdb_start_again "marker2 here"
 gdb_test "print C" ".*id = 42.*" "print value of Child& in f2"
 gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child& in f2"
 
+gdb_start_again "marker4 here"
+gdb_test "print C" ".*id = 42.*" "print value of Child&& in f2"
+gdb_test "print f1(C)" ".* = 42.*" "print value of f1 on Child&& in f2"
+
 gdb_start_again "marker3 here"
 gdb_test "print R" ".*id = 42.*" "print value of Parent& in f1"
 
+gdb_start_again "marker5 here"
+gdb_test "print R" ".*id = 42.*" "print value of Parent&& in f1"
+
 gdb_start_again "breakpoint MQ here"
 gdb_test "print f1(MQ)" ".* = 53"
 gdb_test "print mf1(MQ)" ".* = 106"
@@ -64,3 +78,8 @@ gdb_test "print mf2(MQ)" ".* = 106"
 gdb_test "print f1(MQR)" ".* = 53"
 gdb_test "print mf1(MQR)" ".* = 106"
 gdb_test "print mf2(MQR)" ".* = 106"
+gdb_test "print f1(static_cast<MultiChild&&>(MQ))" ".* = 53"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf1(static_cast<MultiChild&&>(MQ))" ".* = 106"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf2(static_cast<MultiChild&&>(MQ))" ".* = 106"
diff --git a/gdb/testsuite/gdb.cp/ref-types.cc b/gdb/testsuite/gdb.cp/ref-types.cc
index 2c124a9..dafec19 100644
--- a/gdb/testsuite/gdb.cp/ref-types.cc
+++ b/gdb/testsuite/gdb.cp/ref-types.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 int main2(void);
 
 void marker1 (void)
@@ -39,6 +41,18 @@ int main(void)
     as[2] = 2;
     as[3] = 3;
 
+    short t = -1;
+    short *pt;
+    short &&rrt = std::move(t);
+    pt = &rrt;
+    short *&&rrpt = std::move(pt);
+    short at[4];
+    at[0] = 0;
+    at[1] = 1;
+    at[2] = 2;
+    at[3] = 3;
+    short (&&rrat)[4] = std::move(at);
+
     marker1();
 
     main2();
@@ -66,15 +80,25 @@ int main2(void)
     float F;
     double D;
     char &rC = C;
+    char &&rrC = 'A';
     unsigned char &rUC = UC;
+    unsigned char &&rrUC = 21;
     short &rS = S;
+    short &&rrS = -14;
     unsigned short &rUS = US;
+    unsigned short &&rrUS = 7;
     int &rI = I;
+    int &&rrI = 102;
     unsigned int &rUI = UI;
+    unsigned int &&rrUI = 1002;
     long &rL = L;
+    long &&rrL = -234;
     unsigned long &rUL = UL;
+    unsigned long &&rrUL = 234;
     float &rF = F;
+    float &&rrF = 1.25E10;
     double &rD = D;
+    double &&rrD = -1.375E-123;
     C = 'A';
     UC = 21;
     S = -14;
diff --git a/gdb/testsuite/gdb.cp/ref-types.exp b/gdb/testsuite/gdb.cp/ref-types.exp
index 3b557f9..682646a 100644
--- a/gdb/testsuite/gdb.cp/ref-types.exp
+++ b/gdb/testsuite/gdb.cp/ref-types.exp
@@ -24,7 +24,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -127,6 +128,35 @@ gdb_test "print ras\[1\]" ".\[0-9\]* = 1" "print value of ras\[1\]"
 gdb_test "print ras\[2\]" ".\[0-9\]* = 2" "print value of ras\[2\]"
 gdb_test "print ras\[3\]" ".\[0-9\]* = 3" "print value of ras\[3\]"
 
+# rvalue reference tests
+
+gdb_test_multiple "print rrt" "print value of rrt" {
+    -re ".\[0-9\]* = \\(short( int)? &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
+}
+
+gdb_test "ptype rrt" "type = short( int)? &&" "ptype rrt"
+
+gdb_test "print *rrpt" ".$decimal = -1" "print value of *rrpt"
+
+# gdb had a bug about dereferencing a pointer type
+# that would lead to wrong results
+# if we try to examine memory at pointer value.
+
+gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
+
+gdb_test "ptype rrpt" "type = short( int)? \\*&&" "ptype rrpt"
+
+gdb_test "print rrat\[0\]" ".$decimal = 0" "print value of rrat\[0\]"
+
+gdb_test "ptype rrat" "type = short( int)? \\\(&&\\\)\\\[4\\\]" "ptype rrat"
+
+gdb_test "print rrat\[1\]" ".$decimal = 1" "print value of rrat\[1\]"
+gdb_test "print rrat\[2\]" ".$decimal = 2" "print value of rrat\[2\]"
+gdb_test "print rrat\[3\]" ".$decimal = 3" "print value of rrat\[3\]"
+
 
 if ![runto 'f'] then {
     perror "couldn't run to f"
@@ -270,3 +300,63 @@ gdb_test "print rD" \
     ".\[0-9\]* = \\(double &\\) @$hex: -1.375e-123.*" \
     "print value of rD"
 
+#
+# test rvalue reference types
+#
+
+gdb_test "ptype rrC" "type = char &&"
+
+gdb_test "ptype rrUC" "type = unsigned char &&"
+
+gdb_test "ptype rrS" "type = short( int)? &&" "ptype rrS"
+
+gdb_test "ptype rrUS" "type = unsigned short( int)? &&" "ptype rrUS"
+
+gdb_test "ptype rrI" "type = int &&"
+
+gdb_test "ptype rrUI" "type = unsigned int &&"
+
+gdb_test "ptype rrL" "type = long( int)? &&" "ptype rrL"
+
+gdb_test "ptype rrUL" "type = unsigned long( int)? &&" "ptype rrUL"
+
+gdb_test "ptype rrF" "type = float &&"
+
+gdb_test "ptype rrD" "type = double &&"
+
+gdb_test "print rrC" "$decimal = \\(char &&\\) @$hex: 65 \'A\'" \
+    "print value of rrC"
+
+gdb_test "print rrUC" \
+    "$decimal = \\(unsigned char &&\\) @$hex: 21 \'.025\'" \
+    "print value of rrUC"
+
+gdb_test "print rrS" "$decimal = \\(short( int)? &&\\) @$hex: -14" \
+                  "print value of rrS"
+
+gdb_test "print rrUS" \
+         "$decimal = \\(unsigned short( int)? &&\\) @$hex: 7" \
+         "print value of rrUS"
+
+gdb_test "print rrI" "$decimal = \\(int &&\\) @$hex: 102" \
+       "print value of rrI"
+
+gdb_test "print rrUI" \
+    "$decimal = \\(unsigned int &&\\) @$hex: 1002" \
+        "print value of rrUI"
+
+gdb_test "print rrL" \
+       "$decimal = \\(long( int)? &&\\) @$hex: -234" \
+         "print value of rrL"
+
+gdb_test "print rrUL" \
+    "$decimal = \\((unsigned long|long unsigned int)? &&\\) @$hex: 234" \
+    "print value of rrUL"
+
+gdb_test "print rrF" \
+    "$decimal = \\(float &&\\) @$hex: 1.2${decimal}e\\+0?10.*" \
+    "print value of rrF"
+
+gdb_test "print rrD" \
+    "$decimal = \\(double &&\\) @$hex: -1.375e-123.*" \
+    "print value of rrD"
diff --git a/gdb/testsuite/gdb.python/py-value-cc.cc b/gdb/testsuite/gdb.python/py-value-cc.cc
index de819d7..188c4fa 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.cc
+++ b/gdb/testsuite/gdb.python/py-value-cc.cc
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <utility>
+
 class A {
  public:
   int operator+ (const int a1);
@@ -60,8 +62,10 @@ func (const A &a)
 {
   int val = 10;
   int &int_ref = val;
+  int &&int_rref = std::move(val);
   int_ptr ptr = &val;
   int_ptr &int_ptr_ref = ptr;
+  int_ptr &&int_ptr_rref = std::move(ptr);
 
   B b;
   B b1;
diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp
index d7c5e0b..1e48ab6 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.exp
+++ b/gdb/testsuite/gdb.python/py-value-cc.exp
@@ -20,7 +20,8 @@ if { [skip_cplus_tests] } { continue }
 
 standard_testfile .cc
 
-if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
     return -1
 }
 
@@ -39,11 +40,18 @@ gdb_test "python print (str(gdb.parse_and_eval(\"a\").referenced_value().type))"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ref\").type))" "int &"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ref\").referenced_value().type))" "int"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ref\").referenced_value()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").type))" "int &&"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").referenced_value().type))" "int"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").referenced_value()))" "10"
 
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").dereference().type))" "int"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().type))" "int_ptr"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().dereference()))" "10"
 gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().referenced_value()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").dereference().type))" "int"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().type))" "int_ptr"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().dereference()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().referenced_value()))" "10"
 
 # Tests for gdb.Value[gdb.Field]
 gdb_test_no_output "python b = gdb.parse_and_eval('b')" "init b"
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (7 preceding siblings ...)
  2016-03-21 21:03       ` [PATCH v4 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-03-21 21:03       ` Artemiy Volkov
  2016-03-21 21:03       ` [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
                         ` (3 subsequent siblings)
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:03 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch fixes demangling of names containing rvalue reference typenames by
handling DEMANGLE_COMPONENT_RVALUE_REFERENCE demangle component.

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * cp-name-parser.y (ptr_operator): Handle the '&&' token in
    typename.
    * cp-support.c (replace_typedefs): Handle
    DEMANGLE_COMPONENT_RVALUE_REFERENCE.
    * python/py-type.c (typy_lookup_type): Likewise.
---
 gdb/cp-name-parser.y | 4 ++++
 gdb/cp-support.c     | 1 +
 gdb/python/py-type.c | 4 ++++
 3 files changed, 9 insertions(+)

diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index c6a5c34..33fdcea 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -769,6 +769,10 @@ ptr_operator	:	'*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
 			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
 			  $$.last = &d_left ($$.comp); }
+		|	ANDAND
+			{ $$.comp = make_empty (DEMANGLE_COMPONENT_RVALUE_REFERENCE);
+			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+			  $$.last = &d_left ($$.comp); }
 		|	nested_name '*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
 			  $$.comp->u.s_binary.left = $1.comp;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index a71c6ad..af891da 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -520,6 +520,7 @@ replace_typedefs (struct demangle_parse_info *info,
 	case DEMANGLE_COMPONENT_RESTRICT_THIS:
 	case DEMANGLE_COMPONENT_POINTER:
 	case DEMANGLE_COMPONENT_REFERENCE:
+	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
 	  replace_typedefs (info, d_left (ret_comp), finder, data);
 	  break;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 6103a2b..4ec920e 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -811,6 +811,7 @@ typy_lookup_type (struct demangle_component *demangled,
 
   if (demangled_type == DEMANGLE_COMPONENT_POINTER
       || demangled_type == DEMANGLE_COMPONENT_REFERENCE
+      || demangled_type == DEMANGLE_COMPONENT_RVALUE_REFERENCE
       || demangled_type == DEMANGLE_COMPONENT_CONST
       || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
     {
@@ -829,6 +830,9 @@ typy_lookup_type (struct demangle_component *demangled,
 	    case DEMANGLE_COMPONENT_REFERENCE:
 	      rtype = lookup_lvalue_reference_type (type);
 	      break;
+	    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+	      rtype = lookup_rvalue_reference_type (type);
+	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
 	      break;
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (8 preceding siblings ...)
  2016-03-21 21:03       ` [PATCH v4 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2016-03-21 21:03       ` Artemiy Volkov
  2016-03-31 20:37         ` Keith Seitz
  2016-03-21 21:15       ` [PATCH v4 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
                         ` (2 subsequent siblings)
  12 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:03 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

In almost all contexts (except for overload resolution rules and expression
semantics), lvalue and rvalue references are equivalent. That means that in all
but these cases we can replace a TYPE_CODE_REF check to a TYPE_IS_REFERENCE
check and, for switch statements, add a case label for a rvalue reference type
next to a case label for an lvalue reference type. This patch does exactly
that.

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * aarch64-tdep.c (aarch64_type_align)
    (aarch64_extract_return_value, aarch64_store_return_value): Change
    lvalue reference type checks to general reference type checks.
    * amd64-tdep.c (amd64_classify): Likewise.
    * amd64-windows-tdep.c (amd64_windows_passed_by_integer_register):
    Likewise.
    * arm-tdep.c (arm_type_align, arm_extract_return_value)
    (arm_store_return_value): Likewise.
    * ax-gdb.c (gen_fetch, gen_cast): Likewise.
    * c-typeprint.c (c_print_type): Likewise.
    * c-varobj.c (adjust_value_for_child_access, c_value_of_variable)
    (cplus_number_of_children, cplus_describe_child): Likewise.
    * compile/compile-c-symbols.c (generate_vla_size): Likewise.
    * completer.c (expression_completer): Likewise.
    * cp-support.c (make_symbol_overload_list_adl_namespace):
    Likewise.
    * darwin-nat-info.c (info_mach_region_command): Likewise.
    * dwarf2loc.c (entry_data_value_coerce_ref)
    (value_of_dwarf_reg_entry): Likewise.
    * eval.c (ptrmath_type_p, evaluate_subexp_standard)
    (evaluate_subexp_for_address, evaluate_subexp_for_sizeof):
    Likewise.
    * findvar.c (extract_typed_address, store_typed_address):
    Likewise.
    * gdbtypes.c (rank_one_type): Likewise.
    * hppa-tdep.c (hppa64_integral_or_pointer_p): Likewise.
    * infcall.c (value_arg_coerce): Likewise.
    * language.c (pointer_type): Likewise.
    * m32c-tdep.c (m32c_reg_arg_type, m32c_m16c_address_to_pointer):
    Likewise.
    * m88k-tdep.c (m88k_integral_or_pointer_p): Likewise.
    * mn10300-tdep.c (mn10300_type_align): Likewise.
    * msp430-tdep.c (msp430_push_dummy_call): Likewise.
    * ppc-sysv-tdep.c (do_ppc_sysv_return_value)
    (ppc64_sysv_abi_push_param, ppc64_sysv_abi_return_value):
    Likewise.
    * printcmd.c (print_formatted, x_command): Likewise.
    * python/py-type.c (typy_get_composite, typy_template_argument):
    Likewise.
    * python/py-value.c (valpy_referenced_value)
    (valpy_get_dynamic_type, value_has_field): Likewise.
    * s390-linux-tdep.c (s390_function_arg_integer): Likewise.
    * sparc-tdep.c (sparc_integral_or_pointer_p): Likewise.
    * sparc64-tdep.c (sparc64_integral_or_pointer_p): Likewise.
    * spu-tdep.c (spu_scalar_value_p): Likewise.
    * symtab.c (lookup_symbol_aux): Likewise.
    * typeprint.c (whatis_exp, print_type_scalar): Likewise.
    * valarith.c (binop_types_user_defined_p, unop_user_defined_p):
    Likewise.
    * valops.c (value_cast_pointers, value_cast)
    (value_reinterpret_cast, value_dynamic_cast, value_addr, typecmp)
    (value_struct_elt, value_struct_elt_bitpos)
    (value_find_oload_method_list, find_overload_match)
    (value_rtti_indirect_type): Likewise.
    * valprint.c (val_print_scalar_type_p, generic_val_print):
    Likewise.
    * value.c (value_actual_type, value_as_address, unpack_long)
    (pack_long, pack_unsigned_long, coerce_ref_if_computed)
    (coerce_ref): Likewise.
    * varobj.c (varobj_get_value_type): Likewise.
---
 gdb/aarch64-tdep.c              |  5 +++--
 gdb/amd64-tdep.c                |  2 +-
 gdb/amd64-windows-tdep.c        |  1 +
 gdb/arm-tdep.c                  |  5 +++--
 gdb/ax-gdb.c                    |  2 ++
 gdb/c-varobj.c                  | 10 ++++-----
 gdb/compile/compile-c-symbols.c |  2 +-
 gdb/completer.c                 |  3 +--
 gdb/cp-support.c                |  2 +-
 gdb/darwin-nat-info.c           |  2 +-
 gdb/dwarf2loc.c                 |  4 ++--
 gdb/eval.c                      | 14 ++++++------
 gdb/findvar.c                   |  6 ++----
 gdb/gdbtypes.c                  |  5 +++--
 gdb/hppa-tdep.c                 |  1 +
 gdb/infcall.c                   |  3 ++-
 gdb/language.c                  |  3 +--
 gdb/m32c-tdep.c                 |  8 +++----
 gdb/m88k-tdep.c                 |  1 +
 gdb/mn10300-tdep.c              |  1 +
 gdb/msp430-tdep.c               |  2 +-
 gdb/ppc-sysv-tdep.c             |  7 +++---
 gdb/printcmd.c                  |  2 +-
 gdb/python/py-type.c            |  5 ++---
 gdb/python/py-value.c           |  6 +++---
 gdb/s390-linux-tdep.c           |  2 +-
 gdb/sparc-tdep.c                |  1 +
 gdb/sparc64-tdep.c              |  1 +
 gdb/spu-tdep.c                  |  1 +
 gdb/symtab.c                    |  3 +--
 gdb/typeprint.c                 |  4 ++--
 gdb/valarith.c                  |  6 +++---
 gdb/valops.c                    | 47 ++++++++++++++++++-----------------------
 gdb/valprint.c                  |  5 +++--
 gdb/value.c                     | 12 ++++++-----
 gdb/varobj.c                    |  2 +-
 36 files changed, 94 insertions(+), 92 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 77155ef..b54f14e 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -890,6 +890,7 @@ aarch64_type_align (struct type *t)
     case TYPE_CODE_RANGE:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -1613,7 +1614,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the the type is a plain integer, then the access is
@@ -1754,7 +1755,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index a62efde..4b56202 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -672,7 +672,7 @@ amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_CHAR
-       || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
+       || code == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
       && (len == 1 || len == 2 || len == 4 || len == 8))
     theclass[0] = AMD64_INTEGER;
 
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index e05502e..6ae594d 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -55,6 +55,7 @@ amd64_windows_passed_by_integer_register (struct type *type)
       case TYPE_CODE_CHAR:
       case TYPE_CODE_PTR:
       case TYPE_CODE_REF:
+      case TYPE_CODE_RVALUE_REF:
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
 	return (TYPE_LENGTH (type) == 1
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 54a21ef..55dbad1 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3236,6 +3236,7 @@ arm_type_align (struct type *t)
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -7792,7 +7793,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the type is a plain integer, then the access is
@@ -7997,7 +7998,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= 4)
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 7c6cb64..7ec01e7 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -491,6 +491,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
@@ -1001,6 +1002,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* It's implementation-defined, and I'll bet this is what GCC
          does.  */
       break;
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 48e16f9..f7bdee0 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -78,7 +78,7 @@ adjust_value_for_child_access (struct value **value,
      to us, is already supposed to be
      reference-stripped.  */
 
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (*type));
 
   /* Pointers to structures are treated just like
      structures when accessing children.  Don't
@@ -489,7 +489,7 @@ c_value_of_variable (const struct varobj *var,
   struct type *type = get_type (var);
 
   /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
@@ -586,7 +586,7 @@ cplus_number_of_children (const struct varobj *var)
       if (opts.objectprint)
         {
           value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+          lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
 				|| TYPE_CODE (var->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -623,7 +623,7 @@ cplus_number_of_children (const struct varobj *var)
 	  const struct varobj *parent = var->parent;
 
 	  value = parent->value;
-	  lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+	  lookup_actual_type = (TYPE_IS_REFERENCE (parent->type)
 				|| TYPE_CODE (parent->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -728,7 +728,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
   var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
   if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+    lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
 			  || TYPE_CODE (var->type) == TYPE_CODE_PTR);
   value = var->value;
   type = varobj_get_value_type (var);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index dcd530d..c06687f 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -593,7 +593,7 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
diff --git a/gdb/completer.c b/gdb/completer.c
index 5c3b3fc..ec0f65d 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -610,8 +610,7 @@ expression_completer (struct cmd_list_element *ignore,
       for (;;)
 	{
 	  type = check_typedef (type);
-	  if (TYPE_CODE (type) != TYPE_CODE_PTR
-	      && TYPE_CODE (type) != TYPE_CODE_REF)
+	  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
 	    break;
 	  type = TYPE_TARGET_TYPE (type);
 	}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index af891da..1f0b586 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1284,7 +1284,7 @@ make_symbol_overload_list_adl_namespace (struct type *type,
   int i, prefix_len;
 
   while (TYPE_CODE (type) == TYPE_CODE_PTR
-	 || TYPE_CODE (type) == TYPE_CODE_REF
+	 || TYPE_IS_REFERENCE (type)
          || TYPE_CODE (type) == TYPE_CODE_ARRAY
          || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
     {
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 314d265..4b4059a 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -732,7 +732,7 @@ info_mach_region_command (char *exp, int from_tty)
 
   expr = parse_expression (exp);
   val = evaluate_expression (expr);
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (value_type (val)))
     {
       val = value_ind (val);
     }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index ba6ed42..202a8c8 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1337,7 +1337,7 @@ entry_data_value_coerce_ref (const struct value *value)
   struct type *checked_type = check_typedef (value_type (value));
   struct value *target_val;
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (checked_type))
     return NULL;
 
   target_val = (struct value *) value_computed_closure (value);
@@ -1412,7 +1412,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      TYPE_CODE_REF with non-entry data value would give current value - not the
      entry value.  */
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+  if (!TYPE_IS_REFERENCE (checked_type)
       || TYPE_TARGET_TYPE (checked_type) == NULL)
     return outer_val;
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 8969f49..a69c69c 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -640,7 +640,7 @@ static int
 ptrmath_type_p (const struct language_defn *lang, struct type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = TYPE_TARGET_TYPE (type);
 
   switch (TYPE_CODE (type))
@@ -2509,7 +2509,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	{
 	  type = check_typedef (value_type (arg1));
 	  if (TYPE_CODE (type) == TYPE_CODE_PTR
-	      || TYPE_CODE (type) == TYPE_CODE_REF
+	      || TYPE_IS_REFERENCE (type)
 	  /* In C you can dereference an array to get the 1st elt.  */
 	      || TYPE_CODE (type) == TYPE_CODE_ARRAY
 	    )
@@ -2787,7 +2787,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	    {
 	      struct type *type = value_type (result);
 
-	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+	      if (!TYPE_IS_REFERENCE (type))
 		{
 		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
@@ -2890,7 +2890,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var)))
 	goto default_case;
 
       (*pos) += 4;
@@ -2929,7 +2929,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 	{
 	  struct type *type = check_typedef (value_type (x));
 
-	  if (TYPE_CODE (type) == TYPE_CODE_REF)
+	  if (TYPE_IS_REFERENCE (type))
 	    return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			       not_lval);
 	  else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
@@ -3019,7 +3019,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = check_typedef (value_type (val));
       if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF
+	  && !TYPE_IS_REFERENCE (type)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
@@ -3091,7 +3091,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
      the size of the referenced type."  */
   type = check_typedef (type);
   if (exp->language_defn->la_language == language_cplus
-      && TYPE_CODE (type) == TYPE_CODE_REF)
+      && (TYPE_IS_REFERENCE (type)))
     type = check_typedef (TYPE_TARGET_TYPE (type));
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a39d897..b9b8d05 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -169,8 +169,7 @@ extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
 CORE_ADDR
 extract_typed_address (const gdb_byte *buf, struct type *type)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("extract_typed_address: "
 		    "type is not a pointer or reference"));
@@ -242,8 +241,7 @@ store_unsigned_integer (gdb_byte *addr, int len,
 void
 store_typed_address (gdb_byte *buf, struct type *type, CORE_ADDR addr)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("store_typed_address: "
 		    "type is not a pointer or reference"));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 391fd28..c721444 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3476,10 +3476,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   /* See through references, since we can almost make non-references
      references.  */
-  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+  if (TYPE_IS_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                        REFERENCE_CONVERSION_BADNESS));
-  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                        REFERENCE_CONVERSION_BADNESS));
   if (overload_debug)
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index ac507e7..afb3b5e 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -902,6 +902,7 @@ hppa64_integral_or_pointer_p (const struct type *type)
       }
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return (TYPE_LENGTH (type) == 8);
     default:
       break;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index ad2512a..5a2a4a7 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -158,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	struct value *new_value;
 
-	if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+	if (TYPE_IS_REFERENCE (arg_type))
 	  return value_cast_pointers (type, arg, 0);
 
 	/* Cast the value to the reference's target type, and then
diff --git a/gdb/language.c b/gdb/language.c
index 78ec422..c1b0526 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -410,8 +410,7 @@ language_info (int quietly)
 int
 pointer_type (struct type *type)
 {
-  return TYPE_CODE (type) == TYPE_CODE_PTR ||
-    TYPE_CODE (type) == TYPE_CODE_REF;
+  return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type);
 }
 
 \f
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 90bd732..49aa3f5 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2031,7 +2031,7 @@ m32c_reg_arg_type (struct type *type)
   return (code == TYPE_CODE_INT
 	  || code == TYPE_CODE_ENUM
 	  || code == TYPE_CODE_PTR
-	  || code == TYPE_CODE_REF
+	  || TYPE_IS_REFERENCE (type)
 	  || code == TYPE_CODE_BOOL
 	  || code == TYPE_CODE_CHAR);
 }
@@ -2453,8 +2453,7 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   enum type_code target_code;
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   target_code = TYPE_CODE (TYPE_TARGET_TYPE (type));
 
@@ -2533,8 +2532,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR ptr;
   enum type_code target_code;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index 1a3c2cd..2a90a3a 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -165,6 +165,7 @@ m88k_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	/* Allow only 32-bit pointers.  */
 	return (TYPE_LENGTH (type) == 4);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 62d4ca1..79f5c85 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -96,6 +96,7 @@ mn10300_type_align (struct type *type)
     case TYPE_CODE_FLT:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type);
 
     case TYPE_CODE_COMPLEX:
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 4042ec3..1b25339 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -769,7 +769,7 @@ msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 		  if (code_model == MSP_LARGE_CODE_MODEL
 		      && (TYPE_CODE (arg_type) == TYPE_CODE_PTR
-		          || TYPE_CODE (arg_type) == TYPE_CODE_REF
+		          || TYPE_IS_REFERENCE (arg_type)
 			  || TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
 			  || TYPE_CODE (arg_type) == TYPE_CODE_UNION))
 		    {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 140d993..20e2a40 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -805,7 +805,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF
+	    || TYPE_IS_REFERENCE (type)
 	    || TYPE_CODE (type) == TYPE_CODE_ENUM)
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -1493,7 +1493,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF)
+	    || TYPE_IS_REFERENCE (type))
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1999,8 +1999,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index f5c4211..8e6a1d8 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1449,7 +1449,7 @@ x_command (char *exp, int from_tty)
 	*exp = 0;
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
-      if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 259bb70..835f1e4 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -486,8 +486,7 @@ typy_get_composite (struct type *type)
 	}
       END_CATCH
 
-      if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF)
+      if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
 	break;
       type = TYPE_TARGET_TYPE (type);
     }
@@ -967,7 +966,7 @@ typy_template_argument (PyObject *self, PyObject *args)
   TRY
     {
       type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type))
 	type = check_typedef (TYPE_TARGET_TYPE (type));
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7802ae0..7a25984 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -217,6 +217,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -358,8 +359,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
 	  struct value *target;
@@ -1020,7 +1020,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index fc57592..bd338a6 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3152,7 +3152,7 @@ s390_function_arg_integer (struct type *type)
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_BOOL
       || code == TYPE_CODE_PTR
-      || code == TYPE_CODE_REF)
+      || TYPE_IS_REFERENCE (type))
     return 1;
 
   return ((code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 863ef8f..9e4b3f3 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -225,6 +225,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 5e8f17d..382fbc5 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -67,6 +67,7 @@ sparc64_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	int len = TYPE_LENGTH (type);
 	gdb_assert (len == 8);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index 8dad5c3..011ce53 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1338,6 +1338,7 @@ spu_scalar_value_p (struct type *type)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type) <= 16;
 
     default:
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e06104b..7da136e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2179,8 +2179,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
 	  /* I'm not really sure that type of this can ever
 	     be typedefed; just be safe.  */
 	  t = check_typedef (t);
-	  if (TYPE_CODE (t) == TYPE_CODE_PTR
-	      || TYPE_CODE (t) == TYPE_CODE_REF)
+	  if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
 	    t = TYPE_TARGET_TYPE (t);
 
 	  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 48a809b..366654e 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -463,8 +463,7 @@ whatis_exp (char *exp, int show)
   get_user_print_options (&opts);
   if (opts.objectprint)
     {
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
         real_type = value_rtti_indirect_type (val, &full, &top, &using_enc);
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -581,6 +580,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_NAMESPACE:
       error (_("internal error: unhandled type in print_type_scalar"));
       break;
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 7959f3b..5ffa659 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -239,11 +239,11 @@ binop_types_user_defined_p (enum exp_opcode op,
     return 0;
 
   type1 = check_typedef (type1);
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
   type2 = check_typedef (type2);
-  if (TYPE_CODE (type2) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
   return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
@@ -277,7 +277,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   if (op == UNOP_ADDR)
     return 0;
   type1 = check_typedef (value_type (arg1));
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
   return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
 }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1f423a0..2f1fca2 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
     {
       struct value *v2;
 
-      if (TYPE_CODE (type2) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type2))
 	v2 = coerce_ref (arg2);
       else
 	v2 = value_ind (arg2);
@@ -360,24 +360,20 @@ value_cast (struct type *type, struct value *arg2)
   if (value_type (arg2) == type)
     return arg2;
 
-  code1 = TYPE_CODE (check_typedef (type));
-
   /* Check if we are casting struct reference to struct reference.  */
-  if (code1 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (type)))
     {
       /* We dereference type; then we recurse and finally
          we generate value of the given reference.  Nothing wrong with 
 	 that.  */
       struct type *t1 = check_typedef (type);
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
-      struct value *val =  value_cast (dereftype, arg2);
+      struct value *val = value_cast (dereftype, arg2);
 
       return value_ref (val, TYPE_CODE (t1));
     }
 
-  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
-
-  if (code2 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (value_type (arg2))))
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
@@ -388,7 +384,7 @@ value_cast (struct type *type, struct value *arg2)
 
   /* You can't cast to a reference type.  See value_cast_pointers
      instead.  */
-  gdb_assert (code1 != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (type));
 
   /* A cast to an undetermined-length array_type, such as 
      (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
@@ -591,8 +587,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
   dest_type = type;
 
   /* If we are casting to a reference type, transform
-     reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V).  */
-  if (TYPE_CODE (real_type) == TYPE_CODE_REF)
+     reinterpret_cast<T&[&]>(V) to *reinterpret_cast<T*>(&V).  */
+  if (TYPE_IS_REFERENCE (real_type))
     {
       is_ref = 1;
       arg = value_addr (arg);
@@ -730,10 +726,10 @@ value_dynamic_cast (struct type *type, struct value *arg)
   struct type *class_type, *rtti_type;
   struct value *result, *tem, *original_arg = arg;
   CORE_ADDR addr;
-  int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
+  int is_ref = TYPE_IS_REFERENCE (resolved_type);
 
   if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
-      && TYPE_CODE (resolved_type) != TYPE_CODE_REF)
+      && !TYPE_IS_REFERENCE (resolved_type))
     error (_("Argument to dynamic_cast must be a pointer or reference type"));
   if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
       && TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
@@ -1465,9 +1461,9 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     {
-      /* Copy the value, but change the type from (T&) to (T*).  We
+      /* Copy the value, but change the type from (T&[&]) to (T*).  We
          keep the same location information, which is efficient, and
          allows &(&X) to get the location containing the reference.  */
       arg2 = value_copy (arg1);
@@ -1716,7 +1712,7 @@ typecmp (int staticp, int varargs, int nargs,
       tt1 = check_typedef (t1[i].type);
       tt2 = check_typedef (value_type (t2[i]));
 
-      if (TYPE_CODE (tt1) == TYPE_CODE_REF
+      if ((TYPE_IS_REFERENCE (tt1))
 	  /* We should be doing hairy argument matching, as below.  */
 	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
 	      == TYPE_CODE (tt2)))
@@ -1734,14 +1730,13 @@ typecmp (int staticp, int varargs, int nargs,
 	 char *>, and properly access map["hello"], because the
 	 argument to [] will be a reference to a pointer to a char,
 	 and the argument will be a pointer to a char.  */
-      while (TYPE_CODE(tt1) == TYPE_CODE_REF
-	     || TYPE_CODE (tt1) == TYPE_CODE_PTR)
+      while (TYPE_IS_REFERENCE (tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR)
 	{
 	  tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
 	}
       while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
 	     || TYPE_CODE(tt2) == TYPE_CODE_PTR
-	     || TYPE_CODE(tt2) == TYPE_CODE_REF)
+	     || TYPE_IS_REFERENCE (tt2))
 	{
 	  tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
 	}
@@ -2133,7 +2128,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
   /* Follow pointers until we get to a non-pointer.  */
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2222,7 +2217,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
 
   t = check_typedef (value_type (*argp));
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
@@ -2383,7 +2378,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
   t = check_typedef (value_type (*argp));
 
   /* Code snarfed from value_struct_elt.  */
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2794,7 +2789,7 @@ find_overload_match (struct value **args, int nargs,
 
       if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
 	  && (TYPE_CODE (objtype) == TYPE_CODE_PTR
-	      || TYPE_CODE (objtype) == TYPE_CODE_REF))
+	      || TYPE_IS_REFERENCE (objtype)))
 	{
 	  temp = value_addr (temp);
 	}
@@ -3591,7 +3586,7 @@ value_rtti_indirect_type (struct value *v, int *full,
 
   type = value_type (v);
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     target = coerce_ref (v);
   else if (TYPE_CODE (type) == TYPE_CODE_PTR)
     {
@@ -3624,8 +3619,8 @@ value_rtti_indirect_type (struct value *v, int *full,
       target_type = value_type (target);
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_lvalue_reference_type (real_type);
+      if (TYPE_IS_REFERENCE (type))
+        real_type = lookup_reference_type (real_type, TYPE_CODE (type));
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 720942b..9f7f43f 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -280,7 +280,7 @@ int
 val_print_scalar_type_p (struct type *type)
 {
   type = check_typedef (type);
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     {
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
@@ -482,7 +482,7 @@ generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
 			      original_value, options, 0, stream);
 }
 
-/* generic_val_print helper for TYPE_CODE_REF.  */
+/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */
 
 static void
 generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
@@ -865,6 +865,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
 			     original_value, options);
       break;
diff --git a/gdb/value.c b/gdb/value.c
index 738b2b2..1307a37 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1202,8 +1202,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
     {
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
 	 fetch its rtti type.  */
-      if ((TYPE_CODE (result) == TYPE_CODE_PTR
-	  || TYPE_CODE (result) == TYPE_CODE_REF)
+      if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result))
 	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
 	     == TYPE_CODE_STRUCT)
         {
@@ -2855,7 +2854,7 @@ value_as_address (struct value *val)
      ABI-specific code is a more reasonable place to handle it.  */
 
   if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && !TYPE_IS_REFERENCE (value_type (val))
       && gdbarch_integer_to_address_p (gdbarch))
     return gdbarch_integer_to_address (gdbarch, value_type (val),
 				       value_contents (val));
@@ -2912,6 +2911,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
          whether we want this to be true eventually.  */
       return extract_typed_address (valaddr, type);
@@ -3501,6 +3501,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3537,6 +3538,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3744,7 +3746,7 @@ coerce_ref_if_computed (const struct value *arg)
 {
   const struct lval_funcs *funcs;
 
-  if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (check_typedef (value_type (arg))))
     return NULL;
 
   if (value_lval_const (arg) != lval_computed)
@@ -3786,7 +3788,7 @@ coerce_ref (struct value *arg)
   if (retval)
     return retval;
 
-  if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (value_type_arg_tmp))
     return arg;
 
   enc_type = check_typedef (value_enclosing_type (arg));
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 6f56cba..2917432 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2176,7 +2176,7 @@ varobj_get_value_type (const struct varobj *var)
 
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = get_target_type (type);
 
   type = check_typedef (type);
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v4 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (9 preceding siblings ...)
  2016-03-21 21:03       ` [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-03-21 21:15       ` Artemiy Volkov
  2016-03-31 20:35       ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
  12 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-03-21 21:15 UTC (permalink / raw)
  To: gdb-patches; +Cc: keiths, palves, Artemiy Volkov

This patch introduces changes to rank_one_type() dealing with ranking an rvalue
reference type when selecting a best viable function from a set of candidate
functions. The 4 new added rules for rvalue references are:

1) An rvalue argument cannot be bound to a non-const lvalue reference parameter
and an lvalue argument cannot be bound to an rvalue reference parameter.
[C++11 13.3.3.1.4p3]

2) If a conversion to one type of reference is an identity conversion, and a
conversion to the second type of reference is a non-identity conversion, choose
the first type. [C++11 13.3.3.2p3]

3) An rvalue should be first tried to bind to an rvalue reference, and then to
an lvalue reference. [C++11 13.3.3.2p3]

4) An lvalue reference to a function gets higher priority than an rvalue
reference to a function. [C++11 13.3.3.2p3]

gdb/ChangeLog:

2016-03-21  Artemiy Volkov  <artemiyv@acm.org>

    * gdbtypes.c (rank_one_type): Implement overloading
    resolution rules regarding rvalue references.
---
 gdb/gdbtypes.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index c721444..06c7312 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -58,6 +58,8 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
 const struct rank BOOL_CONVERSION_BADNESS = {3,0};
 const struct rank BASE_CONVERSION_BADNESS = {2,0};
 const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0};
+const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0};
 const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
 const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
 const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
@@ -3465,15 +3467,65 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 {
   struct rank rank = {0,0};
 
-  if (types_equal (parm, arg))
-    return EXACT_MATCH_BADNESS;
-
   /* Resolve typedefs */
   if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
     parm = check_typedef (parm);
   if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
     arg = check_typedef (arg);
 
+  if (value != NULL)
+    {
+      /* An rvalue argument cannot be bound to a non-const lvalue
+         reference parameter...  */
+      if (VALUE_LVAL (value) == not_lval
+          && TYPE_CODE (parm) == TYPE_CODE_REF
+          && !TYPE_CONST (parm->main_type->target_type))
+        return INCOMPATIBLE_TYPE_BADNESS;
+
+      /* ... and an lvalue argument cannot be bound to an rvalue
+         reference parameter.  [C++ 13.3.3.1.4p3]  */
+      if (VALUE_LVAL (value) != not_lval
+          && TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
+        return INCOMPATIBLE_TYPE_BADNESS;
+    }
+
+  if (types_equal (parm, arg))
+    return EXACT_MATCH_BADNESS;
+
+  /* An lvalue reference to a function should get higher priority than an
+     rvalue reference to a function.  */
+
+  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
+      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
+    {
+      return (sum_ranks (rank_one_type (parm,
+              lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
+              DIFFERENT_REFERENCE_TYPE_BADNESS));
+    }
+
+  /* If a conversion to one type of reference is an identity conversion, and a
+     conversion to the second type of reference is a non-identity conversion,
+     choose the first type.  */
+
+  if (value != NULL && TYPE_IS_REFERENCE (parm) && TYPE_IS_REFERENCE (arg)
+     && TYPE_CODE (parm) != TYPE_CODE (arg))
+    {
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
+              TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
+    }
+
+  /* An rvalue should be first tried to bind to an rvalue reference, and then to
+     an lvalue reference.  */
+
+  if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
+      && VALUE_LVAL (value) == not_lval)
+    {
+      if (TYPE_IS_REFERENCE (arg))
+	arg = TYPE_TARGET_TYPE (arg);
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
+			 LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
+    }
+
   /* See through references, since we can almost make non-references
      references.  */
 
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (10 preceding siblings ...)
  2016-03-21 21:15       ` [PATCH v4 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2016-03-31 20:35       ` Keith Seitz
  2016-04-02  8:48         ` Artemiy Volkov
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
  12 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-03-31 20:35 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

On 03/21/2016 01:59 PM, Artemiy Volkov wrote:
> Hi all,
> 
> this is my fourth take on fixing gdb/14441 which deals with C++0x rvalue
> references.
> 

There are two small nits (see replies in #8 and #9), otherwise, this
series looks ready for a final evaluation by a maintainer.

Since the nits are really minor, I recommend just replying [to my
messages] with corrections on those two specific patches instead of
reposting the entire series.

Thank you for your patch (and patience)!

Keith


^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-03-21 21:02       ` [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-03-31 20:35         ` Keith Seitz
  2016-04-02  8:28           ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-03-31 20:35 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches

One little nit. As I mentioned in #0, I would just reply to this
message, posting the correction.

On 03/21/2016 01:59 PM, Artemiy Volkov wrote:
> diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
> index d70cdd1..17fdfb2 100644
> --- a/gdb/python/py-xmethods.c
> +++ b/gdb/python/py-xmethods.c
> @@ -548,10 +548,10 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
>        if (!types_equal (obj_type, this_ptr))
>  	obj = value_cast (this_ptr, obj);
>      }
> -  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
> +  else if (TYPE_IS_REFERENCE (obj_type))
>      {
> -      struct type *this_ref = lookup_lvalue_reference_type (this_type);
> -
> +      struct type *this_ref
> +        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
>        if (!types_equal (obj_type, this_ref))
>  	obj = value_cast (this_ref, obj);
>      }
> @@ -634,10 +634,10 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
>        if (!types_equal (obj_type, this_ptr))
>  	obj = value_cast (this_ptr, obj);
>      }
> -  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
> +  else if (TYPE_IS_REFERENCE (obj_type))
>      {
> -      struct type *this_ref = lookup_lvalue_reference_type (this_type);
> -
> +      struct type *this_ref
> +        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
>        if (!types_equal (obj_type, this_ref))
>  	obj = value_cast (this_ref, obj);
>      }

Both of the above hunks need to keep the deleted whitespace. We like a
blank line between the (last) variable declaration and the first line of
code:

  else if (TYPE_IS_REFERENCE 9obj_type))
    {
      struct type *this_ref
        = lookup_reference_type (this_type, TYPE_CODE (obj_type));

      if (!types_equal (obj_type, this_ref))
        ...
    }

Keith


^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-03-21 21:03       ` [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-03-31 20:37         ` Keith Seitz
  2016-04-02  8:42           ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Keith Seitz @ 2016-03-31 20:37 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches@sourceware.org ml

One more (very very) small nit; please repost this single patch for
final maintainer review.

On 03/21/2016 01:59 PM, Artemiy Volkov wrote:

> diff --git a/gdb/valops.c b/gdb/valops.c
> index 1f423a0..2f1fca2 100644
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
[snip]
> @@ -1716,7 +1712,7 @@ typecmp (int staticp, int varargs, int nargs,
>        tt1 = check_typedef (t1[i].type);
>        tt2 = check_typedef (value_type (t2[i]));
>  
> -      if (TYPE_CODE (tt1) == TYPE_CODE_REF
> +      if ((TYPE_IS_REFERENCE (tt1))
>  	  /* We should be doing hairy argument matching, as below.  */
>  	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
>  	      == TYPE_CODE (tt2)))

Looks like an extra set of parentheses sneaked in here.

Yup, that's it!

Keith


^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-03-31 20:35         ` Keith Seitz
@ 2016-04-02  8:28           ` Artemiy Volkov
  2016-04-02  8:45             ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-04-02  8:28 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Thu, Mar 31, 2016 at 01:35:37PM -0700, Keith Seitz wrote:

[snip]

> Both of the above hunks need to keep the deleted whitespace. We like a
> blank line between the (last) variable declaration and the first line of
> code:
> 
>   else if (TYPE_IS_REFERENCE 9obj_type))
>     {
>       struct type *this_ref
>         = lookup_reference_type (this_type, TYPE_CODE (obj_type));
> 
>       if (!types_equal (obj_type, this_ref))
>         ...
>     }

OK, see the fix below.

---
 gdb/python/lib/gdb/command/explore.py |  2 +-
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 |  3 +++
 gdb/python/py-xmethods.c              | 10 ++++++----
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/gdb/python/lib/gdb/command/explore.py
b/gdb/python/lib/gdb/command/explore.py
index 6c9f17b..ed25fa6 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,7 +319,6 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
-
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
 
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index c22e8a9..59b7df2 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 4ec920e..259bb70 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 141f180..7802ae0 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -768,6 +768,9 @@ valpy_getitem (PyObject *self, PyObject *key)
          else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
            res_val = value_cast (lookup_lvalue_reference_type
(base_class_type),
                                  tmp);
+         else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+           res_val = value_cast (lookup_rvalue_reference_type
(base_class_type),
+                                 tmp);
          else
            res_val = value_cast (base_class_type, tmp);
        }
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index d70cdd1..debc3a8 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -548,9 +548,10 @@ gdbpy_get_xmethod_result_type (const struct
extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
        obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
        obj = value_cast (this_ref, obj);
@@ -634,9 +635,10 @@ gdbpy_invoke_xmethod (const struct
extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
        obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
        obj = value_cast (this_ref, obj);
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-03-31 20:37         ` Keith Seitz
@ 2016-04-02  8:42           ` Artemiy Volkov
  0 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-04-02  8:42 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches@sourceware.org ml

On Thu, Mar 31, 2016 at 01:36:57PM -0700, Keith Seitz wrote:
> One more (very very) small nit; please repost this single patch for
> final maintainer review.
> 
> On 03/21/2016 01:59 PM, Artemiy Volkov wrote:
> 
> > diff --git a/gdb/valops.c b/gdb/valops.c
> > index 1f423a0..2f1fca2 100644
> > --- a/gdb/valops.c
> > +++ b/gdb/valops.c
> [snip]
> > @@ -1716,7 +1712,7 @@ typecmp (int staticp, int varargs, int nargs,
> >        tt1 = check_typedef (t1[i].type);
> >        tt2 = check_typedef (value_type (t2[i]));
> >  
> > -      if (TYPE_CODE (tt1) == TYPE_CODE_REF
> > +      if ((TYPE_IS_REFERENCE (tt1))
> >  	  /* We should be doing hairy argument matching, as below.  */
> >  	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
> >  	      == TYPE_CODE (tt2)))
> 
> Looks like an extra set of parentheses sneaked in here.

Fix is below. I have also rebased this one against the current master
branch.

---
 gdb/aarch64-tdep.c              |  5 +++--
 gdb/amd64-tdep.c                |  2 +-
 gdb/amd64-windows-tdep.c        |  1 +
 gdb/arm-tdep.c                  |  5 +++--
 gdb/ax-gdb.c                    |  2 ++
 gdb/c-varobj.c                  | 10 ++++-----
 gdb/compile/compile-c-symbols.c |  2 +-
 gdb/completer.c                 |  3 +--
 gdb/cp-support.c                |  2 +-
 gdb/darwin-nat-info.c           |  2 +-
 gdb/dwarf2loc.c                 |  4 ++--
 gdb/eval.c                      | 14 ++++++------
 gdb/findvar.c                   |  6 ++----
 gdb/gdbtypes.c                  |  5 +++--
 gdb/hppa-tdep.c                 |  1 +
 gdb/infcall.c                   |  3 ++-
 gdb/language.c                  |  3 +--
 gdb/m32c-tdep.c                 |  8 +++----
 gdb/m88k-tdep.c                 |  1 +
 gdb/mn10300-tdep.c              |  1 +
 gdb/msp430-tdep.c               |  2 +-
 gdb/ppc-sysv-tdep.c             |  7 +++---
 gdb/printcmd.c                  |  2 +-
 gdb/python/py-type.c            |  5 ++---
 gdb/python/py-value.c           |  6 +++---
 gdb/s390-linux-tdep.c           |  2 +-
 gdb/sparc-tdep.c                |  1 +
 gdb/sparc64-tdep.c              |  1 +
 gdb/spu-tdep.c                  |  1 +
 gdb/symtab.c                    |  3 +--
 gdb/typeprint.c                 |  4 ++--
 gdb/valarith.c                  |  6 +++---
 gdb/valops.c                    | 47 ++++++++++++++++++-----------------------
 gdb/valprint.c                  |  5 +++--
 gdb/value.c                     | 12 ++++++-----
 gdb/varobj.c                    |  2 +-
 36 files changed, 94 insertions(+), 92 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 77155ef..b54f14e 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -890,6 +890,7 @@ aarch64_type_align (struct type *t)
     case TYPE_CODE_RANGE:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -1613,7 +1614,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
           || TYPE_CODE (type) == TYPE_CODE_CHAR
           || TYPE_CODE (type) == TYPE_CODE_BOOL
           || TYPE_CODE (type) == TYPE_CODE_PTR
-          || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_IS_REFERENCE (type)
           || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the the type is a plain integer, then the access is
@@ -1754,7 +1755,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
           || TYPE_CODE (type) == TYPE_CODE_CHAR
           || TYPE_CODE (type) == TYPE_CODE_BOOL
           || TYPE_CODE (type) == TYPE_CODE_PTR
-          || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_IS_REFERENCE (type)
           || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index a62efde..4b56202 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -672,7 +672,7 @@ amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_CHAR
-       || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
+       || code == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
       && (len == 1 || len == 2 || len == 4 || len == 8))
     theclass[0] = AMD64_INTEGER;
 
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index e05502e..6ae594d 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -55,6 +55,7 @@ amd64_windows_passed_by_integer_register (struct type *type)
       case TYPE_CODE_CHAR:
       case TYPE_CODE_PTR:
       case TYPE_CODE_REF:
+      case TYPE_CODE_RVALUE_REF:
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
        return (TYPE_LENGTH (type) == 1
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 0412f71..4524ca5 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3347,6 +3347,7 @@ arm_type_align (struct type *t)
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -7903,7 +7904,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
           || TYPE_CODE (type) == TYPE_CODE_CHAR
           || TYPE_CODE (type) == TYPE_CODE_BOOL
           || TYPE_CODE (type) == TYPE_CODE_PTR
-          || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_IS_REFERENCE (type)
           || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the type is a plain integer, then the access is
@@ -8108,7 +8109,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
           || TYPE_CODE (type) == TYPE_CODE_CHAR
           || TYPE_CODE (type) == TYPE_CODE_BOOL
           || TYPE_CODE (type) == TYPE_CODE_PTR
-          || TYPE_CODE (type) == TYPE_CODE_REF
+          || TYPE_IS_REFERENCE (type)
           || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= 4)
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 7c6cb64..7ec01e7 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -491,6 +491,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
@@ -1001,6 +1002,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* It's implementation-defined, and I'll bet this is what GCC
          does.  */
       break;
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 48e16f9..f7bdee0 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -78,7 +78,7 @@ adjust_value_for_child_access (struct value **value,
      to us, is already supposed to be
      reference-stripped.  */
 
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (*type));
 
   /* Pointers to structures are treated just like
      structures when accessing children.  Don't
@@ -489,7 +489,7 @@ c_value_of_variable (const struct varobj *var,
   struct type *type = get_type (var);
 
   /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
@@ -586,7 +586,7 @@ cplus_number_of_children (const struct varobj *var)
       if (opts.objectprint)
         {
           value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+          lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
                                || TYPE_CODE (var->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -623,7 +623,7 @@ cplus_number_of_children (const struct varobj *var)
          const struct varobj *parent = var->parent;
 
          value = parent->value;
-         lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+         lookup_actual_type = (TYPE_IS_REFERENCE (parent->type)
                                || TYPE_CODE (parent->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -728,7 +728,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
   var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
   if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+    lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
                          || TYPE_CODE (var->type) == TYPE_CODE_PTR);
   value = var->value;
   type = varobj_get_value_type (var);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index dcd530d..c06687f 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -593,7 +593,7 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
diff --git a/gdb/completer.c b/gdb/completer.c
index 5c3b3fc..ec0f65d 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -610,8 +610,7 @@ expression_completer (struct cmd_list_element *ignore,
       for (;;)
        {
          type = check_typedef (type);
-         if (TYPE_CODE (type) != TYPE_CODE_PTR
-             && TYPE_CODE (type) != TYPE_CODE_REF)
+         if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
            break;
          type = TYPE_TARGET_TYPE (type);
        }
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index af891da..1f0b586 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1284,7 +1284,7 @@ make_symbol_overload_list_adl_namespace (struct type *type,
   int i, prefix_len;
 
   while (TYPE_CODE (type) == TYPE_CODE_PTR
-        || TYPE_CODE (type) == TYPE_CODE_REF
+        || TYPE_IS_REFERENCE (type)
          || TYPE_CODE (type) == TYPE_CODE_ARRAY
          || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
     {
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 314d265..4b4059a 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -732,7 +732,7 @@ info_mach_region_command (char *exp, int from_tty)
 
   expr = parse_expression (exp);
   val = evaluate_expression (expr);
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (value_type (val)))
     {
       val = value_ind (val);
     }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index ba6ed42..202a8c8 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1337,7 +1337,7 @@ entry_data_value_coerce_ref (const struct value *value)
   struct type *checked_type = check_typedef (value_type (value));
   struct value *target_val;
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (checked_type))
     return NULL;
 
   target_val = (struct value *) value_computed_closure (value);
@@ -1412,7 +1412,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      TYPE_CODE_REF with non-entry data value would give current value - not the
      entry value.  */
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+  if (!TYPE_IS_REFERENCE (checked_type)
       || TYPE_TARGET_TYPE (checked_type) == NULL)
     return outer_val;
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 734203f..e319461 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -640,7 +640,7 @@ static int
 ptrmath_type_p (const struct language_defn *lang, struct type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = TYPE_TARGET_TYPE (type);
 
   switch (TYPE_CODE (type))
@@ -2510,7 +2510,7 @@ evaluate_subexp_standard (struct type *expect_type,
        {
          type = check_typedef (value_type (arg1));
          if (TYPE_CODE (type) == TYPE_CODE_PTR
-             || TYPE_CODE (type) == TYPE_CODE_REF
+             || TYPE_IS_REFERENCE (type)
          /* In C you can dereference an array to get the 1st elt.  */
              || TYPE_CODE (type) == TYPE_CODE_ARRAY
            )
@@ -2788,7 +2788,7 @@ evaluate_subexp_standard (struct type *expect_type,
            {
              struct type *type = value_type (result);
 
-             if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+             if (!TYPE_IS_REFERENCE (type))
                {
                  type = lookup_lvalue_reference_type (type);
                  result = allocate_value (type);
@@ -2891,7 +2891,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var)))
        goto default_case;
 
       (*pos) += 4;
@@ -2930,7 +2930,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
        {
          struct type *type = check_typedef (value_type (x));
 
-         if (TYPE_CODE (type) == TYPE_CODE_REF)
+         if (TYPE_IS_REFERENCE (type))
            return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
                               not_lval);
          else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
@@ -3020,7 +3020,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = check_typedef (value_type (val));
       if (TYPE_CODE (type) != TYPE_CODE_PTR
-         && TYPE_CODE (type) != TYPE_CODE_REF
+         && !TYPE_IS_REFERENCE (type)
          && TYPE_CODE (type) != TYPE_CODE_ARRAY)
        error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
@@ -3092,7 +3092,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
      the size of the referenced type."  */
   type = check_typedef (type);
   if (exp->language_defn->la_language == language_cplus
-      && TYPE_CODE (type) == TYPE_CODE_REF)
+      && (TYPE_IS_REFERENCE (type)))
     type = check_typedef (TYPE_TARGET_TYPE (type));
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a39d897..b9b8d05 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -169,8 +169,7 @@ extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
 CORE_ADDR
 extract_typed_address (const gdb_byte *buf, struct type *type)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
                    _("extract_typed_address: "
                    "type is not a pointer or reference"));
@@ -242,8 +241,7 @@ store_unsigned_integer (gdb_byte *addr, int len,
 void
 store_typed_address (gdb_byte *buf, struct type *type, CORE_ADDR addr)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
                    _("store_typed_address: "
                    "type is not a pointer or reference"));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 391fd28..c721444 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3476,10 +3476,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   /* See through references, since we can almost make non-references
      references.  */
-  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+  if (TYPE_IS_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                        REFERENCE_CONVERSION_BADNESS));
-  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                        REFERENCE_CONVERSION_BADNESS));
   if (overload_debug)
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index ac507e7..afb3b5e 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -902,6 +902,7 @@ hppa64_integral_or_pointer_p (const struct type *type)
       }
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return (TYPE_LENGTH (type) == 8);
     default:
       break;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index ad2512a..5a2a4a7 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -158,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
        struct value *new_value;
 
-       if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+       if (TYPE_IS_REFERENCE (arg_type))
          return value_cast_pointers (type, arg, 0);
 
        /* Cast the value to the reference's target type, and then
diff --git a/gdb/language.c b/gdb/language.c
index 78ec422..c1b0526 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -410,8 +410,7 @@ language_info (int quietly)
 int
 pointer_type (struct type *type)
 {
-  return TYPE_CODE (type) == TYPE_CODE_PTR ||
-    TYPE_CODE (type) == TYPE_CODE_REF;
+  return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type);
 }
 
 \f
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 90bd732..49aa3f5 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2031,7 +2031,7 @@ m32c_reg_arg_type (struct type *type)
   return (code == TYPE_CODE_INT
          || code == TYPE_CODE_ENUM
          || code == TYPE_CODE_PTR
-         || code == TYPE_CODE_REF
+         || TYPE_IS_REFERENCE (type)
          || code == TYPE_CODE_BOOL
          || code == TYPE_CODE_CHAR);
 }
@@ -2453,8 +2453,7 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   enum type_code target_code;
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-             TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   target_code = TYPE_CODE (TYPE_TARGET_TYPE (type));
 
@@ -2533,8 +2532,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR ptr;
   enum type_code target_code;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-             TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index 1a3c2cd..2a90a3a 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -165,6 +165,7 @@ m88k_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
        /* Allow only 32-bit pointers.  */
        return (TYPE_LENGTH (type) == 4);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 62d4ca1..79f5c85 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -96,6 +96,7 @@ mn10300_type_align (struct type *type)
     case TYPE_CODE_FLT:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type);
 
     case TYPE_CODE_COMPLEX:
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 4042ec3..1b25339 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -769,7 +769,7 @@ msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
                  if (code_model == MSP_LARGE_CODE_MODEL
                      && (TYPE_CODE (arg_type) == TYPE_CODE_PTR
-                         || TYPE_CODE (arg_type) == TYPE_CODE_REF
+                         || TYPE_IS_REFERENCE (arg_type)
                          || TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
                          || TYPE_CODE (arg_type) == TYPE_CODE_UNION))
                    {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 140d993..20e2a40 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -805,7 +805,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
            || TYPE_CODE (type) == TYPE_CODE_CHAR
            || TYPE_CODE (type) == TYPE_CODE_BOOL
            || TYPE_CODE (type) == TYPE_CODE_PTR
-           || TYPE_CODE (type) == TYPE_CODE_REF
+           || TYPE_IS_REFERENCE (type)
            || TYPE_CODE (type) == TYPE_CODE_ENUM)
           && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -1493,7 +1493,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
            || TYPE_CODE (type) == TYPE_CODE_BOOL
            || TYPE_CODE (type) == TYPE_CODE_CHAR
            || TYPE_CODE (type) == TYPE_CODE_PTR
-           || TYPE_CODE (type) == TYPE_CODE_REF)
+           || TYPE_IS_REFERENCE (type))
           && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1999,8 +1999,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index f5c4211..8e6a1d8 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1449,7 +1449,7 @@ x_command (char *exp, int from_tty)
        *exp = 0;
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
-      if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (value_type (val)))
        val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 259bb70..835f1e4 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -486,8 +486,7 @@ typy_get_composite (struct type *type)
        }
       END_CATCH
 
-      if (TYPE_CODE (type) != TYPE_CODE_PTR
-         && TYPE_CODE (type) != TYPE_CODE_REF)
+      if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
        break;
       type = TYPE_TARGET_TYPE (type);
     }
@@ -967,7 +966,7 @@ typy_template_argument (PyObject *self, PyObject *args)
   TRY
     {
       type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type))
        type = check_typedef (TYPE_TARGET_TYPE (type));
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 7802ae0..7a25984 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -217,6 +217,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -358,8 +359,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-          || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
          && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
        {
          struct value *target;
@@ -1020,7 +1020,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index fc57592..bd338a6 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3152,7 +3152,7 @@ s390_function_arg_integer (struct type *type)
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_BOOL
       || code == TYPE_CODE_PTR
-      || code == TYPE_CODE_REF)
+      || TYPE_IS_REFERENCE (type))
     return 1;
 
   return ((code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 863ef8f..9e4b3f3 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -225,6 +225,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 5e8f17d..382fbc5 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -67,6 +67,7 @@ sparc64_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
        int len = TYPE_LENGTH (type);
        gdb_assert (len == 8);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index 8dad5c3..011ce53 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1338,6 +1338,7 @@ spu_scalar_value_p (struct type *type)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type) <= 16;
 
     default:
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e06104b..7da136e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2179,8 +2179,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
          /* I'm not really sure that type of this can ever
             be typedefed; just be safe.  */
          t = check_typedef (t);
-         if (TYPE_CODE (t) == TYPE_CODE_PTR
-             || TYPE_CODE (t) == TYPE_CODE_REF)
+         if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
            t = TYPE_TARGET_TYPE (t);
 
          if (TYPE_CODE (t) != TYPE_CODE_STRUCT
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 48a809b..366654e 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -463,8 +463,7 @@ whatis_exp (char *exp, int show)
   get_user_print_options (&opts);
   if (opts.objectprint)
     {
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-          || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
          && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
         real_type = value_rtti_indirect_type (val, &full, &top, &using_enc);
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -581,6 +580,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_NAMESPACE:
       error (_("internal error: unhandled type in print_type_scalar"));
       break;
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 7959f3b..5ffa659 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -239,11 +239,11 @@ binop_types_user_defined_p (enum exp_opcode op,
     return 0;
 
   type1 = check_typedef (type1);
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
   type2 = check_typedef (type2);
-  if (TYPE_CODE (type2) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
   return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
@@ -277,7 +277,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   if (op == UNOP_ADDR)
     return 0;
   type1 = check_typedef (value_type (arg1));
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
   return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
 }
diff --git a/gdb/valops.c b/gdb/valops.c
index 1f423a0..745ad47 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
     {
       struct value *v2;
 
-      if (TYPE_CODE (type2) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type2))
        v2 = coerce_ref (arg2);
       else
        v2 = value_ind (arg2);
@@ -360,24 +360,20 @@ value_cast (struct type *type, struct value *arg2)
   if (value_type (arg2) == type)
     return arg2;
 
-  code1 = TYPE_CODE (check_typedef (type));
-
   /* Check if we are casting struct reference to struct reference.  */
-  if (code1 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (type)))
     {
       /* We dereference type; then we recurse and finally
          we generate value of the given reference.  Nothing wrong with 
         that.  */
       struct type *t1 = check_typedef (type);
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
-      struct value *val =  value_cast (dereftype, arg2);
+      struct value *val = value_cast (dereftype, arg2);
 
       return value_ref (val, TYPE_CODE (t1));
     }
 
-  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
-
-  if (code2 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (value_type (arg2))))
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
@@ -388,7 +384,7 @@ value_cast (struct type *type, struct value *arg2)
 
   /* You can't cast to a reference type.  See value_cast_pointers
      instead.  */
-  gdb_assert (code1 != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (type));
 
   /* A cast to an undetermined-length array_type, such as 
      (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
@@ -591,8 +587,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
   dest_type = type;
 
   /* If we are casting to a reference type, transform
-     reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V).  */
-  if (TYPE_CODE (real_type) == TYPE_CODE_REF)
+     reinterpret_cast<T&[&]>(V) to *reinterpret_cast<T*>(&V).  */
+  if (TYPE_IS_REFERENCE (real_type))
     {
       is_ref = 1;
       arg = value_addr (arg);
@@ -730,10 +726,10 @@ value_dynamic_cast (struct type *type, struct value *arg)
   struct type *class_type, *rtti_type;
   struct value *result, *tem, *original_arg = arg;
   CORE_ADDR addr;
-  int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
+  int is_ref = TYPE_IS_REFERENCE (resolved_type);
 
   if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
-      && TYPE_CODE (resolved_type) != TYPE_CODE_REF)
+      && !TYPE_IS_REFERENCE (resolved_type))
     error (_("Argument to dynamic_cast must be a pointer or reference type"));
   if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
       && TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
@@ -1465,9 +1461,9 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     {
-      /* Copy the value, but change the type from (T&) to (T*).  We
+      /* Copy the value, but change the type from (T&[&]) to (T*).  We
          keep the same location information, which is efficient, and
          allows &(&X) to get the location containing the reference.  */
       arg2 = value_copy (arg1);
@@ -1716,7 +1712,7 @@ typecmp (int staticp, int varargs, int nargs,
       tt1 = check_typedef (t1[i].type);
       tt2 = check_typedef (value_type (t2[i]));
 
-      if (TYPE_CODE (tt1) == TYPE_CODE_REF
+      if (TYPE_IS_REFERENCE (tt1)
          /* We should be doing hairy argument matching, as below.  */
          && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
              == TYPE_CODE (tt2)))
@@ -1734,14 +1730,13 @@ typecmp (int staticp, int varargs, int nargs,
         char *>, and properly access map["hello"], because the
         argument to [] will be a reference to a pointer to a char,
         and the argument will be a pointer to a char.  */
-      while (TYPE_CODE(tt1) == TYPE_CODE_REF
-            || TYPE_CODE (tt1) == TYPE_CODE_PTR)
+      while (TYPE_IS_REFERENCE (tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR)
        {
          tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
        }
       while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
             || TYPE_CODE(tt2) == TYPE_CODE_PTR
-            || TYPE_CODE(tt2) == TYPE_CODE_REF)
+            || TYPE_IS_REFERENCE (tt2))
        {
          tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
        }
@@ -2133,7 +2128,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
   /* Follow pointers until we get to a non-pointer.  */
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2222,7 +2217,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
 
   t = check_typedef (value_type (*argp));
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
@@ -2383,7 +2378,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
   t = check_typedef (value_type (*argp));
 
   /* Code snarfed from value_struct_elt.  */
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2794,7 +2789,7 @@ find_overload_match (struct value **args, int nargs,
 
       if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
          && (TYPE_CODE (objtype) == TYPE_CODE_PTR
-             || TYPE_CODE (objtype) == TYPE_CODE_REF))
+             || TYPE_IS_REFERENCE (objtype)))
        {
          temp = value_addr (temp);
        }
@@ -3591,7 +3586,7 @@ value_rtti_indirect_type (struct value *v, int *full,
 
   type = value_type (v);
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     target = coerce_ref (v);
   else if (TYPE_CODE (type) == TYPE_CODE_PTR)
     {
@@ -3624,8 +3619,8 @@ value_rtti_indirect_type (struct value *v, int *full,
       target_type = value_type (target);
       real_type = make_cv_type (TYPE_CONST (target_type),
                                TYPE_VOLATILE (target_type), real_type, NULL);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_lvalue_reference_type (real_type);
+      if (TYPE_IS_REFERENCE (type))
+        real_type = lookup_reference_type (real_type, TYPE_CODE (type));
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 720942b..9f7f43f 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -280,7 +280,7 @@ int
 val_print_scalar_type_p (struct type *type)
 {
   type = check_typedef (type);
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     {
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
@@ -482,7 +482,7 @@ generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
                              original_value, options, 0, stream);
 }
 
-/* generic_val_print helper for TYPE_CODE_REF.  */
+/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */
 
 static void
 generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
@@ -865,6 +865,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
                             original_value, options);
       break;
diff --git a/gdb/value.c b/gdb/value.c
index 8268b08..1307a37 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1202,8 +1202,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
     {
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
         fetch its rtti type.  */
-      if ((TYPE_CODE (result) == TYPE_CODE_PTR
-          || TYPE_CODE (result) == TYPE_CODE_REF)
+      if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result))
          && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
             == TYPE_CODE_STRUCT)
         {
@@ -2855,7 +2854,7 @@ value_as_address (struct value *val)
      ABI-specific code is a more reasonable place to handle it.  */
 
   if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && !TYPE_IS_REFERENCE (value_type (val))
       && gdbarch_integer_to_address_p (gdbarch))
     return gdbarch_integer_to_address (gdbarch, value_type (val),
                                       value_contents (val));
@@ -2912,6 +2911,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
          whether we want this to be true eventually.  */
       return extract_typed_address (valaddr, type);
@@ -3501,6 +3501,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3537,6 +3538,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3744,7 +3746,7 @@ coerce_ref_if_computed (const struct value *arg)
 {
   const struct lval_funcs *funcs;
 
-  if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (check_typedef (value_type (arg))))
     return NULL;
 
   if (value_lval_const (arg) != lval_computed)
@@ -3786,7 +3788,7 @@ coerce_ref (struct value *arg)
   if (retval)
     return retval;
 
-  if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (value_type_arg_tmp))
     return arg;
 
   enc_type = check_typedef (value_enclosing_type (arg));
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 6f56cba..2917432 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2176,7 +2176,7 @@ varobj_get_value_type (const struct varobj *var)
 
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = get_target_type (type);
 
   type = check_typedef (type);
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-04-02  8:28           ` Artemiy Volkov
@ 2016-04-02  8:45             ` Artemiy Volkov
  0 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-04-02  8:45 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Sat, Apr 02, 2016 at 01:27:09AM -0700, Artemiy Volkov wrote:
> On Thu, Mar 31, 2016 at 01:35:37PM -0700, Keith Seitz wrote:
> 
> [snip]
> 
> > Both of the above hunks need to keep the deleted whitespace. We like a
> > blank line between the (last) variable declaration and the first line of
> > code:
> > 
> >   else if (TYPE_IS_REFERENCE 9obj_type))
> >     {
> >       struct type *this_ref
> >         = lookup_reference_type (this_type, TYPE_CODE (obj_type));
> > 
> >       if (!types_equal (obj_type, this_ref))
> >         ...
> >     }
> 

Whoops, please disregard my previous message as the patch will not
apply. Here is the correct version.

---
 gdb/python/lib/gdb/command/explore.py |  2 +-
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 |  3 +++
 gdb/python/py-xmethods.c              | 10 ++++++----
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
index 6c9f17b..ed25fa6 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,7 +319,6 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
-
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
 
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index c22e8a9..59b7df2 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 4ec920e..259bb70 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 141f180..7802ae0 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -768,6 +768,9 @@ valpy_getitem (PyObject *self, PyObject *key)
          else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
            res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
                                  tmp);
+         else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+           res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
+                                 tmp);
          else
            res_val = value_cast (base_class_type, tmp);
        }
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index d70cdd1..debc3a8 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -548,9 +548,10 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
        obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
        obj = value_cast (this_ref, obj);
@@ -634,9 +635,10 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
        obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
        obj = value_cast (this_ref, obj);
-- 
2.7.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-03-31 20:35       ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
@ 2016-04-02  8:48         ` Artemiy Volkov
  2016-04-05 18:23           ` Pedro Alves
  0 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-04-02  8:48 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Thu, Mar 31, 2016 at 01:35:03PM -0700, Keith Seitz wrote:
> On 03/21/2016 01:59 PM, Artemiy Volkov wrote:
> > Hi all,
> > 
> > this is my fourth take on fixing gdb/14441 which deals with C++0x rvalue
> > references.
> > 
> 
> There are two small nits (see replies in #8 and #9), otherwise, this
> series looks ready for a final evaluation by a maintainer.
> 
> Since the nits are really minor, I recommend just replying [to my
> messages] with corrections on those two specific patches instead of
> reposting the entire series.

Done and done. I hope that's OK that I didn't resend the description and
changelog parts.

> 
> Thank you for your patch (and patience)!

Same here about the patience part :)

Artemiy 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-04-02  8:48         ` Artemiy Volkov
@ 2016-04-05 18:23           ` Pedro Alves
  2016-04-06  8:31             ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Pedro Alves @ 2016-04-05 18:23 UTC (permalink / raw)
  To: Artemiy Volkov, Keith Seitz; +Cc: gdb-patches

On 04/02/2016 09:47 AM, Artemiy Volkov wrote:
> On Thu, Mar 31, 2016 at 01:35:03PM -0700, Keith Seitz wrote:
>> On 03/21/2016 01:59 PM, Artemiy Volkov wrote:
>>> Hi all,
>>>
>>> this is my fourth take on fixing gdb/14441 which deals with C++0x rvalue
>>> references.
>>>
>>
>> There are two small nits (see replies in #8 and #9), otherwise, this
>> series looks ready for a final evaluation by a maintainer.
>>
>> Since the nits are really minor, I recommend just replying [to my
>> messages] with corrections on those two specific patches instead of
>> reposting the entire series.
> 
> Done and done. I hope that's OK that I didn't resend the description and
> changelog parts.
> 
>>
>> Thank you for your patch (and patience)!
> 
> Same here about the patience part :)

Thanks you very much for this patch set, and big thanks to Keith
for the review.

I read the series and it looks pretty good to me.  The only
thing I'm not sure about is the hardcoding of "-std=c++11"
in tests.  GCC 6 switches to -std=gnu++14  by default, for instance,
and I wouldn't want the tests to not cover whatever the compiler
uses by default.  Note also that that's -std=gnu++14, not the stricter
-std=c++14 mode.  Could we make the testcases gracefully skip rvalue
reference bits using #if __cplusplus?

BTW, please fix up all comments and commit logs to mention C++11
instead of C++0x.  :-)

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-04-05 18:23           ` Pedro Alves
@ 2016-04-06  8:31             ` Artemiy Volkov
  2016-04-12 11:49               ` Pedro Alves
  0 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-04-06  8:31 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Keith Seitz, gdb-patches

On Tue, Apr 05, 2016 at 07:23:29PM +0100, Pedro Alves wrote:
> Thanks you very much for this patch set, and big thanks to Keith
> for the review.
> 
> I read the series and it looks pretty good to me.  The only
> thing I'm not sure about is the hardcoding of "-std=c++11"
> in tests.  GCC 6 switches to -std=gnu++14  by default, for instance,
> and I wouldn't want the tests to not cover whatever the compiler
> uses by default.  Note also that that's -std=gnu++14, not the stricter
> -std=c++14 mode.  Could we make the testcases gracefully skip rvalue
> reference bits using #if __cplusplus?

Point about -std=gnu++ vs. -std=c++ taken, I'll fix it in v5.

My idea here was to use the earliest version of the C++ standard which
supports rvalue references and compile with that, since compiling with
every version after that should produce a functionally identical
program. So I'd say for every version of GCC capable of processing (GNU)
C++11+ code we should hardcode -std=gnu++11, based on the assumption
that the supplied version of the compiler is working correctly using any
standard. IOW I think we should be testing GDB, not GCC here. 

That said, I think your approach has an advantage of letting the
testsuite pass when using an old compiler not supporting C++11. If we
should cater for those, then this consideration outweighs the ones in
the paragraph above. If not, then for the reasons given above, I think
we should leave -std=gnu++11 in place.

WDYT?

> 
> BTW, please fix up all comments and commit logs to mention C++11
> instead of C++0x.  :-)

Sure thing. Will fix in v5.

Thanks,
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-04-06  8:31             ` Artemiy Volkov
@ 2016-04-12 11:49               ` Pedro Alves
  2016-04-19 15:51                 ` Artemiy Volkov
  0 siblings, 1 reply; 109+ messages in thread
From: Pedro Alves @ 2016-04-12 11:49 UTC (permalink / raw)
  To: Artemiy Volkov; +Cc: Keith Seitz, gdb-patches

On 04/06/2016 09:30 AM, Artemiy Volkov wrote:
> On Tue, Apr 05, 2016 at 07:23:29PM +0100, Pedro Alves wrote:
>> Thanks you very much for this patch set, and big thanks to Keith
>> for the review.
>>
>> I read the series and it looks pretty good to me.  The only
>> thing I'm not sure about is the hardcoding of "-std=c++11"
>> in tests.  GCC 6 switches to -std=gnu++14  by default, for instance,
>> and I wouldn't want the tests to not cover whatever the compiler
>> uses by default.  Note also that that's -std=gnu++14, not the stricter
>> -std=c++14 mode.  Could we make the testcases gracefully skip rvalue
>> reference bits using #if __cplusplus?
> 
> Point about -std=gnu++ vs. -std=c++ taken, I'll fix it in v5.
> 
> My idea here was to use the earliest version of the C++ standard which
> supports rvalue references and compile with that, since compiling with
> every version after that should produce a functionally identical
> program. So I'd say for every version of GCC capable of processing (GNU)
> C++11+ code we should hardcode -std=gnu++11, based on the assumption
> that the supplied version of the compiler is working correctly using any
> standard. 
> IOW I think we should be testing GDB, not GCC here. 

I wouldn't want to generalize that assumption: C++11 is different enough that
there's even been a need to break ABI.  E.g., consider a test that involves
printing or passing a std::string as param in an infcall; these may behave
differently depending on C++ version.  The ABI tags feature added to handle
the ABI break also affect namespaces, parsing, and mangling handling in
GDB, and can cause issues when code is compiled in C++11 mode, but not in
C++03, and vice versa.  On ABI tags issues, I'm thinking of PR19436 for example.
So GDB needs to be able to debug code compiled with all C++ variants.

> That said, I think your approach has an advantage of letting the
> testsuite pass when using an old compiler not supporting C++11. If we
> should cater for those, then this consideration outweighs the ones in
> the paragraph above. If not, then for the reasons given above, I think
> we should leave -std=gnu++11 in place.
> 
> WDYT?

I think we need to consider the pattern being introduced here, in general.

For instance -- what will we do when we decide to test something
C++14/C++17...-specific and find we could do that by just doing a 
small tweak to .cc file?  Would we bump the testcase's C++ version, losing
coverage of C++11 mode?  In effect, that's what happened here.
The only difference is that C++03 is feeling old by now, while C++17 feels
too-new.

However, C++03 is not old enough to be called "ancient" and "don't care",
and what feels "new" is a moving target.  Also, not sure all supported
compilers accept "-std=gnu++11"; we may need to try compiling with
different flags.

How about something around this:

 - Don't pass any explicit -std flag in the .exp files at all.
 - Make these .exp tests gracefully cope with either C++03 or C++11, by
   skipping the C++11-specific parts when testing with C++03.
 - Run tests with CXX_FOR_TARGET="g++ -std=gnu++03"
 - Run tests with CXX_FOR_TARGET="g++ -std=gnu++11"

After this is working, we could have these affected core-functionality
tests themselves automatically run with multiple languages (c++03/c++11/...)
That is, basically, we could factor the testcases to move their bodies to
procedures taking a language version as parameter, and then have the testcases
call the procedure multiple times.

Alternatively, we could split the rvalue reference testing to separate
files.  My feeling is that it's a bit nicer that rvalue and lval reference
testing is side by side in the same tests.  But that might depend on the
specific testcase.  You'll have a better view into this here, though.

WDYT?

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-04-12 11:49               ` Pedro Alves
@ 2016-04-19 15:51                 ` Artemiy Volkov
  2016-04-22 11:31                   ` Pedro Alves
  0 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-04-19 15:51 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Keith Seitz, gdb-patches@sourceware.org ml

Hi Pedro, sorry for the delay...

On Tue, Apr 12, 2016 at 2:49 PM, Pedro Alves <palves@redhat.com> wrote:
> I wouldn't want to generalize that assumption: C++11 is different enough that
> there's even been a need to break ABI.  E.g., consider a test that involves
> printing or passing a std::string as param in an infcall; these may behave
> differently depending on C++ version.  The ABI tags feature added to handle
> the ABI break also affect namespaces, parsing, and mangling handling in
> GDB, and can cause issues when code is compiled in C++11 mode, but not in
> C++03, and vice versa.  On ABI tags issues, I'm thinking of PR19436 for example.
> So GDB needs to be able to debug code compiled with all C++ variants.

Yes, I agree. Adding -std=c++11 to the .exp files covering so much core
functionality wasn't right.

> I think we need to consider the pattern being introduced here, in general.
>
> For instance -- what will we do when we decide to test something
> C++14/C++17...-specific and find we could do that by just doing a
> small tweak to .cc file?  Would we bump the testcase's C++ version, losing
> coverage of C++11 mode?  In effect, that's what happened here.
> The only difference is that C++03 is feeling old by now, while C++17 feels
> too-new.
>
> However, C++03 is not old enough to be called "ancient" and "don't care",
> and what feels "new" is a moving target.  Also, not sure all supported
> compilers accept "-std=gnu++11"; we may need to try compiling with
> different flags.
>
> How about something around this:
>
>  - Don't pass any explicit -std flag in the .exp files at all.
>  - Make these .exp tests gracefully cope with either C++03 or C++11, by
>    skipping the C++11-specific parts when testing with C++03.
>  - Run tests with CXX_FOR_TARGET="g++ -std=gnu++03"
>  - Run tests with CXX_FOR_TARGET="g++ -std=gnu++11"
>
> After this is working, we could have these affected core-functionality
> tests themselves automatically run with multiple languages (c++03/c++11/...)
> That is, basically, we could factor the testcases to move their bodies to
> procedures taking a language version as parameter, and then have the testcases
> call the procedure multiple times.
>
> Alternatively, we could split the rvalue reference testing to separate
> files.  My feeling is that it's a bit nicer that rvalue and lval reference
> testing is side by side in the same tests.  But that might depend on the
> specific testcase.  You'll have a better view into this here, though.
>
> WDYT?
>

Actually, this pattern has already been introduced: see
gdb.base/nested-subp[1-3].exp and gdb.cp/enum-class.exp. The authors of
these tests hardcoded the standard version in the additional_flags
variable. And I think this is the best way to go here -- IMO the cost of
the implementation you suggested outweighs the benefits. I understand the
idea of having the rvalue ref tests and the corresponding pointer/lvalue
ref tests next to each other, but that would cause too much pollution by
lots of "#ifdef __cplusplus >= ..." and reduced readability. And if we
group the rvalue ref tests together to make it just one #ifdef, why don't
we move those tests out to a separate file in the first place? Also, using
this scheme we would have to create a way to run only specific testcases
twice, which doesn't look like a clean solution, or maybe we'd have to run
the whole gdb.cp/* part of testsuite twice which would be unwarranted
waste of time. And people who want to run all of it using C++03 and C++11
stds can do it by hand.

So yeah, IMO the least of evils here would be to split rvalue reference
tests to separate files and to hardcode -std=gnu++11 in the .exp files.
This solution is much simpler, it keeps the source files clean, it assures
that each testcase will be run once (which is not a bad thing regarding
the time it takes to run the whole testsuite).

What do you say? Am I missing something?

Thanks,
Artemiy

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb
  2016-04-19 15:51                 ` Artemiy Volkov
@ 2016-04-22 11:31                   ` Pedro Alves
  0 siblings, 0 replies; 109+ messages in thread
From: Pedro Alves @ 2016-04-22 11:31 UTC (permalink / raw)
  To: artemiyv; +Cc: Keith Seitz, gdb-patches@sourceware.org ml

On 04/19/2016 04:51 PM, Artemiy Volkov wrote:

> Actually, this pattern has already been introduced: see
> gdb.base/nested-subp[1-3].exp and gdb.cp/enum-class.exp. The authors of
> these tests hardcoded the standard version in the additional_flags
> variable. And I think this is the best way to go here -- IMO the cost of
> the implementation you suggested outweighs the benefits. I understand the
> idea of having the rvalue ref tests and the corresponding pointer/lvalue
> ref tests next to each other, but that would cause too much pollution by
> lots of "#ifdef __cplusplus >= ..." and reduced readability. And if we
> group the rvalue ref tests together to make it just one #ifdef, why don't
> we move those tests out to a separate file in the first place?

Alright, that's exactly the thought process that I was expecting.

> Also, using
> this scheme we would have to create a way to run only specific testcases
> twice, which doesn't look like a clean solution, 

Note we do that in many places, by moving test code to procedures, and
then calling the procedure several times.  gdb.linespec/ls-errs.exp
is one example that tries multiples languages.

> or maybe we'd have to run
> the whole gdb.cp/* part of testsuite twice which would be unwarranted
> waste of time. And people who want to run all of it using C++03 and C++11
> stds can do it by hand.
> 
> So yeah, IMO the least of evils here would be to split rvalue reference
> tests to separate files and to hardcode -std=gnu++11 in the .exp files.
> This solution is much simpler, it keeps the source files clean, it assures
> that each testcase will be run once (which is not a bad thing regarding
> the time it takes to run the whole testsuite).
> 
> What do you say? Am I missing something?

I say let's do this then.
Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 00/11] [PR gdb/14441] Support C++11 rvalue references in gdb
  2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
                         ` (11 preceding siblings ...)
  2016-03-31 20:35       ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
@ 2016-06-06 19:22       ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
                           ` (11 more replies)
  12 siblings, 12 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

Hi all,

this is my fifth take on fixing gdb/14441 which deals with C++11 rvalue
references.

The approach is rather straightforward and the work for the most part consisted
of mimicking the behavior for regular references. In gdbtypes.c, several helper
functions were introduced and some parameterized by the reference kind to
simplify the access to reference type objects API.

The only interesting part is the addition of overloading resolution rules
with regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
13.3.3.2 were accounted for at the beginning of rank_one_type().

With this patch it is now also possible to fix the evaluation of decltype,
which should return a plain type object, an lvalue reference or an rvalue
reference depending on a type category of the type of its operand. However,
this would require introduction of the type category notion to gdb, which I
think only needs adding a new constant to lval_type and propagating the type
category through different parts of an expression in gdb/valops.c. I'm willing
to do this if this patchset turns out to be OK.

Changes from v1 consist of dropping the libiberty part of 05/11 and the
consequent testsuite changes. I have learned that introducing rvalue reference
support to the demangler in cplus-dem.c is completely unnecessary, since
virtually all contemporary compilers generate symbol names handled in
cp-demangle.c. Therefore I have removed some of the testcases in
gdb.cp/demangle.exp and switched the others to use the gnu-v3 demangling style.

Changes from v2 are numerous coding style fixes, improvements and
simplifications of the changelog, reorganization and reordering of the
patchset, removal of redundant code in gdb/python/*, addition of a couple of
python tests, and a few bugfixes.

Changes from v3 are a few more coding style / English grammar fixes and code
simplifications left over from v2.

Changes from v4 consist for the most part of reorganizing the additions to the
testsuite: instead of putting the newly created testcases next to the matching
lvalue reference tests, we create new files in the testsuite to place them
into; also a small bug in the python part of the patchset has been fixed and
the whole thing rebased against the current master branch. I have also added
the PR number to the Changelog entries in the commit messages.

Artemiy Volkov (11):
  gdb: gdbtypes: add definitions for rvalue reference type
  gdb: gdbtypes: change {lookup,make}_reference_type() API
  gdb: valops: add ability to return rvalue reference values from
    value_ref()
  gdb: parse: support rvalue reference type
  gdb: demangle: implement demangling for rvalue reference typenames
  gdb: print: implement correct printing of rvalue reference types and
    values
  gdb: dwarf2read: support DW_TAG_rvalue_reference type
  gdb: python: support rvalue references in the gdb module
  gdb: convert lvalue reference type check to general reference type
    check
  gdb: gdbtypes: add rvalue references to overloading resolution
  gdb: testsuite: add rvalue reference tests

 gdb/aarch64-tdep.c                                 |   5 +-
 gdb/ada-lang.c                                     |   2 +-
 gdb/amd64-tdep.c                                   |   2 +-
 gdb/amd64-windows-tdep.c                           |   1 +
 gdb/arm-tdep.c                                     |   5 +-
 gdb/ax-gdb.c                                       |   2 +
 gdb/c-exp.y                                        |   6 +-
 gdb/c-typeprint.c                                  |  10 +-
 gdb/c-valprint.c                                   |  14 +-
 gdb/c-varobj.c                                     |  10 +-
 gdb/compile/compile-c-symbols.c                    |   2 +-
 gdb/completer.c                                    |   3 +-
 gdb/cp-name-parser.y                               |   4 +
 gdb/cp-support.c                                   |   3 +-
 gdb/darwin-nat-info.c                              |   2 +-
 gdb/dwarf2loc.c                                    |   4 +-
 gdb/dwarf2read.c                                   |  15 +-
 gdb/eval.c                                         |  16 +-
 gdb/f-exp.y                                        |   2 +-
 gdb/findvar.c                                      |   6 +-
 gdb/gdbtypes.c                                     | 105 +++++++++++--
 gdb/gdbtypes.h                                     |  20 ++-
 gdb/guile/scm-type.c                               |   2 +-
 gdb/guile/scm-value.c                              |   2 +-
 gdb/hppa-tdep.c                                    |   1 +
 gdb/infcall.c                                      |   5 +-
 gdb/language.c                                     |   3 +-
 gdb/m32c-tdep.c                                    |   8 +-
 gdb/m88k-tdep.c                                    |   1 +
 gdb/mn10300-tdep.c                                 |   1 +
 gdb/msp430-tdep.c                                  |   2 +-
 gdb/parse.c                                        |  39 ++---
 gdb/parser-defs.h                                  |   1 +
 gdb/ppc-sysv-tdep.c                                |   7 +-
 gdb/printcmd.c                                     |   2 +-
 gdb/python/lib/gdb/command/explore.py              |   2 +-
 gdb/python/lib/gdb/types.py                        |   4 +-
 gdb/python/py-type.c                               |  14 +-
 gdb/python/py-value.c                              |  37 +++--
 gdb/python/py-xmethods.c                           |  10 +-
 gdb/s390-linux-tdep.c                              |   2 +-
 gdb/sparc-tdep.c                                   |   1 +
 gdb/sparc64-tdep.c                                 |   1 +
 gdb/spu-tdep.c                                     |   1 +
 gdb/stabsread.c                                    |   3 +-
 gdb/symtab.c                                       |   3 +-
 gdb/testsuite/gdb.cp/demangle.exp                  |  36 +++++
 gdb/testsuite/gdb.cp/rvalue-ref-casts.cc           |  56 +++++++
 gdb/testsuite/gdb.cp/rvalue-ref-casts.exp          |  76 ++++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-overload.cc        |  39 +++++
 gdb/testsuite/gdb.cp/rvalue-ref-overload.exp       | 103 +++++++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-params.cc          |  74 +++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-params.exp         |  61 ++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc          |  73 +++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp         |  43 ++++++
 gdb/testsuite/gdb.cp/rvalue-ref-types.cc           |  73 +++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-types.exp          | 165 +++++++++++++++++++++
 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc |  55 +++++++
 .../gdb.python/py-rvalue-ref-value-cc.exp          |  56 +++++++
 gdb/typeprint.c                                    |   4 +-
 gdb/valarith.c                                     |   6 +-
 gdb/valops.c                                       |  70 ++++-----
 gdb/valprint.c                                     |   5 +-
 gdb/value.c                                        |  12 +-
 gdb/value.h                                        |   2 +-
 gdb/varobj.c                                       |   2 +-
 66 files changed, 1235 insertions(+), 167 deletions(-)
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-casts.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-casts.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-params.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-params.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-types.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-types.exp
 create mode 100644 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc
 create mode 100644 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.exp

-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (7 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
                           ` (2 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch fixes demangling of names containing rvalue reference typenames by
handling DEMANGLE_COMPONENT_RVALUE_REFERENCE demangle component.

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * cp-name-parser.y (ptr_operator): Handle the '&&' token in
    typename.
    * cp-support.c (replace_typedefs): Handle
    DEMANGLE_COMPONENT_RVALUE_REFERENCE.
    * python/py-type.c (typy_lookup_type): Likewise.
---
 gdb/cp-name-parser.y | 4 ++++
 gdb/cp-support.c     | 1 +
 gdb/python/py-type.c | 4 ++++
 3 files changed, 9 insertions(+)

diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index c6a5c34..33fdcea 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -769,6 +769,10 @@ ptr_operator	:	'*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
 			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
 			  $$.last = &d_left ($$.comp); }
+		|	ANDAND
+			{ $$.comp = make_empty (DEMANGLE_COMPONENT_RVALUE_REFERENCE);
+			  $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+			  $$.last = &d_left ($$.comp); }
 		|	nested_name '*' qualifiers_opt
 			{ $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
 			  $$.comp->u.s_binary.left = $1.comp;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 5662f86..a917ede 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -520,6 +520,7 @@ replace_typedefs (struct demangle_parse_info *info,
 	case DEMANGLE_COMPONENT_RESTRICT_THIS:
 	case DEMANGLE_COMPONENT_POINTER:
 	case DEMANGLE_COMPONENT_REFERENCE:
+	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
 	  replace_typedefs (info, d_left (ret_comp), finder, data);
 	  break;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 6103a2b..4ec920e 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -811,6 +811,7 @@ typy_lookup_type (struct demangle_component *demangled,
 
   if (demangled_type == DEMANGLE_COMPONENT_POINTER
       || demangled_type == DEMANGLE_COMPONENT_REFERENCE
+      || demangled_type == DEMANGLE_COMPONENT_RVALUE_REFERENCE
       || demangled_type == DEMANGLE_COMPONENT_CONST
       || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
     {
@@ -829,6 +830,9 @@ typy_lookup_type (struct demangle_component *demangled,
 	    case DEMANGLE_COMPONENT_REFERENCE:
 	      rtype = lookup_lvalue_reference_type (type);
 	      break;
+	    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
+	      rtype = lookup_rvalue_reference_type (type);
+	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
 	      break;
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (9 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-19 15:08         ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 rvalue references in gdb Artemiy Volkov
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch introduces changes to rank_one_type() dealing with ranking an rvalue
reference type when selecting a best viable function from a set of candidate
functions. The 4 new added rules for rvalue references are:

1) An rvalue argument cannot be bound to a non-const lvalue reference parameter
and an lvalue argument cannot be bound to an rvalue reference parameter.
[C++11 13.3.3.1.4p3]

2) If a conversion to one type of reference is an identity conversion, and a
conversion to the second type of reference is a non-identity conversion, choose
the first type. [C++11 13.3.3.2p3]

3) An rvalue should be first tried to bind to an rvalue reference, and then to
an lvalue reference. [C++11 13.3.3.2p3]

4) An lvalue reference to a function gets higher priority than an rvalue
reference to a function. [C++11 13.3.3.2p3]

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * gdbtypes.c (rank_one_type): Implement overloading
    resolution rules regarding rvalue references.
---
 gdb/gdbtypes.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 3058504..392e619 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -58,6 +58,8 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
 const struct rank BOOL_CONVERSION_BADNESS = {3,0};
 const struct rank BASE_CONVERSION_BADNESS = {2,0};
 const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0};
+const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0};
 const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
 const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
 const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
@@ -3500,15 +3502,65 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 {
   struct rank rank = {0,0};
 
-  if (types_equal (parm, arg))
-    return EXACT_MATCH_BADNESS;
-
   /* Resolve typedefs */
   if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
     parm = check_typedef (parm);
   if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
     arg = check_typedef (arg);
 
+  if (value != NULL)
+    {
+      /* An rvalue argument cannot be bound to a non-const lvalue
+         reference parameter...  */
+      if (VALUE_LVAL (value) == not_lval
+          && TYPE_CODE (parm) == TYPE_CODE_REF
+          && !TYPE_CONST (parm->main_type->target_type))
+        return INCOMPATIBLE_TYPE_BADNESS;
+
+      /* ... and an lvalue argument cannot be bound to an rvalue
+         reference parameter.  [C++ 13.3.3.1.4p3]  */
+      if (VALUE_LVAL (value) != not_lval
+          && TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
+        return INCOMPATIBLE_TYPE_BADNESS;
+    }
+
+  if (types_equal (parm, arg))
+    return EXACT_MATCH_BADNESS;
+
+  /* An lvalue reference to a function should get higher priority than an
+     rvalue reference to a function.  */
+
+  if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
+      && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
+    {
+      return (sum_ranks (rank_one_type (parm,
+              lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
+              DIFFERENT_REFERENCE_TYPE_BADNESS));
+    }
+
+  /* If a conversion to one type of reference is an identity conversion, and a
+     conversion to the second type of reference is a non-identity conversion,
+     choose the first type.  */
+
+  if (value != NULL && TYPE_IS_REFERENCE (parm) && TYPE_IS_REFERENCE (arg)
+     && TYPE_CODE (parm) != TYPE_CODE (arg))
+    {
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
+              TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
+    }
+
+  /* An rvalue should be first tried to bind to an rvalue reference, and then to
+     an lvalue reference.  */
+
+  if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
+      && VALUE_LVAL (value) == not_lval)
+    {
+      if (TYPE_IS_REFERENCE (arg))
+	arg = TYPE_TARGET_TYPE (arg);
+      return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
+			 LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
+    }
+
   /* See through references, since we can almost make non-references
      references.  */
 
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (4 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
                           ` (5 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

Make gdb DWARF reader understand the DW_TAG_rvalue_reference type tag. Handling
of this tag is done in the existing read_tag_reference_type() function, to
which we add a new parameter representing the kind of reference type
(lvalue vs rvalue).

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * dwarf2read.c (process_die, read_type_die_1): Handle the
    DW_TAG_rvalue_reference_type DIE.
    (read_tag_reference_type): Add new parameter "refcode".
---
 gdb/dwarf2read.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index d70ecab..55e4777 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8308,6 +8308,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;
 
@@ -14344,16 +14345,19 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
    the user defined type vector.  */
 
 static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+                          enum type_code refcode)
 {
   struct comp_unit_head *cu_header = &cu->header;
   struct type *type, *target_type;
   struct attribute *attr;
 
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
   target_type = die_type (die, cu);
 
   /* The die_type call above may have already set the type for this DIE.  */
@@ -14361,7 +14365,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_lvalue_reference_type (target_type);
+  type = lookup_reference_type (target_type, refcode);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
@@ -19143,7 +19147,10 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
       this_type = read_tag_ptr_to_member_type (die, cu);
       break;
     case DW_TAG_reference_type:
-      this_type = read_tag_reference_type (die, cu);
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+      break;
+    case DW_TAG_rvalue_reference_type:
+      this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
       break;
     case DW_TAG_const_type:
       this_type = read_tag_const_type (die, cu);
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (5 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
                           ` (4 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch introduces preliminal definitions regarding C++11 rvalue references
to the gdb type system. In addition to an enum type_code entry, a field in
struct type and an accessor macro for that which are created similarly to the
lvalue references counterparts, we also introduce a TYPE_REFERENCE convenience
macro used to check for both kinds of references simultaneously as they are
equivalent in many contexts.

gdb/Changelog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * gdbtypes.h (enum type_code) <TYPE_CODE_RVALUE_REF>: New constant.
    (TYPE_IS_REFERENCE): New macro.
    (struct type): Add rvalue_reference_type field.
    (TYPE_RVALUE_REFERENCE_TYPE): New macro.
---
 gdb/gdbtypes.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index c651c88..bdb8354 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -160,6 +160,8 @@ enum type_code
 
     TYPE_CODE_REF,		/**< C++ Reference types */
 
+    TYPE_CODE_RVALUE_REF,	/**< C++ rvalue reference types */
+
     TYPE_CODE_CHAR,		/**< *real* character type */
 
     /* * Boolean type.  0 is false, 1 is true, and other values are
@@ -362,6 +364,11 @@ enum type_instance_flag_value
 #define TYPE_ATOMIC(t) \
   (TYPE_INSTANCE_FLAGS (t) & TYPE_INSTANCE_FLAG_ATOMIC)
 
+/* * True if this type represents either an lvalue or lvalue reference type.  */
+
+#define TYPE_IS_REFERENCE(t) \
+  (TYPE_CODE (t) == TYPE_CODE_REF || TYPE_CODE (t) == TYPE_CODE_RVALUE_REF)
+
 /* * Instruction-space delimited type.  This is for Harvard architectures
    which have separate instruction and data address spaces (and perhaps
    others).
@@ -767,6 +774,10 @@ struct type
 
   struct type *reference_type;
 
+  /* * A C++ rvalue reference type added in C++11. */
+
+  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 const, volatile, code-space, data-space, and
@@ -1229,6 +1240,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,
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
                           ` (9 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

In almost all contexts (except for overload resolution rules and expression
semantics), lvalue and rvalue references are equivalent. That means that in all
but these cases we can replace a TYPE_CODE_REF check to a TYPE_IS_REFERENCE
check and, for switch statements, add a case label for a rvalue reference type
next to a case label for an lvalue reference type. This patch does exactly
that.

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * aarch64-tdep.c (aarch64_type_align)
    (aarch64_extract_return_value, aarch64_store_return_value): Change
    lvalue reference type checks to general reference type checks.
    * amd64-tdep.c (amd64_classify): Likewise.
    * amd64-windows-tdep.c (amd64_windows_passed_by_integer_register):
    Likewise.
    * arm-tdep.c (arm_type_align, arm_extract_return_value)
    (arm_store_return_value): Likewise.
    * ax-gdb.c (gen_fetch, gen_cast): Likewise.
    * c-typeprint.c (c_print_type): Likewise.
    * c-varobj.c (adjust_value_for_child_access, c_value_of_variable)
    (cplus_number_of_children, cplus_describe_child): Likewise.
    * compile/compile-c-symbols.c (generate_vla_size): Likewise.
    * completer.c (expression_completer): Likewise.
    * cp-support.c (make_symbol_overload_list_adl_namespace):
    Likewise.
    * darwin-nat-info.c (info_mach_region_command): Likewise.
    * dwarf2loc.c (entry_data_value_coerce_ref)
    (value_of_dwarf_reg_entry): Likewise.
    * eval.c (ptrmath_type_p, evaluate_subexp_standard)
    (evaluate_subexp_for_address, evaluate_subexp_for_sizeof):
    Likewise.
    * findvar.c (extract_typed_address, store_typed_address):
    Likewise.
    * gdbtypes.c (rank_one_type): Likewise.
    * hppa-tdep.c (hppa64_integral_or_pointer_p): Likewise.
    * infcall.c (value_arg_coerce): Likewise.
    * language.c (pointer_type): Likewise.
    * m32c-tdep.c (m32c_reg_arg_type, m32c_m16c_address_to_pointer):
    Likewise.
    * m88k-tdep.c (m88k_integral_or_pointer_p): Likewise.
    * mn10300-tdep.c (mn10300_type_align): Likewise.
    * msp430-tdep.c (msp430_push_dummy_call): Likewise.
    * ppc-sysv-tdep.c (do_ppc_sysv_return_value)
    (ppc64_sysv_abi_push_param, ppc64_sysv_abi_return_value):
    Likewise.
    * printcmd.c (print_formatted, x_command): Likewise.
    * python/py-type.c (typy_get_composite, typy_template_argument):
    Likewise.
    * python/py-value.c (valpy_referenced_value)
    (valpy_get_dynamic_type, value_has_field): Likewise.
    * s390-linux-tdep.c (s390_function_arg_integer): Likewise.
    * sparc-tdep.c (sparc_integral_or_pointer_p): Likewise.
    * sparc64-tdep.c (sparc64_integral_or_pointer_p): Likewise.
    * spu-tdep.c (spu_scalar_value_p): Likewise.
    * symtab.c (lookup_symbol_aux): Likewise.
    * typeprint.c (whatis_exp, print_type_scalar): Likewise.
    * valarith.c (binop_types_user_defined_p, unop_user_defined_p):
    Likewise.
    * valops.c (value_cast_pointers, value_cast)
    (value_reinterpret_cast, value_dynamic_cast, value_addr, typecmp)
    (value_struct_elt, value_struct_elt_bitpos)
    (value_find_oload_method_list, find_overload_match)
    (value_rtti_indirect_type): Likewise.
    * valprint.c (val_print_scalar_type_p, generic_val_print):
    Likewise.
    * value.c (value_actual_type, value_as_address, unpack_long)
    (pack_long, pack_unsigned_long, coerce_ref_if_computed)
    (coerce_ref): Likewise.
    * varobj.c (varobj_get_value_type): Likewise.
---
 gdb/aarch64-tdep.c              |  5 +++--
 gdb/amd64-tdep.c                |  2 +-
 gdb/amd64-windows-tdep.c        |  1 +
 gdb/arm-tdep.c                  |  5 +++--
 gdb/ax-gdb.c                    |  2 ++
 gdb/c-varobj.c                  | 10 ++++-----
 gdb/compile/compile-c-symbols.c |  2 +-
 gdb/completer.c                 |  3 +--
 gdb/cp-support.c                |  2 +-
 gdb/darwin-nat-info.c           |  2 +-
 gdb/dwarf2loc.c                 |  4 ++--
 gdb/eval.c                      | 14 ++++++-------
 gdb/findvar.c                   |  6 ++----
 gdb/gdbtypes.c                  |  5 +++--
 gdb/hppa-tdep.c                 |  1 +
 gdb/infcall.c                   |  3 ++-
 gdb/language.c                  |  3 +--
 gdb/m32c-tdep.c                 |  8 +++-----
 gdb/m88k-tdep.c                 |  1 +
 gdb/mn10300-tdep.c              |  1 +
 gdb/msp430-tdep.c               |  2 +-
 gdb/ppc-sysv-tdep.c             |  7 +++----
 gdb/printcmd.c                  |  2 +-
 gdb/python/py-type.c            |  5 ++---
 gdb/python/py-value.c           |  6 +++---
 gdb/s390-linux-tdep.c           |  2 +-
 gdb/sparc-tdep.c                |  1 +
 gdb/sparc64-tdep.c              |  1 +
 gdb/spu-tdep.c                  |  1 +
 gdb/symtab.c                    |  3 +--
 gdb/typeprint.c                 |  4 ++--
 gdb/valarith.c                  |  6 +++---
 gdb/valops.c                    | 45 ++++++++++++++++++-----------------------
 gdb/valprint.c                  |  5 +++--
 gdb/value.c                     | 12 ++++++-----
 gdb/varobj.c                    |  2 +-
 36 files changed, 93 insertions(+), 91 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 88fcf4b..59638c4 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -882,6 +882,7 @@ aarch64_type_align (struct type *t)
     case TYPE_CODE_RANGE:
     case TYPE_CODE_BITSTRING:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -1599,7 +1600,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the the type is a plain integer, then the access is
@@ -1737,7 +1738,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= X_REGISTER_SIZE)
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 6289d21..c689148 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -673,7 +673,7 @@ amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
        || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_CHAR
-       || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
+       || code == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
       && (len == 1 || len == 2 || len == 4 || len == 8))
     theclass[0] = AMD64_INTEGER;
 
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index 1bec6de..e9ff49f 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -55,6 +55,7 @@ amd64_windows_passed_by_integer_register (struct type *type)
       case TYPE_CODE_CHAR:
       case TYPE_CODE_PTR:
       case TYPE_CODE_REF:
+      case TYPE_CODE_RVALUE_REF:
       case TYPE_CODE_STRUCT:
       case TYPE_CODE_UNION:
 	return (TYPE_LENGTH (type) == 1
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 278f639..7e23ed1 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3343,6 +3343,7 @@ arm_type_align (struct type *t)
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_BOOL:
       return TYPE_LENGTH (t);
@@ -7899,7 +7900,7 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       /* If the type is a plain integer, then the access is
@@ -8104,7 +8105,7 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
 	   || TYPE_CODE (type) == TYPE_CODE_BOOL
 	   || TYPE_CODE (type) == TYPE_CODE_PTR
-	   || TYPE_CODE (type) == TYPE_CODE_REF
+	   || TYPE_IS_REFERENCE (type)
 	   || TYPE_CODE (type) == TYPE_CODE_ENUM)
     {
       if (TYPE_LENGTH (type) <= 4)
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 7c6cb64..7ec01e7 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -491,6 +491,7 @@ gen_fetch (struct agent_expr *ax, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
@@ -1001,6 +1002,7 @@ gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type)
     {
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* It's implementation-defined, and I'll bet this is what GCC
          does.  */
       break;
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 48e16f9..f7bdee0 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -78,7 +78,7 @@ adjust_value_for_child_access (struct value **value,
      to us, is already supposed to be
      reference-stripped.  */
 
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (*type));
 
   /* Pointers to structures are treated just like
      structures when accessing children.  Don't
@@ -489,7 +489,7 @@ c_value_of_variable (const struct varobj *var,
   struct type *type = get_type (var);
 
   /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
@@ -586,7 +586,7 @@ cplus_number_of_children (const struct varobj *var)
       if (opts.objectprint)
         {
           value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+          lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
 				|| TYPE_CODE (var->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -623,7 +623,7 @@ cplus_number_of_children (const struct varobj *var)
 	  const struct varobj *parent = var->parent;
 
 	  value = parent->value;
-	  lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+	  lookup_actual_type = (TYPE_IS_REFERENCE (parent->type)
 				|| TYPE_CODE (parent->type) == TYPE_CODE_PTR);
         }
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
@@ -728,7 +728,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
   var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
   if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+    lookup_actual_type = (TYPE_IS_REFERENCE (var->type)
 			  || TYPE_CODE (var->type) == TYPE_CODE_PTR);
   value = var->value;
   type = varobj_get_value_type (var);
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index dcd530d..c06687f 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -593,7 +593,7 @@ generate_vla_size (struct compile_c_instance *compiler,
 {
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = check_typedef (TYPE_TARGET_TYPE (type));
 
   switch (TYPE_CODE (type))
diff --git a/gdb/completer.c b/gdb/completer.c
index 5c3b3fc..ec0f65d 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -610,8 +610,7 @@ expression_completer (struct cmd_list_element *ignore,
       for (;;)
 	{
 	  type = check_typedef (type);
-	  if (TYPE_CODE (type) != TYPE_CODE_PTR
-	      && TYPE_CODE (type) != TYPE_CODE_REF)
+	  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
 	    break;
 	  type = TYPE_TARGET_TYPE (type);
 	}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index a917ede..eb02c02 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1284,7 +1284,7 @@ make_symbol_overload_list_adl_namespace (struct type *type,
   int i, prefix_len;
 
   while (TYPE_CODE (type) == TYPE_CODE_PTR
-	 || TYPE_CODE (type) == TYPE_CODE_REF
+	 || TYPE_IS_REFERENCE (type)
          || TYPE_CODE (type) == TYPE_CODE_ARRAY
          || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
     {
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 314d265..4b4059a 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -732,7 +732,7 @@ info_mach_region_command (char *exp, int from_tty)
 
   expr = parse_expression (exp);
   val = evaluate_expression (expr);
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (value_type (val)))
     {
       val = value_ind (val);
     }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index adb0ac2..cd7a683 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1343,7 +1343,7 @@ entry_data_value_coerce_ref (const struct value *value)
   struct type *checked_type = check_typedef (value_type (value));
   struct value *target_val;
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (checked_type))
     return NULL;
 
   target_val = (struct value *) value_computed_closure (value);
@@ -1418,7 +1418,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      TYPE_CODE_REF with non-entry data value would give current value - not the
      entry value.  */
 
-  if (TYPE_CODE (checked_type) != TYPE_CODE_REF
+  if (!TYPE_IS_REFERENCE (checked_type)
       || TYPE_TARGET_TYPE (checked_type) == NULL)
     return outer_val;
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 182a6c3..b73eb7f 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -640,7 +640,7 @@ static int
 ptrmath_type_p (const struct language_defn *lang, struct type *type)
 {
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = TYPE_TARGET_TYPE (type);
 
   switch (TYPE_CODE (type))
@@ -2510,7 +2510,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	{
 	  type = check_typedef (value_type (arg1));
 	  if (TYPE_CODE (type) == TYPE_CODE_PTR
-	      || TYPE_CODE (type) == TYPE_CODE_REF
+	      || TYPE_IS_REFERENCE (type)
 	  /* In C you can dereference an array to get the 1st elt.  */
 	      || TYPE_CODE (type) == TYPE_CODE_ARRAY
 	    )
@@ -2788,7 +2788,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	    {
 	      struct type *type = value_type (result);
 
-	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+	      if (!TYPE_IS_REFERENCE (type))
 		{
 		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
@@ -2891,7 +2891,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to.  Let value_addr() deal with it.  */
-      if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var)))
 	goto default_case;
 
       (*pos) += 4;
@@ -2930,7 +2930,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
 	{
 	  struct type *type = check_typedef (value_type (x));
 
-	  if (TYPE_CODE (type) == TYPE_CODE_REF)
+	  if (TYPE_IS_REFERENCE (type))
 	    return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			       not_lval);
 	  else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
@@ -3020,7 +3020,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = check_typedef (value_type (val));
       if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF
+	  && !TYPE_IS_REFERENCE (type)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
@@ -3092,7 +3092,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
      the size of the referenced type."  */
   type = check_typedef (type);
   if (exp->language_defn->la_language == language_cplus
-      && TYPE_CODE (type) == TYPE_CODE_REF)
+      && (TYPE_IS_REFERENCE (type)))
     type = check_typedef (TYPE_TARGET_TYPE (type));
   return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a39d897..b9b8d05 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -169,8 +169,7 @@ extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
 CORE_ADDR
 extract_typed_address (const gdb_byte *buf, struct type *type)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("extract_typed_address: "
 		    "type is not a pointer or reference"));
@@ -242,8 +241,7 @@ store_unsigned_integer (gdb_byte *addr, int len,
 void
 store_typed_address (gdb_byte *buf, struct type *type, CORE_ADDR addr)
 {
-  if (TYPE_CODE (type) != TYPE_CODE_PTR
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
     internal_error (__FILE__, __LINE__,
 		    _("store_typed_address: "
 		    "type is not a pointer or reference"));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ed31303..3058504 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3511,10 +3511,11 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   /* See through references, since we can almost make non-references
      references.  */
-  if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+  if (TYPE_IS_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                        REFERENCE_CONVERSION_BADNESS));
-  if (TYPE_CODE (parm) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                        REFERENCE_CONVERSION_BADNESS));
   if (overload_debug)
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index f879a25..49445a8 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -898,6 +898,7 @@ hppa64_integral_or_pointer_p (const struct type *type)
       }
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return (TYPE_LENGTH (type) == 8);
     default:
       break;
diff --git a/gdb/infcall.c b/gdb/infcall.c
index ad2512a..5a2a4a7 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -158,10 +158,11 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	struct value *new_value;
 
-	if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+	if (TYPE_IS_REFERENCE (arg_type))
 	  return value_cast_pointers (type, arg, 0);
 
 	/* Cast the value to the reference's target type, and then
diff --git a/gdb/language.c b/gdb/language.c
index 8469754..15ee998 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -410,8 +410,7 @@ language_info (int quietly)
 int
 pointer_type (struct type *type)
 {
-  return TYPE_CODE (type) == TYPE_CODE_PTR ||
-    TYPE_CODE (type) == TYPE_CODE_REF;
+  return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type);
 }
 
 \f
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 59927a6..7f38a67 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2030,7 +2030,7 @@ m32c_reg_arg_type (struct type *type)
   return (code == TYPE_CODE_INT
 	  || code == TYPE_CODE_ENUM
 	  || code == TYPE_CODE_PTR
-	  || code == TYPE_CODE_REF
+	  || TYPE_IS_REFERENCE (type)
 	  || code == TYPE_CODE_BOOL
 	  || code == TYPE_CODE_CHAR);
 }
@@ -2452,8 +2452,7 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   enum type_code target_code;
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   target_code = TYPE_CODE (TYPE_TARGET_TYPE (type));
 
@@ -2532,8 +2531,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
   CORE_ADDR ptr;
   enum type_code target_code;
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR ||
-	      TYPE_CODE (type) == TYPE_CODE_REF);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));
 
   ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
 
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
index 1a3c2cd..2a90a3a 100644
--- a/gdb/m88k-tdep.c
+++ b/gdb/m88k-tdep.c
@@ -165,6 +165,7 @@ m88k_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	/* Allow only 32-bit pointers.  */
 	return (TYPE_LENGTH (type) == 4);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 9ef88a8..c0c4c35 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -96,6 +96,7 @@ mn10300_type_align (struct type *type)
     case TYPE_CODE_FLT:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type);
 
     case TYPE_CODE_COMPLEX:
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 84189dc..1d878d5 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -768,7 +768,7 @@ msp430_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 		  if (code_model == MSP_LARGE_CODE_MODEL
 		      && (TYPE_CODE (arg_type) == TYPE_CODE_PTR
-		          || TYPE_CODE (arg_type) == TYPE_CODE_REF
+		          || TYPE_IS_REFERENCE (arg_type)
 			  || TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
 			  || TYPE_CODE (arg_type) == TYPE_CODE_UNION))
 		    {
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 140d993..20e2a40 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -805,7 +805,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *func_type,
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF
+	    || TYPE_IS_REFERENCE (type)
 	    || TYPE_CODE (type) == TYPE_CODE_ENUM)
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
@@ -1493,7 +1493,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	    || TYPE_CODE (type) == TYPE_CODE_BOOL
 	    || TYPE_CODE (type) == TYPE_CODE_CHAR
 	    || TYPE_CODE (type) == TYPE_CODE_PTR
-	    || TYPE_CODE (type) == TYPE_CODE_REF)
+	    || TYPE_IS_REFERENCE (type))
 	   && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       ULONGEST word = 0;
@@ -1999,8 +1999,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 
   /* All pointers live in r3.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_PTR
-      || TYPE_CODE (valtype) == TYPE_CODE_REF)
+  if (TYPE_CODE (valtype) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (valtype))
     {
       int regnum = tdep->ppc_gp0_regnum + 3;
 
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index f5c4211..8e6a1d8 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1449,7 +1449,7 @@ x_command (char *exp, int from_tty)
 	*exp = 0;
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
-      if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (value_type (val)))
 	val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 259bb70..835f1e4 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -486,8 +486,7 @@ typy_get_composite (struct type *type)
 	}
       END_CATCH
 
-      if (TYPE_CODE (type) != TYPE_CODE_PTR
-	  && TYPE_CODE (type) != TYPE_CODE_REF)
+      if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type))
 	break;
       type = TYPE_TARGET_TYPE (type);
     }
@@ -967,7 +966,7 @@ typy_template_argument (PyObject *self, PyObject *args)
   TRY
     {
       type = check_typedef (type);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type))
 	type = check_typedef (TYPE_TARGET_TYPE (type));
     }
   CATCH (except, RETURN_MASK_ALL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index a422796..ee17ebf 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -217,6 +217,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -370,8 +371,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
 	  struct value *target;
@@ -1031,7 +1031,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 2106333..cc08f61 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -3148,7 +3148,7 @@ s390_function_arg_integer (struct type *type)
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_BOOL
       || code == TYPE_CODE_PTR
-      || code == TYPE_CODE_REF)
+      || TYPE_IS_REFERENCE (type))
     return 1;
 
   return ((code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT)
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 5a8acce..d85902a 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -225,6 +225,7 @@ sparc_integral_or_pointer_p (const struct type *type)
       return (len == 1 || len == 2 || len == 4 || len == 8);
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Allow either 32-bit or 64-bit pointers.  */
       return (len == 4 || len == 8);
     default:
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 5e8f17d..382fbc5 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -67,6 +67,7 @@ sparc64_integral_or_pointer_p (const struct type *type)
       return 1;
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       {
 	int len = TYPE_LENGTH (type);
 	gdb_assert (len == 8);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index ea3229c..eb9a16d 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1338,6 +1338,7 @@ spu_scalar_value_p (struct type *type)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       return TYPE_LENGTH (type) <= 16;
 
     default:
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f7a207a..b332670 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2179,8 +2179,7 @@ lookup_symbol_aux (const char *name, const struct block *block,
 	  /* I'm not really sure that type of this can ever
 	     be typedefed; just be safe.  */
 	  t = check_typedef (t);
-	  if (TYPE_CODE (t) == TYPE_CODE_PTR
-	      || TYPE_CODE (t) == TYPE_CODE_REF)
+	  if (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
 	    t = TYPE_TARGET_TYPE (t);
 
 	  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 48a809b..366654e 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -463,8 +463,7 @@ whatis_exp (char *exp, int show)
   get_user_print_options (&opts);
   if (opts.objectprint)
     {
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-	   || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
 	  && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
         real_type = value_rtti_indirect_type (val, &full, &top, &using_enc);
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -581,6 +580,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
     case TYPE_CODE_METHODPTR:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_NAMESPACE:
       error (_("internal error: unhandled type in print_type_scalar"));
       break;
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 254d998..337be9e 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -247,11 +247,11 @@ binop_types_user_defined_p (enum exp_opcode op,
     return 0;
 
   type1 = check_typedef (type1);
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
 
   type2 = check_typedef (type2);
-  if (TYPE_CODE (type2) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type2))
     type2 = check_typedef (TYPE_TARGET_TYPE (type2));
 
   return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
@@ -285,7 +285,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
   if (op == UNOP_ADDR)
     return 0;
   type1 = check_typedef (value_type (arg1));
-  if (TYPE_CODE (type1) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type1))
     type1 = check_typedef (TYPE_TARGET_TYPE (type1));
   return TYPE_CODE (type1) == TYPE_CODE_STRUCT;
 }
diff --git a/gdb/valops.c b/gdb/valops.c
index c2fc0db..f1b6c5f 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -317,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2,
     {
       struct value *v2;
 
-      if (TYPE_CODE (type2) == TYPE_CODE_REF)
+      if (TYPE_IS_REFERENCE (type2))
 	v2 = coerce_ref (arg2);
       else
 	v2 = value_ind (arg2);
@@ -360,24 +360,20 @@ value_cast (struct type *type, struct value *arg2)
   if (value_type (arg2) == type)
     return arg2;
 
-  code1 = TYPE_CODE (check_typedef (type));
-
   /* Check if we are casting struct reference to struct reference.  */
-  if (code1 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (type)))
     {
       /* We dereference type; then we recurse and finally
          we generate value of the given reference.  Nothing wrong with 
 	 that.  */
       struct type *t1 = check_typedef (type);
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
-      struct value *val =  value_cast (dereftype, arg2);
+      struct value *val = value_cast (dereftype, arg2);
 
       return value_ref (val, TYPE_CODE (t1));
     }
 
-  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
-
-  if (code2 == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (check_typedef (value_type (arg2))))
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
@@ -388,7 +384,7 @@ value_cast (struct type *type, struct value *arg2)
 
   /* You can't cast to a reference type.  See value_cast_pointers
      instead.  */
-  gdb_assert (code1 != TYPE_CODE_REF);
+  gdb_assert (!TYPE_IS_REFERENCE (type));
 
   /* A cast to an undetermined-length array_type, such as 
      (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
@@ -591,8 +587,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
   dest_type = type;
 
   /* If we are casting to a reference type, transform
-     reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V).  */
-  if (TYPE_CODE (real_type) == TYPE_CODE_REF)
+     reinterpret_cast<T&[&]>(V) to *reinterpret_cast<T*>(&V).  */
+  if (TYPE_IS_REFERENCE (real_type))
     {
       is_ref = 1;
       arg = value_addr (arg);
@@ -730,10 +726,10 @@ value_dynamic_cast (struct type *type, struct value *arg)
   struct type *class_type, *rtti_type;
   struct value *result, *tem, *original_arg = arg;
   CORE_ADDR addr;
-  int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
+  int is_ref = TYPE_IS_REFERENCE (resolved_type);
 
   if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
-      && TYPE_CODE (resolved_type) != TYPE_CODE_REF)
+      && !TYPE_IS_REFERENCE (resolved_type))
     error (_("Argument to dynamic_cast must be a pointer or reference type"));
   if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
       && TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
@@ -1468,7 +1464,7 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     {
       if (value_bits_synthetic_pointer (arg1, value_embedded_offset (arg1),
 	  TARGET_CHAR_BIT * TYPE_LENGTH (type)))
@@ -1734,7 +1730,7 @@ typecmp (int staticp, int varargs, int nargs,
       tt1 = check_typedef (t1[i].type);
       tt2 = check_typedef (value_type (t2[i]));
 
-      if (TYPE_CODE (tt1) == TYPE_CODE_REF
+      if (TYPE_IS_REFERENCE (tt1)
 	  /* We should be doing hairy argument matching, as below.  */
 	  && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1)))
 	      == TYPE_CODE (tt2)))
@@ -1752,14 +1748,13 @@ typecmp (int staticp, int varargs, int nargs,
 	 char *>, and properly access map["hello"], because the
 	 argument to [] will be a reference to a pointer to a char,
 	 and the argument will be a pointer to a char.  */
-      while (TYPE_CODE(tt1) == TYPE_CODE_REF
-	     || TYPE_CODE (tt1) == TYPE_CODE_PTR)
+      while (TYPE_IS_REFERENCE (tt1) || TYPE_CODE (tt1) == TYPE_CODE_PTR)
 	{
 	  tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
 	}
       while (TYPE_CODE(tt2) == TYPE_CODE_ARRAY
 	     || TYPE_CODE(tt2) == TYPE_CODE_PTR
-	     || TYPE_CODE(tt2) == TYPE_CODE_REF)
+	     || TYPE_IS_REFERENCE (tt2))
 	{
 	  tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
 	}
@@ -2151,7 +2146,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
   /* Follow pointers until we get to a non-pointer.  */
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2238,7 +2233,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
 
   t = check_typedef (value_type (*argp));
 
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
@@ -2399,7 +2394,7 @@ value_find_oload_method_list (struct value **argp, const char *method,
   t = check_typedef (value_type (*argp));
 
   /* Code snarfed from value_struct_elt.  */
-  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
     {
       *argp = value_ind (*argp);
       /* Don't coerce fn pointer to fn and then back again!  */
@@ -2808,7 +2803,7 @@ find_overload_match (struct value **args, int nargs,
 
       if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
 	  && (TYPE_CODE (objtype) == TYPE_CODE_PTR
-	      || TYPE_CODE (objtype) == TYPE_CODE_REF))
+	      || TYPE_IS_REFERENCE (objtype)))
 	{
 	  temp = value_addr (temp);
 	}
@@ -3604,7 +3599,7 @@ value_rtti_indirect_type (struct value *v, int *full,
 
   type = value_type (v);
   type = check_typedef (type);
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     target = coerce_ref (v);
   else if (TYPE_CODE (type) == TYPE_CODE_PTR)
     {
@@ -3637,8 +3632,8 @@ value_rtti_indirect_type (struct value *v, int *full,
       target_type = value_type (target);
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_lvalue_reference_type (real_type);
+      if (TYPE_IS_REFERENCE (type))
+        real_type = lookup_reference_type (real_type, TYPE_CODE (type));
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 64407e8..af58b15 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -280,7 +280,7 @@ int
 val_print_scalar_type_p (struct type *type)
 {
   type = check_typedef (type);
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
+  while (TYPE_IS_REFERENCE (type))
     {
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
@@ -534,7 +534,7 @@ get_value_addr_contents (struct value *deref_val)
     }
 }
 
-/* generic_val_print helper for TYPE_CODE_REF.  */
+/* generic_val_print helper for TYPE_CODE_{RVALUE_,}REF.  */
 
 static void
 generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
@@ -934,6 +934,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       generic_val_print_ref (type, valaddr, embedded_offset, stream, recurse,
 			     original_value, options);
       break;
diff --git a/gdb/value.c b/gdb/value.c
index 35fb503..e6a8e49 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1202,8 +1202,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
     {
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
 	 fetch its rtti type.  */
-      if ((TYPE_CODE (result) == TYPE_CODE_PTR
-	   || TYPE_CODE (result) == TYPE_CODE_REF)
+      if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result))
 	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
 	     == TYPE_CODE_STRUCT
 	  && !value_optimized_out (value))
@@ -2887,7 +2886,7 @@ value_as_address (struct value *val)
      ABI-specific code is a more reasonable place to handle it.  */
 
   if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && !TYPE_IS_REFERENCE (value_type (val))
       && gdbarch_integer_to_address_p (gdbarch))
     return gdbarch_integer_to_address (gdbarch, value_type (val),
 				       value_contents (val));
@@ -2944,6 +2943,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
          whether we want this to be true eventually.  */
       return extract_typed_address (valaddr, type);
@@ -3544,6 +3544,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3580,6 +3581,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_PTR:
       store_typed_address (buf, type, (CORE_ADDR) num);
       break;
@@ -3787,7 +3789,7 @@ coerce_ref_if_computed (const struct value *arg)
 {
   const struct lval_funcs *funcs;
 
-  if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (check_typedef (value_type (arg))))
     return NULL;
 
   if (value_lval_const (arg) != lval_computed)
@@ -3829,7 +3831,7 @@ coerce_ref (struct value *arg)
   if (retval)
     return retval;
 
-  if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+  if (!TYPE_IS_REFERENCE (value_type_arg_tmp))
     return arg;
 
   enc_type = check_typedef (value_enclosing_type (arg));
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 6f56cba..2917432 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2176,7 +2176,7 @@ varobj_get_value_type (const struct varobj *var)
 
   type = check_typedef (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_IS_REFERENCE (type))
     type = get_target_type (type);
 
   type = check_typedef (type);
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-20 19:07           ` Pedro Alves
  2016-06-06 19:23         ` [PATCH v5 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
                           ` (8 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch adds the ability to inspect rvalue reference types and values using
the gdb python module. This is achieved by creating two wrappers for
valpy_reference_value(), using the ReferenceExplorer class to handle the
objects of rvalue reference types and placing necessary checks for a
TYPE_CODE_RVALUE_REF type code next to the checks for a TYPE_CODE_REF type
code.

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * python/lib/gdb/command/explore.py: Support exploring values
    of rvalue reference types.
    * python/lib/gdb/types.py: Implement get_basic_type() for
    rvalue reference types.
    * python/py-type.c (pyty_codes) <TYPE_CODE_RVALUE_REF>: New
    constant.
    * python/py-value.c (valpy_getitem): Add an rvalue reference
    check.
    (valpy_reference_value): Add new parameter "refcode".
    (valpy_lvalue_reference_value, valpy_rvalue_reference_value):
    New wrappers for valpy_reference_value().
    * python/py-xmethods.c (gdbpy_get_xmethod_result_type)
    (gdbpy_invoke_xmethod): Likewise.
---
 gdb/python/lib/gdb/command/explore.py |  2 +-
 gdb/python/lib/gdb/types.py           |  4 +++-
 gdb/python/py-type.c                  |  1 +
 gdb/python/py-value.c                 | 26 +++++++++++++++++++++-----
 gdb/python/py-xmethods.c              | 10 ++++++----
 5 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/gdb/python/lib/gdb/command/explore.py b/gdb/python/lib/gdb/command/explore.py
index 6c9f17b..ed25fa6 100644
--- a/gdb/python/lib/gdb/command/explore.py
+++ b/gdb/python/lib/gdb/command/explore.py
@@ -132,6 +132,7 @@ class Explorer(object):
             gdb.TYPE_CODE_UNION : CompoundExplorer,
             gdb.TYPE_CODE_PTR : PointerExplorer,
             gdb.TYPE_CODE_REF : ReferenceExplorer,
+            gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
             gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
             gdb.TYPE_CODE_ARRAY : ArrayExplorer
         }
@@ -318,7 +319,6 @@ class ReferenceExplorer(object):
         Explorer.explore_type(name, target_type, is_child)
         return False
 
-
 class ArrayExplorer(object):
     """Internal class used to explore arrays."""
 
diff --git a/gdb/python/lib/gdb/types.py b/gdb/python/lib/gdb/types.py
index c22e8a9..59b7df2 100644
--- a/gdb/python/lib/gdb/types.py
+++ b/gdb/python/lib/gdb/types.py
@@ -31,8 +31,10 @@ def get_basic_type(type_):
     """
 
     while (type_.code == gdb.TYPE_CODE_REF or
+           type_.code == gdb.TYPE_CODE_RVALUE_REF or
            type_.code == gdb.TYPE_CODE_TYPEDEF):
-        if type_.code == gdb.TYPE_CODE_REF:
+        if (type_.code == gdb.TYPE_CODE_REF or
+            type_.code == gdb.TYPE_CODE_RVALUE_REF):
             type_ = type_.target()
         else:
             type_ = type_.strip_typedefs()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 4ec920e..259bb70 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] =
   ENTRY (TYPE_CODE_METHODPTR),
   ENTRY (TYPE_CODE_MEMBERPTR),
   ENTRY (TYPE_CODE_REF),
+  ENTRY (TYPE_CODE_RVALUE_REF),
   ENTRY (TYPE_CODE_CHAR),
   ENTRY (TYPE_CODE_BOOL),
   ENTRY (TYPE_CODE_COMPLEX),
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 73cc6bd..a422796 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -239,7 +239,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
 /* Return a value which is a reference to the value.  */
 
 static PyObject *
-valpy_reference_value (PyObject *self, PyObject *args)
+valpy_reference_value (PyObject *self, PyObject *args, enum type_code refcode)
 {
   PyObject *result = NULL;
 
@@ -249,7 +249,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF));
+      result = value_to_value_object (value_ref (self_val, refcode));
 
       do_cleanups (cleanup);
     }
@@ -262,6 +262,18 @@ valpy_reference_value (PyObject *self, PyObject *args)
   return result;
 }
 
+static PyObject *
+valpy_lvalue_reference_value (PyObject *self, PyObject *args)
+{
+  return valpy_reference_value (self, args, TYPE_CODE_REF);
+}
+
+static PyObject *
+valpy_rvalue_reference_value (PyObject *self, PyObject *args)
+{
+  return valpy_reference_value (self, args, TYPE_CODE_RVALUE_REF);
+}
+
 /* Return a "const" qualified version of the value.  */
 
 static PyObject *
@@ -598,8 +610,7 @@ value_has_field (struct value *v, PyObject *field)
     {
       val_type = value_type (v);
       val_type = check_typedef (val_type);
-      if (TYPE_CODE (val_type) == TYPE_CODE_REF
-	  || TYPE_CODE (val_type) == TYPE_CODE_PTR)
+      if (TYPE_IS_REFERENCE (val_type) || TYPE_CODE (val_type) == TYPE_CODE_PTR)
       val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
 
       type_code = TYPE_CODE (val_type);
@@ -768,6 +779,9 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
 	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
 	                          tmp);
+	  else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+	    res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
+	                          tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
@@ -1776,8 +1790,10 @@ reinterpret_cast operator."
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
   { "referenced_value", valpy_referenced_value, METH_NOARGS,
     "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
-  { "reference_value", valpy_reference_value, METH_NOARGS,
+  { "reference_value", valpy_lvalue_reference_value, METH_NOARGS,
     "Return a value of type TYPE_CODE_REF referencing this value." },
+  { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
+    "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
   { "const_value", valpy_const_value, METH_NOARGS,
     "Return a 'const' qualied version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index d70cdd1..debc3a8 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -548,9 +548,10 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
 	obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
@@ -634,9 +635,10 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_ptr))
 	obj = value_cast (this_ptr, obj);
     }
-  else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
+  else if (TYPE_IS_REFERENCE (obj_type))
     {
-      struct type *this_ref = lookup_lvalue_reference_type (this_type);
+      struct type *this_ref
+        = lookup_reference_type (this_type, TYPE_CODE (obj_type));
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (6 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
                           ` (3 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch provides the ability to print out names of rvalue reference types
and values of those types. This is done in full similarity to regular
references, and as with them, we don't print out "const" suffix because all
rvalue references are const.

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * c-typeprint.c (c_print_type, c_type_print_varspec_prefix)
    (c_type_print_modifier, c_type_print_varspec_suffix)
    (c_type_print_base): Support printing rvalue reference types.
    * c-valprint.c (c_val_print, c_value_print): Support printing
    rvalue reference values.
---
 gdb/c-typeprint.c | 10 ++++++----
 gdb/c-valprint.c  |  6 +++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index ed16fc3..569a803 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -112,7 +112,7 @@ c_print_type (struct type *type,
 		      && !TYPE_VECTOR (type))
 		  || code == TYPE_CODE_MEMBERPTR
 		  || code == TYPE_CODE_METHODPTR
-		  || code == TYPE_CODE_REF)))
+		  || TYPE_IS_REFERENCE (type))))
 	fputs_filtered (" ", stream);
       need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
       c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
@@ -341,9 +341,10 @@ c_type_print_varspec_prefix (struct type *type,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
 				   stream, show, 1, 0, flags);
-      fprintf_filtered (stream, "&");
+      fprintf_filtered (stream, TYPE_CODE(type) == TYPE_CODE_REF ? "&" : "&&");
       c_type_print_modifier (type, stream, 1, need_post_space);
       break;
 
@@ -410,8 +411,7 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
      every reference is `const'.  */
-  if (TYPE_CONST (type)
-      && TYPE_CODE (type) != TYPE_CODE_REF)
+  if (TYPE_CONST (type) && !TYPE_IS_REFERENCE (type))
     {
       if (need_pre_space)
 	fprintf_filtered (stream, " ");
@@ -726,6 +726,7 @@ c_type_print_varspec_suffix (struct type *type,
 
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
 				   show, 1, 0, flags);
       break;
@@ -894,6 +895,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBERPTR:
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
     case TYPE_CODE_METHODPTR:
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 637acf0..f2e4fa2 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -540,6 +540,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_FLAGS:
     case TYPE_CODE_FUNC:
@@ -585,8 +586,7 @@ c_value_print (struct value *val, struct ui_file *stream,
   val_type = value_type (val);
   type = check_typedef (val_type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_PTR
-      || TYPE_CODE (type) == TYPE_CODE_REF)
+  if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
     {
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway.
@@ -637,7 +637,7 @@ c_value_print (struct value *val, struct ui_file *stream,
 
 	  if (is_ref)
 	    {
-	      val = value_ref (value_ind (val));
+	      val = value_ref (value_ind (val), refcode);
 	      type = value_type (val);
 	    }
 
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (2 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-20 19:04           ` Pedro Alves
  2016-06-06 19:23         ` [PATCH v5 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
                           ` (7 subsequent siblings)
  11 siblings, 1 reply; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch adds tests for the initial rvalue reference support patchset.  All
of the new tests are practically mirrored regular references tests and, except
for the demangler ones, are introduced in new files, which are set to be
compiled with -std=gnu++11.  Tested are printing of rvalue reference types and
values, rvalue reference parameters in function overloading, demangling of
function names containing rvalue reference parameters, casts to rvalue
reference types, application of the sizeof operator to rvalue reference types
and values, and support for rvalue references within the gdb python module.

gdb/testsuite/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * gdb.cp/demangle.exp: Add rvalue reference tests.
    * gdb.cp/rvalue-ref-casts.cc: New file.
    * gdb.cp/rvalue-ref-casts.exp: New file.
    * gdb.cp/rvalue-ref-overload.cc: New file.
    * gdb.cp/rvalue-ref-overload.exp: New file.
    * gdb.cp/rvalue-ref-params.cc: New file.
    * gdb.cp/rvalue-ref-params.exp: New file.
    * gdb.cp/rvalue-ref-sizeof.cc: New file.
    * gdb.cp/rvalue-ref-sizeof.exp: New file.
    * gdb.cp/rvalue-ref-types.cc: New file.
    * gdb.cp/rvalue-ref-types.exp: New file.
    * gdb.python/py-rvalue-ref-value-cc.cc: New file.
    * gdb.python/py-rvalue-ref-value-cc.exp: New file.
---
 gdb/testsuite/gdb.cp/demangle.exp                  |  36 +++++
 gdb/testsuite/gdb.cp/rvalue-ref-casts.cc           |  56 +++++++
 gdb/testsuite/gdb.cp/rvalue-ref-casts.exp          |  76 ++++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-overload.cc        |  39 +++++
 gdb/testsuite/gdb.cp/rvalue-ref-overload.exp       | 103 +++++++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-params.cc          |  74 +++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-params.exp         |  61 ++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc          |  73 +++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp         |  43 ++++++
 gdb/testsuite/gdb.cp/rvalue-ref-types.cc           |  73 +++++++++
 gdb/testsuite/gdb.cp/rvalue-ref-types.exp          | 165 +++++++++++++++++++++
 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc |  55 +++++++
 .../gdb.python/py-rvalue-ref-value-cc.exp          |  56 +++++++
 13 files changed, 910 insertions(+)
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-casts.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-casts.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-params.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-params.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-types.cc
 create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-types.exp
 create mode 100644 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc
 create mode 100644 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.exp

diff --git a/gdb/testsuite/gdb.cp/demangle.exp b/gdb/testsuite/gdb.cp/demangle.exp
index 96c90db..c007097 100644
--- a/gdb/testsuite/gdb.cp/demangle.exp
+++ b/gdb/testsuite/gdb.cp/demangle.exp
@@ -123,20 +123,27 @@ proc test_gnu_style_demangling {} {
     test_demangling "gnu: Append__15NameChooserViewPCc" \
 	"NameChooserView::Append\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: ArrowheadIntersects__9ArrowLineP9ArrowheadR6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)"
+    test_demangling_exact "gnu-v3: _ZN9ArrowLine19ArrowheadIntersectsEP9ArrowheadO6BoxObjP7Graphic" "ArrowLine::ArrowheadIntersects(Arrowhead*, BoxObj&&, Graphic*)"
     test_demangling_exact "gnu: AtEnd__13ivRubberGroup" "ivRubberGroup::AtEnd(void)"
     test_demangling_exact "gnu: BgFilter__9ivTSolverP12ivInteractor" "ivTSolver::BgFilter(ivInteractor *)"
     test_demangling "gnu: BitPatterntoa__FRC10BitPatternccc" \
 	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const) &, char, char, char\[)\]+"
+    test_demangling "gnu-v3: _Z13BitPatterntoaOK10BitPatternccc" \
+	"BitPatterntoa\[(\]+(const BitPattern|BitPattern const)&&, char, char, char\[)\]+"
     test_demangling_exact "gnu: Check__6UArrayi" "UArray::Check(int)"
     test_demangling_exact "gnu: CoreConstDecls__8TextCodeR7ostream" "TextCode::CoreConstDecls(ostream &)"
+    test_demangling_exact "gnu-v3: _ZN8TextCode14CoreConstDeclsEO7ostream" "TextCode::CoreConstDecls(ostream&&)"
     test_demangling_exact "gnu: Detach__8StateVarP12StateVarView" "StateVar::Detach(StateVarView *)"
     test_demangling_exact "gnu: Done__9ComponentG8Iterator" "Component::Done(Iterator)"
     test_demangling "gnu: DrawDestinationTransformedImage__FP7_XImageiiT0iiUlUiiiUiUlUlP4_XGCRC13ivTransformeriiii" \
 	"DrawDestinationTransformedImage\[(\]+_XImage \[*\]+, int, int, _XImage \[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC \[*\]+, (const ivTransformer|ivTransformer const) &, int, int, int, int\[)\]+"
+    test_demangling "gnu-v3: _Z31DrawDestinationTransformedImageP7_XImageiiS0_iimjiijmmP4_XGCOK13ivTransformeriiii" \
+	"DrawDestinationTransformedImage\[(\]+_XImage\[*\]+, int, int, _XImage\[*\]+, int, int, unsigned long, unsigned int, int, int, unsigned int, unsigned long, unsigned long, _XGC\[*\]+, (const ivTransformer|ivTransformer const)&&, int, int, int, int\[)\]+"
 
     test_demangling "gnu: Edit__12StringEditorPCcii" \
 	"StringEditor::Edit\[(\]+(const char|char const) \[*\]+, int, int\[)\]+"
     test_demangling_exact "gnu: Effect__11RelateManipR7ivEvent" "RelateManip::Effect(ivEvent &)"
+    test_demangling_exact "gnu-v3: _ZN11RelateManip6EffectEO7ivEvent" "RelateManip::Effect(ivEvent&&)"
     test_demangling "gnu: FilterName__FPCc" \
 	"FilterName\[(\]+(const char|char const) \[*\]+\[)\]+"
     test_demangling "gnu: Filter__6PSTextPCci" \
@@ -206,16 +213,21 @@ proc test_gnu_style_demangling {} {
 	"iv2_6_MenuItem::iv2_6_MenuItem\[(\]+int, (const char|char const) \[*\]+, ivInteractor \[*\]+\[)\]+"
 
     test_demangling_exact "gnu: __20DisplayList_IteratorR11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList &)"
+    test_demangling_exact "gnu-v3: _ZN20DisplayList_IteratorC4EO11DisplayList" "DisplayList_Iterator::DisplayList_Iterator(DisplayList&&)"
     test_demangling_exact "gnu: __3fooRT0" "foo::foo(foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EOS_" "foo::foo(foo&&)"
     test_demangling_exact "gnu: __3fooiN31" "foo::foo(int, int, int, int)"
     test_demangling "gnu: __3fooiPCc" \
 	"foo::foo\[(\]+int, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __3fooiRT0iT2iT2" "foo::foo(int, foo &, int, foo &, int, foo &)"
+    test_demangling_exact "gnu-v3: _ZN3fooC4EiOS_iS0_iS0_" "foo::foo(int, foo&&, int, foo&&, int, foo&&)"
     test_demangling "gnu: __6GetOptiPPcPCc" \
 	"GetOpt::GetOpt\[(\]+int, char \[*\]+\[*\]+, (const char|char const) \[*\]+\[)\]+"
     test_demangling_exact "gnu: __6KeyMapPT0" "KeyMap::KeyMap(KeyMap *)"
     test_demangling "gnu: __7ivWorldPCcRiPPcPC12ivOptionDescPC14ivPropertyData" \
 	"ivWorld::ivWorld\[(\]+(const char|char const) \[*\]+, int &, char \[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const) \[*\]+, (const ivPropertyData|ivPropertyData const) \[*\]+\[)\]+"
+    test_demangling "gnu-v3: _ZN7ivWorldC2EPKcOiPPcPK12ivOptionDescPK14ivPropertyData" \
+	"ivWorld::ivWorld\[(\]+(const char|char const)\[*\]+, int&&, char\[*\]+\[*\]+, (const ivOptionDesc|ivOptionDesc const)\[*\]+, (const ivPropertyData|ivPropertyData const)\[*\]+\[)\]+"
     test_demangling "gnu: __7procbufPCci" \
 	"procbuf::procbuf\[(\]+(const char|char const) \[*\]+, int\[)\]+"
     test_demangling_exact "gnu: __8ArrowCmdP6EditorUiUi" "ArrowCmd::ArrowCmd(Editor *, unsigned int, unsigned int)"
@@ -295,6 +307,8 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: append__7ivGlyphPT0" "ivGlyph::append(ivGlyph *)"
     test_demangling "gnu: arg__FRC7Complex" \
 	"arg\[(\]+(const Complex|Complex const) &\[)\]+"
+    test_demangling "gnu-v3: _Z3argOK7Complex" \
+	"arg\[(\]+(const Complex|Complex const)&&\[)\]+"
     test_demangling_exact "gnu: clearok__FP7_win_sti" "clearok(_win_st *, int)"
 
     test_demangling_exact "gnu: complexfunc2__FPFPc_i" "complexfunc2(int (*)(char *))"
@@ -305,10 +319,16 @@ proc test_gnu_style_demangling {} {
     test_demangling_exact "gnu: complexfunc7__FPFPFPc_i_PFl_i" "complexfunc7(int (*(*)(int (*)(char *)))(long))"
     test_demangling "gnu: contains__C9BitStringRC10BitPattern" \
 	"BitString::contains\[(\]+(const BitPattern|BitPattern const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK10BitPattern" \
+	"BitString::contains\[(\]+(const BitPattern|BitPattern const)&&\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRC12BitSubStringi" \
 	"BitString::contains\[(\]+(const BitSubString|BitSubString const) &, int\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOK12BitSubStringi" \
+	"BitString::contains\[(\]+(const BitSubString|BitSubString const)&&, int\[)\]+ const"
     test_demangling "gnu: contains__C9BitStringRT0" \
 	"BitString::contains\[(\]+(const BitString|BitString const) &\[)\]+ const"
+    test_demangling "gnu-v3: _ZNK9BitString8containsEOKS_" \
+	"BitString::contains\[(\]+(const BitString|BitString const)&&\[)\]+ const"
     test_demangling "gnu: div__FPC6IntRepT0P6IntRep" \
 	"div\[(\]+(const IntRep|IntRep const) \[*\]+, (const IntRep|IntRep const) \[*\]+, IntRep \[*\]+\[)\]+"
     test_demangling "gnu: div__FPC6IntReplP6IntRep" \
@@ -436,18 +456,26 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity3PixRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE3PixC4EOKS2_" \
+	"List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const&&)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0" \
 	"List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC2EOKS0_PS2_" \
+	"List<VHDLEntity>::element::element(VHDLEntity const&&, List<VHDLEntity>::element*)"
 
     test_demangling_exact "gnu: __Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element" \
 	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityE7elementC4EOKS2_" \
+	"List<VHDLEntity>::element::element(List<VHDLEntity>::element const&&)"
 
     test_demangling_exact "gnu: __cl__C11VHDLLibraryGt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::operator()(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >) const"
 
     test_demangling_exact "gnu: __cl__Ct4List1Z10VHDLEntityRCQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityEclEOKNS1_3PixE" \
+	"List<VHDLEntity>::operator()(List<VHDLEntity>::Pix const&&) const"
 
     test_demangling_exact "gnu: __ne__FPvRCQ2t4List1Z10VHDLEntity3Pix" \
 	"operator!=(void *, List<VHDLEntity>::Pix const &)"
@@ -457,6 +485,8 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4List1Z10VHDLEntityRCt4List1Z10VHDLEntity" \
 	"List<VHDLEntity>::List(List<VHDLEntity> const &)"
+    test_demangling_exact "gnu-v3: _ZN4ListI10VHDLEntityEC4EOKS1_" \
+	"List<VHDLEntity>::List(List<VHDLEntity> const&&)"
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(void)"
@@ -466,12 +496,18 @@ proc test_gnu_style_demangling {} {
 
     test_demangling_exact "gnu: __t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityRCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &)"
+    test_demangling_exact "gnu-v3: _ZN4PixXI11VHDLLibrary14VHDLLibraryRep4ListI10VHDLEntityEEC2EOKS5_" \
+	"PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const&&)"
 
     test_demangling_exact "gnu: nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity" \
 	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const"
+    test_demangling_exact "gnu-v3: _ZNK11VHDLLibrary5nextEEO4PixXIS_14VHDLLibraryRep4ListI10VHDLEntityEE" \
+	"VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >&&) const"
 
     test_demangling_exact "gnu: next__Ct4List1Z10VHDLEntityRQ2t4List1Z10VHDLEntity3Pix" \
 	"List<VHDLEntity>::next(List<VHDLEntity>::Pix &) const"
+    test_demangling_exact "gnu-v3: _ZNK4ListI10VHDLEntityE4nextEONS1_3PixE" \
+	"List<VHDLEntity>::next(List<VHDLEntity>::Pix&&) const"
 
     test_demangling_exact "gnu: _GLOBAL_\$D\$set" "global destructors keyed to set"
 
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-casts.cc b/gdb/testsuite/gdb.cp/rvalue-ref-casts.cc
new file mode 100644
index 0000000..9705c5e
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-casts.cc
@@ -0,0 +1,56 @@
+#include <utility>
+
+struct A
+{
+  int a;
+  A (int aa): a (aa) {}
+};
+
+struct B: public A
+{
+  int b;
+  B (int aa, int bb): A (aa), b(bb) {}
+};
+
+
+struct Alpha
+{
+  virtual void x() { }
+};
+
+struct Gamma
+{
+};
+
+struct Derived : public Alpha
+{
+};
+
+struct VirtuallyDerived : public virtual Alpha
+{
+};
+
+struct DoublyDerived : public VirtuallyDerived,
+		       public virtual Alpha,
+		       public Gamma
+{
+};
+
+int
+main (int argc, char **argv)
+{
+  A *a = new B(42, 1729);
+  B *b = (B *) a;
+  A &ar = *b;
+  B &br = (B&)ar;
+  A &&arr = std::move(A(42));
+  B &&brr = std::move(B(42, 1729));
+
+  Derived derived;
+  DoublyDerived doublyderived;
+
+  Alpha *ad = &derived;
+  Alpha *add = &doublyderived;
+
+  return 0;  /* breakpoint spot: rvalue-ref-casts.exp: 1 */
+}
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-casts.exp b/gdb/testsuite/gdb.cp/rvalue-ref-casts.exp
new file mode 100644
index 0000000..b756cd9
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-casts.exp
@@ -0,0 +1,76 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite
+
+# C++11 rvalue reference type casting tests, based on gdb.cp/casts.exp.
+#
+
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if [get_compiler_info "c++"] {
+    return -1
+}
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=gnu++11"}]} {
+    return -1
+}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# Prevent symbol on address 0x0 being printed.
+gdb_test_no_output "set print symbol off"
+
+gdb_test "break [gdb_get_line_number "rvalue-ref-casts.exp: 1"]" \
+    "Breakpoint.*at.* file .*" \
+    ""
+
+gdb_test "continue" "Breakpoint .* at .*casts.cc.*" ""
+
+# Check upcasting.
+gdb_test "print (A &&) br" ".* = .A &&.* {a = 42}" \
+    "cast derived class rvalue reference to base class rvalue reference"
+
+# Check downcasting.
+gdb_test "print (B &&) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "cast base class rvalue reference to derived class rvalue reference"
+
+# Check compiler casting
+
+set nonzero_hex "0x\[0-9A-Fa-f\]\[0-9A-Fa-f\]+"
+
+gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
+    "let compiler cast base class rvalue reference to derived class rvalue reference"
+
+gdb_test "print static_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "static_cast to rvalue reference type"
+
+gdb_test "print reinterpret_cast<A &&> (*b)" " = \\(A \\&\\&\\) @$hex: {a = 42}" \
+    "reinterpret_cast to rvalue reference type"
+
+gdb_test "print dynamic_cast<Alpha &&> (derived)" \
+    " = \\(Alpha \\&\\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
+    "dynamic_cast simple upcast to rvalue reference"
+
+gdb_test "print dynamic_cast<VirtuallyDerived &&> (*ad)" \
+    "dynamic_cast failed" \
+    "dynamic_cast to rvalue reference to non-existing base"
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc b/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
new file mode 100644
index 0000000..ca1ac1c
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
@@ -0,0 +1,39 @@
+#include <stddef.h>
+#include <utility>
+
+class foo;
+
+typedef foo &foo_lval_ref;
+typedef foo &&foo_rval_ref;
+
+class foo {
+public:
+  foo  ();
+  foo  (foo_lval_ref);
+  foo  (foo_rval_ref);
+  ~foo ();
+
+int overload1arg (foo_lval_ref);
+int overload1arg (foo_rval_ref);
+};
+
+void marker1 ()
+{}
+
+int main () 
+{
+    foo foo_rr_instance1;
+    foo arg;
+    marker1 (); // marker1-returns-here
+    return 0; 
+}
+
+foo::foo  ()                  {}
+foo::foo  (foo_lval_ref afoo)      {}
+foo::foo  (foo_rval_ref afoo)      {}
+foo::~foo ()                       {}
+
+/* Some functions to test overloading by varying one argument type. */
+
+int foo::overload1arg (foo_lval_ref arg)           { return 1; }
+int foo::overload1arg (foo_rval_ref arg)           { return 2; }
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
new file mode 100644
index 0000000..fc94fc6
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
@@ -0,0 +1,103 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite
+
+# Tests for overloaded member functions with rvalue reference parameters,
+# based on gdb.cp/overload.exp.
+
+set ws "\[\r\n\t \]+"
+set nl "\[\r\n\]+"
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=gnu++11"}]} {
+    return -1
+}
+
+# Set it up at a breakpoint so we can play with the variable values.
+
+if ![runto 'marker1'] then {
+    perror "couldn't run to marker1"
+    continue
+}
+
+# Prevent symbol on address 0x0 being printed.
+gdb_test_no_output "set print symbol off"
+gdb_test "up" ".*main.*" "up from marker1"
+
+# Print the monster class type.
+# See virtfunc.exp for a discussion of ptype.
+#
+# This is hairy to begin with.  It is even more hairy because of the
+# XX_* alternate patterns to catch the KFAIL and XFAIL cases.
+
+set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
+set re_fields   ""
+set re_ctor	"foo\\(void\\);${ws}foo\\(foo_lval_ref\\);${ws}foo\\(foo_rval_ref\\);"
+set re_dtor	"~foo\\((void|)\\);"
+set XX_dtor	"~foo\\(int\\);"
+set re_methods "${ws}int overload1arg\\(foo_lval_ref\\);"
+append re_methods "${ws}int overload1arg\\(foo_rval_ref\\);"
+set re_synth	"foo & operator=\\(foo const ?&\\);"
+
+gdb_test_multiple "ptype foo_rr_instance1" "ptype foo_rr_instance1" {
+    -re "type = $re_class${ws}$re_synth${ws}$re_dtor${ws}$re_ctor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
+	# gcc 2.95.3 -gstabs+, no "const" on "const char *"
+	# TODO: gdb.base/constvar.exp has XFAILed this kind of problem for a
+	# long time, but an XFAIL really needs an external bug report.
+	# -- chastain 2003-12-31
+	# setup_xfail "*-*-*"
+	# fail "ptype foo_rr_instance1"
+	# TODO: this should be a KFAIL.
+	pass "ptype foo_rr_instance1 (shorter match)"
+    }
+    -re "type = $re_class${ws}$re_synth${ws}$re_dtor${ws}$re_ctor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
+	# gcc 2.95.3 -gstabs+ if "const char *" ever gets fixed
+	pass "ptype foo_rr_instance1"
+    }
+    -re "type = $re_class${ws}$re_fields${ws}$re_ctor${ws}$XX_dtor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
+	# gcc 3.3.2 -gdwarf-2, "~foo(int)"
+	# TODO: kfail this
+	# kfail "gdb/1113" "ptype foo_rr_instance1"
+	pass "ptype foo_rr_instance1 (shorter match)"
+    }
+    -re "type = $re_class{ws}$re_ctor${ws}$re_dtor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
+	# gcc 3.3.2 -gdwarf-2, if the dtor bug gets fixed
+	# gcc HEAD -gdwarf-2 (abi-2)
+	# TODO: just pass this
+	pass "ptype foo_rr_instance1 (shorter match)"
+    }
+    -re "type = $re_class${ws}$re_synth${ws}$re_ctor${ws}$re_dtor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
+	# gcc 3.3.2 -gstabs+
+	# TODO: enough with the "shorter match"
+	pass "ptype foo_rr_instance1 (shorter match)"
+    }
+    -re "type = $re_class${ws}$re_ctor${ws}$re_dtor${ws}$re_methods${ws}$re_synth$nl\}$nl$gdb_prompt $" {
+	# gcc HEAD -gstabs+ (abi-2)
+	pass "ptype foo_rr_instance1 (shorter match)"
+    }
+}
+
+gdb_test "print foo_rr_instance1.overload1arg(arg)" \
+    "\\$\[0-9\]+ = 1" \
+    "print call overloaded func foo & arg"
+
+gdb_test "print foo_rr_instance1.overload1arg(static_cast<foo&&>(arg))" \
+    "\\$\[0-9\]+ = 2" \
+    "print call overloaded func foo && arg"
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-params.cc b/gdb/testsuite/gdb.cp/rvalue-ref-params.cc
new file mode 100644
index 0000000..467b0e6
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-params.cc
@@ -0,0 +1,74 @@
+/* This test script is part of GDB, the GNU debugger.
+
+   Copyright 2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* based on ref-params.cc */
+
+#include <utility>
+
+struct Parent {
+  Parent (int id0) : id(id0) { }
+  int id;
+};
+
+struct Child : public Parent {
+  Child (int id0) : Parent(id0) { }
+};
+
+int f1(Parent&& R)
+{
+  return R.id;			/* Set breakpoint marker3 here.  */
+}
+
+int f2(Child&& C)
+{
+  return f1(std::move(C));                 /* Set breakpoint marker2 here.  */
+}
+
+struct OtherParent {
+  OtherParent (int other_id0) : other_id(other_id0) { }
+  int other_id;
+};
+
+struct MultiChild : public Parent, OtherParent {
+  MultiChild (int id0) : Parent(id0), OtherParent(id0 * 2) { }
+};
+
+int mf1(OtherParent&& R)
+{
+  return R.other_id;
+}
+
+int mf2(MultiChild&& C)
+{
+  return mf1(std::move(C));
+}
+
+int main(void) 
+{
+  Child Q(42);
+  Child& QR = Q;
+
+  /* Set breakpoint marker1 here.  */
+
+  f1(Child(42));
+  f2(Child(42));
+
+  MultiChild MQ(53);
+  MultiChild& MQR = MQ;
+
+  mf2(std::move(MQ));			/* Set breakpoint MQ here.  */
+}
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-params.exp b/gdb/testsuite/gdb.cp/rvalue-ref-params.exp
new file mode 100644
index 0000000..e1d01c2
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-params.exp
@@ -0,0 +1,61 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests for rvalue reference parameters of types and their subtypes in GDB,
+# based on gdb.cp/ref-params.exp.
+
+#
+# test running programs
+#
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[build_executable $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=gnu++11"}] == 1} {
+    return -1
+}
+
+gdb_exit
+
+proc gdb_start_again { text } {
+    global binfile
+    global srcfile
+
+    clean_restart $binfile
+
+    runto ${srcfile}:[gdb_get_line_number $text]
+}
+
+gdb_start_again "marker1 here"
+gdb_test "print f1(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f1 on (Child&&) in main"
+
+gdb_start_again "marker1 here"
+gdb_test "print f2(static_cast<Child&&>(Q))" ".* = 42.*" "print value of f2 on (Child&&) in main"
+
+gdb_start_again "marker2 here"
+gdb_test "print C" ".*id = 42.*" "print value of Child&& in f2"
+gdb_test "print f1(static_cast<Child&&>(C))" ".* = 42.*" "print value of f1 on Child&& in f2"
+
+gdb_start_again "marker3 here"
+gdb_test "print R" ".*id = 42.*" "print value of Parent&& in f1"
+
+gdb_start_again "breakpoint MQ here"
+gdb_test "print f1(static_cast<MultiChild&&>(MQ))" ".* = 53"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf1(static_cast<MultiChild&&>(MQ))" ".* = 106"
+gdb_start_again "breakpoint MQ here"
+gdb_test "print mf2(static_cast<MultiChild&&>(MQ))" ".* = 106"
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc b/gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc
new file mode 100644
index 0000000..a747d6f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc
@@ -0,0 +1,73 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014-2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <utility>
+
+struct Class
+{
+  int a;
+  char b;
+  long c;
+
+  Class () : a (1), b ('2'), c (3) { }
+};
+
+union Union
+{
+  Class *kp;
+  char a;
+  int b;
+  long c;
+};
+
+enum Enum { A, B, C, D };
+
+typedef unsigned char a4[4];
+typedef unsigned char a8[8];
+typedef unsigned char a12[12];
+typedef Class c4[4];
+typedef Union u8[8];
+typedef Enum e12[12];
+
+#define T(N)					\
+  N N ## obj;					\
+  N&& N ## _rref = std::move(N ## obj);         \
+  N* N ## p = &(N ## obj);			\
+  N*&& N ## p_rref = std::move(N ## p);         \
+  int size_ ## N = sizeof (N ## _rref);		\
+  int size_ ## N ## p = sizeof (N ## p_rref);	\
+
+int
+main (void)
+{
+  T (char);
+  T (int);
+  T (long);
+  T (float);
+  T (double);
+  T (a4);
+  T (a8);
+  T (a12);
+  T (Class);
+  T (Union);
+  T (Enum);
+  T (c4);
+  T (u8);
+  T (e12);
+
+  return 0; /* break here */
+}
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp b/gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp
new file mode 100644
index 0000000..1f6c911
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp
@@ -0,0 +1,43 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# sizeof() tests with rvalue ref parameter types, based on
+# gdb.cp/cpsizeof.exp.
+
+standard_testfile .cc
+
+if {[skip_cplus_tests]} { continue }
+
+if {[prepare_for_testing ${testfile}.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=gnu++11"}] } {
+     return -1
+}
+
+if {![runto_main]} {
+    perror "could not run to main"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "break here"]
+gdb_continue_to_breakpoint "break here"
+
+# Compare sizeof from the compiler and gdb.  Do this once with the actual
+# type name and once with a reference variable.
+foreach v {char int long float double a4 a8 a12 Class Union Enum c4 u8 e12} {
+    gdb_test "print size_$v == sizeof (${v}&&)" "= true"
+    gdb_test "print size_$v == sizeof (${v}_rref)" "= true"
+    gdb_test "print size_${v}p == sizeof (${v}*&&)" "= true"
+    gdb_test "print size_${v}p == sizeof (${v}p_rref)" "= true"
+}
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-types.cc b/gdb/testsuite/gdb.cp/rvalue-ref-types.cc
new file mode 100644
index 0000000..602644f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-types.cc
@@ -0,0 +1,73 @@
+/* This test script is part of GDB, the GNU debugger.
+
+   Copyright 1999-2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <utility>
+
+int main2(void);
+
+void marker1 (void)
+{
+    
+}
+
+
+
+int main(void)
+{
+    short t = -1;
+    short *pt;
+    short &&rrt = std::move(t);
+    pt = &rrt;
+    short *&&rrpt = std::move(pt);
+    short at[4];
+    at[0] = 0;
+    at[1] = 1;
+    at[2] = 2;
+    at[3] = 3;
+    short (&&rrat)[4] = std::move(at);
+
+    marker1();
+
+    main2();
+
+    return 0;
+}
+
+int f()
+{
+    int f1;
+    f1 = 1;
+    return f1;
+}
+
+int main2(void)
+{
+    char &&rrC = 'A';
+    unsigned char &&rrUC = 21;
+    short &&rrS = -14;
+    unsigned short &&rrUS = 7;
+    int &&rrI = 102;
+    unsigned int &&rrUI = 1002;
+    long &&rrL = -234;
+    unsigned long &&rrUL = 234;
+    float &&rrF = 1.25E10;
+    double &&rrD = -1.375E-123;
+    f();
+
+    return 0;
+    
+}
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-types.exp b/gdb/testsuite/gdb.cp/rvalue-ref-types.exp
new file mode 100644
index 0000000..33c5ea8
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-types.exp
@@ -0,0 +1,165 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests for reference types with short type variables in GDB, based on
+# gdb.cp/ref-types.exp.
+
+#
+# test running programs
+#
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=gnu++11"}]} {
+    return -1
+}
+
+#
+# set it up at a breakpoint so we can play with the variable values
+#
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+if ![runto 'marker1'] then {
+    perror "couldn't run to marker1"
+    continue
+}
+
+gdb_test "up" ".*main.*" "up from marker1 1"
+
+proc gdb_start_again {} {
+    global srcdir
+    global subdir
+    global binfile
+    global gdb_prompt
+    global decimal
+
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load ${binfile}
+
+    #
+    # set it up at a breakpoint so we can play with the variable values
+    #
+    if ![runto_main] then {
+	perror "couldn't run to breakpoint"
+	continue
+    }
+
+    if ![runto 'marker1'] then {
+	perror "couldn't run to marker1"
+	continue
+    }
+
+    gdb_test "up" ".*main.*" "up from marker1 2"
+}
+
+
+gdb_test_multiple "print rrt" "print value of rrt" {
+    -re ".\[0-9\]* = \\(short( int)? &&\\) @$hex: -1.*$gdb_prompt $" {
+        pass "print value of rrt"
+    }
+    eof { fail "print rrt ($gdb dumped core) (fixme)" ; gdb_start_again ; }
+}
+
+gdb_test "ptype rrt" "type = short( int)? &&" "ptype rrt"
+
+gdb_test "print *rrpt" ".$decimal = -1" "print value of *rrpt"
+
+# gdb had a bug about dereferencing a pointer type
+# that would lead to wrong results
+# if we try to examine memory at pointer value.
+
+gdb_test "x /hd rrpt" "$hex:\[ \t\]*-1" "examine value at rrpt"
+
+gdb_test "ptype rrpt" "type = short( int)? \\*&&" "ptype rrpt"
+
+gdb_test "print rrat\[0\]" ".$decimal = 0" "print value of rrat\[0\]"
+
+gdb_test "ptype rrat" "type = short( int)? \\\(&&\\\)\\\[4\\\]" "ptype rrat"
+
+gdb_test "print rrat\[1\]" ".$decimal = 1" "print value of rrat\[1\]"
+gdb_test "print rrat\[2\]" ".$decimal = 2" "print value of rrat\[2\]"
+gdb_test "print rrat\[3\]" ".$decimal = 3" "print value of rrat\[3\]"
+
+
+if ![runto 'f'] then {
+    perror "couldn't run to f"
+    continue
+}
+
+gdb_test "up" ".main2.*" "up from f"
+
+gdb_test "ptype rrC" "type = char &&"
+
+gdb_test "ptype rrUC" "type = unsigned char &&"
+
+gdb_test "ptype rrS" "type = short( int)? &&" "ptype rrS"
+
+gdb_test "ptype rrUS" "type = unsigned short( int)? &&" "ptype rrUS"
+
+gdb_test "ptype rrI" "type = int &&"
+
+gdb_test "ptype rrUI" "type = unsigned int &&"
+
+gdb_test "ptype rrL" "type = long( int)? &&" "ptype rrL"
+
+gdb_test "ptype rrUL" "type = unsigned long( int)? &&" "ptype rrUL"
+
+gdb_test "ptype rrF" "type = float &&"
+
+gdb_test "ptype rrD" "type = double &&"
+
+gdb_test "print rrC" "$decimal = \\(char &&\\) @$hex: 65 \'A\'" \
+    "print value of rrC"
+
+gdb_test "print rrUC" \
+    "$decimal = \\(unsigned char &&\\) @$hex: 21 \'.025\'" \
+    "print value of rrUC"
+
+gdb_test "print rrS" "$decimal = \\(short( int)? &&\\) @$hex: -14" \
+                  "print value of rrS"
+
+gdb_test "print rrUS" \
+         "$decimal = \\(unsigned short( int)? &&\\) @$hex: 7" \
+         "print value of rrUS"
+
+gdb_test "print rrI" "$decimal = \\(int &&\\) @$hex: 102" \
+       "print value of rrI"
+
+gdb_test "print rrUI" \
+    "$decimal = \\(unsigned int &&\\) @$hex: 1002" \
+        "print value of rrUI"
+
+gdb_test "print rrL" \
+       "$decimal = \\(long( int)? &&\\) @$hex: -234" \
+         "print value of rrL"
+
+gdb_test "print rrUL" \
+    "$decimal = \\((unsigned long|long unsigned int)? &&\\) @$hex: 234" \
+    "print value of rrUL"
+
+gdb_test "print rrF" \
+    "$decimal = \\(float &&\\) @$hex: 1.2${decimal}e\\+0?10.*" \
+    "print value of rrF"
+
+gdb_test "print rrD" \
+    "$decimal = \\(double &&\\) @$hex: -1.375e-123.*" \
+    "print value of rrD"
diff --git a/gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc b/gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc
new file mode 100644
index 0000000..5edad1a
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc
@@ -0,0 +1,55 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2016 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <utility>
+
+class A {
+ public:
+  int operator+ (const int a1);
+
+ public:
+  int a;
+};
+
+int
+A::operator+ (const int a1)
+{
+  return a + a1;
+}
+
+class B : public A {
+ public:
+  char a;
+};
+
+typedef int *int_ptr;
+
+int
+main ()
+{
+  int val = 10;
+  int &&int_rref = std::move(val);
+  int_ptr ptr = &val;
+  int_ptr &&int_ptr_rref = std::move(ptr);
+
+  B b;
+  b.a = 'b';
+  (&b)->A::a = 100;
+  B &&b_rref = std::move(b);
+
+  return 0; /* Break here.  */
+}
diff --git a/gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.exp b/gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.exp
new file mode 100644
index 0000000..f039957
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.exp
@@ -0,0 +1,56 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.  It tests the mechanism
+# exposing rvalue reference values to Python.  It is based on
+# gdb.python/py-value-cc.exp.
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile \
+    {debug c++ additional_flags="-std=c++11"}]} {
+    return -1
+}
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if ![runto_main] {
+   return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here."]
+gdb_continue_to_breakpoint "Break here" ".*Break here.*"
+
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").type))" "int &&"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").referenced_value().type))" "int"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_rref\").referenced_value()))" "10"
+
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").dereference().type))" "int"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().type))" "int_ptr"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().dereference()))" "10"
+gdb_test "python print (str(gdb.parse_and_eval(\"int_ptr_rref\").referenced_value().referenced_value()))" "10"
+
+gdb_test_no_output "python b = gdb.parse_and_eval('b')" "init b"
+gdb_test_no_output "python b_rref = gdb.parse_and_eval('b_rref')" "init b_rref"
+gdb_test_no_output "python b_fields = b.type.fields()" "init b_fields"
+
+gdb_test "python print(b_rref\[b_fields\[1\]\])" "98 'b'" "b_rref.a via field"
+gdb_test "python print(b_rref\[b_fields\[0\]\].type.target())" "A" \
+  "type of b_rref's base class via field"
+gdb_test "python print(b_rref\[b_fields\[0\]\]\['a'\])" "100" \
+  "b_rref.A::a via field"
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (3 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type Artemiy Volkov
                           ` (6 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

This patch implements correct parsing of C++11 rvalue reference typenames.
This is done in full similarity to the handling of regular references by adding
a '&&' token handling in c-exp.y, defining an rvalue reference type piece, and
implementing a follow type derivation in follow_types().

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * c-exp.y (ptr_operator): Handle the '&&' token in the typename.
    * parse.c (insert_type): Change assert statement.
    (follow_types): Handle rvalue reference types.
    * parser-defs.h (enum type_pieces) <tp_rvalue_reference>: New
    constant.
---
 gdb/c-exp.y       |  6 +++++-
 gdb/parse.c       | 39 ++++++++++++++++++++++-----------------
 gdb/parser-defs.h |  1 +
 3 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 29f672f..c32e3f7 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -744,7 +744,7 @@ exp	:	SIZEOF '(' type ')'	%prec UNARY
 			       says of sizeof:  "When applied to a reference
 			       or a reference type, the result is the size of
 			       the referenced type."  */
-			  if (TYPE_CODE (type) == TYPE_CODE_REF)
+			  if (TYPE_IS_REFERENCE (type))
 			    type = check_typedef (TYPE_TARGET_TYPE (type));
 			  write_exp_elt_longcst (pstate,
 						 (LONGEST) TYPE_LENGTH (type));
@@ -1085,6 +1085,10 @@ ptr_operator:
 			{ insert_type (tp_reference); }
 	|	'&' ptr_operator
 			{ insert_type (tp_reference); }
+	|       ANDAND
+			{ insert_type (tp_rvalue_reference); }
+	|       ANDAND ptr_operator
+			{ insert_type (tp_rvalue_reference); }
 	;
 
 ptr_operator_ts: ptr_operator
diff --git a/gdb/parse.c b/gdb/parse.c
index 9d07da8..35b5a01 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1470,10 +1470,10 @@ insert_into_type_stack (int slot, union type_stack_elt element)
 }
 
 /* Insert a new type, TP, at the bottom of the type stack.  If TP is
-   tp_pointer or tp_reference, it is inserted at the bottom.  If TP is
-   a qualifier, it is inserted at slot 1 (just above a previous
-   tp_pointer) if there is anything on the stack, or simply pushed if
-   the stack is empty.  Other values for TP are invalid.  */
+   tp_pointer, tp_reference or tp_rvalue_reference, it is inserted at the
+   bottom.  If TP is a qualifier, it is inserted at slot 1 (just above a
+   previous tp_pointer) if there is anything on the stack, or simply pushed
+   if the stack is empty.  Other values for TP are invalid.  */
 
 void
 insert_type (enum type_pieces tp)
@@ -1482,7 +1482,8 @@ insert_type (enum type_pieces tp)
   int slot;
 
   gdb_assert (tp == tp_pointer || tp == tp_reference
-	      || tp == tp_const || tp == tp_volatile);
+	      || tp == tp_rvalue_reference || tp == tp_const
+	      || tp == tp_volatile);
 
   /* If there is anything on the stack (we know it will be a
      tp_pointer), insert the qualifier above it.  Otherwise, simply
@@ -1695,18 +1696,22 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_lvalue_reference_type (follow_type);
-	if (make_const)
-	  follow_type = make_cv_type (make_const, 
-				      TYPE_VOLATILE (follow_type), 
-				      follow_type, 0);
-	if (make_volatile)
-	  follow_type = make_cv_type (TYPE_CONST (follow_type), 
-				      make_volatile, 
-				      follow_type, 0);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type, 
-						      make_addr_space);
+	 follow_type = lookup_lvalue_reference_type (follow_type);
+	 goto process_reference;
+	case tp_rvalue_reference:
+	 follow_type = lookup_rvalue_reference_type (follow_type);
+	process_reference:
+	 if (make_const)
+	   follow_type = make_cv_type (make_const,
+				       TYPE_VOLATILE (follow_type),
+				       follow_type, 0);
+	 if (make_volatile)
+	   follow_type = make_cv_type (TYPE_CONST (follow_type),
+				       make_volatile,
+				       follow_type, 0);
+	 if (make_addr_space)
+	   follow_type = make_type_with_address_space (follow_type,
+						       make_addr_space);
 	make_const = make_volatile = 0;
 	make_addr_space = 0;
 	break;
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 1b1d3c3..c474150 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -127,6 +127,7 @@ enum type_pieces
     tp_end = -1, 
     tp_pointer, 
     tp_reference, 
+    tp_rvalue_reference,
     tp_array, 
     tp_function,
     tp_function_with_arguments,
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (8 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
  2016-06-19 15:08         ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 rvalue references in gdb Artemiy Volkov
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

Parameterize lookup_reference_type() and make_reference_type() by the kind of
reference type we want to look up. Create two wrapper functions
lookup_{lvalue,rvalue}_reference_type() for lookup_reference_type() to simplify
the API. Change all callers to use the new API.

gdb/Changelog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * dwarf2read.c (read_tag_reference_type): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
    * eval.c (evaluate_subexp_standard): Likewise.
    * f-exp.y: Likewise.
    * gdbtypes.c (make_reference_type, lookup_reference_type):
    Generalize with rvalue reference types.
    (lookup_lvalue_reference_type, lookup_rvalue_reference_type): New
    convenience wrappers for lookup_reference_type().
    * gdbtypes.h (make_reference_type, lookup_reference_type): Add a
    reference kind parameter.
    (lookup_lvalue_reference_type, lookup_rvalue_reference_type): Add
    wrappers for lookup_reference_type().
    * guile/scm-type.c (gdbscm_type_reference): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
    * guile/scm-value.c (gdbscm_value_dynamic_type): Likewise.
    * parse.c (follow_types): Likewise.
    * python/py-type.c (typy_reference, typy_lookup_type): Likewise.
    * python/py-value.c (valpy_get_dynamic_type, valpy_getitem):
    Likewise.
    * python/py-xmethods.c (gdbpy_get_xmethod_result_type)
    (gdbpy_invoke_xmethod): Likewise.
    * stabsread.c: Provide extra argument to make_reference_type()
    call.
    * valops.c (value_ref, value_rtti_indirect_type): Use
    lookup_lvalue_reference_type() instead of lookup_reference_type().
---
 gdb/dwarf2read.c         |  2 +-
 gdb/eval.c               |  2 +-
 gdb/f-exp.y              |  2 +-
 gdb/gdbtypes.c           | 42 +++++++++++++++++++++++++++++++++---------
 gdb/gdbtypes.h           |  8 ++++++--
 gdb/guile/scm-type.c     |  2 +-
 gdb/guile/scm-value.c    |  2 +-
 gdb/parse.c              |  2 +-
 gdb/python/py-type.c     |  4 ++--
 gdb/python/py-value.c    |  5 +++--
 gdb/python/py-xmethods.c |  4 ++--
 gdb/stabsread.c          |  3 ++-
 gdb/valops.c             |  4 ++--
 13 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 6658a38..d70ecab 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14361,7 +14361,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = lookup_reference_type (target_type);
+  type = lookup_lvalue_reference_type (target_type);
   attr = dwarf2_attr (die, DW_AT_byte_size, cu);
   if (attr)
     {
diff --git a/gdb/eval.c b/gdb/eval.c
index de1c663..182a6c3 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2790,7 +2790,7 @@ evaluate_subexp_standard (struct type *expect_type,
 
 	      if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
 		{
-		  type = lookup_reference_type (type);
+		  type = lookup_lvalue_reference_type (type);
 		  result = allocate_value (type);
 		}
 	    }
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index e3148a3..7308f06 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -512,7 +512,7 @@ ptype	:	typebase
 			follow_type = lookup_pointer_type (follow_type);
 			break;
 		      case tp_reference:
-			follow_type = lookup_reference_type (follow_type);
+			follow_type = lookup_lvalue_reference_type (follow_type);
 			break;
 		      case tp_array:
 			array_size = pop_type_int ();
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 9e1759b..ed31303 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -384,15 +384,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. REFCODE denotes
+   the kind of reference type to lookup (lvalue or rvalue reference).  */
 
 struct type *
-make_reference_type (struct type *type, struct type **typeptr)
+make_reference_type (struct type *type, struct type **typeptr,
+                      enum type_code refcode)
 {
   struct type *ntype;	/* New type */
+  struct type **reftype;
   struct type *chain;
 
-  ntype = TYPE_REFERENCE_TYPE (type);
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
+           : TYPE_RVALUE_REFERENCE_TYPE (type));
 
   if (ntype)
     {
@@ -421,7 +427,10 @@ make_reference_type (struct type *type, struct type **typeptr)
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
-  TYPE_REFERENCE_TYPE (type) = ntype;
+  reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
+             : &TYPE_RVALUE_REFERENCE_TYPE (type));
+
+  *reftype = ntype;
 
   /* FIXME!  Assume the machine has only one representation for
      references, and that it matches the (only) representation for
@@ -429,10 +438,9 @@ make_reference_type (struct type *type, struct type **typeptr)
 
   TYPE_LENGTH (ntype) =
     gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
-  TYPE_CODE (ntype) = TYPE_CODE_REF;
+  TYPE_CODE (ntype) = refcode;
 
-  if (!TYPE_REFERENCE_TYPE (type))	/* Remember it, if don't have one.  */
-    TYPE_REFERENCE_TYPE (type) = ntype;
+  *reftype = ntype;
 
   /* Update the length of all the other variants of this type.  */
   chain = TYPE_CHAIN (ntype);
@@ -449,9 +457,25 @@ make_reference_type (struct type *type, struct type **typeptr)
    details.  */
 
 struct type *
-lookup_reference_type (struct type *type)
+lookup_reference_type (struct type *type, enum type_code refcode)
+{
+  return make_reference_type (type, (struct type **) 0, refcode);
+}
+
+/* Lookup the lvalue reference type for the type TYPE.  */
+
+struct type *
+lookup_lvalue_reference_type (struct type *type)
+{
+  return lookup_reference_type (type, TYPE_CODE_REF);
+}
+
+/* Lookup the rvalue reference type for the type TYPE.  */
+
+struct type *
+lookup_rvalue_reference_type (struct type *type)
 {
-  return make_reference_type (type, (struct type **) 0);
+  return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
 }
 
 /* Lookup a function type that returns type TYPE.  TYPEPTR, if
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index bdb8354..13c06ee 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1727,9 +1727,13 @@ 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);
 
-extern struct type *lookup_reference_type (struct type *);
+extern struct type *lookup_reference_type (struct type *, enum type_code);
+extern struct type *lookup_lvalue_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_reference_type (struct type *, struct type **,
+                                         enum type_code);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 2acdfad..888624d 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -854,7 +854,7 @@ gdbscm_type_reference (SCM self)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 1cdf953..fff3817 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -601,7 +601,7 @@ gdbscm_value_dynamic_type (SCM self)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+		type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
diff --git a/gdb/parse.c b/gdb/parse.c
index 2b00708..9d07da8 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1695,7 +1695,7 @@ follow_types (struct type *follow_type)
 	make_addr_space = 0;
 	break;
       case tp_reference:
-	follow_type = lookup_reference_type (follow_type);
+	follow_type = lookup_lvalue_reference_type (follow_type);
 	if (make_const)
 	  follow_type = make_cv_type (make_const, 
 				      TYPE_VOLATILE (follow_type), 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 03cc8d9..6103a2b 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -667,7 +667,7 @@ typy_reference (PyObject *self, PyObject *args)
 
   TRY
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -827,7 +827,7 @@ typy_lookup_type (struct demangle_component *demangled,
 	  switch (demangled_type)
 	    {
 	    case DEMANGLE_COMPONENT_REFERENCE:
-	      rtype =  lookup_reference_type (type);
+	      rtype = lookup_lvalue_reference_type (type);
 	      break;
 	    case DEMANGLE_COMPONENT_POINTER:
 	      rtype = lookup_pointer_type (type);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 21e9247..e1eb7bb 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -376,7 +376,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
 	      if (was_pointer)
 		type = lookup_pointer_type (type);
 	      else
-		type = lookup_reference_type (type);
+		type = lookup_lvalue_reference_type (type);
 	    }
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -766,7 +766,8 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
 	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
 	  else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
-	    res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
+	                          tmp);
 	  else
 	    res_val = value_cast (base_class_type, tmp);
 	}
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 58bb783..d70cdd1 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -550,7 +550,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
@@ -636,7 +636,7 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
     }
   else if (TYPE_CODE (obj_type) == TYPE_CODE_REF)
     {
-      struct type *this_ref = lookup_reference_type (this_type);
+      struct type *this_ref = lookup_lvalue_reference_type (this_type);
 
       if (!types_equal (obj_type, this_ref))
 	obj = value_cast (this_ref, obj);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 74260b7..60691a1 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -1772,7 +1772,8 @@ again:
 
     case '&':			/* Reference to another type */
       type1 = read_type (pp, objfile);
-      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile));
+      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile),
+                                  TYPE_CODE_REF);
       break;
 
     case 'f':			/* Function returning another type */
diff --git a/gdb/valops.c b/gdb/valops.c
index 7f9cb93..8252f06 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1526,7 +1526,7 @@ value_ref (struct value *arg1)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
   return arg2;
 }
 
@@ -3629,7 +3629,7 @@ value_rtti_indirect_type (struct value *v, int *full,
       real_type = make_cv_type (TYPE_CONST (target_type),
 				TYPE_VOLATILE (target_type), real_type, NULL);
       if (TYPE_CODE (type) == TYPE_CODE_REF)
-        real_type = lookup_reference_type (real_type);
+        real_type = lookup_lvalue_reference_type (real_type);
       else if (TYPE_CODE (type) == TYPE_CODE_PTR)
         real_type = lookup_pointer_type (real_type);
       else
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* [PATCH v5 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref()
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
@ 2016-06-06 19:23         ` Artemiy Volkov
  2016-06-06 19:23         ` [PATCH v5 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
                           ` (10 subsequent siblings)
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-06 19:23 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths, Artemiy Volkov

Parameterize value_ref() by the kind of reference type the value of which
is requested. Change all callers to use the new API.

gdb/ChangeLog:

2016-06-06  Artemiy Volkov  <artemiyv@acm.org>

    PR gdb/14441
    * ada-lang.c (ada_evaluate_subexp): Adhere to the new
    value_ref() interface.
    * c-valprint.c (c_value_print): Likewise.
    * infcall.c (value_arg_coerce): Likewise.
    * python/py-value.c (valpy_reference_value): Likewise.
    * valops.c (value_cast, value_reinterpret_cast)
    (value_dynamic_cast, typecmp): Likewise.
    (value_ref): Parameterize by kind of return value reference type.
    * value.h (value_ref): Add new parameter "refcode".
---
 gdb/ada-lang.c        |  2 +-
 gdb/c-valprint.c      |  8 ++++++--
 gdb/infcall.c         |  2 +-
 gdb/python/py-value.c |  2 +-
 gdb/valops.c          | 25 +++++++++++++++++--------
 gdb/value.h           |  2 +-
 6 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 412aa97..96b905b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10738,7 +10738,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 		     should return a ref as it should be valid to ask
 		     for its address; so rebuild a ref after coerce.  */
 		  arg1 = ada_coerce_ref (arg1);
-		  return value_ref (arg1);
+		  return value_ref (arg1, TYPE_CODE_REF);
 		}
 	    }
 
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 61302a3..637acf0 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -604,10 +604,14 @@ c_value_print (struct value *val, struct ui_file *stream,
       else if (options->objectprint
 	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
 	{
-	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+	  int is_ref = TYPE_IS_REFERENCE (type);
+	  enum type_code refcode = TYPE_CODE_UNDEF;
 
 	  if (is_ref)
-	    val = value_addr (val);
+	    {
+	      val = value_addr (val);
+	      refcode = TYPE_CODE (type);
+	    }
 
 	  /* Pointer to class, check real type of object.  */
 	  fprintf_filtered (stream, "(");
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 77cd931..ad2512a 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -169,7 +169,7 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
 	   if the value was not previously in memory - in some cases
 	   we should clearly be allowing this, but how?  */
 	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
-	new_value = value_ref (new_value);
+	new_value = value_ref (new_value, TYPE_CODE (type));
 	return new_value;
       }
     case TYPE_CODE_INT:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index e1eb7bb..73cc6bd 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -249,7 +249,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val));
+      result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF));
 
       do_cleanups (cleanup);
     }
diff --git a/gdb/valops.c b/gdb/valops.c
index 8252f06..c2fc0db 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -372,7 +372,7 @@ value_cast (struct type *type, struct value *arg2)
       struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
       struct value *val =  value_cast (dereftype, arg2);
 
-      return value_ref (val); 
+      return value_ref (val, TYPE_CODE (t1));
     }
 
   code2 = TYPE_CODE (check_typedef (value_type (arg2)));
@@ -622,7 +622,8 @@ value_reinterpret_cast (struct type *type, struct value *arg)
     error (_("Invalid reinterpret_cast"));
 
   if (is_ref)
-    result = value_cast (type, value_ref (value_ind (result)));
+    result = value_cast (type, value_ref (value_ind (result),
+                                          TYPE_CODE (type)));
 
   return result;
 }
@@ -816,7 +817,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
 				arg_type,
 				&result) == 1)
 	return value_cast (type,
-			   is_ref ? value_ref (result) : value_addr (result));
+			   is_ref
+			   ? value_ref (result, TYPE_CODE (resolved_type))
+			   : value_addr (result));
     }
 
   /* The second dynamic check specified in 5.2.7.  */
@@ -828,7 +831,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
 			       value_address (tem), tem,
 			       rtti_type, &result) == 1)
     return value_cast (type,
-		       is_ref ? value_ref (result) : value_addr (result));
+		       is_ref
+		       ? value_ref (result, TYPE_CODE (resolved_type))
+		       : value_addr (result));
 
   if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
     return value_zero (type, not_lval);
@@ -1517,16 +1522,20 @@ value_addr (struct value *arg1)
    contents.  */
 
 struct value *
-value_ref (struct value *arg1)
+value_ref (struct value *arg1, enum type_code refcode)
 {
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
+  gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+  if ((TYPE_CODE (type) == TYPE_CODE_REF
+       || TYPE_CODE (type) == TYPE_CODE_RVALUE_REF)
+      && TYPE_CODE (type) == refcode)
     return arg1;
 
   arg2 = value_addr (arg1);
-  deprecated_set_value_type (arg2, lookup_lvalue_reference_type (type));
+  deprecated_set_value_type (arg2, lookup_reference_type (type, refcode));
   return arg2;
 }
 
@@ -1733,7 +1742,7 @@ typecmp (int staticp, int varargs, int nargs,
 	  if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
 	    t2[i] = value_coerce_array (t2[i]);
 	  else
-	    t2[i] = value_ref (t2[i]);
+	    t2[i] = value_ref (t2[i], TYPE_CODE (tt1));
 	  continue;
 	}
 
diff --git a/gdb/value.h b/gdb/value.h
index f8ec854..ed4d3d0 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -725,7 +725,7 @@ extern struct value *value_ind (struct value *arg1);
 
 extern struct value *value_addr (struct value *arg1);
 
-extern struct value *value_ref (struct value *arg1);
+extern struct value *value_ref (struct value *arg1, enum type_code refcode);
 
 extern struct value *value_assign (struct value *toval,
 				   struct value *fromval);
-- 
2.8.3

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v5 00/11] [PR gdb/14441] Support C++11 rvalue references in gdb
  2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
                           ` (10 preceding siblings ...)
  2016-06-06 19:23         ` [PATCH v5 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
@ 2016-06-19 15:08         ` Artemiy Volkov
  11 siblings, 0 replies; 109+ messages in thread
From: Artemiy Volkov @ 2016-06-19 15:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: palves, keiths

On Mon, Jun 06, 2016 at 10:22:14PM +0300, Artemiy Volkov wrote:
> Hi all,
> 
> this is my fifth take on fixing gdb/14441 which deals with C++11 rvalue
> references.
> 
> The approach is rather straightforward and the work for the most part consisted
> of mimicking the behavior for regular references. In gdbtypes.c, several helper
> functions were introduced and some parameterized by the reference kind to
> simplify the access to reference type objects API.
> 
> The only interesting part is the addition of overloading resolution rules
> with regard to rvalue references. All of the cases introduced in 13.3.3.1.4 and
> 13.3.3.2 were accounted for at the beginning of rank_one_type().
> 
> With this patch it is now also possible to fix the evaluation of decltype,
> which should return a plain type object, an lvalue reference or an rvalue
> reference depending on a type category of the type of its operand. However,
> this would require introduction of the type category notion to gdb, which I
> think only needs adding a new constant to lval_type and propagating the type
> category through different parts of an expression in gdb/valops.c. I'm willing
> to do this if this patchset turns out to be OK.
> 
> Changes from v1 consist of dropping the libiberty part of 05/11 and the
> consequent testsuite changes. I have learned that introducing rvalue reference
> support to the demangler in cplus-dem.c is completely unnecessary, since
> virtually all contemporary compilers generate symbol names handled in
> cp-demangle.c. Therefore I have removed some of the testcases in
> gdb.cp/demangle.exp and switched the others to use the gnu-v3 demangling style.
> 
> Changes from v2 are numerous coding style fixes, improvements and
> simplifications of the changelog, reorganization and reordering of the
> patchset, removal of redundant code in gdb/python/*, addition of a couple of
> python tests, and a few bugfixes.
> 
> Changes from v3 are a few more coding style / English grammar fixes and code
> simplifications left over from v2.
> 
> Changes from v4 consist for the most part of reorganizing the additions to the
> testsuite: instead of putting the newly created testcases next to the matching
> lvalue reference tests, we create new files in the testsuite to place them
> into; also a small bug in the python part of the patchset has been fixed and
> the whole thing rebased against the current master branch. I have also added
> the PR number to the Changelog entries in the commit messages.

Ping?

> 
> Artemiy Volkov (11):
>   gdb: gdbtypes: add definitions for rvalue reference type
>   gdb: gdbtypes: change {lookup,make}_reference_type() API
>   gdb: valops: add ability to return rvalue reference values from
>     value_ref()
>   gdb: parse: support rvalue reference type
>   gdb: demangle: implement demangling for rvalue reference typenames
>   gdb: print: implement correct printing of rvalue reference types and
>     values
>   gdb: dwarf2read: support DW_TAG_rvalue_reference type
>   gdb: python: support rvalue references in the gdb module
>   gdb: convert lvalue reference type check to general reference type
>     check
>   gdb: gdbtypes: add rvalue references to overloading resolution
>   gdb: testsuite: add rvalue reference tests
> 
>  gdb/aarch64-tdep.c                                 |   5 +-
>  gdb/ada-lang.c                                     |   2 +-
>  gdb/amd64-tdep.c                                   |   2 +-
>  gdb/amd64-windows-tdep.c                           |   1 +
>  gdb/arm-tdep.c                                     |   5 +-
>  gdb/ax-gdb.c                                       |   2 +
>  gdb/c-exp.y                                        |   6 +-
>  gdb/c-typeprint.c                                  |  10 +-
>  gdb/c-valprint.c                                   |  14 +-
>  gdb/c-varobj.c                                     |  10 +-
>  gdb/compile/compile-c-symbols.c                    |   2 +-
>  gdb/completer.c                                    |   3 +-
>  gdb/cp-name-parser.y                               |   4 +
>  gdb/cp-support.c                                   |   3 +-
>  gdb/darwin-nat-info.c                              |   2 +-
>  gdb/dwarf2loc.c                                    |   4 +-
>  gdb/dwarf2read.c                                   |  15 +-
>  gdb/eval.c                                         |  16 +-
>  gdb/f-exp.y                                        |   2 +-
>  gdb/findvar.c                                      |   6 +-
>  gdb/gdbtypes.c                                     | 105 +++++++++++--
>  gdb/gdbtypes.h                                     |  20 ++-
>  gdb/guile/scm-type.c                               |   2 +-
>  gdb/guile/scm-value.c                              |   2 +-
>  gdb/hppa-tdep.c                                    |   1 +
>  gdb/infcall.c                                      |   5 +-
>  gdb/language.c                                     |   3 +-
>  gdb/m32c-tdep.c                                    |   8 +-
>  gdb/m88k-tdep.c                                    |   1 +
>  gdb/mn10300-tdep.c                                 |   1 +
>  gdb/msp430-tdep.c                                  |   2 +-
>  gdb/parse.c                                        |  39 ++---
>  gdb/parser-defs.h                                  |   1 +
>  gdb/ppc-sysv-tdep.c                                |   7 +-
>  gdb/printcmd.c                                     |   2 +-
>  gdb/python/lib/gdb/command/explore.py              |   2 +-
>  gdb/python/lib/gdb/types.py                        |   4 +-
>  gdb/python/py-type.c                               |  14 +-
>  gdb/python/py-value.c                              |  37 +++--
>  gdb/python/py-xmethods.c                           |  10 +-
>  gdb/s390-linux-tdep.c                              |   2 +-
>  gdb/sparc-tdep.c                                   |   1 +
>  gdb/sparc64-tdep.c                                 |   1 +
>  gdb/spu-tdep.c                                     |   1 +
>  gdb/stabsread.c                                    |   3 +-
>  gdb/symtab.c                                       |   3 +-
>  gdb/testsuite/gdb.cp/demangle.exp                  |  36 +++++
>  gdb/testsuite/gdb.cp/rvalue-ref-casts.cc           |  56 +++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-casts.exp          |  76 ++++++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-overload.cc        |  39 +++++
>  gdb/testsuite/gdb.cp/rvalue-ref-overload.exp       | 103 +++++++++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-params.cc          |  74 +++++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-params.exp         |  61 ++++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc          |  73 +++++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp         |  43 ++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-types.cc           |  73 +++++++++
>  gdb/testsuite/gdb.cp/rvalue-ref-types.exp          | 165 +++++++++++++++++++++
>  gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc |  55 +++++++
>  .../gdb.python/py-rvalue-ref-value-cc.exp          |  56 +++++++
>  gdb/typeprint.c                                    |   4 +-
>  gdb/valarith.c                                     |   6 +-
>  gdb/valops.c                                       |  70 ++++-----
>  gdb/valprint.c                                     |   5 +-
>  gdb/value.c                                        |  12 +-
>  gdb/value.h                                        |   2 +-
>  gdb/varobj.c                                       |   2 +-
>  66 files changed, 1235 insertions(+), 167 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-casts.cc
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-casts.exp
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-params.cc
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-params.exp
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.cc
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-sizeof.exp
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-types.cc
>  create mode 100644 gdb/testsuite/gdb.cp/rvalue-ref-types.exp
>  create mode 100644 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.cc
>  create mode 100644 gdb/testsuite/gdb.python/py-rvalue-ref-value-cc.exp
> 
> -- 
> 2.8.3
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v5 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests
  2016-06-06 19:23         ` [PATCH v5 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
@ 2016-06-20 19:04           ` Pedro Alves
  0 siblings, 0 replies; 109+ messages in thread
From: Pedro Alves @ 2016-06-20 19:04 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches; +Cc: keiths

Thanks a lot for doing this.

On 06/06/2016 08:22 PM, Artemiy Volkov wrote:
> --- /dev/null
> +++ b/gdb/testsuite/gdb.cp/rvalue-ref-casts.cc
> @@ -0,0 +1,56 @@
> +#include <utility>

Please add a GPLv3+ header to all new testsuite files.
Some existing files don't have them, but all new files
are required to.  If you based the file on some pre-existing
file, them we should preserve the copyright year range.  If
that is the case, and the file does not currently have
a header, use the date the original file was first committed
to the sources (git blame/log and/or grepping ChangeLog files
should allow finding easily).

> +main (int argc, char **argv)
> +{
> +  A *a = new B(42, 1729);
> +  B *b = (B *) a;
> +  A &ar = *b;
> +  B &br = (B&)ar;
> +  A &&arr = std::move(A(42));
> +  B &&brr = std::move(B(42, 1729));

All new tests should follow GNU coding conventions too, unless
required otherwise for the particular issue being tested
(which doesn't seem to be the case here).

IOW, missing spaces before parentheses, & and casts:

  B &br = (B &) ar;
  A &&arr = std::move (A (42));
  B &&brr = std::move (B (42, 1729));

> +# Copyright 2016 Free Software Foundation, Inc.
> +
...
> +
> +# C++11 rvalue reference type casting tests, based on gdb.cp/casts.exp.
> +#

If there's copyrightable content in the file that came from gdb.cp/casts.exp,
then please preserve the copyright year range.

On 06/06/2016 08:22 PM, Artemiy Volkov wrote:
> +++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
...
> +#
> +# This is hairy to begin with.  It is even more hairy because of the
> +# XX_* alternate patterns to catch the KFAIL and XFAIL cases.
> +
> +set re_class	"((struct|class) foo \{${ws}public:|struct foo \{)"
> +set re_fields   ""
> +set re_ctor	"foo\\(void\\);${ws}foo\\(foo_lval_ref\\);${ws}foo\\(foo_rval_ref\\);"
> +set re_dtor	"~foo\\((void|)\\);"
> +set XX_dtor	"~foo\\(int\\);"
> +set re_methods "${ws}int overload1arg\\(foo_lval_ref\\);"
> +append re_methods "${ws}int overload1arg\\(foo_rval_ref\\);"
> +set re_synth	"foo & operator=\\(foo const ?&\\);"
> +
> +gdb_test_multiple "ptype foo_rr_instance1" "ptype foo_rr_instance1" {
> +    -re "type = $re_class${ws}$re_synth${ws}$re_dtor${ws}$re_ctor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
> +	# gcc 2.95.3 -gstabs+, no "const" on "const char *"
> +	# TODO: gdb.base/constvar.exp has XFAILed this kind of problem for a
> +	# long time, but an XFAIL really needs an external bug report.
> +	# -- chastain 2003-12-31
> +	# setup_xfail "*-*-*"
> +	# fail "ptype foo_rr_instance1"
> +	# TODO: this should be a KFAIL.
> +	pass "ptype foo_rr_instance1 (shorter match)"
> +    }
> +    -re "type = $re_class${ws}$re_synth${ws}$re_dtor${ws}$re_ctor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
> +	# gcc 2.95.3 -gstabs+ if "const char *" ever gets fixed
> +	pass "ptype foo_rr_instance1"
> +    }
> +    -re "type = $re_class${ws}$re_fields${ws}$re_ctor${ws}$XX_dtor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
> +	# gcc 3.3.2 -gdwarf-2, "~foo(int)"
> +	# TODO: kfail this
> +	# kfail "gdb/1113" "ptype foo_rr_instance1"
> +	pass "ptype foo_rr_instance1 (shorter match)"
> +    }
> +    -re "type = $re_class{ws}$re_ctor${ws}$re_dtor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
> +	# gcc 3.3.2 -gdwarf-2, if the dtor bug gets fixed
> +	# gcc HEAD -gdwarf-2 (abi-2)
> +	# TODO: just pass this
> +	pass "ptype foo_rr_instance1 (shorter match)"
> +    }
> +    -re "type = $re_class${ws}$re_synth${ws}$re_ctor${ws}$re_dtor${ws}$re_methods$nl\}$nl$gdb_prompt $" {
> +	# gcc 3.3.2 -gstabs+
> +	# TODO: enough with the "shorter match"
> +	pass "ptype foo_rr_instance1 (shorter match)"
> +    }
> +    -re "type = $re_class${ws}$re_ctor${ws}$re_dtor${ws}$re_methods${ws}$re_synth$nl\}$nl$gdb_prompt $" {
> +	# gcc HEAD -gstabs+ (abi-2)
> +	pass "ptype foo_rr_instance1 (shorter match)"
> +    }


Several references to TODOs and kfails, etc. that are likely
not really relevant here.  Can we clean this up?

(same comments apply to the other files).

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH v5 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module
  2016-06-06 19:23         ` [PATCH v5 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
@ 2016-06-20 19:07           ` Pedro Alves
  0 siblings, 0 replies; 109+ messages in thread
From: Pedro Alves @ 2016-06-20 19:07 UTC (permalink / raw)
  To: Artemiy Volkov, gdb-patches; +Cc: keiths

On 06/06/2016 08:22 PM, Artemiy Volkov wrote:
> This patch adds the ability to inspect rvalue reference types and values using
> the gdb python module. This is achieved by creating two wrappers for
> valpy_reference_value(), using the ReferenceExplorer class to handle the
> objects of rvalue reference types and placing necessary checks for a
> TYPE_CODE_RVALUE_REF type code next to the checks for a TYPE_CODE_REF type
> code.

The new Python API needs to be documented in the manual, along with a
corresponding NEWS entry.  

I'd say that gdb's new support for rvalue references would
deserve a NEWS entry of its own too.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 109+ messages in thread

end of thread, other threads:[~2016-06-20 19:07 UTC | newest]

Thread overview: 109+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-20 22:35 [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
2015-12-20 22:35 ` [PATCH 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
2015-12-20 22:35 ` [PATCH 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
2015-12-20 22:35 ` [PATCH 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
2015-12-20 22:35 ` [PATCH 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
2015-12-20 22:35 ` [PATCH 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
2015-12-20 22:35 ` [PATCH 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
2015-12-20 22:35 ` [PATCH 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
2015-12-20 22:35 ` [PATCH 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
2015-12-30 19:17   ` Pedro Alves
2015-12-20 22:35 ` [PATCH 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
2015-12-20 22:35 ` [PATCH 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
2015-12-20 22:35 ` [PATCH 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
2015-12-28 21:09 ` [PATCH 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
2016-01-20  9:42   ` Yao Qi
2016-01-19 18:54 ` [PATCH v2 " Artemiy Volkov
2016-01-19 18:54   ` [PATCH v2 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
2016-02-19 18:53     ` Keith Seitz
2016-01-19 18:54   ` [PATCH v2 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
2016-02-19 18:50     ` Keith Seitz
2016-01-19 18:54   ` [PATCH v2 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
2016-02-19 18:54     ` Keith Seitz
2016-01-19 18:54   ` [PATCH v2 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
2016-02-19 18:56     ` Keith Seitz
2016-01-19 18:54   ` [PATCH v2 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
2016-02-19 18:52     ` Keith Seitz
2016-01-19 18:54   ` [PATCH v2 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
2016-02-19 18:49     ` Keith Seitz
2016-02-23  7:04       ` Artemiy Volkov
2016-02-25  1:22         ` Keith Seitz
2016-02-25  1:32           ` Artemiy Volkov
2016-02-25  1:41             ` Keith Seitz
2016-02-25  1:45               ` Artemiy Volkov
2016-01-19 18:55   ` [PATCH v2 10/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
2016-02-19 19:48     ` Keith Seitz
2016-01-19 18:55   ` [PATCH v2 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
2016-02-19 20:05     ` Keith Seitz
2016-01-19 18:55   ` [PATCH v2 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
2016-02-19 18:57     ` Keith Seitz
2016-01-19 18:55   ` [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
2016-02-19 19:46     ` Keith Seitz
2016-01-19 18:55   ` [PATCH v2 08/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
2016-02-19 19:01     ` Keith Seitz
2016-02-26  5:08       ` Artemiy Volkov
2016-02-19 18:49   ` [PATCH v2 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
2016-02-23  6:04     ` Artemiy Volkov
2016-03-05  3:20   ` [PATCH v3 " Artemiy Volkov
2016-03-05  3:20     ` [PATCH v3 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
2016-03-16 22:41       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
2016-03-16 22:48       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
2016-03-16 22:45       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
2016-03-16 22:32       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
2016-03-16 22:08       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
2016-03-16 22:22       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
2016-03-16 22:26       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
2016-03-16 22:25       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_AT_rvalue_reference type Artemiy Volkov
2016-03-16 22:28       ` Keith Seitz
2016-03-05  3:20     ` [PATCH v3 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
2016-03-16 22:19       ` Keith Seitz
2016-03-20 12:10         ` Artemiy Volkov
2016-03-05  3:20     ` [PATCH v3 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
2016-03-16 22:23       ` Keith Seitz
2016-03-21 21:02     ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
2016-03-31 20:35         ` Keith Seitz
2016-04-02  8:28           ` Artemiy Volkov
2016-04-02  8:45             ` Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
2016-03-21 21:02       ` [PATCH v4 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
2016-03-21 21:03       ` [PATCH v4 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
2016-03-21 21:03       ` [PATCH v4 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
2016-03-21 21:03       ` [PATCH v4 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
2016-03-31 20:37         ` Keith Seitz
2016-04-02  8:42           ` Artemiy Volkov
2016-03-21 21:15       ` [PATCH v4 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
2016-03-31 20:35       ` [PATCH v4 00/11] [PR gdb/14441] Support C++0x rvalue references in gdb Keith Seitz
2016-04-02  8:48         ` Artemiy Volkov
2016-04-05 18:23           ` Pedro Alves
2016-04-06  8:31             ` Artemiy Volkov
2016-04-12 11:49               ` Pedro Alves
2016-04-19 15:51                 ` Artemiy Volkov
2016-04-22 11:31                   ` Pedro Alves
2016-06-06 19:22       ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 " Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 03/11] [PR gdb/14441] gdb: valops: add ability to return rvalue reference values from value_ref() Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 09/11] [PR gdb/14441] gdb: convert lvalue reference type check to general reference type check Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 08/11] [PR gdb/14441] gdb: python: support rvalue references in the gdb module Artemiy Volkov
2016-06-20 19:07           ` Pedro Alves
2016-06-06 19:23         ` [PATCH v5 11/11] [PR gdb/14441] gdb: testsuite: add rvalue reference tests Artemiy Volkov
2016-06-20 19:04           ` Pedro Alves
2016-06-06 19:23         ` [PATCH v5 04/11] [PR gdb/14441] gdb: parse: support rvalue reference type Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 07/11] [PR gdb/14441] gdb: dwarf2read: support DW_TAG_rvalue_reference type Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 01/11] [PR gdb/14441] gdb: gdbtypes: add definitions for rvalue reference type Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 06/11] [PR gdb/14441] gdb: print: implement correct printing of rvalue reference types and values Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 05/11] [PR gdb/14441] gdb: demangle: implement demangling for rvalue reference typenames Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 02/11] [PR gdb/14441] gdb: gdbtypes: change {lookup,make}_reference_type() API Artemiy Volkov
2016-06-06 19:23         ` [PATCH v5 10/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution Artemiy Volkov
2016-06-19 15:08         ` [PATCH v5 00/11] [PR gdb/14441] Support C++11 rvalue references in gdb Artemiy Volkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).