Implement late-specified return type using 'auto'.
* cp-tree.h (struct cp_declarator): Add late_return_type field to function declarator. * parser.c (cp_parser_late_return_type_opt): New fn. (cp_parser_direct_declarator): Use it. (make_call_declarator): Put it in the declarator. * decl.c (grokdeclarator): Splice in late-specified return type. * pt.c (splice_late_return_type): New fn. From-SVN: r139848
This commit is contained in:
parent
3699867372
commit
f57ca1ea5f
6 changed files with 82 additions and 3 deletions
|
@ -1,3 +1,14 @@
|
|||
2008-08-31 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Implement late-specified return type using 'auto'.
|
||||
* cp-tree.h (struct cp_declarator): Add late_return_type field to
|
||||
function declarator.
|
||||
* parser.c (cp_parser_late_return_type_opt): New fn.
|
||||
(cp_parser_direct_declarator): Use it.
|
||||
(make_call_declarator): Put it in the declarator.
|
||||
* decl.c (grokdeclarator): Splice in late-specified return type.
|
||||
* pt.c (splice_late_return_type): New fn.
|
||||
|
||||
2008-08-29 Michael Meissner <gnu@the-meissners.org>
|
||||
|
||||
* decl.c (builtin_function_1): Take a bool argument to decide
|
||||
|
|
|
@ -4108,6 +4108,8 @@ struct cp_declarator {
|
|||
cp_cv_quals qualifiers;
|
||||
/* The exception-specification for the function. */
|
||||
tree exception_specification;
|
||||
/* The late-specified return type, if any. */
|
||||
tree late_return_type;
|
||||
} function;
|
||||
/* For arrays. */
|
||||
struct {
|
||||
|
@ -4525,6 +4527,7 @@ extern tree check_explicit_specialization (tree, tree, int, int);
|
|||
extern tree make_auto (void);
|
||||
extern tree do_auto_deduction (tree, tree, tree);
|
||||
extern tree type_uses_auto (tree);
|
||||
extern tree splice_late_return_type (tree, tree);
|
||||
extern bool is_auto (const_tree);
|
||||
extern tree process_template_parm (tree, tree, bool, bool);
|
||||
extern tree end_template_parm_list (tree);
|
||||
|
|
|
@ -8220,6 +8220,12 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
/* Pick up the exception specifications. */
|
||||
raises = declarator->u.function.exception_specification;
|
||||
|
||||
/* Handle a late-specified return type. */
|
||||
type = splice_late_return_type
|
||||
(type, declarator->u.function.late_return_type);
|
||||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Say it's a definition only for the CALL_EXPR
|
||||
closest to the identifier. */
|
||||
funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
|
||||
|
|
|
@ -853,7 +853,7 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs)
|
|||
VAR_DECLs or FUNCTION_DECLs) should do that directly. */
|
||||
|
||||
static cp_declarator *make_call_declarator
|
||||
(cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree);
|
||||
(cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree, tree);
|
||||
static cp_declarator *make_array_declarator
|
||||
(cp_declarator *, tree);
|
||||
static cp_declarator *make_pointer_declarator
|
||||
|
@ -1015,7 +1015,8 @@ cp_declarator *
|
|||
make_call_declarator (cp_declarator *target,
|
||||
cp_parameter_declarator *parms,
|
||||
cp_cv_quals cv_qualifiers,
|
||||
tree exception_specification)
|
||||
tree exception_specification,
|
||||
tree late_return_type)
|
||||
{
|
||||
cp_declarator *declarator;
|
||||
|
||||
|
@ -1024,6 +1025,7 @@ make_call_declarator (cp_declarator *target,
|
|||
declarator->u.function.parameters = parms;
|
||||
declarator->u.function.qualifiers = cv_qualifiers;
|
||||
declarator->u.function.exception_specification = exception_specification;
|
||||
declarator->u.function.late_return_type = late_return_type;
|
||||
if (target)
|
||||
{
|
||||
declarator->parameter_pack_p = target->parameter_pack_p;
|
||||
|
@ -1726,6 +1728,8 @@ static enum tree_code cp_parser_ptr_operator
|
|||
(cp_parser *, tree *, cp_cv_quals *);
|
||||
static cp_cv_quals cp_parser_cv_qualifier_seq_opt
|
||||
(cp_parser *);
|
||||
static tree cp_parser_late_return_type_opt
|
||||
(cp_parser *);
|
||||
static tree cp_parser_declarator_id
|
||||
(cp_parser *, bool);
|
||||
static tree cp_parser_type_id
|
||||
|
@ -13021,6 +13025,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
{
|
||||
cp_cv_quals cv_quals;
|
||||
tree exception_specification;
|
||||
tree late_return;
|
||||
|
||||
if (ctor_dtor_or_conv_p)
|
||||
*ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
|
||||
|
@ -13034,11 +13039,15 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
exception_specification
|
||||
= cp_parser_exception_specification_opt (parser);
|
||||
|
||||
late_return
|
||||
= cp_parser_late_return_type_opt (parser);
|
||||
|
||||
/* Create the function-declarator. */
|
||||
declarator = make_call_declarator (declarator,
|
||||
params,
|
||||
cv_quals,
|
||||
exception_specification);
|
||||
exception_specification,
|
||||
late_return);
|
||||
/* Any subsequent parameter lists are to do with
|
||||
return type, so are not those of the declared
|
||||
function. */
|
||||
|
@ -13516,6 +13525,30 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
|
|||
return cv_quals;
|
||||
}
|
||||
|
||||
/* Parse a late-specified return type, if any. This is not a separate
|
||||
non-terminal, but part of a function declarator, which looks like
|
||||
|
||||
-> type-id
|
||||
|
||||
Returns the type indicated by the type-id. */
|
||||
|
||||
static tree
|
||||
cp_parser_late_return_type_opt (cp_parser* parser)
|
||||
{
|
||||
cp_token *token;
|
||||
|
||||
/* Peek at the next token. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
/* A late-specified return type is indicated by an initial '->'. */
|
||||
if (token->type != CPP_DEREF)
|
||||
return NULL_TREE;
|
||||
|
||||
/* Consume the ->. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
return cp_parser_type_id (parser);
|
||||
}
|
||||
|
||||
/* Parse a declarator-id.
|
||||
|
||||
declarator-id:
|
||||
|
|
17
gcc/cp/pt.c
17
gcc/cp/pt.c
|
@ -16769,6 +16769,23 @@ do_auto_deduction (tree type, tree init, tree auto_node)
|
|||
return tsubst (type, targs, tf_warning_or_error, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Substitutes LATE_RETURN_TYPE for 'auto' in TYPE and returns the
|
||||
result. */
|
||||
|
||||
tree
|
||||
splice_late_return_type (tree type, tree late_return_type)
|
||||
{
|
||||
tree argvec;
|
||||
|
||||
if (late_return_type == NULL_TREE)
|
||||
return type;
|
||||
argvec = make_tree_vec (1);
|
||||
TREE_VEC_ELT (argvec, 0) = late_return_type;
|
||||
if (processing_template_decl)
|
||||
argvec = add_to_template_args (current_template_args (), argvec);
|
||||
return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto'. */
|
||||
|
||||
bool
|
||||
|
|
9
gcc/testsuite/g++.dg/cpp0x/auto6.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/auto6.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// { dg-options "-std=c++0x" }
|
||||
|
||||
auto f() -> int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
auto add(T t, U u) -> decltype (t+u); // { dg-bogus "not declared" "" { xfail *-*-* } }
|
Loading…
Add table
Reference in a new issue