This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[PATCH 4/5] Preserve function argument types while parsing


This fixes PR exp/9608.  The bug is that function parameter types in C
expressions are dropped.  You can see this most easily with:

    whatis int (*) (int)

Right now gdb will print "int (*)()".

Built and regtested on x86-64 Fedora 16.
New test case included.

	* c-exp.y (%union) <tvec>: Change type.
	(func_mod): Now uses <tvec> type.
	(exp): Update for tvec change.
	(direct_abs_decl): Push the typelist.
	(func_mod): Return a typelist.
	(nonempty_typelist): Update for tvec change.
	* gdbtypes.c (lookup_function_type_with_arguments): New function.
	* gdbtypes.h (lookup_function_type_with_arguments): Declare.
	* parse.c (pop_type_list): New function.
	(push_typelist): New function.
	(follow_types): Handle tp_function_with_arguments.
	* parser-defs.h (type_ptr): New typedef.  Define a VEC.
	(enum type_pieces) <tp_function_with_arguments>: New constant.
	(union type_stack_elt) <typelist_val>: New field.
	(push_typelist): Declare.

	* gdb.base/whatis.exp: Add regression test.
---
 gdb/c-exp.y                       |   40 ++++++++++++++++++++++--------------
 gdb/gdbtypes.c                    |   19 +++++++++++++++++
 gdb/gdbtypes.h                    |    4 +++
 gdb/parse.c                       |   33 ++++++++++++++++++++++++++++++
 gdb/parser-defs.h                 |    9 +++++++-
 gdb/testsuite/gdb.base/whatis.exp |    4 +++
 6 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 5ea5704..8890f74 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -155,7 +155,7 @@ void yyerror (char *);
     struct internalvar *ivar;
 
     struct stoken_vector svec;
-    struct type **tvec;
+    VEC (type_ptr) *tvec;
     int *ivec;
 
     struct type_stack *type_stack;
@@ -170,7 +170,7 @@ static struct stoken operator_stoken (const char *);
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
 %type <lval> rcurly
 %type <tval> type typebase
-%type <tvec> nonempty_typelist
+%type <tvec> nonempty_typelist func_mod
 /* %type <bval> block */
 
 /* Fancy type parsing.  */
@@ -442,13 +442,19 @@ arglist	:	arglist ',' exp   %prec ABOVE_COMMA
 
 exp     :       exp '(' nonempty_typelist ')' const_or_volatile
 			{ int i;
+			  VEC (type_ptr) *type_list = $3;
+			  struct type *type_elt;
+			  LONGEST len = VEC_length (type_ptr, type_list);
+
 			  write_exp_elt_opcode (TYPE_INSTANCE);
-			  write_exp_elt_longcst ((LONGEST) $<ivec>3[0]);
-			  for (i = 0; i < $<ivec>3[0]; ++i)
-			    write_exp_elt_type ($<tvec>3[i + 1]);
-			  write_exp_elt_longcst((LONGEST) $<ivec>3[0]);
+			  write_exp_elt_longcst (len);
+			  for (i = 0;
+			       VEC_iterate (type_ptr, type_list, i, type_elt);
+			       ++i)
+			    write_exp_elt_type (type_elt);
+			  write_exp_elt_longcst(len);
 			  write_exp_elt_opcode (TYPE_INSTANCE);
-			  free ($3);
+			  VEC_free (type_ptr, type_list);
 			}
 	;
 
@@ -1001,12 +1007,12 @@ direct_abs_decl: '(' abs_decl ')'
 	| 	direct_abs_decl func_mod
 			{
 			  push_type_stack ($1);
-			  push_type (tp_function);
+			  push_typelist ($2);
 			  $$ = get_type_stack ();
 			}
 	|	func_mod
 			{
-			  push_type (tp_function);
+			  push_typelist ($1);
 			  $$ = get_type_stack ();
 			}
 	;
@@ -1018,8 +1024,9 @@ array_mod:	'[' ']'
 	;
 
 func_mod:	'(' ')'
+			{ $$ = NULL; }
 	|	'(' nonempty_typelist ')'
-			{ free ($2); }
+			{ $$ = $2; }
 	;
 
 /* We used to try to recognize pointer to member types here, but
@@ -1218,14 +1225,15 @@ typename:	TYPENAME
 
 nonempty_typelist
 	:	type
-		{ $$ = (struct type **) malloc (sizeof (struct type *) * 2);
-		  $<ivec>$[0] = 1;	/* Number of types in vector */
-		  $$[1] = $1;
+		{
+		  VEC (type_ptr) *typelist = NULL;
+		  VEC_safe_push (type_ptr, typelist, $1);
+		  $$ = typelist;
 		}
 	|	nonempty_typelist ',' type
-		{ int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);
-		  $$ = (struct type **) realloc ((char *) $1, len);
-		  $$[$<ivec>$[0]] = $3;
+		{
+		  VEC_safe_push (type_ptr, $1, $3);
+		  $$ = $1;
 		}
 	;
 
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 0eec874..bcc2edf 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -462,6 +462,25 @@ lookup_function_type (struct type *type)
   return make_function_type (type, (struct type **) 0);
 }
 
