aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-07-06 14:47:00 +0000
committerTom Tromey <tromey@redhat.com>2012-07-06 14:47:00 +0000
commit71918a863fdc11435a0f47a1b3e49bfdf44f6ef5 (patch)
treeeec937131aa13c30d07f679b04e427899e4f7238
parentfcde5961ebacc85a85adcf858c751dc9c11f8d58 (diff)
downloadgdb-71918a863fdc11435a0f47a1b3e49bfdf44f6ef5.zip
gdb-71918a863fdc11435a0f47a1b3e49bfdf44f6ef5.tar.gz
gdb-71918a863fdc11435a0f47a1b3e49bfdf44f6ef5.tar.bz2
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.
-rw-r--r--gdb/ChangeLog19
-rw-r--r--gdb/c-exp.y40
-rw-r--r--gdb/gdbtypes.c19
-rw-r--r--gdb/gdbtypes.h4
-rw-r--r--gdb/parse.c33
-rw-r--r--gdb/parser-defs.h9
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.base/whatis.exp4
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"