diff options
-rw-r--r-- | gdb/ChangeLog | 19 | ||||
-rw-r--r-- | gdb/c-exp.y | 40 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 19 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 4 | ||||
-rw-r--r-- | gdb/parse.c | 33 | ||||
-rw-r--r-- | gdb/parser-defs.h | 9 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/whatis.exp | 4 |
8 files changed, 115 insertions, 17 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 073c93a..650b6f7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,24 @@ 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. (abs_decl, direct_abs_decl): Use <type_stack> type. Update. (ptr_operator_ts): New production. 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/ChangeLog b/gdb/testsuite/ChangeLog index ed2fcf1..6a297e2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 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. 2012-07-04 Jan Kratochvil <jan.kratochvil@redhat.com> 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" |