PR exp/9608:

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

View File

@ -1,3 +1,22 @@
2012-07-06 Tom Tromey <tromey@redhat.com>
PR exp/9608:
* 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.
2012-07-06 Tom Tromey <tromey@redhat.com>
* c-exp.y (%union) <type_stack>: New field.

View File

@ -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;
}
;

View File

@ -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

View File

@ -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);

View File

@ -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 ();

View File

@ -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);

View File

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

View File

@ -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"