Commit 2b7a3abf by Dodji Seketeli Committed by Dodji Seketeli

re PR c++/31754 (Improve column number accuracy in error messages)

2008-07-11 Dodji Seketeli <dseketel@redhat.com>

	PR c++/31754
	* pt.c, semantic.c:
	* semantic.c (qualified_name_lookup_error, finish_id_expression):
	add a location_t parameter so that
	error message can have a more accurate location.
	* cp-tree.h: updated prototype
	* pt.c (tsubst_qualified_id): use location in error messages.
	* parser.c (cp_parser_postfix_expression,
	cp_parser_objc_statement, cp_parser_trait_expr,
	cp_parser_token_is_class_key,
	cp_parser_uncommitted_to_tentative_parse_p,
	cp_parser_check_for_invalid_template_id, cp_parser_is_string_literal,
	cp_parser_error, cp_parser_name_lookup_error,
	cp_parser_simulate_error, cp_parser_check_decl_spec,
	cp_parser_check_decl_spec, cp_parser_non_integral_constant_expression,
	cp_parser_diagnose_invalid_type_name,
	cp_parser_parse_and_diagnose_invalid_type_name,
	cp_parser_require_pragma_eol, cp_parser_make_typename_type,
	cp_parser_string_literal, cp_parser_primary_expression,
	cp_parser_primary_expression, cp_parser_unqualified_id,
	cp_parser_nested_name_specifier_opt, cp_parser_postfix_expression,
	cp_parser_postfix_dot_deref_expression, cp_parser_new_expression,
	cp_parser_direct_new_declarator, cp_parser_builtin_offsetof,
	cp_parser_label_for_labeled_statement, cp_parser_statement_seq_opt,
	cp_parser_jump_statement, cp_parser_block_declaration,
	cp_parser_simple_declaration, cp_parser_decl_specifier_seq,
	cp_parser_function_specifier_opt, cp_parser_decltype,
	cp_parser_mem_initializer_list, cp_parser_mem_initializer,
	cp_parser_mem_initializer_id, cp_parser_template_parameter,
	cp_parser_type_parameter, cp_parser_template_id, cp_parser_template_name,
	cp_parser_template_argument): likewise.

