[04/11,PR,gdb/14441] gdb: parse: support rvalue reference type

Message ID 1450661481-31178-5-git-send-email-artemiyv@acm.org
State New, archived
Headers

Commit Message

Artemiy Volkov Dec. 21, 2015, 1:31 a.m. UTC
  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(-)
  

Patch

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,