+/* Given a type TYPE and argument types, return the appropriate
+   function type.  */
+
+struct type *
+lookup_function_type_with_arguments (struct type *type,
+				     int nparams,
+				     struct type **param_types)
+{
+  struct type *fn = make_function_type (type, (struct type **) 0);
+  int i;
+
+  TYPE_NFIELDS (fn) = nparams;
+  TYPE_FIELDS (fn) = TYPE_ZALLOC (fn, nparams * sizeof (struct field));
+  for (i = 0; i < nparams; ++i)
+    TYPE_FIELD_TYPE (fn, i) = param_types[i];
+
+  return fn;
+}
+
 /* Identify address space identifier by name --
    return the integer flag defined in gdbtypes.h.  */
 extern int
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 3b4edea..17bfbc5 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1520,6 +1520,10 @@ extern struct type *make_function_type (struct type *, struct type **);
 
 extern struct type *lookup_function_type (struct type *);
 
+extern struct type *lookup_function_type_with_arguments (struct type *,
+							 int,
+							 struct type **);
+
 extern struct type *create_range_type (struct type *, struct type *, LONGEST,
 				       LONGEST);
 
diff --git a/gdb/parse.c b/gdb/parse.c
index b1ad832..897002d 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1483,6 +1483,15 @@ pop_type_int (void)
   return 0;
 }
 
+/* Pop a type list element from the global type stack.  */
+
+static VEC (type_ptr) *
+pop_typelist (void)
+{
+  gdb_assert (type_stack.depth);
+  return type_stack.elements[--type_stack.depth].typelist_val;
+}
+
 /* Pop a type_stack element from the global type stack.  */
 
 static struct type_stack *
@@ -1545,6 +1554,17 @@ type_stack_cleanup (void *arg)
   xfree (stack);
 }
 
+/* Push a function type with arguments onto the global type stack.
+   LIST holds the argument types.  */
+
+void
+push_typelist (VEC (type_ptr) *list)
+{
+  check_type_stack_depth ();
+  type_stack.elements[type_stack.depth++].typelist_val = list;
+  push_type (tp_function_with_arguments);
+}
+
 /* Pop the type stack and return the type which corresponds to FOLLOW_TYPE
    as modified by all the stuff on the stack.  */
 struct type *
@@ -1632,6 +1652,19 @@ follow_types (struct type *follow_type)
 	follow_type = lookup_function_type (follow_type);
 	break;
 
+      case tp_function_with_arguments:
+	{
+	  VEC (type_ptr) *args = pop_typelist ();
+
+	  follow_type
+	    = lookup_function_type_with_arguments (follow_type,
+						   VEC_length (type_ptr, args),
+						   VEC_address (type_ptr,
+								args));
+	  VEC_free (type_ptr, args);
+	}
+	break;
+
       case tp_type_stack:
 	{
 	  struct type_stack *stack = pop_type_stack ();
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 0649189..86f3bdf 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -25,6 +25,7 @@
 #define PARSER_DEFS_H 1
 
 #include "doublest.h"
+#include "vec.h"
 
 struct block;
 
@@ -107,6 +108,8 @@ struct objc_class_str
     int class;
   };
 
+typedef struct type *type_ptr;
+DEF_VEC_P (type_ptr);
 
 /* For parsing of complicated types.
    An array should be preceded in the list by the size of the array.  */
@@ -116,7 +119,8 @@ enum type_pieces
     tp_pointer, 
     tp_reference, 
     tp_array, 
-    tp_function, 
+    tp_function,
+    tp_function_with_arguments,
     tp_const, 
     tp_volatile, 
     tp_space_identifier,
@@ -128,6 +132,7 @@ union type_stack_elt
     enum type_pieces piece;
     int int_val;
     struct type_stack *stack_val;
+    VEC (type_ptr) *typelist_val;
   };
 
 /* The type stack is an instance of this structure.  */
@@ -225,6 +230,8 @@ extern void push_type_stack (struct type_stack *stack);
 
 extern void type_stack_cleanup (void *arg);
 
+extern void push_typelist (VEC (type_ptr) *typelist);
+
 extern int length_of_subexp (struct expression *, int);
 
 extern int dump_subexp (struct expression *, struct ui_file *, int);
diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp
index 71f2e79..336901d 100644
--- a/gdb/testsuite/gdb.base/whatis.exp
+++ b/gdb/testsuite/gdb.base/whatis.exp
@@ -491,3 +491,7 @@ gdb_test "whatis int *(**)()" \
 gdb_test "whatis char (*(*)())\[23\]" \
     "type = char \\(\\*\\(\\*\\)\\(\\)\\)\\\[23\\\]" \
     "whatis applied to pointer to function returning pointer to array"
+
+gdb_test "whatis int (*)(int, int)" \
+    "type = int \\(\\*\\)\\(int, int\\)" \
+    "whatis applied to pointer to function taking int,int and returning int"
-- 
1.7.7.6


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