/* Look for the `~'. */
cp_parser_require (parser, CPP_COMPL, RT_COMPL);
- /* Once we see the ~, this has to be a pseudo-destructor. */
- if (!processing_template_decl && !cp_parser_error_occurred (parser))
- cp_parser_commit_to_tentative_parse (parser);
-
/* Look for the type-name again. We are not responsible for
checking that it matches the first type-name. */
*type = cp_parser_nonclass_name (parser);
otherwise. */
static bool
-cp_parser_token_starts_cast_expression (cp_token *token)
+cp_parser_tokens_start_cast_expression (cp_parser *parser)
{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
switch (token->type)
{
case CPP_COMMA:
case CPP_EOF:
return false;
+ case CPP_OPEN_PAREN:
+ /* In ((type ()) () the last () isn't a valid cast-expression,
+ so the whole must be parsed as postfix-expression. */
+ return cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ != CPP_CLOSE_PAREN;
+
/* '[' may start a primary-expression in obj-c++. */
case CPP_OPEN_SQUARE:
return c_dialect_objc ();
parenthesized ctor such as `(T ())' that looks like a cast to
function returning T. */
if (!cp_parser_error_occurred (parser)
- && cp_parser_token_starts_cast_expression (cp_lexer_peek_token
- (parser->lexer)))
+ && cp_parser_tokens_start_cast_expression (parser))
{
cp_parser_parse_definitely (parser);
expr = cp_parser_cast_expression (parser,
range_expr = error_mark_node;
stmt = begin_range_for_stmt (scope, init);
finish_range_for_decl (stmt, range_decl, range_expr);
- if (!type_dependent_expression_p (range_expr)
+ if (range_expr != error_mark_node
+ && !type_dependent_expression_p (range_expr)
+ /* The length of an array might be dependent. */
+ && COMPLETE_TYPE_P (TREE_TYPE (range_expr))
/* do_auto_deduction doesn't mess with template init-lists. */
&& !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
do_range_for_auto_deduction (range_decl, range_expr);
parm_loc,
parameter,
is_non_type,
- is_parameter_pack,
- 0);
+ is_parameter_pack);
else
{
tree err_parm = build_tree_list (parameter, parameter);
/* Look up the type-name. */
type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
- if (TREE_CODE (type_decl) == USING_DECL)
- {
- if (!DECL_DEPENDENT_P (type_decl))
- type_decl = strip_using_decl (type_decl);
- else if (USING_DECL_TYPENAME_P (type_decl))
- {
- /* We have found a type introduced by a using
- declaration at class scope that refers to a dependent
- type.
-
- using typename :: [opt] nested-name-specifier unqualified-id ;
- */
- type_decl = make_typename_type (TREE_TYPE (type_decl),
- DECL_NAME (type_decl),
- typename_type, tf_error);
- if (type_decl != error_mark_node)
- type_decl = TYPE_NAME (type_decl);
- }
- }
+ type_decl = strip_using_decl (type_decl);
if (TREE_CODE (type_decl) != TYPE_DECL
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
typename_type,
/*complain=*/tf_error);
/* If the `typename' keyword is in effect and DECL is not a type
- decl. Then type is non existant. */
+ decl, then type is non existent. */
else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
- type = NULL_TREE;
- else
- type = check_elaborated_type_specifier (tag_type, decl,
+ ;
+ else if (TREE_CODE (decl) == TYPE_DECL)
+ type = check_elaborated_type_specifier (tag_type, decl,
/*allow_template_p=*/true);
+ else if (decl == error_mark_node)
+ type = error_mark_node;
}
if (!type)
cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
{
cp_token *token;
- tree type;
+ tree type, save_ccp, save_ccr;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* Consume the ->. */
cp_lexer_consume_token (parser->lexer);
+ save_ccp = current_class_ptr;
+ save_ccr = current_class_ref;
if (quals >= 0)
{
/* DR 1207: 'this' is in scope in the trailing return type. */
- gcc_assert (current_class_ptr == NULL_TREE);
inject_this_parameter (current_class_type, quals);
}
type = cp_parser_trailing_type_id (parser);
if (quals >= 0)
- current_class_ptr = current_class_ref = NULL_TREE;
+ {
+ current_class_ptr = save_ccp;
+ current_class_ref = save_ccr;
+ }
return type;
}
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{
/* In C++11, [ could start a lambda-introducer. */
+ bool non_const = false;
+
cp_parser_parse_tentatively (parser);
cp_lexer_consume_token (parser->lexer);
- designator = cp_parser_constant_expression (parser, false, NULL);
+ designator = cp_parser_constant_expression (parser, true, &non_const);
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
cp_parser_require (parser, CPP_EQ, RT_EQ);
if (!cp_parser_parse_definitely (parser))
designator = NULL_TREE;
+ else if (non_const)
+ require_potential_rvalue_constant_expression (designator);
}
else
designator = NULL_TREE;
{
/* Parse the template parameters. */
parameter_list = cp_parser_template_parameter_list (parser);
- fixup_template_parms ();
}
/* Get the deferred access checks from the parameter list. These
tree cast;
bool nonconst_p;
+ if (!type)
+ type = error_mark_node;
+
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);