/* C++ Parser.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2005, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC.
static tree cp_parser_class_specifier
(cp_parser *);
static tree cp_parser_class_head
- (cp_parser *, bool *, tree *, tree *);
+ (cp_parser *, bool *);
static enum tag_types cp_parser_class_key
(cp_parser *);
static void cp_parser_member_specification_opt
TREE_TYPE (tparm))))
found = false;
}
- if (found)
+ if (found
+ && ix == VEC_length (tree, args)
+ /* May be this should be sufficient_parms_p instead,
+ depending on how exactly should user-defined literals
+ work in presence of default arguments on the literal
+ operator parameters. */
+ && argtypes == void_list_node)
return fn;
}
}
parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE;
}
- if (scope && name && BASELINK_P (name))
+ if (parser->scope && name && BASELINK_P (name))
adjust_result_of_qualified_name_lookup
- (name, BINFO_TYPE (BASELINK_ACCESS_BINFO (name)), scope);
+ (name, parser->scope, scope);
postfix_expression
= finish_class_member_access_expr (postfix_expression, name,
template_p,
/* 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,
lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
lhs_type = ERROR_MARK;
+ if (cp_parser_error_occurred (parser))
+ return error_mark_node;
+
for (;;)
{
/* Get an operator token. */
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);
its name; we will look it up again during template instantiation. */
if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl))
{
- tree scope = CP_DECL_CONTEXT (get_first_fn (decl));
+ tree scope = ovl_scope (decl);
if (TYPE_P (scope) && dependent_type_p (scope))
return identifier;
}
/* 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_require (parser, CPP_EQ, RT_EQ);
+ if (cp_parser_error_occurred (parser))
+ return error_mark_node;
+
/* Now we are going to parse the type-id of the declaration. */
/*
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_parser_function_body changed its state. */
if (check_body_p)
{
- list = body;
- if (TREE_CODE (list) == BIND_EXPR)
- list = BIND_EXPR_BODY (list);
- if (TREE_CODE (list) == STATEMENT_LIST
- && STATEMENT_LIST_TAIL (list) != NULL)
+ list = cur_stmt_list;
+ if (STATEMENT_LIST_TAIL (list))
last = STATEMENT_LIST_TAIL (list)->stmt;
}
/* Parse the function-body. */
&& 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;
decl = TYPE_NAME (decl);
}
+ decl = strip_using_decl (decl);
+
/* Check to see that it is really the name of a class. */
if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
&& TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
bool saved_in_unbraced_linkage_specification_p;
tree old_scope = NULL_TREE;
tree scope = NULL_TREE;
- tree bases;
cp_token *closing_brace;
push_deferring_access_checks (dk_no_deferred);
/* Parse the class-head. */
type = cp_parser_class_head (parser,
- &nested_name_specifier_p,
- &attributes,
- &bases);
+ &nested_name_specifier_p);
/* If the class-head was a semantic disaster, skip the entire body
of the class. */
if (!type)
return error_mark_node;
}
- /* Process the base classes. If they're invalid, skip the
- entire class body. */
- if (!xref_basetypes (type, bases))
- {
- /* Consuming the closing brace yields better error messages
- later on. */
- if (cp_parser_skip_to_closing_brace (parser))
- cp_lexer_consume_token (parser->lexer);
- pop_deferring_access_checks ();
- return error_mark_node;
- }
-
/* Issue an error message if type-definitions are forbidden here. */
cp_parser_check_type_definition (parser);
/* Remember that we are defining one more class. */
scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
old_scope = push_inner_scope (scope);
}
- type = begin_class_definition (type, attributes);
+ type = begin_class_definition (type);
if (type == error_mark_node)
/* If the type is erroneous, skip the entire body of the class. */
static tree
cp_parser_class_head (cp_parser* parser,
- bool* nested_name_specifier_p,
- tree *attributes_p,
- tree *bases)
+ bool* nested_name_specifier_p)
{
tree nested_name_specifier;
enum tag_types class_key;
tree id = NULL_TREE;
tree type = NULL_TREE;
tree attributes;
+ tree bases;
cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
bool template_id_p = false;
bool qualified_p = false;
num_templates = 0;
parser->colon_corrects_to_scope_p = false;
- *bases = NULL_TREE;
-
/* Look for the class-key. */
class_key = cp_parser_class_key (parser);
if (class_key == none_type)
else if (type == error_mark_node)
type = NULL_TREE;
+ if (type)
+ {
+ /* Apply attributes now, before any use of the class as a template
+ argument in its base list. */
+ cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
+ fixup_attribute_variants (type);
+ }
+
/* We will have entered the scope containing the class; the names of
base classes should be looked up in that context. For example:
/* Get the list of base-classes, if there is one. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
- *bases = cp_parser_base_clause (parser);
+ bases = cp_parser_base_clause (parser);
+ else
+ bases = NULL_TREE;
+
+ /* If we're really defining a class, process the base classes.
+ If they're invalid, fail. */
+ if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
+ && !xref_basetypes (type, bases))
+ type = NULL_TREE;
done:
/* Leave the scope given by the nested-name-specifier. We will
if (type)
DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
- *attributes_p = attributes;
if (type && (virt_specifiers & VIRT_SPEC_FINAL))
CLASSTYPE_FINAL (type) = 1;
out:
possible that this fact is an oversight in the
standard, since a pure function may be defined
outside of the class-specifier. */
- if (initializer)
+ if (initializer && initializer_token_start)
error_at (initializer_token_start->location,
"pure-specifier on function-definition");
decl = cp_parser_save_member_function_body (parser,
{
/* 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);