This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

two expression patches


Sami asked me to send these to the list.

A while back I wrote a couple of expression-related fixes to gdb.
They are pending upstream, but it seems like a good idea to send them
here as well, to make sure nobody is duplicating work.

Neither of these is very critical IMO.

The first one is for PR 2506.  This implements C-style string constant
concatenation.  E.g., try:

    (gdb) print "x" "y"

It should print "xy".  Nobody is likely to type this; I thought that
perhaps it could come up via cut-and-paste (not super likely) or macro
expansion (which AFAICT only I use :).


The second one fixes PR 2409, parsing of a certain type of type name:

    (gdb) whatis void (**) ()
    (gdb) whatis void (** const) ()
    (gdb) whatis void (* const *) ()

At least one of these (I forget) gives the wrong answer right now, or
just does not parse.

Again, not super important.  And, this one is a bit incomplete... I
suspect that to keep argument types around in cast expressions we will
need to redo some of the type-stack stuff.  Also I wonder whether it
is fully correct for references, and whether it needs an update for
the new rvalue ("&&") references.


I can put these on a branch, or whatever, but I suspect they aren't
important enough to bother with.

Tom

projecttype:gdb
email:tromey@gcc.gnu.org
revision:6c1547c90970178011b3d9f7547005eb441c1f49
configure:
make:
check:

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9194f04..19b9135 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-20  Tom Tromey  <tromey@redhat.com>
+
+	PR gdb/2506:
+	* c-exp.y (string_exp): New production.
+	(exp): Use it.
+
 2008-08-20  Pedro Alves  <pedro@codesourcery.com>
 
 	* linespec.c (symtab_from_filename): Also throw NOT_FOUND_ERROR if
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index bd04dc2..be79f15 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -182,7 +182,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
 %token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
 %token <voidval> COMPLETE
 %token <tsym> TYPENAME
-%type <sval> name
+%type <sval> name string_exp
 %type <ssym> name_not_typename
 %type <tsym> typename
 
@@ -560,7 +560,36 @@ exp	:	SIZEOF '(' type ')'	%prec UNARY
 			  write_exp_elt_opcode (OP_LONG); }
 	;
 
