aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c98
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