(func_mod, exp): Use parameter_typelist.
	(parameter_typelist): New production.
	(tokentab3): Add "..." token.
	* eval.c (make_params): Handle varargs.
	* gdbtypes.c (lookup_function_type_with_arguments): Handle
	varargs.
testsuite
	* gdb.base/whatis.exp: Add test.
+2012-07-06  Tom Tromey  <tromey@redhat.com>
+
+       * c-exp.y (DOTDOTDOT): New token.
+       (func_mod, exp): Use parameter_typelist.
+       (parameter_typelist): New production.
+       (tokentab3): Add "..." token.
+       * eval.c (make_params): Handle varargs.
+       * gdbtypes.c (lookup_function_type_with_arguments): Handle
+       varargs.
+
 2012-07-06  Tom Tromey  <tromey@redhat.com>
 
        PR exp/9608:
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
 %type <lval> rcurly
 %type <tval> type typebase
-%type <tvec> nonempty_typelist func_mod
+%type <tvec> nonempty_typelist func_mod parameter_typelist
 /* %type <bval> block */
 
 /* Fancy type parsing.  */
 %type <bval> block
 %left COLONCOLON
 
+%token DOTDOTDOT
+
 \f
 %%
 
                        { arglist_len++; }
        ;
 
-exp     :       exp '(' nonempty_typelist ')' const_or_volatile
+exp     :       exp '(' parameter_typelist ')' const_or_volatile
                        { int i;
                          VEC (type_ptr) *type_list = $3;
                          struct type *type_elt;
 
 func_mod:      '(' ')'
                        { $$ = NULL; }
-       |       '(' nonempty_typelist ')'
+       |       '(' parameter_typelist ')'
                        { $$ = $2; }
        ;
 
                }
        ;
 
+parameter_typelist:
+               nonempty_typelist
+       |       nonempty_typelist ',' DOTDOTDOT
+                       {
+                         VEC_safe_push (type_ptr, $1, NULL);
+                         $$ = $1;
+                       }
+       ;
+
 nonempty_typelist
        :       type
                {
   {
     {">>=", ASSIGN_MODIFY, BINOP_RSH, 0},
     {"<<=", ASSIGN_MODIFY, BINOP_LSH, 0},
-    {"->*", ARROW_STAR, BINOP_END, 1}
+    {"->*", ARROW_STAR, BINOP_END, 1},
+    {"...", DOTDOTDOT, BINOP_END, 0}
   };
 
 static const struct token tokentab2[] =
 
   TYPE_CODE (type) = TYPE_CODE_METHOD;
   TYPE_VPTR_FIELDNO (type) = -1;
   TYPE_CHAIN (type) = type;
+  if (num_types > 0 && param_types[num_types - 1] == NULL)
+    {
+      --num_types;
+      TYPE_VARARGS (type) = 1;
+    }
   TYPE_NFIELDS (type) = num_types;
   TYPE_FIELDS (type) = (struct field *)
     TYPE_ZALLOC (type, sizeof (struct field) * num_types);
 
 }
 
 /* Given a type TYPE and argument types, return the appropriate
-   function type.  */
+   function type.  If the final type in PARAM_TYPES is NULL, make a
+   varargs function.  */
 
 struct type *
 lookup_function_type_with_arguments (struct type *type,
   struct type *fn = make_function_type (type, (struct type **) 0);
   int i;
 
+  if (nparams > 0 && param_types[nparams - 1] == NULL)
+    {
+      --nparams;
+      TYPE_VARARGS (fn) = 1;
+    }
+
   TYPE_NFIELDS (fn) = nparams;
   TYPE_FIELDS (fn) = TYPE_ZALLOC (fn, nparams * sizeof (struct field));
   for (i = 0; i < nparams; ++i)
 
 }
 
 /* Push a function type with arguments onto the global type stack.
-   LIST holds the argument types.  */
+   LIST holds the argument types.  If the final item in LIST is NULL,
+   then the function will be varargs.  */
 
 void
 push_typelist (VEC (type_ptr) *list)
 
+2012-07-06  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.base/whatis.exp: Add test.
+
 2012-07-06  Tom Tromey  <tromey@redhat.com>
 
        * gdb.base/whatis.exp: Add regression test.
 
 gdb_test "whatis int (*)(int, int)" \
     "type = int \\(\\*\\)\\(int, int\\)" \
     "whatis applied to pointer to function taking int,int and returning int"
+
+gdb_test "whatis int (*)(const int *, ...)" \
+    "type = int \\(\\*\\)\\(const int \\*, \\.\\.\\.\\)" \
+    "whatis applied to pointer to function taking const int ptr and varargs and returning int"