-exp	:	STRING
+string_exp:
+		STRING
+			{
+			  /* We copy the string here, and not in the
+			     lexer, to guarantee that we do not leak a
+			     string.  Note that we follow the
+			     NUL-termination convention of the
+			     lexer.  */
+			  $$.length = $1.length;
+			  $$.ptr = xmalloc ($1.length + 1);
+			  memcpy ($$.ptr, $1.ptr, $1.length + 1);
+			}
+
+	|	string_exp STRING
+			{
+			  /* Note that we NUL-terminate here, but just
+			     for convenience.  */
+			  struct stoken t;
+			  t.length = $1.length + $2.length;
+			  t.ptr = xmalloc (t.length + 1);
+			  memcpy (t.ptr, $1.ptr, $1.length);
+			  memcpy (t.ptr + $1.length, $2.ptr, $2.length);
+			  t.ptr[t.length] = '\0';
+			  xfree ($1.ptr);
+			  xfree ($2.ptr);
+			  $$ = t;
+			}
+		;
+
+exp	:	string_exp
 			{ /* C strings are converted into array constants with
 			     an explicit null byte added at the end.  Thus
 			     the array upper bound is the string length.
@@ -581,7 +610,9 @@ exp	:	STRING
 			  write_exp_elt_opcode (OP_ARRAY);
 			  write_exp_elt_longcst ((LONGEST) 0);
 			  write_exp_elt_longcst ((LONGEST) ($1.length));
-			  write_exp_elt_opcode (OP_ARRAY); }
+			  write_exp_elt_opcode (OP_ARRAY);
+			  xfree ($1.ptr);
+			}
 	;
 
 /* C++.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 110832d..06b87fe 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-08-20  Tom Tromey  <tromey@redhat.com>
+
+	* gdb.base/exprs.exp (test_expr): Add test for string
+	concatenation.
+
 2008-08-20  Pedro Alves  <pedro@codesourcery.com>
 
 	* gdb.base/pending.exp: Test pending breakpoints without symbols
diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp
index e25de77..ad60aad 100644
--- a/gdb/testsuite/gdb.base/exprs.exp
+++ b/gdb/testsuite/gdb.base/exprs.exp
@@ -248,3 +248,6 @@ gdb_test "print (void*) ((long long) (unsigned long) -1 + 1)" \
 if [expr ! $ok] { setup_xfail "*-*-*" }
 gdb_test "print (void*) (~((long long)(unsigned long) -1) - 1)" \
 	"warning: value truncated.*" "truncate (void*) 0xffffffff00000000 - 1"
+
+# String concatentation.
+test_expr "print \"x\" \"y\"" "\\$\[0-9\]* = \"xy\""
projecttype:gdb
email:tromey@gcc.gnu.org
revision:487e37302379bf0cf2810f8d6c529844117b8ba9
configure:
make:
check:

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3e47523..986759c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2008-08-20  Tom Tromey  <tromey@redhat.com>
+
+	PR gdb/2409:
+	* parser-defs.h (insert_type, insert_type_address_space): Declare.
+	(push_type_address_space): Remove.
+	* parse.c (insert_into_type_stack): New function.
+	(insert_type): Likewise.
+	(insert_type_address_space): Rename from push_type_address_space.
+	Insert tp_space_identifier.
+	* c-exp.y (ptr_operator): New production.
+	(abs_decl): Use ptr_operator.
+	(space_identifier): Call insert_type_address_space.
+	(ptype): Don't use const_or_volatile_or_space_identifier.
+	(const_or_volatile_noopt): Call insert_type.
+
 2008-08-18  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* rs6000-tdep.c (struct rs6000_framedata): Add gpr_mask, used_bl,
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index bd04dc2..79034c8 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -162,7 +162,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
 /* %type <bval> block */
 
 /* Fancy type parsing.  */
-%type <voidval> func_mod direct_abs_decl abs_decl
+%type <voidval> func_mod direct_abs_decl abs_decl ptr_operator
 %type <tval> ptype
 %type <lval> array_mod
 
@@ -771,9 +771,7 @@ variable:	name_not_typename
 	;
 
 space_identifier : '@' NAME
-		{ push_type_address_space (copy_name ($2.stoken));
-		  push_type (tp_space_identifier);
-		}
+		{ insert_type_address_space (copy_name ($2.stoken)); }
 	;
 
 const_or_volatile: const_or_volatile_noopt
@@ -792,14 +790,23 @@ const_or_volatile_or_space_identifier:
 	|
 	;
 
-abs_decl:	'*'
-			{ push_type (tp_pointer); $$ = 0; }
-	|	'*' abs_decl
-			{ push_type (tp_pointer); $$ = $2; }
+ptr_operator:
+		ptr_operator '*'
+			{ insert_type (tp_pointer); }
+		const_or_volatile_or_space_identifier
+			{ $$ = 0; }
+	|	'*' 
+			{ insert_type (tp_pointer); }
+		const_or_volatile_or_space_identifier
+			{ $$ = 0; }
 	|	'&'
-			{ push_type (tp_reference); $$ = 0; }
-	|	'&' abs_decl
-			{ push_type (tp_reference); $$ = $2; }
+			{ insert_type (tp_reference); $$ = 0; }
+	|	'&' ptr_operator
+			{ insert_type (tp_reference); $$ = 0; }
+	;
+
+abs_decl:	ptr_operator direct_abs_decl
+	|	ptr_operator
 	|	direct_abs_decl
 	;
 
@@ -1044,7 +1051,7 @@ nonempty_typelist
 	;
 
 ptype	:	typebase
-	|	ptype const_or_volatile_or_space_identifier abs_decl const_or_volatile_or_space_identifier
+	|	ptype abs_decl
 		{ $$ = follow_types ($1); }
 	;
 
@@ -1053,13 +1060,13 @@ const_and_volatile: 	CONST_KEYWORD VOLATILE_KEYWORD
 	;
 
 const_or_volatile_noopt:  	const_and_volatile 
-			{ push_type (tp_const);
-			  push_type (tp_volatile); 
+			{ insert_type (tp_const);
+			  insert_type (tp_volatile); 
 			}
 	| 		CONST_KEYWORD
-			{ push_type (tp_const); }
+			{ insert_type (tp_const); }
 	| 		VOLATILE_KEYWORD
-			{ push_type (tp_volatile); }
+			{ insert_type (tp_volatile); }
 	;
 
 name	:	NAME { $$ = $1.stoken; }
diff --git a/gdb/parse.c b/gdb/parse.c
index b587ec3..c4bbf71 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1153,6 +1153,49 @@ check_type_stack_depth (void)
     }
 }
 
