#include "coretypes.h"
#include "tm.h"
#include "dyn-string.h"
-#include "varray.h"
#include "cpplib.h"
#include "tree.h"
#include "cp-tree.h"
declarator->attributes = NULL_TREE;
declarator->declarator = NULL;
declarator->parameter_pack_p = false;
+ declarator->id_loc = UNKNOWN_LOCATION;
return declarator;
}
static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
static VEC(tree,gc) *cp_parser_parenthesized_expression_list
- (cp_parser *, bool, bool, bool, bool *);
+ (cp_parser *, int, bool, bool, bool *);
+/* Values for the second parameter of cp_parser_parenthesized_expression_list. */
+enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
static tree cp_parser_unary_expression
cp_lexer_consume_token (parser->lexer);
return null_node;
+ /* The `nullptr' literal. */
+ case RID_NULLPTR:
+ cp_lexer_consume_token (parser->lexer);
+ return nullptr_node;
+
/* Recognize the `this' keyword. */
case RID_THIS:
cp_lexer_consume_token (parser->lexer);
}
gcc_assert (!scope || TYPE_P (scope));
- /* If the name is of the form "X::~X" it's OK. */
+ /* If the name is of the form "X::~X" it's OK even if X is a
+ typedef. */
token = cp_lexer_peek_token (parser->lexer);
if (scope
&& token->type == CPP_NAME
&& (cp_lexer_peek_nth_token (parser->lexer, 2)->type
!= CPP_LESS)
- && constructor_name_p (token->u.value, scope))
+ && (token->u.value == TYPE_IDENTIFIER (scope)
+ || constructor_name_p (token->u.value, scope)))
{
cp_lexer_consume_token (parser->lexer);
return build_nt (BIT_NOT_EXPR, scope);
/* Parse a typedef-name or enum-name. */
scope = cp_parser_nonclass_name (parser);
+
+ /* "If the name found does not designate a namespace or a class,
+ enumeration, or dependent type, the program is ill-formed."
+
+ We cover classes and dependent types above and namespaces below,
+ so this code is only looking for enums. */
+ if (!scope || TREE_CODE (scope) != TYPE_DECL
+ || TREE_CODE (TREE_TYPE (scope)) != ENUMERAL_TYPE)
+ cp_parser_simulate_error (parser);
+
successful_parse_p = cp_parser_parse_definitely (parser);
}
/* If that didn't work, try for a namespace-name. */
parser->integral_constant_expression_p = false;
}
args = (cp_parser_parenthesized_expression_list
- (parser, /*is_attribute_list=*/false,
+ (parser, non_attr,
/*cast_p=*/false, /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL));
if (is_builtin_constant_p)
Returns a vector of trees. Each element is a representation of an
assignment-expression. NULL is returned if the ( and or ) are
missing. An empty, but allocated, vector is returned on no
- expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is true
- if this is really an attribute list being parsed. If
+ expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is id_attr
+ if we are parsing an attribute list for an attribute that wants a
+ plain identifier argument, normal_attr for an attribute that wants
+ an expression, or non_attr if we aren't parsing an attribute list. If
NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
not all of the expressions in the list were constant. */
static VEC(tree,gc) *
cp_parser_parenthesized_expression_list (cp_parser* parser,
- bool is_attribute_list,
+ int is_attribute_list,
bool cast_p,
bool allow_expansion_p,
bool *non_constant_p)
{
VEC(tree,gc) *expression_list;
- bool fold_expr_p = is_attribute_list;
+ bool fold_expr_p = is_attribute_list != non_attr;
tree identifier = NULL_TREE;
bool saved_greater_than_is_operator_p;
/* At the beginning of attribute lists, check to see if the
next token is an identifier. */
- if (is_attribute_list
+ if (is_attribute_list == id_attr
&& cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
{
cp_token *token;
/* After the first item, attribute lists look the same as
expression lists. */
- is_attribute_list = false;
+ is_attribute_list = non_attr;
get_comma:;
/* If the next token isn't a `,', then we are done. */
/* Parse the expression-list. */
expression_list = (cp_parser_parenthesized_expression_list
- (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+ (parser, non_attr, /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL));
return expression_list;
}
else
expression_list = (cp_parser_parenthesized_expression_list
- (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+ (parser, non_attr, /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL));
return expression_list;
LAMBDA_EXPR_LOCATION (lambda_expr)
= cp_lexer_peek_token (parser->lexer)->location;
+ if (cp_unevaluated_operand)
+ error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
+ "lambda-expression in unevaluated context");
+
/* We may be in the middle of deferred access check. Disable
it now. */
push_deferring_access_checks (dk_no_deferred);
declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR),
sfk_none);
- quals = TYPE_UNQUALIFIED;
- if (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) == NULL_TREE
- && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
- {
- /* A lambda with no captures has a static op() and a conversion op
- to function type. */
- if (LAMBDA_EXPR_MUTABLE_P (lambda_expr))
- error ("lambda expression with no captures declared mutable");
- return_type_specs.storage_class = sc_static;
- }
- else if (!LAMBDA_EXPR_MUTABLE_P (lambda_expr))
- quals = TYPE_QUAL_CONST;
+ quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
+ ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
declarator = make_call_declarator (declarator, param_list, quals,
exception_spec,
/*late_return_type=*/NULL_TREE);
+ declarator->id_loc = LAMBDA_EXPR_LOCATION (lambda_expr);
fco = grokmethod (&return_type_specs,
declarator,
else
{
VEC(tree,gc)* vec;
- vec = cp_parser_parenthesized_expression_list (parser, false,
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);
bounds = fold_non_dependent_expr (bounds);
/* Normally, the array bound must be an integral constant
expression. However, as an extension, we allow VLAs
- in function scopes. */
- else if (!parser->in_function_body)
+ in function scopes as long as they aren't part of a
+ parameter declaration. */
+ else if (!parser->in_function_body
+ || current_binding_level->kind == sk_function_parms)
{
- error_at (token->location,
- "array bound is not an integer constant");
+ cp_parser_error (parser,
+ "array bound is not an integer constant");
bounds = error_mark_node;
}
else if (processing_template_decl && !error_operand_p (bounds))
else if (token->type == CPP_OPEN_PAREN)
{
VEC(tree,gc) *vec;
- vec = cp_parser_parenthesized_expression_list (parser, false,
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
non_constant_p);
end_specialization ();
--parser->num_template_parameter_lists;
}
+
+ if (type)
+ DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
*attributes_p = attributes;
return type;
}
if (token->type == CPP_OPEN_PAREN)
{
VEC(tree,gc) *vec;
+ int attr_flag = (attribute_takes_identifier_p (identifier)
+ ? id_attr : normal_attr);
vec = cp_parser_parenthesized_expression_list
- (parser, true, /*cast_p=*/false,
+ (parser, attr_flag, /*cast_p=*/false,
/*allow_expansion_p=*/false,
/*non_constant_p=*/NULL);
if (vec == NULL)
}
- vec = cp_parser_parenthesized_expression_list (parser, false,
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
/*cast_p=*/true,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);