* 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.
+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.
struct internalvar *ivar;
struct stoken_vector svec;
- struct type **tvec;
+ VEC (type_ptr) *tvec;
int *ivec;
struct type_stack *type_stack;
%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. */
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);
}
;
| 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 ();
}
;
;
func_mod: '(' ')'
+ { $$ = NULL; }
| '(' nonempty_typelist ')'
- { free ($2); }
+ { $$ = $2; }
;
/* We used to try to recognize pointer to member types here, but
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;
}
;
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
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);
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 *
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 *
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 ();
#define PARSER_DEFS_H 1
#include "doublest.h"
+#include "vec.h"
struct block;
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. */
tp_pointer,
tp_reference,
tp_array,
- tp_function,
+ tp_function,
+ tp_function_with_arguments,
tp_const,
tp_volatile,
tp_space_identifier,
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. */
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);
+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.
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"