diff options
author | Russell Yanofsky <russ@yanofsky.org> | 2007-05-31 01:18:22 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-05-31 01:18:22 +0000 |
commit | 8af2fec40bfd6889ab47b47d0a9cfaa5102c2507 (patch) | |
tree | 6d0815a650d1201c2dd1e4b249977bfe4379c548 /gcc/cp/parser.c | |
parent | 0ae581acf1fbef4189f22a23a00b6d827aee4b1b (diff) | |
download | gcc-8af2fec40bfd6889ab47b47d0a9cfaa5102c2507.zip gcc-8af2fec40bfd6889ab47b47d0a9cfaa5102c2507.tar.gz gcc-8af2fec40bfd6889ab47b47d0a9cfaa5102c2507.tar.bz2 |
re PR c++/7412 ([DR 106] References to references)
2007-05-30 Russell Yanofsky <russ@yanofsky.org>
Douglas Gregor <doug.gregor@gmail.com>
Pedro Lamarao <pedro.lamarao@mndfck.org>
Howard Hinnant <howard.hinnant@gmail.com>
PR c++/7412
PR c++/29939
* g++.dg/cpp0x/rv8p.C: New.
* g++.dg/cpp0x/temp-constructor-bug.C: New.
* g++.dg/cpp0x/cast-bug.C: New.
* g++.dg/cpp0x/elision_weak.C: New.
* g++.dg/cpp0x/collapse-bug.C: New.
* g++.dg/cpp0x/rv3p.C: New.
* g++.dg/cpp0x/rv7n.C: New.
* g++.dg/cpp0x/overload-conv-1.C: New.
* g++.dg/cpp0x/rv2n.C: New.
* g++.dg/cpp0x/deduce.C: New.
* g++.dg/cpp0x/temp-va-arg-bug.C: New.
* g++.dg/cpp0x/rv6p.C: New.
* g++.dg/cpp0x/template_deduction.C: New.
* g++.dg/cpp0x/implicit-copy.C: New.
* g++.dg/cpp0x/rv1p.C: New.
* g++.dg/cpp0x/cast.C: New.
* g++.dg/cpp0x/rv5n.C: New.
* g++.dg/cpp0x/collapse.C: New.
* g++.dg/cpp0x/overload-conv-2.C: New.
* g++.dg/cpp0x/rv4p.C: New.
* g++.dg/cpp0x/rvo.C: New.
* g++.dg/cpp0x/iop.C: New.
* g++.dg/cpp0x/rv3n.C: New.
* g++.dg/cpp0x/rv7p.C: New.
* g++.dg/cpp0x/reference_collapsing.C: New.
* g++.dg/cpp0x/overload.C: New.
* g++.dg/cpp0x/named.C: New.
* g++.dg/cpp0x/rv2p.C: New.
* g++.dg/cpp0x/rv6n.C: New.
* g++.dg/cpp0x/not_special.C: New.
* g++.dg/cpp0x/bind.C: New.
* g++.dg/cpp0x/rv1n.C: New.
* g++.dg/cpp0x/rv5p.C: New.
* g++.dg/cpp0x/elision.C: New.
* g++.dg/cpp0x/named_refs.C: New.
* g++.dg/cpp0x/unnamed_refs.C: New.
* g++.dg/cpp0x/rv4n.C: New.
* g++.dg/cpp0x/elision_neg.C: New.
* g++.dg/init/copy7.C: Run in C++98 mode.
* g++.dg/overload/arg1.C: Ditto.
* g++.dg/overload/arg4.C: Ditto.
2007-05-30 Russell Yanofsky <russ@yanofsky.org>
Douglas Gregor <doug.gregor@gmail.com>
Pedro Lamarao <pedro.lamarao@mndfck.org>
Howard Hinnant <howard.hinnant@gmail.com>
PR c++/7412
PR c++/29939
* typeck.c (comptypes): Don't consider rvalue and lvalue
reference types to be equivalent.
(check_return_expr): Move from certain lvalues when returning
them.
* decl.c (grokdeclarator): Implement reference collapsing.
(copy_fn_p): Don't consider constructors taking rvalue references
to be copy constructors.
(move_fn_p): New.
* call.c (conversion): New "rvaluedness_matches_p" member.
(convert_class_to_reference): Require reference type as first
parameter instead of base type.
(reference_binding): Add logic to handle rvalue references.
(implicit_conversion): Update inaccurate comment.
(convert_like_real): Disable creation of temporaries that are
impossible to initialize for types with move constructors.
(build_over_call): Elide move constructors when possible.
(maybe_handle_implicit_object): Set "rvaluedness_matches_p".
(maybe_handle_ref_bind): Return conversion instead of type node.
(compare_ics): Add logic to use "rvaluedness_matches_p" values to
determine preferred conversion sequences.
* cp-tree.h (TYPE_REF_IS_RVALUE): New.
(LOOKUP_PREFER_RVALUE): New.
(DECL_MOVE_CONSTRUCTOR_P): New.
(struct cp_declarator): Add "reference" member for reference
types, with new "rvalue_ref" flag.
(cp_build_reference_type): Declare.
(move_fn_p): Declare.
* error.c (dump_type_prefix): Format rvalue reference types
correctly in error messages.
* except.c (build_throw): Move from certain lvalues when
throwing.
* mangle.c (write_type): Mangle rvalue references differently
than regular references.
* parser.c (make_reference_declarator): Add boolean parameter for
rvalue references.
(cp_parser_make_indirect_declarator): New.
(cp_parser_new_declarator_opt): Call
cp_parser_make_indirect_declarator.
(cp_parser_conversion_declarator_opt): Ditto.
(cp_parser_declarator): Ditto.
(cp_parser_ptr_operator): Parse "&&" tokens into rvalue reference
declarators.
* pt.c (tsubst): Implement reference collapsing.
(maybe_adjust_types_for_deduction): Implement special template
parameter deduction rule for rvalue references.
(type_unification_real): Update calls to
maybe_adjust_types_for_deduction.
(try_one_overload): Ditto.
(unify_pack_expansion): Ditto.
* tree.c (lvalue_p_1): Handle rvalue reference types.
(cp_build_reference_type): New.
From-SVN: r125211
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 98 |
1 files changed, 54 insertions, 44 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e7b90b2..c1a3276 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -858,7 +858,7 @@ static cp_declarator *make_array_declarator static cp_declarator *make_pointer_declarator (cp_cv_quals, cp_declarator *); static cp_declarator *make_reference_declarator - (cp_cv_quals, cp_declarator *); + (cp_cv_quals, cp_declarator *, bool); static cp_parameter_declarator *make_parameter_declarator (cp_decl_specifier_seq *, cp_declarator *, tree); static cp_declarator *make_ptrmem_declarator @@ -960,14 +960,15 @@ make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target) /* Like make_pointer_declarator -- but for references. */ cp_declarator * -make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target) +make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target, + bool rvalue_ref) { cp_declarator *declarator; declarator = make_declarator (cdk_reference); declarator->declarator = target; - declarator->u.pointer.qualifiers = cv_qualifiers; - declarator->u.pointer.class_type = NULL_TREE; + declarator->u.reference.qualifiers = cv_qualifiers; + declarator->u.reference.rvalue_ref = rvalue_ref; if (target) { declarator->parameter_pack_p = target->parameter_pack_p; @@ -2015,6 +2016,8 @@ static bool cp_parser_is_keyword (cp_token *, enum rid); static tree cp_parser_make_typename_type (cp_parser *, tree, tree); +static cp_declarator * cp_parser_make_indirect_declarator + (enum tree_code, tree, cp_cv_quals, cp_declarator *); /* Returns nonzero if we are parsing tentatively. */ @@ -2689,6 +2692,27 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id) return make_typename_type (scope, id, typename_type, tf_error); } +/* This is a wrapper around the + make_{pointer,ptrmem,reference}_declarator functions that decides + which one to call based on the CODE and CLASS_TYPE arguments. The + CODE argument should be one of the values returned by + cp_parser_ptr_operator. */ +static cp_declarator * +cp_parser_make_indirect_declarator (enum tree_code code, tree class_type, + cp_cv_quals cv_qualifiers, + cp_declarator *target) +{ + if (code == INDIRECT_REF) + if (class_type == NULL_TREE) + return make_pointer_declarator (cv_qualifiers, target); + else + return make_ptrmem_declarator (cv_qualifiers, class_type, target); + else if (code == ADDR_EXPR && class_type == NULL_TREE) + return make_reference_declarator (cv_qualifiers, target, false); + else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE) + return make_reference_declarator (cv_qualifiers, target, true); + gcc_unreachable (); +} /* Create a new C++ parser. */ @@ -5532,15 +5556,8 @@ cp_parser_new_declarator_opt (cp_parser* parser) /* Parse another optional declarator. */ declarator = cp_parser_new_declarator_opt (parser); - /* Create the representation of the declarator. */ - if (type) - declarator = make_ptrmem_declarator (cv_quals, type, declarator); - else if (code == INDIRECT_REF) - declarator = make_pointer_declarator (cv_quals, declarator); - else - declarator = make_reference_declarator (cv_quals, declarator); - - return declarator; + return cp_parser_make_indirect_declarator + (code, type, cv_quals, declarator); } /* If the next token is a `[', there is a direct-new-declarator. */ @@ -8460,16 +8477,8 @@ cp_parser_conversion_declarator_opt (cp_parser* parser) /* Parse another optional declarator. */ declarator = cp_parser_conversion_declarator_opt (parser); - /* Create the representation of the declarator. */ - if (class_type) - declarator = make_ptrmem_declarator (cv_quals, class_type, - declarator); - else if (code == INDIRECT_REF) - declarator = make_pointer_declarator (cv_quals, declarator); - else - declarator = make_reference_declarator (cv_quals, declarator); - - return declarator; + return cp_parser_make_indirect_declarator + (code, class_type, cv_quals, declarator); } return NULL; @@ -12072,15 +12081,8 @@ cp_parser_declarator (cp_parser* parser, && !cp_parser_parse_definitely (parser)) declarator = NULL; - /* Build the representation of the ptr-operator. */ - if (class_type) - declarator = make_ptrmem_declarator (cv_quals, - class_type, - declarator); - else if (code == INDIRECT_REF) - declarator = make_pointer_declarator (cv_quals, declarator); - else - declarator = make_reference_declarator (cv_quals, declarator); + declarator = cp_parser_make_indirect_declarator + (code, class_type, cv_quals, declarator); } /* Everything else is a direct-declarator. */ else @@ -12558,12 +12560,15 @@ cp_parser_direct_declarator (cp_parser* parser, & cv-qualifier-seq [opt] Returns INDIRECT_REF if a pointer, or pointer-to-member, was used. - Returns ADDR_EXPR if a reference was used. In the case of a - pointer-to-member, *TYPE is filled in with the TYPE containing the - member. *CV_QUALS is filled in with the cv-qualifier-seq, or - TYPE_UNQUALIFIED, if there are no cv-qualifiers. Returns - ERROR_MARK if an error occurred. */ - + Returns ADDR_EXPR if a reference was used, or NON_LVALUE_EXPR for + an rvalue reference. In the case of a pointer-to-member, *TYPE is + filled in with the TYPE containing the member. *CV_QUALS is + filled in with the cv-qualifier-seq, or TYPE_UNQUALIFIED, if there + are no cv-qualifiers. Returns ERROR_MARK if an error occurred. + Note that the tree codes returned by this function have nothing + to do with the types of trees that will be eventually be created + to represent the pointer or reference type being parsed. They are + just constants with suggestive names. */ static enum tree_code cp_parser_ptr_operator (cp_parser* parser, tree* type, @@ -12579,13 +12584,18 @@ cp_parser_ptr_operator (cp_parser* parser, /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); - /* If it's a `*' or `&' we have a pointer or reference. */ - if (token->type == CPP_MULT || token->type == CPP_AND) - { - /* Remember which ptr-operator we were processing. */ - code = (token->type == CPP_AND ? ADDR_EXPR : INDIRECT_REF); - /* Consume the `*' or `&'. */ + /* If it's a `*', `&' or `&&' we have a pointer or reference. */ + if (token->type == CPP_MULT) + code = INDIRECT_REF; + else if (token->type == CPP_AND) + code = ADDR_EXPR; + else if (flag_cpp0x && token->type == CPP_AND_AND) /* C++0x only */ + code = NON_LVALUE_EXPR; + + if (code != ERROR_MARK) + { + /* Consume the `*', `&' or `&&'. */ cp_lexer_consume_token (parser->lexer); /* A `*' can be followed by a cv-qualifier-seq, and so can a |