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 5/5] Handle varargs function types


This adds support for varargs function types to the C parser.

It adopts a convention that a trailing NULL type means that the
function is varargs.  I did this out of convenience.

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

	* c-exp.y (DOTDOTDOT): New token.
	(func_mod, exp): Use parameter_typelist.
	(parameter_typelist): New production.
	(tokentab3): Add "..." token.
	* eval.c (make_params): Handle varargs.
	* gdbtypes.c (lookup_function_type_with_arguments): Handle
	varargs.

	* gdb.base/whatis.exp: Add test.
---
 gdb/c-exp.y                       |   20 ++++++++++++++++----
 gdb/eval.c                        |    5 +++++
 gdb/gdbtypes.c                    |    9 ++++++++-
 gdb/parse.c                       |    3 ++-
 gdb/testsuite/gdb.base/whatis.exp |    4 ++++
 5 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 8890f74..14fd53d 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -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 func_mod
+%type <tvec> nonempty_typelist func_mod parameter_typelist
 /* %type <bval> block */
 
 /* Fancy type parsing.  */
@@ -254,6 +254,8 @@ static struct stoken operator_stoken (const char *);
 %type <bval> block
 %left COLONCOLON
 
+%token DOTDOTDOT
+
 
 %%
 
@@ -440,7 +442,7 @@ arglist	:	arglist ',' exp   %prec ABOVE_COMMA
 			{ arglist_len++; }
 	;
 
-exp     :       exp '(' nonempty_typelist ')' const_or_volatile
+exp     :       exp '(' parameter_typelist ')' const_or_volatile
 			{ int i;
 			  VEC (type_ptr) *type_list = $3;
 			  struct type *type_elt;
@@ -1025,7 +1027,7 @@ array_mod:	'[' ']'
 
 func_mod:	'(' ')'
 			{ $$ = NULL; }
-	|	'(' nonempty_typelist ')'
+	|	'(' parameter_typelist ')'
 			{ $$ = $2; }
 	;
 
@@ -1223,6 +1225,15 @@ typename:	TYPENAME
 		}
 	;
 
+parameter_typelist:
+		nonempty_typelist
+	|	nonempty_typelist ',' DOTDOTDOT
+			{
+			  VEC_safe_push (type_ptr, $1, NULL);
+			  $$ = $1;
+			}
+	;
+
 nonempty_typelist
 	:	type
 		{
@@ -1942,7 +1953,8 @@ static const struct token tokentab3[] =
   {
     {">>=", ASSIGN_MODIFY, BINOP_RSH, 0},
     {"<<=", ASSIGN_MODIFY, BINOP_LSH, 0},
-    {"->*", ARROW_STAR, BINOP_END, 1}
+    {"->*", ARROW_STAR, BINOP_END, 1},
+    {"...", DOTDOTDOT, BINOP_END, 0}
   };
 
 static const struct token tokentab2[] =
diff --git a/gdb/eval.c b/gdb/eval.c
index 3d43406..13f997f 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -769,6 +769,11 @@ make_params (int num_types, struct type **param_types)
   TYPE_CODE (type) = TYPE_CODE_METHOD;
   TYPE_VPTR_FIELDNO (type) = -1;
   TYPE_CHAIN (type) = type;
+  if (num_types > 0 && param_types[num_types - 1] == NULL)
+    {
+      --num_types;
+      TYPE_VARARGS (type) = 1;
+    }
   TYPE_NFIELDS (type) = num_types;
   TYPE_FIELDS (type) = (struct field *)
     TYPE_ZALLOC (type, sizeof (struct field) * num_types);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index bcc2edf..cb25e71 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -463,7 +463,8 @@ lookup_function_type (struct type *type)
 }
 
 /* Given a type TYPE and argument types, return the appropriate
-   function type.  */
+   function type.  If the final type in PARAM_TYPES is NULL, make a
+   varargs function.  */
 
 struct type *
 lookup_function_type_with_arguments (struct type *type,
@@ -473,6 +474,12 @@ lookup_function_type_with_arguments (struct type *type,
   struct type *fn = make_function_type (type, (struct type **) 0);
   int i;
 
+  if (nparams > 0 && param_types[nparams - 1] == NULL)
+    {
+      --nparams;
+      TYPE_VARARGS (fn) = 1;
+    }
+
   TYPE_NFIELDS (fn) = nparams;
   TYPE_FIELDS (fn) = TYPE_ZALLOC (fn, nparams * sizeof (struct field));
   for (i = 0; i < nparams; ++i)
diff --git a/gdb/parse.c b/gdb/parse.c
index 897002d..529c517 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1555,7 +1555,8 @@ type_stack_cleanup (void *arg)
 }
 
 /* Push a function type with arguments onto the global type stack.
-   LIST holds the argument types.  */
+   LIST holds the argument types.  If the final item in LIST is NULL,
+   then the function will be varargs.  */
 
 void
 push_typelist (VEC (type_ptr) *list)
diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp
index 336901d..9365485 100644
--- a/gdb/testsuite/gdb.base/whatis.exp
+++ b/gdb/testsuite/gdb.base/whatis.exp
@@ -495,3 +495,7 @@ gdb_test "whatis char (*(*)())\[23\]" \
 gdb_test "whatis int (*)(int, int)" \
     "type = int \\(\\*\\)\\(int, int\\)" \
     "whatis applied to pointer to function taking int,int and returning int"
+
+gdb_test "whatis int (*)(const int *, ...)" \
+    "type = int \\(\\*\\)\\(const int \\*, \\.\\.\\.\\)" \
+    "whatis applied to pointer to function taking const int ptr and varargs 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]