PR exp/9608:
authorTom Tromey <tromey@redhat.com>
Fri, 6 Jul 2012 14:47:00 +0000 (14:47 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 6 Jul 2012 14:47:00 +0000 (14:47 +0000)
* 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.

gdb/ChangeLog
gdb/c-exp.y
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/parse.c
gdb/parser-defs.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/whatis.exp

index 073c93ad6ce81b6d383e0ae79012ed7511abf2f7..650b6f76cc2258f0eaf75942fd155470ff668da8 100644 (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.
index 5ea57041d815c7f29509d37576c463282c959ee2..8890f74555f1d4465a7c115b86b25ee1e2fcacc3 100644 (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;
                }
        ;
 
index 0eec874bc8739bc384638dd6b710d1023f4d7956..bcc2edf70e6fac62153800ab7608a2ff76121ffa 100644 (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
index 3b4edea21e4b9682faf285d1d3059e318f3a1fc4..17bfbc55b31dae69d80d980aa06befecd6b4f830 100644 (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);
 
index b1ad8320b9a51568fbc9a991c8a78338a603cdf2..897002d91154aa34b0cf04161a6e36c72701c083 100644 (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 ();
index 06491893ddc7e8ebba5ac43e52f3ddf2b13aa15e..86f3bdf10632b4e1003bc219efbe7e3db0155c39 100644 (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);
index ed2fcf11ad69e32a34a705b33e060dae16a12f8c..6a297e2dad779503d7876d01808c4e6cd64f23f6 100644 (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.
index 71f2e79d33b9493605d1601e2a004edce2ea682d..336901d78e292ec89a5635471825be016342da07 100644 (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"