+/* A helper function for insert_type and insert_type_address_space.
+   This does work of expanding the type stack and inserting the new
+   element, ELEMENT, into the stack at location SLOT.  */
+
+static void
+insert_into_type_stack (int slot, union type_stack_elt element)
+{
+  check_type_stack_depth ();
+
+  if (slot < type_stack_depth)
+    memmove (&type_stack[slot + 1], &type_stack[slot],
+	     (type_stack_depth - slot) * sizeof (union type_stack_elt));
+  type_stack[slot] = element;
+  ++type_stack_depth;
+}
+
+/* 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.  */
+
+void
+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);
+
+  /* If there is anything on the stack (we know it will be a
+     tp_pointer), insert the qualifier above it.  Otherwise, simply
+     push this on the top of the stack.  */
+  if (type_stack_depth && (tp == tp_const || tp == tp_volatile))
+    slot = 1;
+  else
+    slot = 0;
+
+  element.piece = tp;
+  insert_into_type_stack (slot, element);
+}
+
 void
 push_type (enum type_pieces tp)
 {
@@ -1167,10 +1210,32 @@ push_type_int (int n)
   type_stack[type_stack_depth++].int_val = n;
 }
 
+/* Insert a tp_space_identifier and the corresponding address space
+   value into the stack.  STRING is the name of an address space, as
+   recognized by address_space_name_to_int.  If the stack is empty,
+   the new elements are simply pushed.  If the stack is not empty,
+   this function assumes that the first item on the stack is a
+   tp_pointer, and the new values are inserted above the first
+   item.  */
+
 void
-push_type_address_space (char *string)
+insert_type_address_space (char *string)
 {
-  push_type_int (address_space_name_to_int (string));
+  union type_stack_elt element;
+  int slot;
+
+  /* If there is anything on the stack (we know it will be a
+     tp_pointer), insert the address space qualifier above it.
+     Otherwise, simply push this on the top of the stack.  */
+  if (type_stack_depth)
+    slot = 1;
+  else
+    slot = 0;
+
+  element.piece = tp_space_identifier;
+  insert_into_type_stack (slot, element);
+  element.int_val = address_space_name_to_int (string);
+  insert_into_type_stack (slot, element);
 }
 
 enum type_pieces
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index f49ff9e..b1380a3 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -148,11 +148,13 @@ extern int end_arglist (void);
 
 extern char *copy_name (struct stoken);
 
+extern void insert_type (enum type_pieces);
+
 extern void push_type (enum type_pieces);
 
 extern void push_type_int (int);
 
-extern void push_type_address_space (char *);
+extern void insert_type_address_space (char *);
 
 extern enum type_pieces pop_type (void);
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 831a2f4..06299e4 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-08-20  Tom Tromey  <tromey@redhat.com>
+
+	* gdb.base/whatis.exp: Add tests.
+
 2008-08-18  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* gdb.arch/powerpc-prologue.exp: Correct saved registers.
diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp
index d480995..ec75d3f 100644
--- a/gdb/testsuite/gdb.base/whatis.exp
+++ b/gdb/testsuite/gdb.base/whatis.exp
@@ -471,3 +471,17 @@ gdb_test "whatis char_addr" \
 gdb_test "whatis a_char_addr" \
     "type = char_addr" \
     "whatis applied to variable defined by typedef"
+
+# Regression tests for PR 2409.
+
+gdb_test "whatis void (**)()" \
+  "type = void \\(\\*\\*\\)\\(\\)" \
+  "whatis applied to pointer to pointer to function"
+
+gdb_test "whatis void (** const)()" \
+  "type = void \\(\\*\\*\\ const)\\(\\)" \
+  "whatis applied to const pointer to pointer to function"
+
+gdb_test "whatis void (* const *)()" \
+  "type = void \\(\\* const \\*\\)\\(\\)" \
+  "whatis applied to pointer to const pointer to function"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]