* 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.
testsuite
	* gdb.base/whatis.exp: Add test.
This commit is contained in:
Tom Tromey 2012-07-06 14:48:48 +00:00
parent 71918a863f
commit a6fb9c08a9
7 changed files with 49 additions and 6 deletions

View file

@ -1,3 +1,13 @@
2012-07-06 Tom Tromey <tromey@redhat.com>
* 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.
2012-07-06 Tom Tromey <tromey@redhat.com> 2012-07-06 Tom Tromey <tromey@redhat.com>
PR exp/9608: PR exp/9608:

View file

@ -170,7 +170,7 @@ static struct stoken operator_stoken (const char *);
%type <voidval> exp exp1 type_exp start variable qualified_name lcurly %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
%type <lval> rcurly %type <lval> rcurly
%type <tval> type typebase %type <tval> type typebase
%type <tvec> nonempty_typelist func_mod %type <tvec> nonempty_typelist func_mod parameter_typelist
/* %type <bval> block */ /* %type <bval> block */
/* Fancy type parsing. */ /* Fancy type parsing. */
@ -254,6 +254,8 @@ static struct stoken operator_stoken (const char *);
%type <bval> block %type <bval> block
%left COLONCOLON %left COLONCOLON
%token DOTDOTDOT
%% %%
@ -440,7 +442,7 @@ arglist : arglist ',' exp %prec ABOVE_COMMA
{ arglist_len++; } { arglist_len++; }
; ;
exp : exp '(' nonempty_typelist ')' const_or_volatile exp : exp '(' parameter_typelist ')' const_or_volatile
{ int i; { int i;
VEC (type_ptr) *type_list = $3; VEC (type_ptr) *type_list = $3;
struct type *type_elt; struct type *type_elt;
@ -1025,7 +1027,7 @@ array_mod: '[' ']'
func_mod: '(' ')' func_mod: '(' ')'
{ $$ = NULL; } { $$ = NULL; }
| '(' nonempty_typelist ')' | '(' parameter_typelist ')'
{ $$ = $2; } { $$ = $2; }
; ;
@ -1223,6 +1225,15 @@ typename: TYPENAME
} }
; ;
parameter_typelist:
nonempty_typelist
| nonempty_typelist ',' DOTDOTDOT
{
VEC_safe_push (type_ptr, $1, NULL);
$$ = $1;
}
;
nonempty_typelist nonempty_typelist
: type : type
{ {
@ -1942,7 +1953,8 @@ static const struct token tokentab3[] =
{ {
{">>=", ASSIGN_MODIFY, BINOP_RSH, 0}, {">>=", ASSIGN_MODIFY, BINOP_RSH, 0},
{"<<=", ASSIGN_MODIFY, BINOP_LSH, 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[] = static const struct token tokentab2[] =

View file

@ -769,6 +769,11 @@ make_params (int num_types, struct type **param_types)
TYPE_CODE (type) = TYPE_CODE_METHOD; TYPE_CODE (type) = TYPE_CODE_METHOD;
TYPE_VPTR_FIELDNO (type) = -1; TYPE_VPTR_FIELDNO (type) = -1;
TYPE_CHAIN (type) = type; 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_NFIELDS (type) = num_types;
TYPE_FIELDS (type) = (struct field *) TYPE_FIELDS (type) = (struct field *)
TYPE_ZALLOC (type, sizeof (struct field) * num_types); TYPE_ZALLOC (type, sizeof (struct field) * num_types);

View file

@ -463,7 +463,8 @@ lookup_function_type (struct type *type)
} }
/* Given a type TYPE and argument types, return the appropriate /* 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 * struct type *
lookup_function_type_with_arguments (struct type *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); struct type *fn = make_function_type (type, (struct type **) 0);
int i; int i;
if (nparams > 0 && param_types[nparams - 1] == NULL)
{
--nparams;
TYPE_VARARGS (fn) = 1;
}
TYPE_NFIELDS (fn) = nparams; TYPE_NFIELDS (fn) = nparams;
TYPE_FIELDS (fn) = TYPE_ZALLOC (fn, nparams * sizeof (struct field)); TYPE_FIELDS (fn) = TYPE_ZALLOC (fn, nparams * sizeof (struct field));
for (i = 0; i < nparams; ++i) for (i = 0; i < nparams; ++i)

View file

@ -1555,7 +1555,8 @@ type_stack_cleanup (void *arg)
} }
/* Push a function type with arguments onto the global type stack. /* 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 void
push_typelist (VEC (type_ptr) *list) push_typelist (VEC (type_ptr) *list)

View file

@ -1,3 +1,7 @@
2012-07-06 Tom Tromey <tromey@redhat.com>
* gdb.base/whatis.exp: Add test.
2012-07-06 Tom Tromey <tromey@redhat.com> 2012-07-06 Tom Tromey <tromey@redhat.com>
* gdb.base/whatis.exp: Add regression test. * gdb.base/whatis.exp: Add regression test.

View file

@ -495,3 +495,7 @@ gdb_test "whatis char (*(*)())\[23\]" \
gdb_test "whatis int (*)(int, int)" \ gdb_test "whatis int (*)(int, int)" \
"type = int \\(\\*\\)\\(int, int\\)" \ "type = int \\(\\*\\)\\(int, int\\)" \
"whatis applied to pointer to function taking int,int and returning 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"