diff options
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 |