From-SVN: r137716
parent 941a9479
2008-07-11 Dodji Seketeli <dseketel@redhat.com>
PR c++/31754
* pt.c, semantic.c:
* semantic.c (qualified_name_lookup_error, finish_id_expression):
add a location_t parameter so that
error message can have a more accurate location.
* cp-tree.h: updated prototype
* pt.c (tsubst_qualified_id): use location in error messages.
* parser.c (cp_parser_postfix_expression,
cp_parser_objc_statement, cp_parser_trait_expr,
cp_parser_token_is_class_key,
cp_parser_uncommitted_to_tentative_parse_p,
cp_parser_check_for_invalid_template_id, cp_parser_is_string_literal,
cp_parser_error, cp_parser_name_lookup_error,
cp_parser_simulate_error, cp_parser_check_decl_spec,
cp_parser_check_decl_spec, cp_parser_non_integral_constant_expression,
cp_parser_diagnose_invalid_type_name,
cp_parser_parse_and_diagnose_invalid_type_name,
cp_parser_require_pragma_eol, cp_parser_make_typename_type,
cp_parser_string_literal, cp_parser_primary_expression,
cp_parser_primary_expression, cp_parser_unqualified_id,
cp_parser_nested_name_specifier_opt, cp_parser_postfix_expression,
cp_parser_postfix_dot_deref_expression, cp_parser_new_expression,
cp_parser_direct_new_declarator, cp_parser_builtin_offsetof,
cp_parser_label_for_labeled_statement, cp_parser_statement_seq_opt,
cp_parser_jump_statement, cp_parser_block_declaration,
cp_parser_simple_declaration, cp_parser_decl_specifier_seq,
cp_parser_function_specifier_opt, cp_parser_decltype,
cp_parser_mem_initializer_list, cp_parser_mem_initializer,
cp_parser_mem_initializer_id, cp_parser_template_parameter,
cp_parser_type_parameter, cp_parser_template_id, cp_parser_template_name,
cp_parser_template_argument): likewise.
2008-07-09 Paolo Carlini <paolo.carlini@oracle.com> 2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/36760 PR c++/36760
......
...@@ -4653,13 +4653,15 @@ extern void finish_template_decl (tree); ...@@ -4653,13 +4653,15 @@ extern void finish_template_decl (tree);
extern tree finish_template_type (tree, tree, int); extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool); extern tree finish_base_specifier (tree, tree, bool);
extern void finish_member_declaration (tree); extern void finish_member_declaration (tree);
extern void qualified_name_lookup_error (tree, tree, tree); extern void qualified_name_lookup_error (tree, tree, tree,
location_t);
extern void check_template_keyword (tree); extern void check_template_keyword (tree);
extern tree finish_id_expression (tree, tree, tree, extern tree finish_id_expression (tree, tree, tree,
cp_id_kind *, cp_id_kind *,
bool, bool, bool *, bool, bool, bool *,
bool, bool, bool, bool, bool, bool, bool, bool,
const char **); const char **,
location_t);
extern tree finish_typeof (tree); extern tree finish_typeof (tree);
extern tree finish_offsetof (tree); extern tree finish_offsetof (tree);
extern void finish_decl_cleanup (tree, tree); extern void finish_decl_cleanup (tree, tree);
......
...@@ -1593,7 +1593,7 @@ static tree cp_parser_postfix_expression ...@@ -1593,7 +1593,7 @@ static tree cp_parser_postfix_expression
static tree cp_parser_postfix_open_square_expression static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool); (cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *); (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
static tree cp_parser_parenthesized_expression_list static tree cp_parser_parenthesized_expression_list
(cp_parser *, bool, bool, bool, bool *); (cp_parser *, bool, bool, bool, bool *);
static void cp_parser_pseudo_destructor_name static void cp_parser_pseudo_destructor_name
...@@ -1904,15 +1904,15 @@ static tree cp_parser_objc_statement ...@@ -1904,15 +1904,15 @@ static tree cp_parser_objc_statement
/* Utility Routines */ /* Utility Routines */
static tree cp_parser_lookup_name static tree cp_parser_lookup_name
(cp_parser *, tree, enum tag_types, bool, bool, bool, tree *); (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *, location_t);
static tree cp_parser_lookup_name_simple static tree cp_parser_lookup_name_simple
(cp_parser *, tree); (cp_parser *, tree, location_t);
static tree cp_parser_maybe_treat_template_as_class static tree cp_parser_maybe_treat_template_as_class
(tree, bool); (tree, bool);
static bool cp_parser_check_declarator_template_parameters static bool cp_parser_check_declarator_template_parameters
(cp_parser *, cp_declarator *); (cp_parser *, cp_declarator *, location_t);
static bool cp_parser_check_template_parameters static bool cp_parser_check_template_parameters
(cp_parser *, unsigned); (cp_parser *, unsigned, location_t);
static tree cp_parser_simple_cast_expression static tree cp_parser_simple_cast_expression
(cp_parser *); (cp_parser *);
static tree cp_parser_global_scope_opt static tree cp_parser_global_scope_opt
...@@ -1948,7 +1948,7 @@ static tree cp_parser_trait_expr ...@@ -1948,7 +1948,7 @@ static tree cp_parser_trait_expr
static bool cp_parser_declares_only_class_p static bool cp_parser_declares_only_class_p
(cp_parser *); (cp_parser *);
static void cp_parser_set_storage_class static void cp_parser_set_storage_class
(cp_parser *, cp_decl_specifier_seq *, enum rid); (cp_parser *, cp_decl_specifier_seq *, enum rid, location_t);
static void cp_parser_set_decl_spec_type static void cp_parser_set_decl_spec_type
(cp_decl_specifier_seq *, tree, bool); (cp_decl_specifier_seq *, tree, bool);
static bool cp_parser_friend_p static bool cp_parser_friend_p
...@@ -1970,7 +1970,7 @@ static enum tag_types cp_parser_token_is_class_key ...@@ -1970,7 +1970,7 @@ static enum tag_types cp_parser_token_is_class_key
static void cp_parser_check_class_key static void cp_parser_check_class_key
(enum tag_types, tree type); (enum tag_types, tree type);
static void cp_parser_check_access_in_redeclaration static void cp_parser_check_access_in_redeclaration
(tree type); (tree type, location_t location);
static bool cp_parser_optional_template_keyword static bool cp_parser_optional_template_keyword
(cp_parser *); (cp_parser *);
static void cp_parser_pre_parsed_nested_name_specifier static void cp_parser_pre_parsed_nested_name_specifier
...@@ -1992,7 +1992,7 @@ static bool cp_parser_uncommitted_to_tentative_parse_p ...@@ -1992,7 +1992,7 @@ static bool cp_parser_uncommitted_to_tentative_parse_p
static void cp_parser_error static void cp_parser_error
(cp_parser *, const char *); (cp_parser *, const char *);
static void cp_parser_name_lookup_error static void cp_parser_name_lookup_error
(cp_parser *, tree, tree, const char *); (cp_parser *, tree, tree, const char *, location_t);
static bool cp_parser_simulate_error static bool cp_parser_simulate_error
(cp_parser *); (cp_parser *);
static bool cp_parser_check_type_definition static bool cp_parser_check_type_definition
...@@ -2004,7 +2004,7 @@ static void cp_parser_check_for_invalid_template_id ...@@ -2004,7 +2004,7 @@ static void cp_parser_check_for_invalid_template_id
static bool cp_parser_non_integral_constant_expression static bool cp_parser_non_integral_constant_expression
(cp_parser *, const char *); (cp_parser *, const char *);
static void cp_parser_diagnose_invalid_type_name static void cp_parser_diagnose_invalid_type_name
(cp_parser *, tree, tree); (cp_parser *, tree, tree, location_t);
static bool cp_parser_parse_and_diagnose_invalid_type_name static bool cp_parser_parse_and_diagnose_invalid_type_name
(cp_parser *); (cp_parser *);
static int cp_parser_skip_to_closing_parenthesis static int cp_parser_skip_to_closing_parenthesis
...@@ -2030,7 +2030,7 @@ static bool cp_parser_is_string_literal ...@@ -2030,7 +2030,7 @@ static bool cp_parser_is_string_literal
static bool cp_parser_is_keyword static bool cp_parser_is_keyword
(cp_token *, enum rid); (cp_token *, enum rid);
static tree cp_parser_make_typename_type static tree cp_parser_make_typename_type
(cp_parser *, tree, tree); (cp_parser *, tree, tree, location_t location);
static cp_declarator * cp_parser_make_indirect_declarator static cp_declarator * cp_parser_make_indirect_declarator
(enum tree_code, tree, cp_cv_quals, cp_declarator *); (enum tree_code, tree, cp_cv_quals, cp_declarator *);
...@@ -2079,7 +2079,7 @@ cp_parser_error (cp_parser* parser, const char* message) ...@@ -2079,7 +2079,7 @@ cp_parser_error (cp_parser* parser, const char* message)
if (token->type == CPP_PRAGMA) if (token->type == CPP_PRAGMA)
{ {
error ("%<#pragma%> is not allowed here"); error ("%H%<#pragma%> is not allowed here", &token->location);
cp_parser_skip_to_pragma_eol (parser, token); cp_parser_skip_to_pragma_eol (parser, token);
return; return;
} }
...@@ -2102,33 +2102,34 @@ static void ...@@ -2102,33 +2102,34 @@ static void
cp_parser_name_lookup_error (cp_parser* parser, cp_parser_name_lookup_error (cp_parser* parser,
tree name, tree name,
tree decl, tree decl,
const char* desired) const char* desired,
location_t location)
{ {
/* If name lookup completely failed, tell the user that NAME was not /* If name lookup completely failed, tell the user that NAME was not
declared. */ declared. */
if (decl == error_mark_node) if (decl == error_mark_node)
{ {
if (parser->scope && parser->scope != global_namespace) if (parser->scope && parser->scope != global_namespace)
error ("%<%E::%E%> has not been declared", error ("%H%<%E::%E%> has not been declared",
parser->scope, name); &location, parser->scope, name);
else if (parser->scope == global_namespace) else if (parser->scope == global_namespace)
error ("%<::%E%> has not been declared", name); error ("%H%<::%E%> has not been declared", &location, name);
else if (parser->object_scope else if (parser->object_scope
&& !CLASS_TYPE_P (parser->object_scope)) && !CLASS_TYPE_P (parser->object_scope))
error ("request for member %qE in non-class type %qT", error ("%Hrequest for member %qE in non-class type %qT",
name, parser->object_scope); &location, name, parser->object_scope);
else if (parser->object_scope) else if (parser->object_scope)
error ("%<%T::%E%> has not been declared", error ("%H%<%T::%E%> has not been declared",
parser->object_scope, name); &location, parser->object_scope, name);
else else
error ("%qE has not been declared", name); error ("%H%qE has not been declared", &location, name);
} }
else if (parser->scope && parser->scope != global_namespace) else if (parser->scope && parser->scope != global_namespace)
error ("%<%E::%E%> %s", parser->scope, name, desired); error ("%H%<%E::%E%> %s", &location, parser->scope, name, desired);
else if (parser->scope == global_namespace) else if (parser->scope == global_namespace)
error ("%<::%E%> %s", name, desired); error ("%H%<::%E%> %s", &location, name, desired);
else else
error ("%qE %s", name, desired); error ("%H%qE %s", &location, name, desired);
} }
/* If we are parsing tentatively, remember that an error has occurred /* If we are parsing tentatively, remember that an error has occurred
...@@ -2149,7 +2150,8 @@ cp_parser_simulate_error (cp_parser* parser) ...@@ -2149,7 +2150,8 @@ cp_parser_simulate_error (cp_parser* parser)
/* Check for repeated decl-specifiers. */ /* Check for repeated decl-specifiers. */
static void static void
cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
location_t location)
{ {
cp_decl_spec ds; cp_decl_spec ds;
...@@ -2162,10 +2164,11 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) ...@@ -2162,10 +2164,11 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
if (ds == ds_long) if (ds == ds_long)
{ {
if (count > 2) if (count > 2)
error ("%<long long long%> is too long for GCC"); error ("%H%<long long long%> is too long for GCC", &location);
else if (pedantic && !in_system_header && warn_long_long else if (pedantic && !in_system_header && warn_long_long
&& cxx_dialect == cxx98) && cxx_dialect == cxx98)
pedwarn ("ISO C++ 1998 does not support %<long long%>"); pedwarn ("%HISO C++ 1998 does not support %<long long%>",
&location);
} }
else if (count > 1) else if (count > 1)
{ {
...@@ -2185,7 +2188,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) ...@@ -2185,7 +2188,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
"__complex", "__complex",
"__thread" "__thread"
}; };
error ("duplicate %qs", decl_spec_names[(int)ds]); error ("%Hduplicate %qs", &location, decl_spec_names[(int)ds]);
} }
} }
} }
...@@ -2301,13 +2304,15 @@ cp_parser_non_integral_constant_expression (cp_parser *parser, ...@@ -2301,13 +2304,15 @@ cp_parser_non_integral_constant_expression (cp_parser *parser,
in duplicate error messages.) */ in duplicate error messages.) */
static void static void
cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id) cp_parser_diagnose_invalid_type_name (cp_parser *parser,
tree scope, tree id,
location_t id_location)
{ {
tree decl, old_scope; tree decl, old_scope;
/* Try to lookup the identifier. */ /* Try to lookup the identifier. */
old_scope = parser->scope; old_scope = parser->scope;
parser->scope = scope; parser->scope = scope;
decl = cp_parser_lookup_name_simple (parser, id); decl = cp_parser_lookup_name_simple (parser, id, id_location);
parser->scope = old_scope; parser->scope = old_scope;
/* If the lookup found a template-name, it means that the user forgot /* If the lookup found a template-name, it means that the user forgot
to specify an argument list. Emit a useful error message. */ to specify an argument list. Emit a useful error message. */
...@@ -2392,6 +2397,7 @@ static bool ...@@ -2392,6 +2397,7 @@ static bool
cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
{ {
tree id; tree id;
cp_token *token = cp_lexer_peek_token (parser->lexer);
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
id = cp_parser_id_expression (parser, id = cp_parser_id_expression (parser,
...@@ -2415,7 +2421,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) ...@@ -2415,7 +2421,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
return false; return false;
/* Emit a diagnostic for the invalid type. */ /* Emit a diagnostic for the invalid type. */
cp_parser_diagnose_invalid_type_name (parser, parser->scope, id); cp_parser_diagnose_invalid_type_name (parser, parser->scope,
id, token->location);
/* Skip to the end of the declaration; there's no point in /* Skip to the end of the declaration; there's no point in
trying to process it. */ trying to process it. */
cp_parser_skip_to_end_of_block_or_statement (parser); cp_parser_skip_to_end_of_block_or_statement (parser);
...@@ -2703,7 +2710,8 @@ cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok) ...@@ -2703,7 +2710,8 @@ cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
using cp_parser_diagnose_invalid_type_name. */ using cp_parser_diagnose_invalid_type_name. */
static tree static tree
cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id) cp_parser_make_typename_type (cp_parser *parser, tree scope,
tree id, location_t id_location)
{ {
tree result; tree result;
if (TREE_CODE (id) == IDENTIFIER_NODE) if (TREE_CODE (id) == IDENTIFIER_NODE)
...@@ -2711,7 +2719,7 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id) ...@@ -2711,7 +2719,7 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id)
result = make_typename_type (scope, id, typename_type, result = make_typename_type (scope, id, typename_type,
/*complain=*/tf_none); /*complain=*/tf_none);
if (result == error_mark_node) if (result == error_mark_node)
cp_parser_diagnose_invalid_type_name (parser, scope, id); cp_parser_diagnose_invalid_type_name (parser, scope, id, id_location);
return result; return result;
} }
return make_typename_type (scope, id, typename_type, tf_error); return make_typename_type (scope, id, typename_type, tf_error);
...@@ -2929,7 +2937,8 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) ...@@ -2929,7 +2937,8 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
if (type == CPP_STRING) if (type == CPP_STRING)
type = tok->type; type = tok->type;
else if (tok->type != CPP_STRING) else if (tok->type != CPP_STRING)
error ("unsupported non-standard concatenation of string literals"); error ("%Hunsupported non-standard concatenation "
"of string literals", &tok->location);
} }
obstack_grow (&str_ob, &str, sizeof (cpp_string)); obstack_grow (&str_ob, &str, sizeof (cpp_string));
...@@ -3108,7 +3117,7 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3108,7 +3117,7 @@ cp_parser_primary_expression (cp_parser *parser,
bool template_arg_p, bool template_arg_p,
cp_id_kind *idk) cp_id_kind *idk)
{ {
cp_token *token; cp_token *token = NULL;
/* Assume the primary expression is not an id-expression. */ /* Assume the primary expression is not an id-expression. */
*idk = CP_ID_KIND_NONE; *idk = CP_ID_KIND_NONE;
...@@ -3206,7 +3215,8 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3206,7 +3215,8 @@ cp_parser_primary_expression (cp_parser *parser,
{ {
/* Statement-expressions are not allowed by the standard. */ /* Statement-expressions are not allowed by the standard. */
if (pedantic) if (pedantic)
pedwarn ("ISO C++ forbids braced-groups within expressions"); pedwarn ("%HISO C++ forbids braced-groups within expressions",
&token->location);
/* And they're not allowed outside of a function-body; you /* And they're not allowed outside of a function-body; you
cannot, for example, write: cannot, for example, write:
...@@ -3217,8 +3227,9 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3217,8 +3227,9 @@ cp_parser_primary_expression (cp_parser *parser,
if (!parser->in_function_body if (!parser->in_function_body
|| parser->in_template_argument_list_p) || parser->in_template_argument_list_p)
{ {
error ("statement-expressions are not allowed outside " error ("%Hstatement-expressions are not allowed outside "
"functions nor in template-argument lists"); "functions nor in template-argument lists",
&token->location);
cp_parser_skip_to_end_of_block_or_statement (parser); cp_parser_skip_to_end_of_block_or_statement (parser);
expr = error_mark_node; expr = error_mark_node;
} }
...@@ -3275,7 +3286,8 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3275,7 +3286,8 @@ cp_parser_primary_expression (cp_parser *parser,
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
if (parser->local_variables_forbidden_p) if (parser->local_variables_forbidden_p)
{ {
error ("%<this%> may not be used in this context"); error ("%H%<this%> may not be used in this context",
&token->location);
return error_mark_node; return error_mark_node;
} }
/* Pointers cannot appear in constant-expressions. */ /* Pointers cannot appear in constant-expressions. */
...@@ -3375,6 +3387,7 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3375,6 +3387,7 @@ cp_parser_primary_expression (cp_parser *parser,
const char *error_msg; const char *error_msg;
bool template_p; bool template_p;
bool done; bool done;
cp_token *id_expr_token;
id_expression: id_expression:
/* Parse the id-expression. */ /* Parse the id-expression. */
...@@ -3387,6 +3400,7 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3387,6 +3400,7 @@ cp_parser_primary_expression (cp_parser *parser,
/*optional_p=*/false); /*optional_p=*/false);
if (id_expression == error_mark_node) if (id_expression == error_mark_node)
return error_mark_node; return error_mark_node;
id_expr_token = token;
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
done = (token->type != CPP_OPEN_SQUARE done = (token->type != CPP_OPEN_SQUARE
&& token->type != CPP_OPEN_PAREN && token->type != CPP_OPEN_PAREN
...@@ -3410,7 +3424,8 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3410,7 +3424,8 @@ cp_parser_primary_expression (cp_parser *parser,
template_p, template_p,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
&ambiguous_decls); &ambiguous_decls,
id_expr_token->location);
/* If the lookup was ambiguous, an error will already have /* If the lookup was ambiguous, an error will already have
been issued. */ been issued. */
if (ambiguous_decls) if (ambiguous_decls)
...@@ -3457,8 +3472,8 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3457,8 +3472,8 @@ cp_parser_primary_expression (cp_parser *parser,
decl = check_for_out_of_scope_variable (decl); decl = check_for_out_of_scope_variable (decl);
if (local_variable_p (decl)) if (local_variable_p (decl))
{ {
error ("local variable %qD may not appear in this context", error ("%Hlocal variable %qD may not appear in this context",
decl); &id_expr_token->location, decl);
return error_mark_node; return error_mark_node;
} }
} }
...@@ -3472,7 +3487,8 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -3472,7 +3487,8 @@ cp_parser_primary_expression (cp_parser *parser,
&parser->non_integral_constant_expression_p, &parser->non_integral_constant_expression_p,
template_p, done, address_p, template_p, done, address_p,
template_arg_p, template_arg_p,
&error_msg)); &error_msg,
id_expr_token->location));
if (error_msg) if (error_msg)
cp_parser_error (parser, error_msg); cp_parser_error (parser, error_msg);
return decl; return decl;
...@@ -3756,7 +3772,8 @@ cp_parser_unqualified_id (cp_parser* parser, ...@@ -3756,7 +3772,8 @@ cp_parser_unqualified_id (cp_parser* parser,
if (scope && TREE_CODE (scope) == NAMESPACE_DECL) if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
{ {
if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
error ("scope %qT before %<~%> is not a class-name", scope); error ("%Hscope %qT before %<~%> is not a class-name",
&token->location, scope);
cp_parser_simulate_error (parser); cp_parser_simulate_error (parser);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
...@@ -3857,8 +3874,8 @@ cp_parser_unqualified_id (cp_parser* parser, ...@@ -3857,8 +3874,8 @@ cp_parser_unqualified_id (cp_parser* parser,
if (declarator_p && scope && !check_dtor_name (scope, type_decl)) if (declarator_p && scope && !check_dtor_name (scope, type_decl))
{ {
if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
error ("declaration of %<~%T%> as member of %qT", error ("%Hdeclaration of %<~%T%> as member of %qT",
type_decl, scope); &token->location, type_decl, scope);
cp_parser_simulate_error (parser); cp_parser_simulate_error (parser);
return error_mark_node; return error_mark_node;
} }
...@@ -3871,8 +3888,8 @@ cp_parser_unqualified_id (cp_parser* parser, ...@@ -3871,8 +3888,8 @@ cp_parser_unqualified_id (cp_parser* parser,
&& !DECL_IMPLICIT_TYPEDEF_P (type_decl) && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
&& !DECL_SELF_REFERENCE_P (type_decl) && !DECL_SELF_REFERENCE_P (type_decl)
&& !cp_parser_uncommitted_to_tentative_parse_p (parser)) && !cp_parser_uncommitted_to_tentative_parse_p (parser))
error ("typedef-name %qD used as destructor declarator", error ("%Htypedef-name %qD used as destructor declarator",
type_decl); &token->location, type_decl);
return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
} }
...@@ -4076,20 +4093,23 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, ...@@ -4076,20 +4093,23 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
&ambiguous_decls); &ambiguous_decls,
token->location);
if (TREE_CODE (decl) == TEMPLATE_DECL) if (TREE_CODE (decl) == TEMPLATE_DECL)
error ("%qD used without template parameters", decl); error ("%H%qD used without template parameters",
&token->location, decl);
else if (ambiguous_decls) else if (ambiguous_decls)
{ {
error ("reference to %qD is ambiguous", error ("%Hreference to %qD is ambiguous",
token->u.value); &token->location, token->u.value);
print_candidates (ambiguous_decls); print_candidates (ambiguous_decls);
decl = error_mark_node; decl = error_mark_node;
} }
else else
cp_parser_name_lookup_error cp_parser_name_lookup_error
(parser, token->u.value, decl, (parser, token->u.value, decl,
"is not a class or namespace"); "is not a class or namespace",
token->location);
} }
parser->scope = error_mark_node; parser->scope = error_mark_node;
error_p = true; error_p = true;
...@@ -4746,7 +4766,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4746,7 +4766,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression postfix_expression
= cp_parser_postfix_dot_deref_expression (parser, token->type, = cp_parser_postfix_dot_deref_expression (parser, token->type,
postfix_expression, postfix_expression,
false, &idk); false, &idk,
token->location);
is_member_access = true; is_member_access = true;
break; break;
...@@ -4860,7 +4881,8 @@ static tree ...@@ -4860,7 +4881,8 @@ static tree
cp_parser_postfix_dot_deref_expression (cp_parser *parser, cp_parser_postfix_dot_deref_expression (cp_parser *parser,
enum cpp_ttype token_type, enum cpp_ttype token_type,
tree postfix_expression, tree postfix_expression,
bool for_offsetof, cp_id_kind *idk) bool for_offsetof, cp_id_kind *idk,
location_t location)
{ {
tree name; tree name;
bool dependent_p; bool dependent_p;
...@@ -4892,7 +4914,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4892,7 +4914,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
/* The type of the POSTFIX_EXPRESSION must be complete. */ /* The type of the POSTFIX_EXPRESSION must be complete. */
if (scope == unknown_type_node) if (scope == unknown_type_node)
{ {
error ("%qE does not have class type", postfix_expression); error ("%H%qE does not have class type", &location, postfix_expression);
scope = NULL_TREE; scope = NULL_TREE;
} }
else else
...@@ -4948,6 +4970,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4948,6 +4970,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
ordinary class member access expression, rather than a ordinary class member access expression, rather than a
pseudo-destructor-name. */ pseudo-destructor-name. */
bool template_p; bool template_p;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Parse the id-expression. */ /* Parse the id-expression. */
name = (cp_parser_id_expression name = (cp_parser_id_expression
(parser, (parser,
...@@ -4975,7 +4998,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4975,7 +4998,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
TYPE_DECL here. That is invalid code. */ TYPE_DECL here. That is invalid code. */
if (TREE_CODE (name) == TYPE_DECL) if (TREE_CODE (name) == TYPE_DECL)
{ {
error ("invalid use of %qD", name); error ("%Hinvalid use of %qD", &token->location, name);
postfix_expression = error_mark_node; postfix_expression = error_mark_node;
} }
else else
...@@ -5538,18 +5561,21 @@ cp_parser_new_expression (cp_parser* parser) ...@@ -5538,18 +5561,21 @@ cp_parser_new_expression (cp_parser* parser)
type-id. */ type-id. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{ {
cp_token *token;
/* Consume the `('. */ /* Consume the `('. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the type-id. */ /* Parse the type-id. */
type = cp_parser_type_id (parser); type = cp_parser_type_id (parser);
/* Look for the closing `)'. */ /* Look for the closing `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
token = cp_lexer_peek_token (parser->lexer);
/* There should not be a direct-new-declarator in this production, /* There should not be a direct-new-declarator in this production,
but GCC used to allowed this, so we check and emit a sensible error but GCC used to allowed this, so we check and emit a sensible error
message for this case. */ message for this case. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{ {
error ("array bound forbidden after parenthesized type-id"); error ("%Harray bound forbidden after parenthesized type-id",
&token->location);
inform ("try removing the parentheses around the type-id"); inform ("try removing the parentheses around the type-id");
cp_parser_direct_new_declarator (parser); cp_parser_direct_new_declarator (parser);
} }
...@@ -5727,6 +5753,7 @@ cp_parser_direct_new_declarator (cp_parser* parser) ...@@ -5727,6 +5753,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
/* The first expression is not required to be constant. */ /* The first expression is not required to be constant. */
if (!declarator) if (!declarator)
{ {
cp_token *token = cp_lexer_peek_token (parser->lexer);
expression = cp_parser_expression (parser, /*cast_p=*/false); expression = cp_parser_expression (parser, /*cast_p=*/false);
/* The standard requires that the expression have integral /* The standard requires that the expression have integral
type. DR 74 adds enumeration types. We believe that the type. DR 74 adds enumeration types. We believe that the
...@@ -5742,8 +5769,8 @@ cp_parser_direct_new_declarator (cp_parser* parser) ...@@ -5742,8 +5769,8 @@ cp_parser_direct_new_declarator (cp_parser* parser)
/*complain=*/true); /*complain=*/true);
if (!expression) if (!expression)
{ {
error ("expression in new-declarator must have integral " error ("%Hexpression in new-declarator must have integral "
"or enumeration type"); "or enumeration type", &token->location);
expression = error_mark_node; expression = error_mark_node;
} }
} }
...@@ -6484,6 +6511,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) ...@@ -6484,6 +6511,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
int save_ice_p, save_non_ice_p; int save_ice_p, save_non_ice_p;
tree type, expr; tree type, expr;
cp_id_kind dummy; cp_id_kind dummy;
cp_token *token;
/* We're about to accept non-integral-constant things, but will /* We're about to accept non-integral-constant things, but will
definitely yield an integral constant expression. Save and definitely yield an integral constant expression. Save and
...@@ -6499,6 +6527,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) ...@@ -6499,6 +6527,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
type = cp_parser_type_id (parser); type = cp_parser_type_id (parser);
/* Look for the `,'. */ /* Look for the `,'. */
cp_parser_require (parser, CPP_COMMA, "%<,%>"); cp_parser_require (parser, CPP_COMMA, "%<,%>");
token = cp_lexer_peek_token (parser->lexer);
/* Build the (type *)null that begins the traditional offsetof macro. */ /* Build the (type *)null that begins the traditional offsetof macro. */
expr = build_static_cast (build_pointer_type (type), null_pointer_node, expr = build_static_cast (build_pointer_type (type), null_pointer_node,
...@@ -6506,10 +6535,10 @@ cp_parser_builtin_offsetof (cp_parser *parser) ...@@ -6506,10 +6535,10 @@ cp_parser_builtin_offsetof (cp_parser *parser)
/* Parse the offsetof-member-designator. We begin as if we saw "expr->". */ /* Parse the offsetof-member-designator. We begin as if we saw "expr->". */
expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, expr, expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, expr,
true, &dummy); true, &dummy, token->location);
while (true) while (true)
{ {
cp_token *token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
switch (token->type) switch (token->type)
{ {
case CPP_OPEN_SQUARE: case CPP_OPEN_SQUARE:
...@@ -6521,7 +6550,8 @@ cp_parser_builtin_offsetof (cp_parser *parser) ...@@ -6521,7 +6550,8 @@ cp_parser_builtin_offsetof (cp_parser *parser)
/* offsetof-member-designator "." identifier */ /* offsetof-member-designator "." identifier */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, expr, expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, expr,
true, &dummy); true, &dummy,
token->location);
break; break;
case CPP_CLOSE_PAREN: case CPP_CLOSE_PAREN:
...@@ -6883,7 +6913,8 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) ...@@ -6883,7 +6913,8 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
if (parser->in_switch_statement_p) if (parser->in_switch_statement_p)
finish_case_label (expr, expr_hi); finish_case_label (expr, expr_hi);
else else
error ("case label %qE not within a switch statement", expr); error ("%Hcase label %qE not within a switch statement",
&token->location, expr);
} }
break; break;
...@@ -6894,7 +6925,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) ...@@ -6894,7 +6925,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
if (parser->in_switch_statement_p) if (parser->in_switch_statement_p)
finish_case_label (NULL_TREE, NULL_TREE); finish_case_label (NULL_TREE, NULL_TREE);
else else
error ("case label not within a switch statement"); error ("%Hcase label not within a switch statement", &token->location);
break; break;
default: default:
...@@ -7012,7 +7043,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr) ...@@ -7012,7 +7043,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
else else
{ {
token = cp_lexer_consume_token (parser->lexer); token = cp_lexer_consume_token (parser->lexer);
error ("%<else%> without a previous %<if%>"); error ("%H%<else%> without a previous %<if%>", &token->location);
} }
} }
...@@ -7514,7 +7545,7 @@ cp_parser_jump_statement (cp_parser* parser) ...@@ -7514,7 +7545,7 @@ cp_parser_jump_statement (cp_parser* parser)
switch (in_statement) switch (in_statement)
{ {
case 0: case 0:
error ("break statement not within loop or switch"); error ("%Hbreak statement not within loop or switch", &token->location);
break; break;
default: default:
gcc_assert ((in_statement & IN_SWITCH_STMT) gcc_assert ((in_statement & IN_SWITCH_STMT)
...@@ -7522,10 +7553,10 @@ cp_parser_jump_statement (cp_parser* parser) ...@@ -7522,10 +7553,10 @@ cp_parser_jump_statement (cp_parser* parser)
statement = finish_break_stmt (); statement = finish_break_stmt ();
break; break;
case IN_OMP_BLOCK: case IN_OMP_BLOCK:
error ("invalid exit from OpenMP structured block"); error ("%Hinvalid exit from OpenMP structured block", &token->location);
break; break;
case IN_OMP_FOR: case IN_OMP_FOR:
error ("break statement used with OpenMP for loop"); error ("%Hbreak statement used with OpenMP for loop", &token->location);
break; break;
} }
cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
...@@ -7535,14 +7566,14 @@ cp_parser_jump_statement (cp_parser* parser) ...@@ -7535,14 +7566,14 @@ cp_parser_jump_statement (cp_parser* parser)
switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT)) switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
{ {
case 0: case 0:
error ("continue statement not within a loop"); error ("%Hcontinue statement not within a loop", &token->location);
break; break;
case IN_ITERATION_STMT: case IN_ITERATION_STMT:
case IN_OMP_FOR: case IN_OMP_FOR:
statement = finish_continue_stmt (); statement = finish_continue_stmt ();
break; break;
case IN_OMP_BLOCK: case IN_OMP_BLOCK:
error ("invalid exit from OpenMP structured block"); error ("%Hinvalid exit from OpenMP structured block", &token->location);
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -7579,7 +7610,7 @@ cp_parser_jump_statement (cp_parser* parser) ...@@ -7579,7 +7610,7 @@ cp_parser_jump_statement (cp_parser* parser)
{ {
/* Issue a warning about this use of a GNU extension. */ /* Issue a warning about this use of a GNU extension. */
if (pedantic) if (pedantic)
pedwarn ("ISO C++ forbids computed gotos"); pedwarn ("%HISO C++ forbids computed gotos", &token->location);
/* Consume the '*' token. */ /* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the dependent expression. */ /* Parse the dependent expression. */
...@@ -7940,7 +7971,7 @@ cp_parser_block_declaration (cp_parser *parser, ...@@ -7940,7 +7971,7 @@ cp_parser_block_declaration (cp_parser *parser,
else if (token1->keyword == RID_LABEL) else if (token1->keyword == RID_LABEL)
{ {
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
error ("%<__label__%> not at the beginning of a block"); error ("%H%<__label__%> not at the beginning of a block", &token1->location);
cp_parser_skip_to_end_of_statement (parser); cp_parser_skip_to_end_of_statement (parser);
/* If the next token is now a `;', consume it. */ /* If the next token is now a `;', consume it. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
...@@ -8074,7 +8105,11 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -8074,7 +8105,11 @@ cp_parser_simple_declaration (cp_parser* parser,
which is erroneous. */ which is erroneous. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
error ("mixing declarations and function-definitions is forbidden"); {
cp_token *token = cp_lexer_peek_token (parser->lexer);
error ("%Hmixing declarations and function-definitions is forbidden",
&token->location);
}
/* Otherwise, we're done with the list of declarators. */ /* Otherwise, we're done with the list of declarators. */
else else
{ {
...@@ -8170,6 +8205,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -8170,6 +8205,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
int* declares_class_or_enum) int* declares_class_or_enum)
{ {
bool constructor_possible_p = !parser->in_declarator_p; bool constructor_possible_p = !parser->in_declarator_p;
cp_token *start_token = NULL;
/* Clear DECL_SPECS. */ /* Clear DECL_SPECS. */
clear_decl_specs (decl_specs); clear_decl_specs (decl_specs);
...@@ -8186,6 +8222,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -8186,6 +8222,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/* Peek at the next token. */ /* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
/* Save the first token of the decl spec list for error
reporting. */
if (!start_token)
start_token = token;
/* Handle attributes. */ /* Handle attributes. */
if (token->keyword == RID_ATTRIBUTE) if (token->keyword == RID_ATTRIBUTE)
{ {
...@@ -8262,15 +8303,17 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -8262,15 +8303,17 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
we're complaining about C++0x compatibility. */ we're complaining about C++0x compatibility. */
warning warning
(OPT_Wc__0x_compat, (OPT_Wc__0x_compat,
"%<auto%> will change meaning in C++0x; please remove it"); "%H%<auto%> will change meaning in C++0x; please remove it",
&token->location);
/* Set the storage class anyway. */ /* Set the storage class anyway. */
cp_parser_set_storage_class (parser, decl_specs, RID_AUTO); cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
token->location);
} }
else else
/* We do not yet support the use of `auto' as a /* We do not yet support the use of `auto' as a
type-specifier. */ type-specifier. */
error ("C++0x %<auto%> specifier not supported"); error ("%HC++0x %<auto%> specifier not supported", &token->location);
break; break;
case RID_REGISTER: case RID_REGISTER:
...@@ -8279,7 +8322,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -8279,7 +8322,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
case RID_MUTABLE: case RID_MUTABLE:
/* Consume the token. */ /* Consume the token. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
cp_parser_set_storage_class (parser, decl_specs, token->keyword); cp_parser_set_storage_class (parser, decl_specs, token->keyword,
token->location);
break; break;
case RID_THREAD: case RID_THREAD:
/* Consume the token. */ /* Consume the token. */
...@@ -8315,7 +8359,6 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -8315,7 +8359,6 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/*is_declaration=*/true, /*is_declaration=*/true,
&decl_spec_declares_class_or_enum, &decl_spec_declares_class_or_enum,
&is_cv_qualifier); &is_cv_qualifier);
*declares_class_or_enum |= decl_spec_declares_class_or_enum; *declares_class_or_enum |= decl_spec_declares_class_or_enum;
/* If this type-specifier referenced a user-defined type /* If this type-specifier referenced a user-defined type
...@@ -8375,12 +8418,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -8375,12 +8418,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
flags |= CP_PARSER_FLAGS_OPTIONAL; flags |= CP_PARSER_FLAGS_OPTIONAL;
} }
cp_parser_check_decl_spec (decl_specs); cp_parser_check_decl_spec (decl_specs, start_token->location);
/* Don't allow a friend specifier with a class definition. */ /* Don't allow a friend specifier with a class definition. */
if (decl_specs->specs[(int) ds_friend] != 0 if (decl_specs->specs[(int) ds_friend] != 0
&& (*declares_class_or_enum & 2)) && (*declares_class_or_enum & 2))
error ("class definition may not be declared a friend"); error ("%Hclass definition may not be declared a friend",
&start_token->location);
} }
/* Parse an (optional) storage-class-specifier. /* Parse an (optional) storage-class-specifier.
...@@ -8436,7 +8480,8 @@ static tree ...@@ -8436,7 +8480,8 @@ static tree
cp_parser_function_specifier_opt (cp_parser* parser, cp_parser_function_specifier_opt (cp_parser* parser,
cp_decl_specifier_seq *decl_specs) cp_decl_specifier_seq *decl_specs)
{ {
switch (cp_lexer_peek_token (parser->lexer)->keyword) cp_token *token = cp_lexer_peek_token (parser->lexer);
switch (token->keyword)
{ {
case RID_INLINE: case RID_INLINE:
if (decl_specs) if (decl_specs)
...@@ -8448,7 +8493,7 @@ cp_parser_function_specifier_opt (cp_parser* parser, ...@@ -8448,7 +8493,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
A member function template shall not be virtual. */ A member function template shall not be virtual. */
if (PROCESSING_REAL_TEMPLATE_DECL_P ()) if (PROCESSING_REAL_TEMPLATE_DECL_P ())
error ("templates may not be %<virtual%>"); error ("%Htemplates may not be %<virtual%>", &token->location);
else if (decl_specs) else if (decl_specs)
++decl_specs->specs[(int) ds_virtual]; ++decl_specs->specs[(int) ds_virtual];
break; break;
...@@ -8602,6 +8647,7 @@ cp_parser_decltype (cp_parser *parser) ...@@ -8602,6 +8647,7 @@ cp_parser_decltype (cp_parser *parser)
const char *saved_message; const char *saved_message;
bool saved_integral_constant_expression_p; bool saved_integral_constant_expression_p;
bool saved_non_integral_constant_expression_p; bool saved_non_integral_constant_expression_p;
cp_token *id_expr_start_token;
/* Look for the `decltype' token. */ /* Look for the `decltype' token. */
if (!cp_parser_require_keyword (parser, RID_DECLTYPE, "%<decltype%>")) if (!cp_parser_require_keyword (parser, RID_DECLTYPE, "%<decltype%>"))
...@@ -8631,6 +8677,7 @@ cp_parser_decltype (cp_parser *parser) ...@@ -8631,6 +8677,7 @@ cp_parser_decltype (cp_parser *parser)
return error_mark_node; return error_mark_node;
/* First, try parsing an id-expression. */ /* First, try parsing an id-expression. */
id_expr_start_token = cp_lexer_peek_token (parser->lexer);
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
expr = cp_parser_id_expression (parser, expr = cp_parser_id_expression (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
...@@ -8653,7 +8700,8 @@ cp_parser_decltype (cp_parser *parser) ...@@ -8653,7 +8700,8 @@ cp_parser_decltype (cp_parser *parser)
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
/*ambiguous_decls=*/NULL); /*ambiguous_decls=*/NULL,
id_expr_start_token->location);
if (expr if (expr
&& expr != error_mark_node && expr != error_mark_node
...@@ -8673,7 +8721,8 @@ cp_parser_decltype (cp_parser *parser) ...@@ -8673,7 +8721,8 @@ cp_parser_decltype (cp_parser *parser)
/*done=*/true, /*done=*/true,
/*address_p=*/false, /*address_p=*/false,
/*template_arg_p=*/false, /*template_arg_p=*/false,
&error_msg)); &error_msg,
id_expr_start_token->location));
if (expr == error_mark_node) if (expr == error_mark_node)
/* We found an id-expression, but it was something that we /* We found an id-expression, but it was something that we
...@@ -8916,17 +8965,20 @@ static void ...@@ -8916,17 +8965,20 @@ static void
cp_parser_mem_initializer_list (cp_parser* parser) cp_parser_mem_initializer_list (cp_parser* parser)
{ {
tree mem_initializer_list = NULL_TREE; tree mem_initializer_list = NULL_TREE;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Let the semantic analysis code know that we are starting the /* Let the semantic analysis code know that we are starting the
mem-initializer-list. */ mem-initializer-list. */
if (!DECL_CONSTRUCTOR_P (current_function_decl)) if (!DECL_CONSTRUCTOR_P (current_function_decl))
error ("only constructors take base initializers"); error ("%Honly constructors take base initializers",
&token->location);
/* Loop through the list. */ /* Loop through the list. */
while (true) while (true)
{ {
tree mem_initializer; tree mem_initializer;
token = cp_lexer_peek_token (parser->lexer);
/* Parse the mem-initializer. */ /* Parse the mem-initializer. */
mem_initializer = cp_parser_mem_initializer (parser); mem_initializer = cp_parser_mem_initializer (parser);
/* If the next token is a `...', we're expanding member initializers. */ /* If the next token is a `...', we're expanding member initializers. */
...@@ -8940,8 +8992,8 @@ cp_parser_mem_initializer_list (cp_parser* parser) ...@@ -8940,8 +8992,8 @@ cp_parser_mem_initializer_list (cp_parser* parser)
if (mem_initializer != error_mark_node if (mem_initializer != error_mark_node
&& !TYPE_P (TREE_PURPOSE (mem_initializer))) && !TYPE_P (TREE_PURPOSE (mem_initializer)))
{ {
error ("cannot expand initializer for member %<%D%>", error ("%Hcannot expand initializer for member %<%D%>",
TREE_PURPOSE (mem_initializer)); &token->location, TREE_PURPOSE (mem_initializer));
mem_initializer = error_mark_node; mem_initializer = error_mark_node;
} }
...@@ -8989,11 +9041,13 @@ cp_parser_mem_initializer (cp_parser* parser) ...@@ -8989,11 +9041,13 @@ cp_parser_mem_initializer (cp_parser* parser)
tree mem_initializer_id; tree mem_initializer_id;
tree expression_list; tree expression_list;
tree member; tree member;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Find out what is being initialized. */ /* Find out what is being initialized. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{ {
permerror ("anachronistic old-style base class initializer"); permerror ("%Hanachronistic old-style base class initializer",
&token->location);
mem_initializer_id = NULL_TREE; mem_initializer_id = NULL_TREE;
} }
else else
...@@ -9044,11 +9098,14 @@ cp_parser_mem_initializer_id (cp_parser* parser) ...@@ -9044,11 +9098,14 @@ cp_parser_mem_initializer_id (cp_parser* parser)
bool template_p = false; bool template_p = false;
tree id; tree id;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* `typename' is not allowed in this context ([temp.res]). */ /* `typename' is not allowed in this context ([temp.res]). */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME)) if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
{ {
error ("keyword %<typename%> not allowed in this context (a qualified " error ("%Hkeyword %<typename%> not allowed in this context (a qualified "
"member initializer is implicitly a type)"); "member initializer is implicitly a type)",
&token->location);
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
} }
/* Look for the optional `::' operator. */ /* Look for the optional `::' operator. */
...@@ -9565,6 +9622,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, ...@@ -9565,6 +9622,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
appropriate diagnostic here. */ appropriate diagnostic here. */
/* Consume the `='. */ /* Consume the `='. */
cp_token *start_token = cp_lexer_peek_token (parser->lexer);
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Find the name of the parameter pack. */ /* Find the name of the parameter pack. */
...@@ -9573,10 +9631,11 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, ...@@ -9573,10 +9631,11 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
id_declarator = id_declarator->declarator; id_declarator = id_declarator->declarator;
if (id_declarator && id_declarator->kind == cdk_id) if (id_declarator && id_declarator->kind == cdk_id)
error ("template parameter pack %qD cannot have a default argument", error ("%Htemplate parameter pack %qD cannot have a default argument",
id_declarator->u.id.unqualified_name); &start_token->location, id_declarator->u.id.unqualified_name);
else else
error ("template parameter pack cannot have a default argument"); error ("%Htemplate parameter pack cannot have a default argument",
&start_token->location);
/* Parse the default argument, but throw away the result. */ /* Parse the default argument, but throw away the result. */
cp_parser_default_argument (parser, /*template_parm_p=*/true); cp_parser_default_argument (parser, /*template_parm_p=*/true);
...@@ -9670,10 +9729,11 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) ...@@ -9670,10 +9729,11 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
if (*is_parameter_pack) if (*is_parameter_pack)
{ {
if (identifier) if (identifier)
error ("template parameter pack %qD cannot have a default argument", error ("%Htemplate parameter pack %qD cannot have a "
identifier); "default argument", &token->location, identifier);
else else
error ("template parameter packs cannot have default arguments"); error ("%Htemplate parameter packs cannot have "
"default arguments", &token->location);
default_argument = NULL_TREE; default_argument = NULL_TREE;
} }
pop_deferring_access_checks (); pop_deferring_access_checks ();
...@@ -9741,6 +9801,9 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) ...@@ -9741,6 +9801,9 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the id-expression. */ /* Parse the id-expression. */
push_deferring_access_checks (dk_no_deferred); push_deferring_access_checks (dk_no_deferred);
/* save token before parsing the id-expression, for error
reporting */
token = cp_lexer_peek_token (parser->lexer);
default_argument default_argument
= cp_parser_id_expression (parser, = cp_parser_id_expression (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
...@@ -9761,7 +9824,8 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) ...@@ -9761,7 +9824,8 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
/*is_template=*/is_template, /*is_template=*/is_template,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
/*ambiguous_decls=*/NULL); /*ambiguous_decls=*/NULL,
token->location);
/* See if the default argument is valid. */ /* See if the default argument is valid. */
default_argument default_argument
= check_template_template_default_arg (default_argument); = check_template_template_default_arg (default_argument);
...@@ -9771,10 +9835,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) ...@@ -9771,10 +9835,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
if (*is_parameter_pack) if (*is_parameter_pack)
{ {
if (identifier) if (identifier)
error ("template parameter pack %qD cannot have a default argument", error ("%Htemplate parameter pack %qD cannot "
identifier); "have a default argument",
&token->location, identifier);
else else
error ("template parameter packs cannot have default arguments"); error ("%Htemplate parameter packs cannot "
"have default arguments",
&token->location);
default_argument = NULL_TREE; default_argument = NULL_TREE;
} }
pop_deferring_access_checks (); pop_deferring_access_checks ();
...@@ -9823,7 +9890,7 @@ cp_parser_template_id (cp_parser *parser, ...@@ -9823,7 +9890,7 @@ cp_parser_template_id (cp_parser *parser,
cp_token_position start_of_id = 0; cp_token_position start_of_id = 0;
deferred_access_check *chk; deferred_access_check *chk;
VEC (deferred_access_check,gc) *access_check; VEC (deferred_access_check,gc) *access_check;
cp_token *next_token, *next_token_2; cp_token *next_token = NULL, *next_token_2 = NULL, *token = NULL;
bool is_identifier; bool is_identifier;
/* If the next token corresponds to a template-id, there is no need /* If the next token corresponds to a template-id, there is no need
...@@ -9871,6 +9938,7 @@ cp_parser_template_id (cp_parser *parser, ...@@ -9871,6 +9938,7 @@ cp_parser_template_id (cp_parser *parser,
/* Parse the template-name. */ /* Parse the template-name. */
is_identifier = false; is_identifier = false;
token = cp_lexer_peek_token (parser->lexer);
template = cp_parser_template_name (parser, template_keyword_p, template = cp_parser_template_name (parser, template_keyword_p,
check_dependency_p, check_dependency_p,
is_declaration, is_declaration,
...@@ -9897,6 +9965,7 @@ cp_parser_template_id (cp_parser *parser, ...@@ -9897,6 +9965,7 @@ cp_parser_template_id (cp_parser *parser,
/* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
CPP_LESS. */ CPP_LESS. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the arguments. */ /* Parse the arguments. */
arguments = cp_parser_enclosed_template_argument_list (parser); arguments = cp_parser_enclosed_template_argument_list (parser);
if (!cp_parser_parse_definitely (parser)) if (!cp_parser_parse_definitely (parser))
...@@ -9911,15 +9980,18 @@ cp_parser_template_id (cp_parser *parser, ...@@ -9911,15 +9980,18 @@ cp_parser_template_id (cp_parser *parser,
} }
/* Otherwise, emit an error about the invalid digraph, but continue /* Otherwise, emit an error about the invalid digraph, but continue
parsing because we got our argument list. */ parsing because we got our argument list. */
permerror ("%<<::%> cannot begin a template-argument list"); permerror ("%H%<<::%> cannot begin a template-argument list",
inform ("%<<:%> is an alternate spelling for %<[%>. Insert whitespace " &next_token->location);
"between %<<%> and %<::%>"); inform ("%H%<<:%> is an alternate spelling for %<[%>. Insert whitespace "
"between %<<%> and %<::%>",
&next_token->location);
if (!flag_permissive) if (!flag_permissive)
{ {
static bool hint; static bool hint;
if (!hint) if (!hint)
{ {
inform ("(if you use %<-fpermissive%> G++ will accept your code)"); inform ("%H(if you use %<-fpermissive%> G++ will accept your code)",
&next_token->location);
hint = true; hint = true;
} }
} }
...@@ -9992,7 +10064,8 @@ cp_parser_template_id (cp_parser *parser, ...@@ -9992,7 +10064,8 @@ cp_parser_template_id (cp_parser *parser,
user, as opposed to simply marking the tentative parse as user, as opposed to simply marking the tentative parse as
failed? */ failed? */
if (cp_parser_error_occurred (parser) && template_id != error_mark_node) if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
error ("parse error in template argument list"); error ("%Hparse error in template argument list",
&token->location);
} }
pop_deferring_access_checks (); pop_deferring_access_checks ();
...@@ -10046,6 +10119,7 @@ cp_parser_template_name (cp_parser* parser, ...@@ -10046,6 +10119,7 @@ cp_parser_template_name (cp_parser* parser,
tree identifier; tree identifier;
tree decl; tree decl;
tree fns; tree fns;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* If the next token is `operator', then we have either an /* If the next token is `operator', then we have either an
operator-function-id or a conversion-function-id. */ operator-function-id or a conversion-function-id. */
...@@ -10105,7 +10179,8 @@ cp_parser_template_name (cp_parser* parser, ...@@ -10105,7 +10179,8 @@ cp_parser_template_name (cp_parser* parser,
cp_token_position start = 0; cp_token_position start = 0;
/* Explain what went wrong. */ /* Explain what went wrong. */
error ("non-template %qD used as template", identifier); error ("%Hnon-template %qD used as template",
&token->location, identifier);
inform ("use %<%T::template %D%> to indicate that it is a template", inform ("use %<%T::template %D%> to indicate that it is a template",
parser->scope, identifier); parser->scope, identifier);
/* If parsing tentatively, find the location of the "<" token. */ /* If parsing tentatively, find the location of the "<" token. */
...@@ -10149,7 +10224,8 @@ cp_parser_template_name (cp_parser* parser, ...@@ -10149,7 +10224,8 @@ cp_parser_template_name (cp_parser* parser,
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
check_dependency_p, check_dependency_p,
/*ambiguous_decls=*/NULL); /*ambiguous_decls=*/NULL,
token->location);
decl = maybe_get_template_decl_from_type_decl (decl); decl = maybe_get_template_decl_from_type_decl (decl);
/* If DECL is a template, then the name was a template-name. */ /* If DECL is a template, then the name was a template-name. */
...@@ -10295,7 +10371,7 @@ cp_parser_template_argument (cp_parser* parser) ...@@ -10295,7 +10371,7 @@ cp_parser_template_argument (cp_parser* parser)
bool template_p; bool template_p;
bool address_p; bool address_p;
bool maybe_type_id = false; bool maybe_type_id = false;
cp_token *token; cp_token *token = NULL, *argument_start_token = NULL;
cp_id_kind idk; cp_id_kind idk;
/* There's really no way to know what we're looking at, so we just /* There's really no way to know what we're looking at, so we just
...@@ -10342,6 +10418,7 @@ cp_parser_template_argument (cp_parser* parser) ...@@ -10342,6 +10418,7 @@ cp_parser_template_argument (cp_parser* parser)
/* We're still not sure what the argument will be. */ /* We're still not sure what the argument will be. */
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
/* Try a template. */ /* Try a template. */
argument_start_token = cp_lexer_peek_token (parser->lexer);
argument = cp_parser_id_expression (parser, argument = cp_parser_id_expression (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
/*check_dependency_p=*/true, /*check_dependency_p=*/true,
...@@ -10364,7 +10441,8 @@ cp_parser_template_argument (cp_parser* parser) ...@@ -10364,7 +10441,8 @@ cp_parser_template_argument (cp_parser* parser)
/*is_template=*/template_p, /*is_template=*/template_p,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
/*ambiguous_decls=*/NULL); /*ambiguous_decls=*/NULL,
argument_start_token->location);
if (TREE_CODE (argument) != TEMPLATE_DECL if (TREE_CODE (argument) != TEMPLATE_DECL
&& TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE) && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
cp_parser_error (parser, "expected template-name"); cp_parser_error (parser, "expected template-name");
...@@ -10616,6 +10694,8 @@ static void ...@@ -10616,6 +10694,8 @@ static void
cp_parser_explicit_specialization (cp_parser* parser) cp_parser_explicit_specialization (cp_parser* parser)
{ {
bool need_lang_pop; bool need_lang_pop;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Look for the `template' keyword. */ /* Look for the `template' keyword. */
cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"); cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>");
/* Look for the `<'. */ /* Look for the `<'. */
...@@ -10630,7 +10710,7 @@ cp_parser_explicit_specialization (cp_parser* parser) ...@@ -10630,7 +10710,7 @@ cp_parser_explicit_specialization (cp_parser* parser)
linkage. */ linkage. */
if (current_lang_name == lang_name_c) if (current_lang_name == lang_name_c)
{ {
error ("template specialization with C linkage"); error ("%Htemplate specialization with C linkage", &token->location);
/* Give it C++ linkage to avoid confusing other parts of the /* Give it C++ linkage to avoid confusing other parts of the
front end. */ front end. */
push_lang_context (lang_name_cplusplus); push_lang_context (lang_name_cplusplus);
...@@ -10955,7 +11035,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, ...@@ -10955,7 +11035,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* We do not yet support the use of `auto' as a /* We do not yet support the use of `auto' as a
type-specifier. */ type-specifier. */
error ("C++0x %<auto%> specifier not supported"); error ("%HC++0x %<auto%> specifier not supported", &token->location);
} }
break; break;
...@@ -11168,12 +11248,13 @@ cp_parser_nonclass_name (cp_parser* parser) ...@@ -11168,12 +11248,13 @@ cp_parser_nonclass_name (cp_parser* parser)
tree type_decl; tree type_decl;
tree identifier; tree identifier;
cp_token *token = cp_lexer_peek_token (parser->lexer);
identifier = cp_parser_identifier (parser); identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node) if (identifier == error_mark_node)
return error_mark_node; return error_mark_node;
/* Look up the type-name. */ /* Look up the type-name. */
type_decl = cp_parser_lookup_name_simple (parser, identifier); type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
if (TREE_CODE (type_decl) != TYPE_DECL if (TREE_CODE (type_decl) != TYPE_DECL
&& (objc_is_id (identifier) || objc_is_class_name (identifier))) && (objc_is_id (identifier) || objc_is_class_name (identifier)))
...@@ -11190,7 +11271,7 @@ cp_parser_nonclass_name (cp_parser* parser) ...@@ -11190,7 +11271,7 @@ cp_parser_nonclass_name (cp_parser* parser)
{ {
if (!cp_parser_simulate_error (parser)) if (!cp_parser_simulate_error (parser))
cp_parser_name_lookup_error (parser, identifier, type_decl, cp_parser_name_lookup_error (parser, identifier, type_decl,
"is not a type"); "is not a type", token->location);
return error_mark_node; return error_mark_node;
} }
/* Remember that the name was used in the definition of the /* Remember that the name was used in the definition of the
...@@ -11239,6 +11320,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11239,6 +11320,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
tree identifier; tree identifier;
tree type = NULL_TREE; tree type = NULL_TREE;
tree attributes = NULL_TREE; tree attributes = NULL_TREE;
cp_token *token = NULL;
/* See if we're looking at the `enum' keyword. */ /* See if we're looking at the `enum' keyword. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM)) if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
...@@ -11308,6 +11390,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11308,6 +11390,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (!template_p) if (!template_p)
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
/* Parse the template-id. */ /* Parse the template-id. */
token = cp_lexer_peek_token (parser->lexer);
decl = cp_parser_template_id (parser, template_p, decl = cp_parser_template_id (parser, template_p,
/*check_dependency_p=*/true, /*check_dependency_p=*/true,
is_declaration); is_declaration);
...@@ -11329,6 +11412,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11329,6 +11412,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (!type) if (!type)
{ {
token = cp_lexer_peek_token (parser->lexer);
identifier = cp_parser_identifier (parser); identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node) if (identifier == error_mark_node)
...@@ -11341,7 +11425,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11341,7 +11425,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (tag_type == typename_type if (tag_type == typename_type
&& TREE_CODE (parser->scope) != NAMESPACE_DECL) && TREE_CODE (parser->scope) != NAMESPACE_DECL)
return cp_parser_make_typename_type (parser, parser->scope, return cp_parser_make_typename_type (parser, parser->scope,
identifier); identifier,
token->location);
/* Look up a qualified name in the usual way. */ /* Look up a qualified name in the usual way. */
if (parser->scope) if (parser->scope)
{ {
...@@ -11353,7 +11438,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11353,7 +11438,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
&ambiguous_decls); &ambiguous_decls,
token->location);
/* If the lookup was ambiguous, an error will already have been /* If the lookup was ambiguous, an error will already have been
issued. */ issued. */
...@@ -11389,7 +11475,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11389,7 +11475,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
{ {
cp_parser_diagnose_invalid_type_name (parser, cp_parser_diagnose_invalid_type_name (parser,
parser->scope, parser->scope,
identifier); identifier,
token->location);
return error_mark_node; return error_mark_node;
} }
...@@ -11489,7 +11576,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11489,7 +11576,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/* An unqualified name was used to reference this type, so /* An unqualified name was used to reference this type, so
there were no qualifying templates. */ there were no qualifying templates. */
if (!cp_parser_check_template_parameters (parser, if (!cp_parser_check_template_parameters (parser,
/*num_templates=*/0)) /*num_templates=*/0,
token->location))
return error_mark_node; return error_mark_node;
type = xref_tag (tag_type, identifier, ts, template_p); type = xref_tag (tag_type, identifier, ts, template_p);
} }
...@@ -11692,6 +11780,8 @@ cp_parser_namespace_name (cp_parser* parser) ...@@ -11692,6 +11780,8 @@ cp_parser_namespace_name (cp_parser* parser)
tree identifier; tree identifier;
tree namespace_decl; tree namespace_decl;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Get the name of the namespace. */ /* Get the name of the namespace. */
identifier = cp_parser_identifier (parser); identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node) if (identifier == error_mark_node)
...@@ -11720,13 +11810,14 @@ cp_parser_namespace_name (cp_parser* parser) ...@@ -11720,13 +11810,14 @@ cp_parser_namespace_name (cp_parser* parser)
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/true, /*is_namespace=*/true,
/*check_dependency=*/true, /*check_dependency=*/true,
/*ambiguous_decls=*/NULL); /*ambiguous_decls=*/NULL,
token->location);
/* If it's not a namespace, issue an error. */ /* If it's not a namespace, issue an error. */
if (namespace_decl == error_mark_node if (namespace_decl == error_mark_node
|| TREE_CODE (namespace_decl) != NAMESPACE_DECL) || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
{ {
if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
error ("%qD is not a namespace-name", identifier); error ("%H%qD is not a namespace-name", &token->location, identifier);
cp_parser_error (parser, "expected namespace-name"); cp_parser_error (parser, "expected namespace-name");
namespace_decl = error_mark_node; namespace_decl = error_mark_node;
} }
...@@ -11841,6 +11932,8 @@ cp_parser_namespace_alias_definition (cp_parser* parser) ...@@ -11841,6 +11932,8 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
tree identifier; tree identifier;
tree namespace_specifier; tree namespace_specifier;
cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Look for the `namespace' keyword. */ /* Look for the `namespace' keyword. */
cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>"); cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>");
/* Look for the identifier. */ /* Look for the identifier. */
...@@ -11851,7 +11944,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser) ...@@ -11851,7 +11944,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
if (!cp_parser_uncommitted_to_tentative_parse_p (parser) if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{ {
error ("%<namespace%> definition is not allowed here"); error ("%H%<namespace%> definition is not allowed here", &token->location);
/* Skip the definition. */ /* Skip the definition. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
if (cp_parser_skip_to_closing_brace (parser)) if (cp_parser_skip_to_closing_brace (parser))
...@@ -11966,6 +12059,7 @@ cp_parser_using_declaration (cp_parser* parser, ...@@ -11966,6 +12059,7 @@ cp_parser_using_declaration (cp_parser* parser,
cp_parser_parse_definitely will be false, as required. */ cp_parser_parse_definitely will be false, as required. */
return cp_parser_parse_definitely (parser); return cp_parser_parse_definitely (parser);
token = cp_lexer_peek_token (parser->lexer);
/* Parse the unqualified-id. */ /* Parse the unqualified-id. */
identifier = cp_parser_unqualified_id (parser, identifier = cp_parser_unqualified_id (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
...@@ -11990,7 +12084,8 @@ cp_parser_using_declaration (cp_parser* parser, ...@@ -11990,7 +12084,8 @@ cp_parser_using_declaration (cp_parser* parser,
/* [namespace.udecl] /* [namespace.udecl]
A using declaration shall not name a template-id. */ A using declaration shall not name a template-id. */
error ("a template-id may not appear in a using-declaration"); error ("%Ha template-id may not appear in a using-declaration",
&token->location);
else else
{ {
if (at_class_scope_p ()) if (at_class_scope_p ())
...@@ -12006,9 +12101,13 @@ cp_parser_using_declaration (cp_parser* parser, ...@@ -12006,9 +12101,13 @@ cp_parser_using_declaration (cp_parser* parser,
} }
else else
{ {
decl = cp_parser_lookup_name_simple (parser, identifier); decl = cp_parser_lookup_name_simple (parser,
identifier,
token->location);
if (decl == error_mark_node) if (decl == error_mark_node)
cp_parser_name_lookup_error (parser, identifier, decl, NULL); cp_parser_name_lookup_error (parser, identifier,
decl, NULL,
token->location);
else if (check_for_bare_parameter_packs (decl)) else if (check_for_bare_parameter_packs (decl))
return false; return false;
else if (!at_namespace_scope_p ()) else if (!at_namespace_scope_p ())
...@@ -12258,7 +12357,8 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12258,7 +12357,8 @@ cp_parser_init_declarator (cp_parser* parser,
int declares_class_or_enum, int declares_class_or_enum,
bool* function_definition_p) bool* function_definition_p)
{ {
cp_token *token; cp_token *token = NULL, *asm_spec_start_token = NULL,
*attributes_start_token = NULL;
cp_declarator *declarator; cp_declarator *declarator;
tree prefix_attributes; tree prefix_attributes;
tree attributes; tree attributes;
...@@ -12292,6 +12392,7 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12292,6 +12392,7 @@ cp_parser_init_declarator (cp_parser* parser,
resume_deferring_access_checks (); resume_deferring_access_checks ();
/* Parse the declarator. */ /* Parse the declarator. */
token = cp_lexer_peek_token (parser->lexer);
declarator declarator
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
&ctor_dtor_or_conv_p, &ctor_dtor_or_conv_p,
...@@ -12306,7 +12407,8 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12306,7 +12407,8 @@ cp_parser_init_declarator (cp_parser* parser,
return error_mark_node; return error_mark_node;
/* Check that the number of template-parameter-lists is OK. */ /* Check that the number of template-parameter-lists is OK. */
if (!cp_parser_check_declarator_template_parameters (parser, declarator)) if (!cp_parser_check_declarator_template_parameters (parser, declarator,
token->location))
return error_mark_node; return error_mark_node;
if (declares_class_or_enum & 2) if (declares_class_or_enum & 2)
...@@ -12323,8 +12425,10 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12323,8 +12425,10 @@ cp_parser_init_declarator (cp_parser* parser,
if (cp_parser_allow_gnu_extensions_p (parser)) if (cp_parser_allow_gnu_extensions_p (parser))
{ {
/* Look for an asm-specification. */ /* Look for an asm-specification. */
asm_spec_start_token = cp_lexer_peek_token (parser->lexer);
asm_specification = cp_parser_asm_specification_opt (parser); asm_specification = cp_parser_asm_specification_opt (parser);
/* And attributes. */ /* And attributes. */
attributes_start_token = cp_lexer_peek_token (parser->lexer);
attributes = cp_parser_attributes_opt (parser); attributes = cp_parser_attributes_opt (parser);
} }
else else
...@@ -12353,9 +12457,12 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12353,9 +12457,12 @@ cp_parser_init_declarator (cp_parser* parser,
/* Neither attributes nor an asm-specification are allowed /* Neither attributes nor an asm-specification are allowed
on a function-definition. */ on a function-definition. */
if (asm_specification) if (asm_specification)
error ("an asm-specification is not allowed on a function-definition"); error ("%Han asm-specification is not allowed "
"on a function-definition",
&asm_spec_start_token->location);
if (attributes) if (attributes)
error ("attributes are not allowed on a function-definition"); error ("%Hattributes are not allowed on a function-definition",
&attributes_start_token->location);
/* This is a function-definition. */ /* This is a function-definition. */
*function_definition_p = true; *function_definition_p = true;
...@@ -12481,6 +12588,7 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12481,6 +12588,7 @@ cp_parser_init_declarator (cp_parser* parser,
{ {
if (function_declarator_p (declarator)) if (function_declarator_p (declarator))
{ {
cp_token *initializer_start_token = cp_lexer_peek_token (parser->lexer);
if (initialization_kind == CPP_EQ) if (initialization_kind == CPP_EQ)
initializer = cp_parser_pure_specifier (parser); initializer = cp_parser_pure_specifier (parser);
else else
...@@ -12489,7 +12597,8 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -12489,7 +12597,8 @@ cp_parser_init_declarator (cp_parser* parser,
know what the user intended, so just silently know what the user intended, so just silently
consume the initializer. */ consume the initializer. */
if (decl != error_mark_node) if (decl != error_mark_node)
error ("initializer provided for function"); error ("%Hinitializer provided for function",
&initializer_start_token->location);
cp_parser_skip_to_closing_parenthesis (parser, cp_parser_skip_to_closing_parenthesis (parser,
/*recovering=*/true, /*recovering=*/true,
/*or_comma=*/false, /*or_comma=*/false,
...@@ -12891,7 +13000,8 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -12891,7 +13000,8 @@ cp_parser_direct_declarator (cp_parser* parser,
in function scopes. */ in function scopes. */
else if (!parser->in_function_body) else if (!parser->in_function_body)
{ {
error ("array bound is not an integer constant"); error ("%Harray bound is not an integer constant",
&token->location);
bounds = error_mark_node; bounds = error_mark_node;
} }
} }
...@@ -12913,6 +13023,7 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -12913,6 +13023,7 @@ cp_parser_direct_declarator (cp_parser* parser,
special_function_kind sfk; special_function_kind sfk;
bool abstract_ok; bool abstract_ok;
bool pack_expansion_p = false; bool pack_expansion_p = false;
cp_token *declarator_id_start_token;
/* Parse a declarator-id */ /* Parse a declarator-id */
abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
...@@ -12931,6 +13042,7 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -12931,6 +13042,7 @@ cp_parser_direct_declarator (cp_parser* parser,
} }
} }
declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
unqualified_name unqualified_name
= cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
qualifying_scope = parser->scope; qualifying_scope = parser->scope;
...@@ -13000,7 +13112,8 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -13000,7 +13112,8 @@ cp_parser_direct_declarator (cp_parser* parser,
/*only_current_p=*/false); /*only_current_p=*/false);
/* If that failed, the declarator is invalid. */ /* If that failed, the declarator is invalid. */
if (TREE_CODE (type) == TYPENAME_TYPE) if (TREE_CODE (type) == TYPENAME_TYPE)
error ("%<%T::%E%> is not a type", error ("%H%<%T::%E%> is not a type",
&declarator_id_start_token->location,
TYPE_CONTEXT (qualifying_scope), TYPE_CONTEXT (qualifying_scope),
TYPE_IDENTIFIER (qualifying_scope)); TYPE_IDENTIFIER (qualifying_scope));
qualifying_scope = type; qualifying_scope = type;
...@@ -13026,7 +13139,8 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -13026,7 +13139,8 @@ cp_parser_direct_declarator (cp_parser* parser,
if (qualifying_scope if (qualifying_scope
&& CLASSTYPE_USE_TEMPLATE (name_type)) && CLASSTYPE_USE_TEMPLATE (name_type))
{ {
error ("invalid use of constructor as a template"); error ("%Hinvalid use of constructor as a template",
&declarator_id_start_token->location);
inform ("use %<%T::%D%> instead of %<%T::%D%> to " inform ("use %<%T::%D%> instead of %<%T::%D%> to "
"name the constructor in a qualified name", "name the constructor in a qualified name",
class_type, class_type,
...@@ -13185,6 +13299,7 @@ cp_parser_ptr_operator (cp_parser* parser, ...@@ -13185,6 +13299,7 @@ cp_parser_ptr_operator (cp_parser* parser,
cp_parser_global_scope_opt (parser, cp_parser_global_scope_opt (parser,
/*current_scope_valid_p=*/false); /*current_scope_valid_p=*/false);
/* Look for the nested-name specifier. */ /* Look for the nested-name specifier. */
token = cp_lexer_peek_token (parser->lexer);
cp_parser_nested_name_specifier (parser, cp_parser_nested_name_specifier (parser,
/*typename_keyword_p=*/false, /*typename_keyword_p=*/false,
/*check_dependency_p=*/true, /*check_dependency_p=*/true,
...@@ -13199,7 +13314,7 @@ cp_parser_ptr_operator (cp_parser* parser, ...@@ -13199,7 +13314,7 @@ cp_parser_ptr_operator (cp_parser* parser,
code = INDIRECT_REF; code = INDIRECT_REF;
if (TREE_CODE (parser->scope) == NAMESPACE_DECL) if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
error ("%qD is a namespace", parser->scope); error ("%H%qD is a namespace", &token->location, parser->scope);
else else
{ {
/* The type of which the member is a member is given by the /* The type of which the member is a member is given by the
...@@ -13274,7 +13389,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) ...@@ -13274,7 +13389,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
if (cv_quals & cv_qualifier) if (cv_quals & cv_qualifier)
{ {
error ("duplicate cv-qualifier"); error ("%Hduplicate cv-qualifier", &token->location);
cp_lexer_purge_token (parser->lexer); cp_lexer_purge_token (parser->lexer);
} }
else else
...@@ -13384,6 +13499,7 @@ cp_parser_type_specifier_seq (cp_parser* parser, ...@@ -13384,6 +13499,7 @@ cp_parser_type_specifier_seq (cp_parser* parser,
{ {
bool seen_type_specifier = false; bool seen_type_specifier = false;
cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL; cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL;
cp_token *start_token = NULL;
/* Clear the TYPE_SPECIFIER_SEQ. */ /* Clear the TYPE_SPECIFIER_SEQ. */
clear_decl_specs (type_specifier_seq); clear_decl_specs (type_specifier_seq);
...@@ -13403,6 +13519,11 @@ cp_parser_type_specifier_seq (cp_parser* parser, ...@@ -13403,6 +13519,11 @@ cp_parser_type_specifier_seq (cp_parser* parser,
continue; continue;
} }
/* record the token of the beginning of the type specifier seq,
for error reporting purposes*/
if (!start_token)
start_token = cp_lexer_peek_token (parser->lexer);
/* Look for the type-specifier. */ /* Look for the type-specifier. */
type_specifier = cp_parser_type_specifier (parser, type_specifier = cp_parser_type_specifier (parser,
flags, flags,
...@@ -13446,7 +13567,7 @@ cp_parser_type_specifier_seq (cp_parser* parser, ...@@ -13446,7 +13567,7 @@ cp_parser_type_specifier_seq (cp_parser* parser,
flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES; flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
} }
cp_parser_check_decl_spec (type_specifier_seq); cp_parser_check_decl_spec (type_specifier_seq, start_token->location);
} }
/* Parse a parameter-declaration-clause. /* Parse a parameter-declaration-clause.
...@@ -13673,7 +13794,7 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -13673,7 +13794,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
cp_decl_specifier_seq decl_specifiers; cp_decl_specifier_seq decl_specifiers;
cp_declarator *declarator; cp_declarator *declarator;
tree default_argument; tree default_argument;
cp_token *token; cp_token *token = NULL, *declarator_token_start = NULL;
const char *saved_message; const char *saved_message;
/* In a template parameter, `>' is not an operator. /* In a template parameter, `>' is not an operator.
...@@ -13742,6 +13863,7 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -13742,6 +13863,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
cp_parser_commit_to_tentative_parse (parser); cp_parser_commit_to_tentative_parse (parser);
/* Parse the declarator. */ /* Parse the declarator. */
declarator_token_start = token;
declarator = cp_parser_declarator (parser, declarator = cp_parser_declarator (parser,
CP_PARSER_DECLARATOR_EITHER, CP_PARSER_DECLARATOR_EITHER,
/*ctor_dtor_or_conv_p=*/NULL, /*ctor_dtor_or_conv_p=*/NULL,
...@@ -13900,7 +14022,7 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -13900,7 +14022,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
/* If we run out of tokens, issue an error message. */ /* If we run out of tokens, issue an error message. */
case CPP_EOF: case CPP_EOF:
case CPP_PRAGMA_EOL: case CPP_PRAGMA_EOL:
error ("file ends in default argument"); error ("%Hfile ends in default argument", &token->location);
done = true; done = true;
break; break;
...@@ -13937,8 +14059,11 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -13937,8 +14059,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
/* Outside of a class definition, we can just parse the /* Outside of a class definition, we can just parse the
assignment-expression. */ assignment-expression. */
else else
{
token = cp_lexer_peek_token (parser->lexer);
default_argument default_argument
= cp_parser_default_argument (parser, template_parm_p); = cp_parser_default_argument (parser, template_parm_p);
}
if (!parser->default_arg_ok_p) if (!parser->default_arg_ok_p)
{ {
...@@ -13946,7 +14071,9 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -13946,7 +14071,9 @@ cp_parser_parameter_declaration (cp_parser *parser,
warning (0, "deprecated use of default argument for parameter of non-function"); warning (0, "deprecated use of default argument for parameter of non-function");
else else
{ {
error ("default arguments are only permitted for function parameters"); error ("%Hdefault arguments are only "
"permitted for function parameters",
&token->location);
default_argument = NULL_TREE; default_argument = NULL_TREE;
} }
} }
...@@ -13962,11 +14089,12 @@ cp_parser_parameter_declaration (cp_parser *parser, ...@@ -13962,11 +14089,12 @@ cp_parser_parameter_declaration (cp_parser *parser,
id_declarator = id_declarator->declarator; id_declarator = id_declarator->declarator;
if (id_declarator && id_declarator->kind == cdk_id) if (id_declarator && id_declarator->kind == cdk_id)
error ("%sparameter pack %qD cannot have a default argument", error ("%H%sparameter pack %qD cannot have a default argument",
&declarator_token_start->location,
kind, id_declarator->u.id.unqualified_name); kind, id_declarator->u.id.unqualified_name);
else else
error ("%sparameter pack cannot have a default argument", error ("%H%sparameter pack cannot have a default argument",
kind); &declarator_token_start->location, kind);
default_argument = NULL_TREE; default_argument = NULL_TREE;
} }
...@@ -14377,10 +14505,12 @@ cp_parser_class_name (cp_parser *parser, ...@@ -14377,10 +14505,12 @@ cp_parser_class_name (cp_parser *parser,
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
check_dependency_p, check_dependency_p,
&ambiguous_decls); &ambiguous_decls,
identifier_token->location);
if (ambiguous_decls) if (ambiguous_decls)
{ {
error ("reference to %qD is ambiguous", identifier); error ("%Hreference to %qD is ambiguous",
&identifier_token->location, identifier);
print_candidates (ambiguous_decls); print_candidates (ambiguous_decls);
if (cp_parser_parsing_tentatively (parser)) if (cp_parser_parsing_tentatively (parser))
{ {
...@@ -14671,7 +14801,7 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14671,7 +14801,7 @@ cp_parser_class_head (cp_parser* parser,
bool invalid_explicit_specialization_p = false; bool invalid_explicit_specialization_p = false;
tree pushed_scope = NULL_TREE; tree pushed_scope = NULL_TREE;
unsigned num_templates; unsigned num_templates;
cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL;
/* Assume no nested-name-specifier will be present. */ /* Assume no nested-name-specifier will be present. */
*nested_name_specifier_p = false; *nested_name_specifier_p = false;
/* Assume no template parameter lists will be used in defining the /* Assume no template parameter lists will be used in defining the
...@@ -14704,6 +14834,7 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14704,6 +14834,7 @@ cp_parser_class_head (cp_parser* parser,
/* Determine the name of the class. Begin by looking for an /* Determine the name of the class. Begin by looking for an
optional nested-name-specifier. */ optional nested-name-specifier. */
nested_name_specifier_token_start = cp_lexer_peek_token (parser->lexer);
nested_name_specifier nested_name_specifier
= cp_parser_nested_name_specifier_opt (parser, = cp_parser_nested_name_specifier_opt (parser,
/*typename_keyword_p=*/false, /*typename_keyword_p=*/false,
...@@ -14714,6 +14845,7 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14714,6 +14845,7 @@ cp_parser_class_head (cp_parser* parser,
identifier. */ identifier. */
if (nested_name_specifier) if (nested_name_specifier)
{ {
type_start_token = cp_lexer_peek_token (parser->lexer);
/* Although the grammar says `identifier', it really means /* Although the grammar says `identifier', it really means
`class-name' or `template-name'. You are only allowed to `class-name' or `template-name'. You are only allowed to
define a class that has already been declared with this define a class that has already been declared with this
...@@ -14777,6 +14909,7 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14777,6 +14909,7 @@ cp_parser_class_head (cp_parser* parser,
an identifier, or nothing at all. */ an identifier, or nothing at all. */
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
/* Check for a template-id. */ /* Check for a template-id. */
type_start_token = cp_lexer_peek_token (parser->lexer);
id = cp_parser_template_id (parser, id = cp_parser_template_id (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
/*check_dependency_p=*/true, /*check_dependency_p=*/true,
...@@ -14828,7 +14961,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14828,7 +14961,8 @@ cp_parser_class_head (cp_parser* parser,
/* Reject typedef-names in class heads. */ /* Reject typedef-names in class heads. */
if (!DECL_IMPLICIT_TYPEDEF_P (type)) if (!DECL_IMPLICIT_TYPEDEF_P (type))
{ {
error ("invalid class name in declaration of %qD", type); error ("%Hinvalid class name in declaration of %qD",
&type_start_token->location, type);
type = NULL_TREE; type = NULL_TREE;
goto done; goto done;
} }
...@@ -14840,10 +14974,13 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14840,10 +14974,13 @@ cp_parser_class_head (cp_parser* parser,
if (scope && !is_ancestor (scope, nested_name_specifier)) if (scope && !is_ancestor (scope, nested_name_specifier))
{ {
if (at_namespace_scope_p ()) if (at_namespace_scope_p ())
error ("declaration of %qD in namespace %qD which does not " error ("%Hdeclaration of %qD in namespace %qD which does not "
"enclose %qD", type, scope, nested_name_specifier); "enclose %qD",
&type_start_token->location,
type, scope, nested_name_specifier);
else else
error ("declaration of %qD in %qD which does not enclose %qD", error ("%Hdeclaration of %qD in %qD which does not enclose %qD",
&type_start_token->location,
type, scope, nested_name_specifier); type, scope, nested_name_specifier);
type = NULL_TREE; type = NULL_TREE;
goto done; goto done;
...@@ -14856,7 +14993,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14856,7 +14993,8 @@ cp_parser_class_head (cp_parser* parser,
class member of a namespace outside of its namespace. */ class member of a namespace outside of its namespace. */
if (scope == nested_name_specifier) if (scope == nested_name_specifier)
{ {
permerror ("extra qualification not allowed"); permerror ("%Hextra qualification not allowed",
&nested_name_specifier_token_start->location);
nested_name_specifier = NULL_TREE; nested_name_specifier = NULL_TREE;
num_templates = 0; num_templates = 0;
} }
...@@ -14867,7 +15005,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14867,7 +15005,8 @@ cp_parser_class_head (cp_parser* parser,
&& parser->num_template_parameter_lists == 0 && parser->num_template_parameter_lists == 0
&& template_id_p) && template_id_p)
{ {
error ("an explicit specialization must be preceded by %<template <>%>"); error ("%Han explicit specialization must be preceded by %<template <>%>",
&type_start_token->location);
invalid_explicit_specialization_p = true; invalid_explicit_specialization_p = true;
/* Take the same action that would have been taken by /* Take the same action that would have been taken by
cp_parser_explicit_specialization. */ cp_parser_explicit_specialization. */
...@@ -14879,7 +15018,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14879,7 +15018,8 @@ cp_parser_class_head (cp_parser* parser,
use "goto done;" to return. */ use "goto done;" to return. */
/* Make sure that the right number of template parameters were /* Make sure that the right number of template parameters were
present. */ present. */
if (!cp_parser_check_template_parameters (parser, num_templates)) if (!cp_parser_check_template_parameters (parser, num_templates,
type_start_token->location))
{ {
/* If something went wrong, there is no point in even trying to /* If something went wrong, there is no point in even trying to
process the class-definition. */ process the class-definition. */
...@@ -14894,7 +15034,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14894,7 +15034,8 @@ cp_parser_class_head (cp_parser* parser,
&& (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0)) && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
|| TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD)) || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
{ {
error ("function template %qD redeclared as a class template", id); error ("%Hfunction template %qD redeclared as a class template",
&type_start_token->location, id);
type = error_mark_node; type = error_mark_node;
} }
else else
...@@ -14975,8 +15116,10 @@ cp_parser_class_head (cp_parser* parser, ...@@ -14975,8 +15116,10 @@ cp_parser_class_head (cp_parser* parser,
that's an error. */ that's an error. */
if (type != error_mark_node && COMPLETE_TYPE_P (type)) if (type != error_mark_node && COMPLETE_TYPE_P (type))
{ {
error ("redefinition of %q#T", type); error ("%Hredefinition of %q#T",
error ("previous definition of %q+#T", type); &type_start_token->location, type);
error ("%Hprevious definition of %q+#T",
&type_start_token->location, type);
type = NULL_TREE; type = NULL_TREE;
goto done; goto done;
} }
...@@ -15131,7 +15274,9 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15131,7 +15274,9 @@ cp_parser_member_declaration (cp_parser* parser)
tree decl; tree decl;
int declares_class_or_enum; int declares_class_or_enum;
bool friend_p; bool friend_p;
cp_token *token; cp_token *token = NULL;
cp_token *decl_spec_token_start = NULL;
cp_token *initializer_token_start = NULL;
int saved_pedantic; int saved_pedantic;
/* Check for the `__extension__' keyword. */ /* Check for the `__extension__' keyword. */
...@@ -15195,6 +15340,7 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15195,6 +15340,7 @@ cp_parser_member_declaration (cp_parser* parser)
return; return;
/* Parse the decl-specifier-seq. */ /* Parse the decl-specifier-seq. */
decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
cp_parser_decl_specifier_seq (parser, cp_parser_decl_specifier_seq (parser,
CP_PARSER_FLAGS_OPTIONAL, CP_PARSER_FLAGS_OPTIONAL,
&decl_specifiers, &decl_specifiers,
...@@ -15240,7 +15386,8 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15240,7 +15386,8 @@ cp_parser_member_declaration (cp_parser* parser)
/* If the `friend' keyword was present, the friend must /* If the `friend' keyword was present, the friend must
be introduced with a class-key. */ be introduced with a class-key. */
if (!declares_class_or_enum) if (!declares_class_or_enum)
error ("a class-key must be used when declaring a friend"); error ("%Ha class-key must be used when declaring a friend",
&decl_spec_token_start->location);
/* In this case: /* In this case:
template <typename T> struct A { template <typename T> struct A {
...@@ -15254,8 +15401,8 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15254,8 +15401,8 @@ cp_parser_member_declaration (cp_parser* parser)
&& TYPE_P (decl_specifiers.type)) && TYPE_P (decl_specifiers.type))
type = decl_specifiers.type; type = decl_specifiers.type;
if (!type || !TYPE_P (type)) if (!type || !TYPE_P (type))
error ("friend declaration does not name a class or " error ("%Hfriend declaration does not name a class or "
"function"); "function", &decl_spec_token_start->location);
else else
make_friend_class (current_class_type, type, make_friend_class (current_class_type, type,
/*complain=*/true); /*complain=*/true);
...@@ -15278,7 +15425,9 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15278,7 +15425,9 @@ cp_parser_member_declaration (cp_parser* parser)
finish_member_declaration (decl); finish_member_declaration (decl);
} }
else else
cp_parser_check_access_in_redeclaration (TYPE_NAME (type)); cp_parser_check_access_in_redeclaration
(TYPE_NAME (type),
decl_spec_token_start->location);
} }
} }
else else
...@@ -15406,6 +15555,7 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15406,6 +15555,7 @@ cp_parser_member_declaration (cp_parser* parser)
for a pure-specifier; otherwise, we look for a for a pure-specifier; otherwise, we look for a
constant-initializer. When we call `grokfield', it will constant-initializer. When we call `grokfield', it will
perform more stringent semantics checks. */ perform more stringent semantics checks. */
initializer_token_start = cp_lexer_peek_token (parser->lexer);
if (function_declarator_p (declarator)) if (function_declarator_p (declarator))
initializer = cp_parser_pure_specifier (parser); initializer = cp_parser_pure_specifier (parser);
else else
...@@ -15430,7 +15580,8 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -15430,7 +15580,8 @@ cp_parser_member_declaration (cp_parser* parser)
standard, since a pure function may be defined standard, since a pure function may be defined
outside of the class-specifier. */ outside of the class-specifier. */
if (initializer) if (initializer)
error ("pure-specifier on function-definition"); error ("%Hpure-specifier on function-definition",
&initializer_token_start->location);
decl = cp_parser_save_member_function_body (parser, decl = cp_parser_save_member_function_body (parser,
&decl_specifiers, &decl_specifiers,
declarator, declarator,
...@@ -15521,7 +15672,7 @@ cp_parser_pure_specifier (cp_parser* parser) ...@@ -15521,7 +15672,7 @@ cp_parser_pure_specifier (cp_parser* parser)
} }
if (PROCESSING_REAL_TEMPLATE_DECL_P ()) if (PROCESSING_REAL_TEMPLATE_DECL_P ())
{ {
error ("templates may not be %<virtual%>"); error ("%Htemplates may not be %<virtual%>", &token->location);
return error_mark_node; return error_mark_node;
} }
...@@ -15723,11 +15874,14 @@ cp_parser_base_specifier (cp_parser* parser) ...@@ -15723,11 +15874,14 @@ cp_parser_base_specifier (cp_parser* parser)
as base classes. */ as base classes. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME)) if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
{ {
token = cp_lexer_peek_token (parser->lexer);
if (!processing_template_decl) if (!processing_template_decl)
error ("keyword %<typename%> not allowed outside of templates"); error ("%Hkeyword %<typename%> not allowed outside of templates",
&token->location);
else else
error ("keyword %<typename%> not allowed in this context " error ("%Hkeyword %<typename%> not allowed in this context "
"(the base class is implicitly a type)"); "(the base class is implicitly a type)",
&token->location);
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
} }
...@@ -16428,7 +16582,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name, ...@@ -16428,7 +16582,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
bool is_template, bool is_template,
bool is_namespace, bool is_namespace,
bool check_dependency, bool check_dependency,
tree *ambiguous_decls) tree *ambiguous_decls,
location_t name_location)
{ {
int flags = 0; int flags = 0;
tree decl; tree decl;
...@@ -16609,7 +16764,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name, ...@@ -16609,7 +16764,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
cp_parser_error, so we incorporate its actions directly. */ cp_parser_error, so we incorporate its actions directly. */
if (!cp_parser_simulate_error (parser)) if (!cp_parser_simulate_error (parser))
{ {
error ("reference to %qD is ambiguous", name); error ("%Hreference to %qD is ambiguous",
&name_location, name);
print_candidates (decl); print_candidates (decl);
} }
return error_mark_node; return error_mark_node;
...@@ -16639,14 +16795,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name, ...@@ -16639,14 +16795,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */ IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */
static tree static tree
cp_parser_lookup_name_simple (cp_parser* parser, tree name) cp_parser_lookup_name_simple (cp_parser* parser, tree name, location_t location)
{ {
return cp_parser_lookup_name (parser, name, return cp_parser_lookup_name (parser, name,
none_type, none_type,
/*is_template=*/false, /*is_template=*/false,
/*is_namespace=*/false, /*is_namespace=*/false,
/*check_dependency=*/true, /*check_dependency=*/true,
/*ambiguous_decls=*/NULL); /*ambiguous_decls=*/NULL,
location);
} }
/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in /* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
...@@ -16699,7 +16856,8 @@ cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p) ...@@ -16699,7 +16856,8 @@ cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
static bool static bool
cp_parser_check_declarator_template_parameters (cp_parser* parser, cp_parser_check_declarator_template_parameters (cp_parser* parser,
cp_declarator *declarator) cp_declarator *declarator,
location_t declarator_location)
{ {
unsigned num_templates; unsigned num_templates;
...@@ -16749,7 +16907,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -16749,7 +16907,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
++num_templates; ++num_templates;
return cp_parser_check_template_parameters (parser, return cp_parser_check_template_parameters (parser,
num_templates); num_templates,
declarator_location);
case cdk_function: case cdk_function:
case cdk_array: case cdk_array:
...@@ -16757,7 +16916,7 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -16757,7 +16916,7 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
case cdk_reference: case cdk_reference:
case cdk_ptrmem: case cdk_ptrmem:
return (cp_parser_check_declarator_template_parameters return (cp_parser_check_declarator_template_parameters
(parser, declarator->declarator)); (parser, declarator->declarator, declarator_location));
case cdk_error: case cdk_error:
return true; return true;
...@@ -16774,7 +16933,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -16774,7 +16933,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
static bool static bool
cp_parser_check_template_parameters (cp_parser* parser, cp_parser_check_template_parameters (cp_parser* parser,
unsigned num_templates) unsigned num_templates,
location_t location)
{ {
/* If there are more template classes than parameter lists, we have /* If there are more template classes than parameter lists, we have
something like: something like:
...@@ -16782,7 +16942,7 @@ cp_parser_check_template_parameters (cp_parser* parser, ...@@ -16782,7 +16942,7 @@ cp_parser_check_template_parameters (cp_parser* parser,
template <class T> void S<T>::R<T>::f (); */ template <class T> void S<T>::R<T>::f (); */
if (parser->num_template_parameter_lists < num_templates) if (parser->num_template_parameter_lists < num_templates)
{ {
error ("too few template-parameter-lists"); error ("%Htoo few template-parameter-lists", &location);
return false; return false;
} }
/* If there are the same number of template classes and parameter /* If there are the same number of template classes and parameter
...@@ -16797,7 +16957,7 @@ cp_parser_check_template_parameters (cp_parser* parser, ...@@ -16797,7 +16957,7 @@ cp_parser_check_template_parameters (cp_parser* parser,
something like: something like:
template <class T> template <class U> void S::f(); */ template <class T> template <class U> void S::f(); */
error ("too many template-parameter-lists"); error ("%Htoo many template-parameter-lists", &location);
return false; return false;
} }
...@@ -17055,12 +17215,14 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, ...@@ -17055,12 +17215,14 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
bool saved_in_unbraced_linkage_specification_p; bool saved_in_unbraced_linkage_specification_p;
bool saved_in_function_body; bool saved_in_function_body;
unsigned saved_num_template_parameter_lists; unsigned saved_num_template_parameter_lists;
cp_token *token;
saved_in_function_body = parser->in_function_body; saved_in_function_body = parser->in_function_body;
parser->in_function_body = true; parser->in_function_body = true;
/* If the next token is `return', then the code may be trying to /* If the next token is `return', then the code may be trying to
make use of the "named return value" extension that G++ used to make use of the "named return value" extension that G++ used to
support. */ support. */
token = cp_lexer_peek_token (parser->lexer);
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN)) if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN))
{ {
/* Consume the `return' keyword. */ /* Consume the `return' keyword. */
...@@ -17069,7 +17231,8 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, ...@@ -17069,7 +17231,8 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
returned. */ returned. */
cp_parser_identifier (parser); cp_parser_identifier (parser);
/* Issue an error message. */ /* Issue an error message. */
error ("named return values are no longer supported"); error ("%Hnamed return values are no longer supported",
&token->location);
/* Skip tokens until we reach the start of the function body. */ /* Skip tokens until we reach the start of the function body. */
while (true) while (true)
{ {
...@@ -17128,8 +17291,10 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ...@@ -17128,8 +17291,10 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
tree parameter_list; tree parameter_list;
bool friend_p = false; bool friend_p = false;
bool need_lang_pop; bool need_lang_pop;
cp_token *token;
/* Look for the `template' keyword. */ /* Look for the `template' keyword. */
token = cp_lexer_peek_token (parser->lexer);
if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>")) if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"))
return; return;
...@@ -17141,7 +17306,8 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ...@@ -17141,7 +17306,8 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
/* 14.5.2.2 [temp.mem] /* 14.5.2.2 [temp.mem]
A local class shall not have member templates. */ A local class shall not have member templates. */
error ("invalid declaration of member template in local class"); error ("%Hinvalid declaration of member template in local class",
&token->location);
cp_parser_skip_to_end_of_block_or_statement (parser); cp_parser_skip_to_end_of_block_or_statement (parser);
return; return;
} }
...@@ -17150,7 +17316,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ...@@ -17150,7 +17316,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
A template ... shall not have C linkage. */ A template ... shall not have C linkage. */
if (current_lang_name == lang_name_c) if (current_lang_name == lang_name_c)
{ {
error ("template with C linkage"); error ("%Htemplate with C linkage", &token->location);
/* Give it C++ linkage to avoid confusing other parts of the /* Give it C++ linkage to avoid confusing other parts of the
front end. */ front end. */
push_lang_context (lang_name_cplusplus); push_lang_context (lang_name_cplusplus);
...@@ -17197,6 +17363,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ...@@ -17197,6 +17363,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
/* There are no access checks when parsing a template, as we do not /* There are no access checks when parsing a template, as we do not
know if a specialization will be a friend. */ know if a specialization will be a friend. */
push_deferring_access_checks (dk_no_check); push_deferring_access_checks (dk_no_check);
token = cp_lexer_peek_token (parser->lexer);
decl = cp_parser_single_declaration (parser, decl = cp_parser_single_declaration (parser,
checks, checks,
member_p, member_p,
...@@ -17209,7 +17376,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) ...@@ -17209,7 +17376,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
if (member_p && !friend_p && decl) if (member_p && !friend_p && decl)
{ {
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL)
cp_parser_check_access_in_redeclaration (decl); cp_parser_check_access_in_redeclaration (decl, token->location);
decl = finish_member_template_decl (decl); decl = finish_member_template_decl (decl);
} }
...@@ -17273,6 +17440,7 @@ cp_parser_single_declaration (cp_parser* parser, ...@@ -17273,6 +17440,7 @@ cp_parser_single_declaration (cp_parser* parser,
tree decl = NULL_TREE; tree decl = NULL_TREE;
cp_decl_specifier_seq decl_specifiers; cp_decl_specifier_seq decl_specifiers;
bool function_definition_p = false; bool function_definition_p = false;
cp_token *decl_spec_token_start;
/* This function is only used when processing a template /* This function is only used when processing a template
declaration. */ declaration. */
...@@ -17284,6 +17452,7 @@ cp_parser_single_declaration (cp_parser* parser, ...@@ -17284,6 +17452,7 @@ cp_parser_single_declaration (cp_parser* parser,
/* Try the `decl-specifier-seq [opt] init-declarator [opt]' /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
alternative. */ alternative. */
decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
cp_parser_decl_specifier_seq (parser, cp_parser_decl_specifier_seq (parser,
CP_PARSER_FLAGS_OPTIONAL, CP_PARSER_FLAGS_OPTIONAL,
&decl_specifiers, &decl_specifiers,
...@@ -17294,7 +17463,8 @@ cp_parser_single_declaration (cp_parser* parser, ...@@ -17294,7 +17463,8 @@ cp_parser_single_declaration (cp_parser* parser,
/* There are no template typedefs. */ /* There are no template typedefs. */
if (decl_specifiers.specs[(int) ds_typedef]) if (decl_specifiers.specs[(int) ds_typedef])
{ {
error ("template declaration of %qs", "typedef"); error ("%Htemplate declaration of %qs",
&decl_spec_token_start->location, "typedef");
decl = error_mark_node; decl = error_mark_node;
} }
...@@ -17357,7 +17527,8 @@ cp_parser_single_declaration (cp_parser* parser, ...@@ -17357,7 +17527,8 @@ cp_parser_single_declaration (cp_parser* parser,
&& explicit_specialization_p && explicit_specialization_p
&& decl_specifiers.storage_class != sc_none) && decl_specifiers.storage_class != sc_none)
{ {
error ("explicit template specialization cannot have a storage class"); error ("%Hexplicit template specialization cannot have a storage class",
&decl_spec_token_start->location);
decl = error_mark_node; decl = error_mark_node;
} }
} }
...@@ -17586,9 +17757,9 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) ...@@ -17586,9 +17757,9 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
is a typo for '>'. Emit an error message and continue. is a typo for '>'. Emit an error message and continue.
Same deal about the token location, but here we can get it Same deal about the token location, but here we can get it
right by consuming the '>>' before issuing the diagnostic. */ right by consuming the '>>' before issuing the diagnostic. */
cp_lexer_consume_token (parser->lexer); cp_token *token = cp_lexer_consume_token (parser->lexer);
error ("spurious %<>>%>, use %<>%> to terminate " error ("%Hspurious %<>>%>, use %<>%> to terminate "
"a template argument list"); "a template argument list", &token->location);
} }
} }
else else
...@@ -17909,14 +18080,15 @@ cp_parser_declares_only_class_p (cp_parser *parser) ...@@ -17909,14 +18080,15 @@ cp_parser_declares_only_class_p (cp_parser *parser)
static void static void
cp_parser_set_storage_class (cp_parser *parser, cp_parser_set_storage_class (cp_parser *parser,
cp_decl_specifier_seq *decl_specs, cp_decl_specifier_seq *decl_specs,
enum rid keyword) enum rid keyword,
location_t location)
{ {
cp_storage_class storage_class; cp_storage_class storage_class;
if (parser->in_unbraced_linkage_specification_p) if (parser->in_unbraced_linkage_specification_p)
{ {
error ("invalid use of %qD in linkage specification", error ("%Hinvalid use of %qD in linkage specification",
ridpointers[keyword]); &location, ridpointers[keyword]);
return; return;
} }
else if (decl_specs->storage_class != sc_none) else if (decl_specs->storage_class != sc_none)
...@@ -17928,7 +18100,7 @@ cp_parser_set_storage_class (cp_parser *parser, ...@@ -17928,7 +18100,7 @@ cp_parser_set_storage_class (cp_parser *parser,
if ((keyword == RID_EXTERN || keyword == RID_STATIC) if ((keyword == RID_EXTERN || keyword == RID_STATIC)
&& decl_specs->specs[(int) ds_thread]) && decl_specs->specs[(int) ds_thread])
{ {
error ("%<__thread%> before %qD", ridpointers[keyword]); error ("%H%<__thread%> before %qD", &location, ridpointers[keyword]);
decl_specs->specs[(int) ds_thread] = 0; decl_specs->specs[(int) ds_thread] = 0;
} }
...@@ -18258,7 +18430,7 @@ cp_parser_check_class_key (enum tag_types class_key, tree type) ...@@ -18258,7 +18430,7 @@ cp_parser_check_class_key (enum tag_types class_key, tree type)
[class.mem/1]. */ [class.mem/1]. */
static void static void
cp_parser_check_access_in_redeclaration (tree decl) cp_parser_check_access_in_redeclaration (tree decl, location_t location)
{ {
if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl))) if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl)))
return; return;
...@@ -18267,7 +18439,7 @@ cp_parser_check_access_in_redeclaration (tree decl) ...@@ -18267,7 +18439,7 @@ cp_parser_check_access_in_redeclaration (tree decl)
!= (current_access_specifier == access_private_node)) != (current_access_specifier == access_private_node))
|| (TREE_PROTECTED (decl) || (TREE_PROTECTED (decl)
!= (current_access_specifier == access_protected_node))) != (current_access_specifier == access_protected_node)))
error ("%qD redeclared with different access", decl); error ("%H%qD redeclared with different access", &location, decl);
} }
/* Look for the `template' keyword, as a syntactic disambiguator. /* Look for the `template' keyword, as a syntactic disambiguator.
...@@ -18284,8 +18456,9 @@ cp_parser_optional_template_keyword (cp_parser *parser) ...@@ -18284,8 +18456,9 @@ cp_parser_optional_template_keyword (cp_parser *parser)
template and what is not. */ template and what is not. */
if (!processing_template_decl) if (!processing_template_decl)
{ {
error ("%<template%> (as a disambiguator) is only allowed " cp_token *token = cp_lexer_peek_token (parser->lexer);
"within templates"); error ("%H%<template%> (as a disambiguator) is only allowed "
"within templates", &token->location);
/* If this part of the token stream is rescanned, the same /* If this part of the token stream is rescanned, the same
error message would be generated. So, we purge the token error message would be generated. So, we purge the token
from the stream. */ from the stream. */
...@@ -18550,7 +18723,8 @@ cp_parser_objc_expression (cp_parser* parser) ...@@ -18550,7 +18723,8 @@ cp_parser_objc_expression (cp_parser* parser)
break; break;
} }
default: default:
error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value); error ("%Hmisplaced %<@%D%> Objective-C++ construct",
&kwd->location, kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser); cp_parser_skip_to_end_of_block_or_statement (parser);
} }
...@@ -18683,15 +18857,18 @@ static tree ...@@ -18683,15 +18857,18 @@ static tree
cp_parser_objc_encode_expression (cp_parser* parser) cp_parser_objc_encode_expression (cp_parser* parser)
{ {
tree type; tree type;
cp_token *token;
cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */ cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
token = cp_lexer_peek_token (parser->lexer);
type = complete_type (cp_parser_type_id (parser)); type = complete_type (cp_parser_type_id (parser));
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
if (!type) if (!type)
{ {
error ("%<@encode%> must specify a type as an argument"); error ("%H%<@encode%> must specify a type as an argument",
&token->location);
return error_mark_node; return error_mark_node;
} }
...@@ -19006,7 +19183,7 @@ cp_parser_objc_selector (cp_parser* parser) ...@@ -19006,7 +19183,7 @@ cp_parser_objc_selector (cp_parser* parser)
if (!cp_parser_objc_selector_p (token->type)) if (!cp_parser_objc_selector_p (token->type))
{ {
error ("invalid Objective-C++ selector name"); error ("%Hinvalid Objective-C++ selector name", &token->location);
return error_mark_node; return error_mark_node;
} }
...@@ -19336,7 +19513,8 @@ cp_parser_objc_protocol_declaration (cp_parser* parser) ...@@ -19336,7 +19513,8 @@ cp_parser_objc_protocol_declaration (cp_parser* parser)
cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
{ {
error ("identifier expected after %<@protocol%>"); tok = cp_lexer_peek_token (parser->lexer);
error ("%Hidentifier expected after %<@protocol%>", &tok->location);
goto finish; goto finish;
} }
...@@ -19472,7 +19650,8 @@ cp_parser_objc_declaration (cp_parser* parser) ...@@ -19472,7 +19650,8 @@ cp_parser_objc_declaration (cp_parser* parser)
cp_parser_objc_end_implementation (parser); cp_parser_objc_end_implementation (parser);
break; break;
default: default:
error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value); error ("%Hmisplaced %<@%D%> Objective-C++ construct",
&kwd->location, kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser); cp_parser_skip_to_end_of_block_or_statement (parser);
} }
} }
...@@ -19603,7 +19782,8 @@ cp_parser_objc_statement (cp_parser * parser) { ...@@ -19603,7 +19782,8 @@ cp_parser_objc_statement (cp_parser * parser) {
case RID_AT_THROW: case RID_AT_THROW:
return cp_parser_objc_throw_statement (parser); return cp_parser_objc_throw_statement (parser);
default: default:
error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value); error ("%Hmisplaced %<@%D%> Objective-C++ construct",
&kwd->location, kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser); cp_parser_skip_to_end_of_block_or_statement (parser);
} }
...@@ -19687,14 +19867,15 @@ cp_parser_omp_clause_name (cp_parser *parser) ...@@ -19687,14 +19867,15 @@ cp_parser_omp_clause_name (cp_parser *parser)
/* Validate that a clause of the given type does not already exist. */ /* Validate that a clause of the given type does not already exist. */
static void static void
check_no_duplicate_clause (tree clauses, enum tree_code code, const char *name) check_no_duplicate_clause (tree clauses, enum tree_code code,
const char *name, location_t location)
{ {
tree c; tree c;
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == code) if (OMP_CLAUSE_CODE (c) == code)
{ {
error ("too many %qs clauses", name); error ("%Htoo many %qs clauses", &location, name);
break; break;
} }
} }
...@@ -19717,10 +19898,12 @@ static tree ...@@ -19717,10 +19898,12 @@ static tree
cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
tree list) tree list)
{ {
cp_token *token;
while (1) while (1)
{ {
tree name, decl; tree name, decl;
token = cp_lexer_peek_token (parser->lexer);
name = cp_parser_id_expression (parser, /*template_p=*/false, name = cp_parser_id_expression (parser, /*template_p=*/false,
/*check_dependency_p=*/true, /*check_dependency_p=*/true,
/*template_p=*/NULL, /*template_p=*/NULL,
...@@ -19729,9 +19912,9 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, ...@@ -19729,9 +19912,9 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
if (name == error_mark_node) if (name == error_mark_node)
goto skip_comma; goto skip_comma;
decl = cp_parser_lookup_name_simple (parser, name); decl = cp_parser_lookup_name_simple (parser, name, token->location);
if (decl == error_mark_node) if (decl == error_mark_node)
cp_parser_name_lookup_error (parser, name, decl, NULL); cp_parser_name_lookup_error (parser, name, decl, NULL, token->location);
else if (kind != 0) else if (kind != 0)
{ {
tree u = build_omp_clause (kind); tree u = build_omp_clause (kind);
...@@ -19781,7 +19964,7 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list) ...@@ -19781,7 +19964,7 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list)
collapse ( constant-expression ) */ collapse ( constant-expression ) */
static tree static tree
cp_parser_omp_clause_collapse (cp_parser *parser, tree list) cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location)
{ {
tree c, num; tree c, num;
location_t loc; location_t loc;
...@@ -19806,11 +19989,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list) ...@@ -19806,11 +19989,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list)
|| (n = tree_low_cst (num, 0)) <= 0 || (n = tree_low_cst (num, 0)) <= 0
|| (int) n != n) || (int) n != n)
{ {
error ("%Hcollapse argument needs positive constant integer expression", &loc); error ("%Hcollapse argument needs positive constant integer expression",
&loc);
return list; return list;
} }
check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
c = build_omp_clause (OMP_CLAUSE_COLLAPSE); c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_COLLAPSE_EXPR (c) = num; OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
...@@ -19822,7 +20006,7 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list) ...@@ -19822,7 +20006,7 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list)
default ( shared | none ) */ default ( shared | none ) */
static tree static tree
cp_parser_omp_clause_default (cp_parser *parser, tree list) cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
{ {
enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
tree c; tree c;
...@@ -19868,7 +20052,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list) ...@@ -19868,7 +20052,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list)
if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
return list; return list;
check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default"); check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
c = build_omp_clause (OMP_CLAUSE_DEFAULT); c = build_omp_clause (OMP_CLAUSE_DEFAULT);
OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_DEFAULT_KIND (c) = kind; OMP_CLAUSE_DEFAULT_KIND (c) = kind;
...@@ -19880,7 +20064,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list) ...@@ -19880,7 +20064,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list)
if ( expression ) */ if ( expression ) */
static tree static tree
cp_parser_omp_clause_if (cp_parser *parser, tree list) cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
{ {
tree t, c; tree t, c;
...@@ -19895,7 +20079,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list) ...@@ -19895,7 +20079,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list)
/*or_comma=*/false, /*or_comma=*/false,
/*consume_paren=*/true); /*consume_paren=*/true);
check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if"); check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if", location);
c = build_omp_clause (OMP_CLAUSE_IF); c = build_omp_clause (OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = t; OMP_CLAUSE_IF_EXPR (c) = t;
...@@ -19908,11 +20092,12 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list) ...@@ -19908,11 +20092,12 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list)
nowait */ nowait */
static tree static tree
cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED, tree list) cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED,
tree list, location_t location)
{ {
tree c; tree c;
check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait"); check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);
c = build_omp_clause (OMP_CLAUSE_NOWAIT); c = build_omp_clause (OMP_CLAUSE_NOWAIT);
OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_CHAIN (c) = list;
...@@ -19923,7 +20108,8 @@ cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED, tree list) ...@@ -19923,7 +20108,8 @@ cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED, tree list)
num_threads ( expression ) */ num_threads ( expression ) */
static tree static tree
cp_parser_omp_clause_num_threads (cp_parser *parser, tree list) cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
location_t location)
{ {
tree t, c; tree t, c;
...@@ -19938,7 +20124,8 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list) ...@@ -19938,7 +20124,8 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list)
/*or_comma=*/false, /*or_comma=*/false,
/*consume_paren=*/true); /*consume_paren=*/true);
check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads"); check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
"num_threads", location);
c = build_omp_clause (OMP_CLAUSE_NUM_THREADS); c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
...@@ -19951,11 +20138,13 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list) ...@@ -19951,11 +20138,13 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list)
ordered */ ordered */
static tree static tree
cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED, tree list) cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED,
tree list, location_t location)
{ {
tree c; tree c;
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered"); check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
"ordered", location);
c = build_omp_clause (OMP_CLAUSE_ORDERED); c = build_omp_clause (OMP_CLAUSE_ORDERED);
OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_CHAIN (c) = list;
...@@ -20032,7 +20221,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list) ...@@ -20032,7 +20221,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
static | dynamic | guided | runtime | auto */ static | dynamic | guided | runtime | auto */
static tree static tree
cp_parser_omp_clause_schedule (cp_parser *parser, tree list) cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
{ {
tree c, t; tree c, t;
...@@ -20080,18 +20269,20 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list) ...@@ -20080,18 +20269,20 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
{ {
cp_token *token;
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
t = cp_parser_assignment_expression (parser, false); t = cp_parser_assignment_expression (parser, false);
if (t == error_mark_node) if (t == error_mark_node)
goto resync_fail; goto resync_fail;
else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
error ("schedule %<runtime%> does not take " error ("%Hschedule %<runtime%> does not take "
"a %<chunk_size%> parameter"); "a %<chunk_size%> parameter", &token->location);
else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO) else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
error ("schedule %<auto%> does not take " error ("%Hschedule %<auto%> does not take "
"a %<chunk_size%> parameter"); "a %<chunk_size%> parameter", &token->location);
else else
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
...@@ -20101,7 +20292,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list) ...@@ -20101,7 +20292,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>")) else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>"))
goto resync_fail; goto resync_fail;
check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule"); check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_CHAIN (c) = list;
return c; return c;
...@@ -20118,11 +20309,12 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list) ...@@ -20118,11 +20309,12 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
untied */ untied */
static tree static tree
cp_parser_omp_clause_untied (cp_parser *parser ATTRIBUTE_UNUSED, tree list) cp_parser_omp_clause_untied (cp_parser *parser ATTRIBUTE_UNUSED,
tree list, location_t location)
{ {
tree c; tree c;
check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied"); check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);
c = build_omp_clause (OMP_CLAUSE_UNTIED); c = build_omp_clause (OMP_CLAUSE_UNTIED);
OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_CHAIN (c) = list;
...@@ -20139,6 +20331,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20139,6 +20331,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
{ {
tree clauses = NULL; tree clauses = NULL;
bool first = true; bool first = true;
cp_token *token = NULL;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)) while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{ {
...@@ -20149,13 +20342,15 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20149,13 +20342,15 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
c_kind = cp_parser_omp_clause_name (parser); c_kind = cp_parser_omp_clause_name (parser);
first = false; first = false;
switch (c_kind) switch (c_kind)
{ {
case PRAGMA_OMP_CLAUSE_COLLAPSE: case PRAGMA_OMP_CLAUSE_COLLAPSE:
clauses = cp_parser_omp_clause_collapse (parser, clauses); clauses = cp_parser_omp_clause_collapse (parser, clauses,
token->location);
c_name = "collapse"; c_name = "collapse";
break; break;
case PRAGMA_OMP_CLAUSE_COPYIN: case PRAGMA_OMP_CLAUSE_COPYIN:
...@@ -20168,7 +20363,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20168,7 +20363,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "copyprivate"; c_name = "copyprivate";
break; break;
case PRAGMA_OMP_CLAUSE_DEFAULT: case PRAGMA_OMP_CLAUSE_DEFAULT:
clauses = cp_parser_omp_clause_default (parser, clauses); clauses = cp_parser_omp_clause_default (parser, clauses,
token->location);
c_name = "default"; c_name = "default";
break; break;
case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
...@@ -20177,7 +20373,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20177,7 +20373,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "firstprivate"; c_name = "firstprivate";
break; break;
case PRAGMA_OMP_CLAUSE_IF: case PRAGMA_OMP_CLAUSE_IF:
clauses = cp_parser_omp_clause_if (parser, clauses); clauses = cp_parser_omp_clause_if (parser, clauses, token->location);
c_name = "if"; c_name = "if";
break; break;
case PRAGMA_OMP_CLAUSE_LASTPRIVATE: case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
...@@ -20186,15 +20382,17 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20186,15 +20382,17 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "lastprivate"; c_name = "lastprivate";
break; break;
case PRAGMA_OMP_CLAUSE_NOWAIT: case PRAGMA_OMP_CLAUSE_NOWAIT:
clauses = cp_parser_omp_clause_nowait (parser, clauses); clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
c_name = "nowait"; c_name = "nowait";
break; break;
case PRAGMA_OMP_CLAUSE_NUM_THREADS: case PRAGMA_OMP_CLAUSE_NUM_THREADS:
clauses = cp_parser_omp_clause_num_threads (parser, clauses); clauses = cp_parser_omp_clause_num_threads (parser, clauses,
token->location);
c_name = "num_threads"; c_name = "num_threads";
break; break;
case PRAGMA_OMP_CLAUSE_ORDERED: case PRAGMA_OMP_CLAUSE_ORDERED:
clauses = cp_parser_omp_clause_ordered (parser, clauses); clauses = cp_parser_omp_clause_ordered (parser, clauses,
token->location);
c_name = "ordered"; c_name = "ordered";
break; break;
case PRAGMA_OMP_CLAUSE_PRIVATE: case PRAGMA_OMP_CLAUSE_PRIVATE:
...@@ -20207,7 +20405,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20207,7 +20405,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "reduction"; c_name = "reduction";
break; break;
case PRAGMA_OMP_CLAUSE_SCHEDULE: case PRAGMA_OMP_CLAUSE_SCHEDULE:
clauses = cp_parser_omp_clause_schedule (parser, clauses); clauses = cp_parser_omp_clause_schedule (parser, clauses,
token->location);
c_name = "schedule"; c_name = "schedule";
break; break;
case PRAGMA_OMP_CLAUSE_SHARED: case PRAGMA_OMP_CLAUSE_SHARED:
...@@ -20216,7 +20415,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20216,7 +20415,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "shared"; c_name = "shared";
break; break;
case PRAGMA_OMP_CLAUSE_UNTIED: case PRAGMA_OMP_CLAUSE_UNTIED:
clauses = cp_parser_omp_clause_untied (parser, clauses); clauses = cp_parser_omp_clause_untied (parser, clauses,
token->location);
c_name = "nowait"; c_name = "nowait";
break; break;
default: default:
...@@ -20229,7 +20429,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, ...@@ -20229,7 +20429,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
/* Remove the invalid clause(s) from the list to avoid /* Remove the invalid clause(s) from the list to avoid
confusing the rest of the compiler. */ confusing the rest of the compiler. */
clauses = prev; clauses = prev;
error ("%qs is not valid for %qs", c_name, where); error ("%H%qs is not valid for %qs", &token->location, c_name, where);
} }
} }
saw_error: saw_error:
...@@ -21315,10 +21515,11 @@ cp_parser_initial_pragma (cp_token *first_token) ...@@ -21315,10 +21515,11 @@ cp_parser_initial_pragma (cp_token *first_token)
cp_lexer_get_preprocessor_token (NULL, first_token); cp_lexer_get_preprocessor_token (NULL, first_token);
if (first_token->type != CPP_PRAGMA_EOL) if (first_token->type != CPP_PRAGMA_EOL)
error ("junk at end of %<#pragma GCC pch_preprocess%>"); error ("%Hjunk at end of %<#pragma GCC pch_preprocess%>",
&first_token->location);
} }
else else
error ("expected string literal"); error ("%Hexpected string literal", &first_token->location);
/* Skip to the end of the pragma. */ /* Skip to the end of the pragma. */
while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF) while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF)
...@@ -21351,7 +21552,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) ...@@ -21351,7 +21552,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
switch (id) switch (id)
{ {
case PRAGMA_GCC_PCH_PREPROCESS: case PRAGMA_GCC_PCH_PREPROCESS:
error ("%<#pragma GCC pch_preprocess%> must be first"); error ("%H%<#pragma GCC pch_preprocess%> must be first",
&pragma_tok->location);
break; break;
case PRAGMA_OMP_BARRIER: case PRAGMA_OMP_BARRIER:
...@@ -21361,8 +21563,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) ...@@ -21361,8 +21563,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_omp_barrier (parser, pragma_tok); cp_parser_omp_barrier (parser, pragma_tok);
return false; return false;
case pragma_stmt: case pragma_stmt:
error ("%<#pragma omp barrier%> may only be " error ("%H%<#pragma omp barrier%> may only be "
"used in compound statements"); "used in compound statements", &pragma_tok->location);
break; break;
default: default:
goto bad_stmt; goto bad_stmt;
...@@ -21376,8 +21578,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) ...@@ -21376,8 +21578,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_omp_flush (parser, pragma_tok); cp_parser_omp_flush (parser, pragma_tok);
return false; return false;
case pragma_stmt: case pragma_stmt:
error ("%<#pragma omp flush%> may only be " error ("%H%<#pragma omp flush%> may only be "
"used in compound statements"); "used in compound statements", &pragma_tok->location);
break; break;
default: default:
goto bad_stmt; goto bad_stmt;
...@@ -21418,8 +21620,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) ...@@ -21418,8 +21620,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
return true; return true;
case PRAGMA_OMP_SECTION: case PRAGMA_OMP_SECTION:
error ("%<#pragma omp section%> may only be used in " error ("%H%<#pragma omp section%> may only be used in "
"%<#pragma omp sections%> construct"); "%<#pragma omp sections%> construct", &pragma_tok->location);
break; break;
default: default:
......
...@@ -9743,7 +9743,7 @@ tsubst_qualified_id (tree qualified_id, tree args, ...@@ -9743,7 +9743,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (complain & tf_error) if (complain & tf_error)
qualified_name_lookup_error (scope, qualified_name_lookup_error (scope,
TREE_OPERAND (qualified_id, 1), TREE_OPERAND (qualified_id, 1),
expr); expr, input_location);
return error_mark_node; return error_mark_node;
} }
...@@ -9752,7 +9752,7 @@ tsubst_qualified_id (tree qualified_id, tree args, ...@@ -9752,7 +9752,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (expr == error_mark_node && complain & tf_error) if (expr == error_mark_node && complain & tf_error)
qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1), qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
expr); expr, input_location);
else if (TYPE_P (scope)) else if (TYPE_P (scope))
{ {
expr = (adjust_result_of_qualified_name_lookup expr = (adjust_result_of_qualified_name_lookup
...@@ -10484,7 +10484,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, ...@@ -10484,7 +10484,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
/*is_type_p=*/false, /*is_type_p=*/false,
/*complain=*/false); /*complain=*/false);
if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST) if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
qualified_name_lookup_error (scope, name, decl); qualified_name_lookup_error (scope, name, decl, input_location);
else else
do_local_using_decl (decl, scope, name); do_local_using_decl (decl, scope, name);
} }
...@@ -10931,7 +10931,8 @@ tsubst_copy_and_build (tree t, ...@@ -10931,7 +10931,8 @@ tsubst_copy_and_build (tree t,
/*done=*/true, /*done=*/true,
/*address_p=*/false, /*address_p=*/false,
/*template_arg_p=*/false, /*template_arg_p=*/false,
&error_msg); &error_msg,
input_location);
if (error_msg) if (error_msg)
error (error_msg); error (error_msg);
if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE) if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE)
...@@ -11460,7 +11461,8 @@ tsubst_copy_and_build (tree t, ...@@ -11460,7 +11461,8 @@ tsubst_copy_and_build (tree t,
} }
else else
{ {
qualified_name_lookup_error (object_type, tmpl, member); qualified_name_lookup_error (object_type, tmpl, member,
input_location);
return error_mark_node; return error_mark_node;
} }
} }
......
...@@ -2502,29 +2502,33 @@ finish_base_specifier (tree base, tree access, bool virtual_p) ...@@ -2502,29 +2502,33 @@ finish_base_specifier (tree base, tree access, bool virtual_p)
} }
/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is /* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is
what we found when we tried to do the lookup. */ what we found when we tried to do the lookup.
LOCATION is the location of the NAME identifier;
The location is used in the error message*/
void void
qualified_name_lookup_error (tree scope, tree name, tree decl) qualified_name_lookup_error (tree scope, tree name,
tree decl, location_t location)
{ {
if (scope == error_mark_node) if (scope == error_mark_node)
; /* We already complained. */ ; /* We already complained. */
else if (TYPE_P (scope)) else if (TYPE_P (scope))
{ {
if (!COMPLETE_TYPE_P (scope)) if (!COMPLETE_TYPE_P (scope))
error ("incomplete type %qT used in nested name specifier", scope); error ("%Hincomplete type %qT used in nested name specifier",
&location, scope);
else if (TREE_CODE (decl) == TREE_LIST) else if (TREE_CODE (decl) == TREE_LIST)
{ {
error ("reference to %<%T::%D%> is ambiguous", scope, name); error ("%Hreference to %<%T::%D%> is ambiguous", &location, scope, name);
print_candidates (decl); print_candidates (decl);
} }
else else
error ("%qD is not a member of %qT", name, scope); error ("%H%qD is not a member of %qT", &location, name, scope);
} }
else if (scope != global_namespace) else if (scope != global_namespace)
error ("%qD is not a member of %qD", name, scope); error ("%H%qD is not a member of %qD", &location, name, scope);
else else
error ("%<::%D%> has not been declared", name); error ("%H%<::%D%> has not been declared", &location, name);
} }
/* If FNS is a member function, a set of member functions, or a /* If FNS is a member function, a set of member functions, or a
...@@ -2589,7 +2593,6 @@ baselink_for_fns (tree fns) ...@@ -2589,7 +2593,6 @@ baselink_for_fns (tree fns)
the use of "this" explicit. the use of "this" explicit.
Upon return, *IDK will be filled in appropriately. */ Upon return, *IDK will be filled in appropriately. */
tree tree
finish_id_expression (tree id_expression, finish_id_expression (tree id_expression,
tree decl, tree decl,
...@@ -2602,7 +2605,8 @@ finish_id_expression (tree id_expression, ...@@ -2602,7 +2605,8 @@ finish_id_expression (tree id_expression,
bool done, bool done,
bool address_p, bool address_p,
bool template_arg_p, bool template_arg_p,
const char **error_msg) const char **error_msg,
location_t location)
{ {
/* Initialize the output parameters. */ /* Initialize the output parameters. */
*idk = CP_ID_KIND_NONE; *idk = CP_ID_KIND_NONE;
...@@ -2632,7 +2636,7 @@ finish_id_expression (tree id_expression, ...@@ -2632,7 +2636,7 @@ finish_id_expression (tree id_expression,
/* If the qualifying type is non-dependent (and the name /* If the qualifying type is non-dependent (and the name
does not name a conversion operator to a dependent does not name a conversion operator to a dependent
type), issue an error. */ type), issue an error. */
qualified_name_lookup_error (scope, id_expression, decl); qualified_name_lookup_error (scope, id_expression, decl, location);
return error_mark_node; return error_mark_node;
} }
else if (!scope) else if (!scope)
......
2008-07-11 Dodji Seketeli <dseketel@redhat.com>
* g++.dg/parse/constructor1.C, g++.dg/parse/error*.C: update these
tests to make them catch column number regressions. Make these tests
run with the -fshow-column option.
* g++.dg/parse/error-column.C: new column number test.
2008-07-11 Richard Guenther <rguenther@suse.de> 2008-07-11 Richard Guenther <rguenther@suse.de>
PR tree-optimization/36765 PR tree-optimization/36765
......
// { dg-do compile }
// { dg-options "-fshow-column" }
ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "" } ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "" }
process_ (0) process_ (0) // { dg-error "3: error: only constructors take base initializers" }
{ {
} }
// { dg-do compile }
// Make sure column information is correctly shown in error reporting
// { dg-options "-fshow-column" }
void foo ()
{
cout << "blah"; // { dg-error "3: error: 'cout'" }
}
// { dg-options "-fshow-column" }
struct INCOMPLETE; struct INCOMPLETE;
template <int> struct X { template <int> struct X {
static INCOMPLETE value; static INCOMPLETE value;
}; };
template <> INCOMPLETE X<1>::value = 0; // { dg-error "" } template <> INCOMPLETE X<1>::value = 0; // { dg-error "30: error: variable 'INCOMPLETE X<1>::value' has initializer but incomplete type" }
// PR c++/3478 // PR c++/3478
// { dg-options "" } // { dg-options "-fshow-column" }
template <typename> struct A template <typename> struct A
{ {
...@@ -11,5 +11,9 @@ template <typename T> void foo() ...@@ -11,5 +11,9 @@ template <typename T> void foo()
enum A<void>::E e1; enum A<void>::E e1;
typename A<T>::E e2; typename A<T>::E e2;
enum A<T>::E e3; enum A<T>::E e3;
enum typename A<T>::E e4; // { dg-error "" } enum typename A<T>::E e4;
} }
// Here, columns nums are not very accurate either. Still acceptable though
// { dg-error "30: error: invalid type in declaration before ';' token" "" { target *-*-* } { 14 } }
// { dg-error "30: error: two or more data types in declaration of 'e4'" "" { target *-*-* } { 14 } }
// { dg-do compile } // { dg-do compile }
// { dg-options "-fshow-column" }"
// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> // Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
// Try to find out when the digraph '<:' is used as a mistake, and parse it // Try to find out when the digraph '<:' is used as a mistake, and parse it
// correctly to avoid cascaded errors. // correctly to avoid cascaded errors.
...@@ -15,16 +16,16 @@ struct Foo ...@@ -15,16 +16,16 @@ struct Foo
}; };
void method(void) { void method(void) {
typename Foo<::B>::template Nested<::B> n; // { dg-error "cannot begin|alternate spelling" } typename Foo<::B>::template Nested<::B> n; // { dg-error "17: error: '<::' cannot begin|17: note: '<:' is an alternate spelling|39: error: '<::' cannot begin|39: note: '<:' is an alternate" }
n.template Nested<B>::method(); n.template Nested<B>::method();
n.template Nested<::B>::method(); // { dg-error "cannot begin|alternate spelling" } n.template Nested<::B>::method(); // { dg-error "22: error: '<::' cannot begin|22: note: '<:' is an alternate" }
Nested<B>::method(); Nested<B>::method();
Nested<::B>::method(); // { dg-error "cannot begin|alternate spelling" } Nested<::B>::method(); // { dg-error "11: error: '<::' cannot begin|11: note: '<:' is an alternate" }
} }
}; };
template <int N> struct Foo2 {}; template <int N> struct Foo2 {};
template struct Foo2<::B>; // { dg-error "cannot begin|alternate spelling|type/value mismatch|expected a constant" } template struct Foo2<::B>; // { dg-error "21: error: '<::' cannot begin|21: note: '<:' is an alternate|25: error: type/value mismatch|25: error: expected a constant" }
int value = 0; int value = 0;
...@@ -32,22 +33,28 @@ void func(void) ...@@ -32,22 +33,28 @@ void func(void)
{ {
Foo<::B> f; // { dg-error "cannot begin|alternate spelling" } Foo<::B> f; // { dg-error "cannot begin|alternate spelling" }
f.Foo<B>::method(); f.Foo<B>::method();
f.Foo<::B>::method(); // { dg-error "cannot begin|alternate spelling" } f.Foo<::B>::method(); // { dg-error "8: error|8: note" }
// Check cases where we the token sequence is the correct one, but there // Check cases where we the token sequence is the correct one, but there
// was no digraph or whitespaces in the middle, so we should not emit // was no digraph or whitespaces in the middle, so we should not emit
// the special error message. // the special error message.
Foo<: :B> k2; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" } Foo<: :B> k2; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
Foo[:B> k1; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" } Foo[:B> k1; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
// { dg-error "" "" { target *-*-* } 40 } // { dg-error "6: error: missing template arguments before" "" { target *-*-* } { 41 } }
// { dg-error "" "" { target *-*-* } 41 } // { dg-error "9: error: expected primary-expression before ':' token" "" { target *-*-* } 41 }
// { dg-error "9: error: expected '\]' before ':' token" "" { target *-*-* } 41 }
// { dg-error "9: error: expected ';' before ':' token" "" { target *-*-* } 41 }
// { dg-error "6: error: missing template arguments before" "" { target *-*-* } 42 }
// { dg-error "7: error: expected primary-expression before ':' token" "" { target *-*-* } 42 }
// { dg-error "7: error: expected '\]' before ':' token" "" { target *-*-* } 42 }
// { dg-error "7: error: expected ';' before ':' token" "" { target *-*-* } 42 }
//
int Foo[2]; int Foo[2];
Foo[::value] = 0; Foo[::value] = 0;
} }
template struct Foo<::B>; // { dg-error "cannot begin|alternate spelling" } template struct Foo<::B>; // { dg-error "20: error: '<::' cannot begin|20: note: '<:' is an alternate" }
// On the first error message, an additional note about the use of // On the first error message, an additional note about the use of
// -fpermissive should be present // -fpermissive should be present
// { dg-error "-fpermissive" "-fpermissive" { target *-*-* } 18 } // { dg-error "17: note: \\(if you use '-fpermissive' G\\+\\+ will accept your code\\)" "-fpermissive" { target *-*-* } 19 }
// { dg-do compile } // { dg-do compile }
// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> // Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
// Make sure the error about '<:' can be turned into a warning // Make sure the error about '<:' can be turned into a warning
// { dg-options "-fpermissive" } // { dg-options "-fpermissive -fshow-column" }
struct B; struct B;
...@@ -9,4 +9,5 @@ template <class A> ...@@ -9,4 +9,5 @@ template <class A>
struct Foo {}; struct Foo {};
Foo<::B> foo; // { dg-bogus "error" "error in place of warning" } Foo<::B> foo; // { dg-bogus "error" "error in place of warning" }
// { dg-error "" "" { target *-*-* } 11 } // { dg-error "4: warning: '<::' cannot begin a template-argument list" "warning <::" { target *-*-* } 11 }
// { dg-error "4: note: '<:' is an alternate spelling for '.'. Insert whitespace between '<' and '::'" "note <:" { target *-*-* } 11 }
// { dg-options "-fshow-column" }
// PR c++/13975 // PR c++/13975
public: // { dg-error "" } public: // { dg-error "1: error: expected unqualified-id before 'public'" }
int i; int i;
protected: // { dg-error "" } protected: // { dg-error "1: error: expected unqualified-id before 'protected'" }
int j; int j;
private: // { dg-error "" } private: // { dg-error "1: error: expected unqualified-id before 'private'" }
int k; int k;
// { dg-options "-fshow-column" }
// PR c++/13970 // PR c++/13970
struct X struct X
...@@ -18,5 +19,5 @@ struct X ...@@ -18,5 +19,5 @@ struct X
Zinc<int>( //); Zinc<int>( //);
// } // }
}; // { dg-error "" } }; // { dg-error "2: error: expected '.' at end of input|1: error: expected primary-expression before '.' token|1: error: expected ';' before '.' token|1: error: expected unqualified-id at end of input" }
// { dg-do compile } // { dg-do compile }
// Contributed by Volker Reichelt <reichelt at gcc dot gnu dot org> // Contributed by Volker Reichelt <reichelt at gcc dot gnu dot org>
// { dg-options "-fshow-column" }
// PR c++/14008: Improve diagnostic on invalid types in declarators. // PR c++/14008: Improve diagnostic on invalid types in declarators.
namespace N namespace N
...@@ -9,29 +10,29 @@ namespace N ...@@ -9,29 +10,29 @@ namespace N
int K; int K;
} }
N::A f2; // { dg-error "without an argument list" } N::A f2; // { dg-error "4: error: invalid use of template-name 'N::A' without an argument list" }
N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" } N::INVALID f3; // { dg-error "4: error: 'INVALID' in namespace 'N' does not name a type" }
N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" } N::C::INVALID f4; // { dg-error "7: error: 'INVALID' in class 'N::C' does not name a type" }
N::K f6; // { dg-error "in namespace 'N' does not name a type" } N::K f6; // { dg-error "4: error: 'K' in namespace 'N' does not name a type" }
typename N::A f7; // { dg-error "without an argument list|outside of template" } typename N::A f7; // { dg-error "1: error: using 'typename' outside of template|13: error: invalid use of template-name 'N::A' without an argument list|17: error: invalid type in declaration before ';' token" }
struct B struct B
{ {
N::A f2; // { dg-error "without an argument list" } N::A f2; // { dg-error "6: error: invalid use of template-name 'N::A' without an argument list" }
N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" } N::INVALID f3; // { dg-error "6: error: 'INVALID' in namespace 'N' does not name a type" }
N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" } N::C::INVALID f4; // { dg-error "9: error: 'INVALID' in class 'N::C' does not name a type" }
N::K f6; // { dg-error "in namespace 'N' does not name a type" } N::K f6; // { dg-error "6: error: 'K' in namespace 'N' does not name a type" }
typename N::A f7; // { dg-error "without an argument list|outside of template" } typename N::A f7; // { dg-error "3: error: using 'typename' outside of template|15: error: invalid use of template-name 'N::A' without an argument list" }
}; };
template <int> template <int>
struct C struct C
{ {
N::A f2; // { dg-error "without an argument list" } N::A f2; // { dg-error "6: error: invalid use of template-name 'N::A' without an argument list" }
N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" } N::INVALID f3; // { dg-error "6: error: 'INVALID' in namespace 'N' does not name a type" }
N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" } N::C::INVALID f4; // { dg-error "9: error: 'INVALID' in class 'N::C' does not name a type" }
N::K f6; // { dg-error "in namespace 'N' does not name a type" } N::K f6; // { dg-error "6: error: 'K' in namespace 'N' does not name a type" }
typename N::A f7; // { dg-error "without an argument list" } typename N::A f7; // { dg-error "15: error: invalid use of template-name 'N::A' without an argument list" }
}; };
// { dg-bogus "" "bogus excess errors in declaration" { xfail *-*-* } 16 } // { dg-bogus "bogus excess errors in declaration" "bogus excess errors in declaration" { xfail *-*-* } 17 }
// { dg-options "-fshow-column" }
// PR c++/16964 // PR c++/16964
struct A struct A
{ {
struct B {}; // { dg-error "previous" } struct B {}; // { dg-error "12: error: previous definition of 'struct A::B'" }
}; };
struct A::B{}; // { dg-error "redefinition" } struct A::B{}; // { dg-error "11: error: redefinition of 'struct A::B'" }
// { dg-options "-fshow-column" }
// PR c++/16965 // PR c++/16965
template <typename T> struct B { template <typename T> struct B {
static int Bar(T); // { dg-error "" } static int Bar(T); // { dg-error "19: error: candidates are: |19: error: " }
}; };
struct D : B<int>, B<char> {}; struct D : B<int>, B<char> {};
int i2 = D::Bar(2); // { dg-error "" } int i2 = D::Bar(2); // { dg-error "13: error: reference to 'Bar' is ambiguous|10: error: reference to 'Bar' is ambiguous" }
// { dg-options "-fshow-column" }
// PR c++/16002 // PR c++/16002
void f() void f()
{ {
double Q *= 5.0; // { dg-error "initializer" } double Q *= 5.0; // { dg-error "12: error: expected initializer before '..' token" }
} }
// { dg-options "-fshow-column -fmessage-length=0 -ansi -pedantic-errors -Wno-long-long " }
// PR C++/17867 // PR C++/17867
struct A struct A
{ // { dg-error "candidate" } { // { dg-error "1: note: candidates are:" }
A(int); A(int);
}; };
...@@ -9,5 +10,5 @@ const A& foo(); ...@@ -9,5 +10,5 @@ const A& foo();
void bar() void bar()
{ {
foo()=A(0); // { dg-error "A" } foo()=A(0); // { dg-error "12: error: no match for 'operator='" }
} }
// { dg-do compile } // { dg-do compile }
// { dg-options "-fshow-column" }
// Properly print CALL_EXPRs while dumping expressions // Properly print CALL_EXPRs while dumping expressions
double g; double g;
...@@ -7,4 +8,8 @@ int func(double); ...@@ -7,4 +8,8 @@ int func(double);
template <int> template <int>
struct Foo {}; struct Foo {};
Foo<func(g)> f; // { dg-error "" "func(g)" } Foo<func(g)> f; // { dg-error "5: error: 'int func.double.' cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
// { dg-error "10: error: 'g' cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
// { dg-error "11: error: a function call cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
// { dg-error "12: error: template argument 1 is invalid" "" { target *-*-* } { 11 } }
// { dg-error "15: error: invalid type in declaration before ';' token" "" { target *-*-* } { 11 } }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/17821 // PR c++/17821
struct A { struct A {
...@@ -11,7 +12,7 @@ struct C { ...@@ -11,7 +12,7 @@ struct C {
}; };
int main() { int main() {
C c; C c;
A(c.p.i); // { dg-error "member.*non-class" } A(c.p.i); // { dg-error "9: error: request for member 'i' in 'c.C::p', which is of non-class type 'B" }
return 0; return 0;
} }
// PR c++/17393 // PR c++/17393
// { dg-options "-Wall" } // { dg-options "-Wall -fshow-column" }
struct A { }; struct A { };
...@@ -7,6 +7,6 @@ void foo() ...@@ -7,6 +7,6 @@ void foo()
{ {
// Check that we do not complain about an unused // Check that we do not complain about an unused
// compiler-generated variable. // compiler-generated variable.
A& = a; // { dg-error "token|declarator|not declared" } A& = a; // { dg-error "6: error: expected unqualified-id before '=' token|8: error: 'a' was not declared in this scope" }
} }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/15786 // PR c++/15786
struct A { struct A {
void foo(bar* p); /* { dg-error "declared" } */ void foo(bar* p); /* { dg-error "12: error: 'bar' has not been declared" } */
}; };
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/19149 // PR c++/19149
struct QChar { struct QChar {
QChar( char c ); QChar( char c );
QChar( const QChar& c ); QChar( const QChar& c );
static const ; // { dg-error "" } //following column number is not accurate enough but will make it for now
static const ; // { dg-error "10: error: declaration does not declare anything" }
}; };
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/19395 // PR c++/19395
struct A { struct A {
typedef int ::X; // { dg-error "" } typedef int ::X; // { dg-error "17: error: typedef name may not be a nested-name-specifier" }
}; };
// { dg-do compile } // { dg-do compile }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// Origin: Steven Bosscher <steven at gcc dot gnu dot org> // Origin: Steven Bosscher <steven at gcc dot gnu dot org>
// PR c++/17401: ICE with invalid pure specifier // PR c++/17401: ICE with invalid pure specifier
...@@ -8,10 +9,10 @@ ...@@ -8,10 +9,10 @@
class foo class foo
{ {
virtual void bar1 () = 0; virtual void bar1 () = 0;
virtual void bar2 () = __null; // { dg-error "invalid pure specifier" } virtual void bar2 () = __null; // { dg-error "32: error: invalid pure specifier" }
virtual void bar3 () = 4; // { dg-error "invalid pure specifier" } virtual void bar3 () = 4; // { dg-error "27: error: invalid pure specifier" }
virtual void bar4 () = A::f; // { dg-error "invalid pure specifier" } virtual void bar4 () = A::f; // { dg-error "27: error: invalid pure specifier" }
virtual void bar5 () = 0l; // { dg-error "invalid pure specifier" } virtual void bar5 () = 0l; // { dg-error "28: error: invalid pure specifier" }
virtual void bar6 () = 00; // { dg-error "invalid pure specifier" } virtual void bar6 () = 00; // { dg-error "28: error: invalid pure specifier" }
virtual void bar7 () = 0x0; // { dg-error "invalid pure specifier" } virtual void bar7 () = 0x0; // { dg-error "29: error: invalid pure specifier" }
}; };
// PR c++/20148 // PR c++/20148
// { dg-options "" } // { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
void foo() void foo()
{ {
if (({int c[2];})) ; // { dg-error "\{\.\.\.\}" } if (({int c[2];})) ; // { dg-error "7: error: ISO C.. forbids|20: error: could not convert" }
} }
void bar() void bar()
{ {
if (({})); // { dg-error "\{\.\.\.\}" } if (({})); // { dg-error "7: error: ISO C.. forbids|11: error: could not convert" }
} }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/20152 // PR c++/20152
struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "previous definition" } struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "24: error: previous definition of 'struct KrSelectionMode'" }
struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "previous definition" } struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "52: error: previous definition of 'struct KrKDESelectionMode'" }
struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "" } struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "8: error: redefinition of 'struct KrSelectionMode'" }
struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "" } struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "8: error: redefinition of 'struct KrKDESelectionMode'" }
KrKDESelectionMode krKDESelectionMode; KrKDESelectionMode krKDESelectionMode;
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/21908 // PR c++/21908
struct virt { virt () {} virt (int i) {} }; struct virt { virt () {} virt (int i) {} };
struct der : public virtual virt { // { dg-error "der" } struct der : public virtual virt { // { dg-error "34: note: der::der" }
der (int i) : virt(i) {} // { dg-error "der" } der (int i) : virt(i) {} // { dg-error "13: note: candidates are: der" }
}; };
struct top : public der { struct top : public der {
// { dg-error "der\\(\\)" "" { target *-*-* } 9 }
top () {} // { dg-bogus "der\\(const" } top () {} // { dg-bogus "der\\(const" }
}; };
// { dg-error "10: error: no matching function for call to 'der" "" { target *-*-* } 9 }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/25637 // PR c++/25637
struct A { struct A {
...@@ -6,7 +7,7 @@ struct A { ...@@ -6,7 +7,7 @@ struct A {
void operator delete(void *); void operator delete(void *);
}; };
struct B { struct B {
friend void A::foo() {} // { dg-error "define" } friend void A::foo() {} // { dg-error "22: error: cannot define member function 'A::foo' within 'B'" }
friend void A::operator delete(void*) {} // { dg-error "define" } friend void A::operator delete(void*) {} // { dg-error "39: error: cannot define member function 'A::operator delete' within 'B'" }
friend A::A() {} // { dg-error "define" } friend A::A() {} // { dg-error "15: error: cannot define member function 'A::A' within 'B'" }
}; };
// { dg-options "-fshow-column" }
// PR c++/10779 // PR c++/10779
static void InstantiateConstraint(const float&, unsigned, static void InstantiateConstraint(const float&, unsigned,
void(*AddFunction)(const TYPE&,bool&, // { dg-error "" } void(*AddFunction)(const TYPE&,bool&,
char*, char*, char*, char*,
unsigned*)); // { dg-error "" } unsigned*));
// { dg-error "64: error: expected ',' or '...' before '&' token" "" { target *-*-* } { 5 } }
/// in the coming test, the column information is broken as it points to
// the end of the declaration instead of pointing to the begining of the
// 'TYPE' identifier. This is due to the warning being generated by the
// declaration groking code (gcc/cp/decl.c) and not the parser. So in that
// code, the exact token location information is lost as the declaration
// groking code manipulates TREEs only. The token location used is then
// the global one that is not accurate enough. Anyway, let's say it is
// good enough for now, until we find a way to propagate token location to
// code paths that manipulate TREEs only.
// { dg-error "64: error: ISO C\\+\\+ forbids declaration of 'TYPE' with no type" "" { target *-*-* } { 7 } }
// PR c++/30854 // PR c++/30854
// { dg-do compile } // { dg-do compile }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
struct A struct A
{ {
...@@ -7,5 +8,5 @@ struct A ...@@ -7,5 +8,5 @@ struct A
A(int); A(int);
}; };
A a = -A(); // { dg-error "no match for.*operator-.*in.*-A\\(\\)" } A a = -A(); // { dg-error "10: error: no match for.*operator-.*in.*-A\\(\\)" }
A b = -A(5); // { dg-error "no match for.*operator-.*in.*-A\\(5\\)" } A b = -A(5); // { dg-error "11: error: no match for.*operator-.*in.*-A\\(5\\)" }
// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/32190 // PR c++/32190
template<typename T> class foo{ }; template<typename T> class foo{ };
int main() { int main() {
foo<int> i; foo<int> i;
foo<foo<int> j; // { dg-error "template argument" } // this column number is not accurate yet, but that will make it for now.
foo<foo<int> j; // { dg-error "18: error: template argument 1 is invalid" }
int k; int k;
int l; int l;
foo<int> m; foo<int> m;
......
// PR c++/12160 // PR c++/12160
// { dg-options "-fshow-column" }
struct X { struct X {
virtual void f(int, virtual void f(int,
itn, // { dg-error "declared" } itn,
int); int);
}; };
// { dg-error "4: error: 'itn' has not been declared" "" { target *-*-* } { 6 } }
// PR c++/13269 // PR c++/13269
// { dg-options "-fshow-column" }
class Foo { int foo() return 0; } }; // { dg-error "" } class Foo { int foo() return 0; } };
// { dg-error "30: error: expected identifier before numeric constant" "" { target *-*-* } { 4 } }
// { dg-error "23: error: named return values are no longer supported" "" { target *-*-* } { 4 } }
// the column number info of this error output is still wrong because the error
// message has been generated by cp_parser_error() which does not
// necessarily allow accurate column number display. At some point, we will
// need make cp_parser_error() report more accurate column numbers.
// { dg-error "30: error: expected '\{' at end of input" "" { target *-*-* } { 4 } }
// { dg-error "35: error: expected unqualified-id before '\}' token" "" {target *-*-* } { 4 } }
// { dg-error "35: error: expected declaration before '\}' token" "" {target *-*-* } { 4 } }
// PR c++/10603 // PR c++/10603
// { dg-options "-fshow-column" }
int f(int not) { // { dg-error "!" } int f(int not) {
return 1-not; // { dg-error "" } return 1-not;
} }
// { dg-error "11: error: expected ',' or '...' before '!' token" "" { target *-*-* } { 4 } }
// { dg-error "15: error: expected primary\\-expression before ';' token" "" { target *-*-* } { 5 } }
// PR c++/12827 // PR c++/12827
// { dg-options "-fshow-column" }
void f(int x void f(int x
int y); // { dg-error "," } int y);
// { dg-error "8: error: expected ',' or '...' before 'int'" "" { target *-*-* } { 5 } }
// PR c++/13438 // PR c++/13438
// { dg-options "-fshow-column" }
struct A { friend typename struct B; }; // { dg-error "" } struct A { friend typename struct B; };
// { dg-error "19: error: using 'typename' outside of template" "" { target *-*-* } { 4 } }
// { dg-error "28: error: expected nested-name-specifier before 'struct'" "" { target *-*-* } { 4 } }
// { dg-error "35: error: multiple types in one declaration" "" { target *-*-* } { 4 } }
// { dg-error "12: error: friend declaration does not name a class or function" "" { target *-*-* } { 4 } }
// PR c++/12613 // PR c++/12613
// { dg-options "" } // { dg-options "-fshow-column" }
enum { FOO = 1, BAR = 2 }; enum { FOO = 1, BAR = 2 };
int a[] = { FOO: 1, BAR: 2 }; // { dg-error "" } int a[] = { FOO: 1, BAR: 2 };
// the following 2 column locations are still not accurate enough
// { dg-error "28: error: name 'FOO' used in a GNU-style designated initializer for an array" "" { target *-*-* } { 5 } }
// { dg-error "28: error: name 'BAR' used in a GNU-style designated initializer for an array" "" { target *-*-* } { 5 } }
// { dg-do assemble } // { dg-do assemble }
// { dg-options "-fshow-column" }
struct A { // { dg-error "" } forward declaration struct A { // { dg-error "" } forward declaration
friend struct B : A { // { dg-error "" } friend struct B : A { // { dg-error "invalid use of incomplete type 'struct A'" }
int x; int x;
}; // { dg-error "" } class definition cannot be a friend }; // { dg-error "class definition may not be declared a friend" "" { target *-*-* } { 5 } }
int y; int y;
}; };
...@@ -273,7 +273,6 @@ proc g++_target_compile { source dest type options } { ...@@ -273,7 +273,6 @@ proc g++_target_compile { source dest type options } {
} }
lappend options "additional_flags=[libio_include_flags]" lappend options "additional_flags=[libio_include_flags]"
lappend options "additional_flags=-fno-show-column"
lappend options "compiler=$GXX_UNDER_TEST" lappend options "compiler=$GXX_UNDER_TEST"
set options [concat $gpp_compile_options $options] set options [concat $gpp_compile_options $options]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment