diff options
author | Dodji Seketeli <dseketel@redhat.com> | 2008-07-11 12:54:22 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2008-07-11 14:54:22 +0200 |
commit | 2b7a3abf6e2488a0b7e4f1bad6b1da3616d60eea (patch) | |
tree | 67a98c7d92d1fd0e083fc056e53338895ee34a08 /gcc | |
parent | 941a9479d0a4d5fb26182ee6c485c4bf210a6499 (diff) | |
download | gcc-2b7a3abf6e2488a0b7e4f1bad6b1da3616d60eea.zip gcc-2b7a3abf6e2488a0b7e4f1bad6b1da3616d60eea.tar.gz gcc-2b7a3abf6e2488a0b7e4f1bad6b1da3616d60eea.tar.bz2 |
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
Diffstat (limited to 'gcc')
41 files changed, 697 insertions, 348 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2143fe2..0161f2e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,37 @@ +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> PR c++/36760 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ed6ae0e..10eba33 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4653,13 +4653,15 @@ extern void finish_template_decl (tree); extern tree finish_template_type (tree, tree, int); extern tree finish_base_specifier (tree, tree, bool); 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 tree finish_id_expression (tree, tree, tree, cp_id_kind *, bool, bool, bool *, bool, bool, bool, bool, - const char **); + const char **, + location_t); extern tree finish_typeof (tree); extern tree finish_offsetof (tree); extern void finish_decl_cleanup (tree, tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 767d14d..2429bfc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1593,7 +1593,7 @@ static tree cp_parser_postfix_expression static tree cp_parser_postfix_open_square_expression (cp_parser *, tree, bool); 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 (cp_parser *, bool, bool, bool, bool *); static void cp_parser_pseudo_destructor_name @@ -1904,15 +1904,15 @@ static tree cp_parser_objc_statement /* Utility Routines */ 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 - (cp_parser *, tree); + (cp_parser *, tree, location_t); static tree cp_parser_maybe_treat_template_as_class (tree, bool); 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 - (cp_parser *, unsigned); + (cp_parser *, unsigned, location_t); static tree cp_parser_simple_cast_expression (cp_parser *); static tree cp_parser_global_scope_opt @@ -1948,7 +1948,7 @@ static tree cp_parser_trait_expr static bool cp_parser_declares_only_class_p (cp_parser *); 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 (cp_decl_specifier_seq *, tree, bool); static bool cp_parser_friend_p @@ -1970,7 +1970,7 @@ static enum tag_types cp_parser_token_is_class_key static void cp_parser_check_class_key (enum tag_types, tree type); static void cp_parser_check_access_in_redeclaration - (tree type); + (tree type, location_t location); static bool cp_parser_optional_template_keyword (cp_parser *); static void cp_parser_pre_parsed_nested_name_specifier @@ -1992,7 +1992,7 @@ static bool cp_parser_uncommitted_to_tentative_parse_p static void cp_parser_error (cp_parser *, const char *); 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 (cp_parser *); static bool cp_parser_check_type_definition @@ -2004,7 +2004,7 @@ static void cp_parser_check_for_invalid_template_id static bool cp_parser_non_integral_constant_expression (cp_parser *, const char *); 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 (cp_parser *); static int cp_parser_skip_to_closing_parenthesis @@ -2030,7 +2030,7 @@ static bool cp_parser_is_string_literal static bool cp_parser_is_keyword (cp_token *, enum rid); 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 (enum tree_code, tree, cp_cv_quals, cp_declarator *); @@ -2079,7 +2079,7 @@ cp_parser_error (cp_parser* parser, const char* message) 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); return; } @@ -2102,33 +2102,34 @@ static void cp_parser_name_lookup_error (cp_parser* parser, tree name, tree decl, - const char* desired) + const char* desired, + location_t location) { /* If name lookup completely failed, tell the user that NAME was not declared. */ if (decl == error_mark_node) { if (parser->scope && parser->scope != global_namespace) - error ("%<%E::%E%> has not been declared", - parser->scope, name); + error ("%H%<%E::%E%> has not been declared", + &location, parser->scope, name); 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 && !CLASS_TYPE_P (parser->object_scope)) - error ("request for member %qE in non-class type %qT", - name, parser->object_scope); + error ("%Hrequest for member %qE in non-class type %qT", + &location, name, parser->object_scope); else if (parser->object_scope) - error ("%<%T::%E%> has not been declared", - parser->object_scope, name); + error ("%H%<%T::%E%> has not been declared", + &location, parser->object_scope, name); 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) - error ("%<%E::%E%> %s", parser->scope, name, desired); + error ("%H%<%E::%E%> %s", &location, parser->scope, name, desired); else if (parser->scope == global_namespace) - error ("%<::%E%> %s", name, desired); + error ("%H%<::%E%> %s", &location, name, desired); else - error ("%qE %s", name, desired); + error ("%H%qE %s", &location, name, desired); } /* If we are parsing tentatively, remember that an error has occurred @@ -2149,7 +2150,8 @@ cp_parser_simulate_error (cp_parser* parser) /* Check for repeated decl-specifiers. */ 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; @@ -2162,10 +2164,11 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) if (ds == ds_long) { 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 && 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) { @@ -2185,7 +2188,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) "__complex", "__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, in duplicate error messages.) */ 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; /* Try to lookup the identifier. */ old_scope = parser->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; /* If the lookup found a template-name, it means that the user forgot to specify an argument list. Emit a useful error message. */ @@ -2392,6 +2397,7 @@ static bool cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) { tree id; + cp_token *token = cp_lexer_peek_token (parser->lexer); cp_parser_parse_tentatively (parser); id = cp_parser_id_expression (parser, @@ -2415,7 +2421,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) return false; /* 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 trying to process it. */ 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) using cp_parser_diagnose_invalid_type_name. */ 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; if (TREE_CODE (id) == IDENTIFIER_NODE) @@ -2711,7 +2719,7 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id) result = make_typename_type (scope, id, typename_type, /*complain=*/tf_none); 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 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) if (type == CPP_STRING) type = tok->type; 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)); @@ -3108,7 +3117,7 @@ cp_parser_primary_expression (cp_parser *parser, bool template_arg_p, cp_id_kind *idk) { - cp_token *token; + cp_token *token = NULL; /* Assume the primary expression is not an id-expression. */ *idk = CP_ID_KIND_NONE; @@ -3206,7 +3215,8 @@ cp_parser_primary_expression (cp_parser *parser, { /* Statement-expressions are not allowed by the standard. */ 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 cannot, for example, write: @@ -3217,8 +3227,9 @@ cp_parser_primary_expression (cp_parser *parser, if (!parser->in_function_body || parser->in_template_argument_list_p) { - error ("statement-expressions are not allowed outside " - "functions nor in template-argument lists"); + error ("%Hstatement-expressions are not allowed outside " + "functions nor in template-argument lists", + &token->location); cp_parser_skip_to_end_of_block_or_statement (parser); expr = error_mark_node; } @@ -3275,7 +3286,8 @@ cp_parser_primary_expression (cp_parser *parser, cp_lexer_consume_token (parser->lexer); 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; } /* Pointers cannot appear in constant-expressions. */ @@ -3375,6 +3387,7 @@ cp_parser_primary_expression (cp_parser *parser, const char *error_msg; bool template_p; bool done; + cp_token *id_expr_token; id_expression: /* Parse the id-expression. */ @@ -3387,6 +3400,7 @@ cp_parser_primary_expression (cp_parser *parser, /*optional_p=*/false); if (id_expression == error_mark_node) return error_mark_node; + id_expr_token = token; token = cp_lexer_peek_token (parser->lexer); done = (token->type != CPP_OPEN_SQUARE && token->type != CPP_OPEN_PAREN @@ -3410,7 +3424,8 @@ cp_parser_primary_expression (cp_parser *parser, template_p, /*is_namespace=*/false, /*check_dependency=*/true, - &ambiguous_decls); + &ambiguous_decls, + id_expr_token->location); /* If the lookup was ambiguous, an error will already have been issued. */ if (ambiguous_decls) @@ -3457,8 +3472,8 @@ cp_parser_primary_expression (cp_parser *parser, decl = check_for_out_of_scope_variable (decl); if (local_variable_p (decl)) { - error ("local variable %qD may not appear in this context", - decl); + error ("%Hlocal variable %qD may not appear in this context", + &id_expr_token->location, decl); return error_mark_node; } } @@ -3472,7 +3487,8 @@ cp_parser_primary_expression (cp_parser *parser, &parser->non_integral_constant_expression_p, template_p, done, address_p, template_arg_p, - &error_msg)); + &error_msg, + id_expr_token->location)); if (error_msg) cp_parser_error (parser, error_msg); return decl; @@ -3756,7 +3772,8 @@ cp_parser_unqualified_id (cp_parser* parser, if (scope && TREE_CODE (scope) == NAMESPACE_DECL) { 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); if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) cp_lexer_consume_token (parser->lexer); @@ -3857,8 +3874,8 @@ cp_parser_unqualified_id (cp_parser* parser, if (declarator_p && scope && !check_dtor_name (scope, type_decl)) { if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) - error ("declaration of %<~%T%> as member of %qT", - type_decl, scope); + error ("%Hdeclaration of %<~%T%> as member of %qT", + &token->location, type_decl, scope); cp_parser_simulate_error (parser); return error_mark_node; } @@ -3871,8 +3888,8 @@ cp_parser_unqualified_id (cp_parser* parser, && !DECL_IMPLICIT_TYPEDEF_P (type_decl) && !DECL_SELF_REFERENCE_P (type_decl) && !cp_parser_uncommitted_to_tentative_parse_p (parser)) - error ("typedef-name %qD used as destructor declarator", - type_decl); + error ("%Htypedef-name %qD used as destructor declarator", + &token->location, 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, /*is_template=*/false, /*is_namespace=*/false, /*check_dependency=*/true, - &ambiguous_decls); + &ambiguous_decls, + token->location); 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) { - error ("reference to %qD is ambiguous", - token->u.value); + error ("%Hreference to %qD is ambiguous", + &token->location, token->u.value); print_candidates (ambiguous_decls); decl = error_mark_node; } else cp_parser_name_lookup_error (parser, token->u.value, decl, - "is not a class or namespace"); + "is not a class or namespace", + token->location); } parser->scope = error_mark_node; error_p = true; @@ -4746,7 +4766,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, postfix_expression = cp_parser_postfix_dot_deref_expression (parser, token->type, postfix_expression, - false, &idk); + false, &idk, + token->location); is_member_access = true; break; @@ -4860,7 +4881,8 @@ static tree cp_parser_postfix_dot_deref_expression (cp_parser *parser, enum cpp_ttype token_type, tree postfix_expression, - bool for_offsetof, cp_id_kind *idk) + bool for_offsetof, cp_id_kind *idk, + location_t location) { tree name; bool dependent_p; @@ -4892,7 +4914,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, /* The type of the POSTFIX_EXPRESSION must be complete. */ 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; } else @@ -4948,6 +4970,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ordinary class member access expression, rather than a pseudo-destructor-name. */ bool template_p; + cp_token *token = cp_lexer_peek_token (parser->lexer); /* Parse the id-expression. */ name = (cp_parser_id_expression (parser, @@ -4975,7 +4998,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, TYPE_DECL here. That is invalid code. */ 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; } else @@ -5538,18 +5561,21 @@ cp_parser_new_expression (cp_parser* parser) type-id. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { + cp_token *token; /* Consume the `('. */ cp_lexer_consume_token (parser->lexer); /* Parse the type-id. */ type = cp_parser_type_id (parser); /* Look for the closing `)'. */ 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, but GCC used to allowed this, so we check and emit a sensible error message for this case. */ 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"); cp_parser_direct_new_declarator (parser); } @@ -5727,6 +5753,7 @@ cp_parser_direct_new_declarator (cp_parser* parser) /* The first expression is not required to be constant. */ if (!declarator) { + cp_token *token = cp_lexer_peek_token (parser->lexer); expression = cp_parser_expression (parser, /*cast_p=*/false); /* The standard requires that the expression have integral type. DR 74 adds enumeration types. We believe that the @@ -5742,8 +5769,8 @@ cp_parser_direct_new_declarator (cp_parser* parser) /*complain=*/true); if (!expression) { - error ("expression in new-declarator must have integral " - "or enumeration type"); + error ("%Hexpression in new-declarator must have integral " + "or enumeration type", &token->location); expression = error_mark_node; } } @@ -6484,6 +6511,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) int save_ice_p, save_non_ice_p; tree type, expr; cp_id_kind dummy; + cp_token *token; /* We're about to accept non-integral-constant things, but will definitely yield an integral constant expression. Save and @@ -6499,6 +6527,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) type = cp_parser_type_id (parser); /* Look for the `,'. */ cp_parser_require (parser, CPP_COMMA, "%<,%>"); + token = cp_lexer_peek_token (parser->lexer); /* Build the (type *)null that begins the traditional offsetof macro. */ expr = build_static_cast (build_pointer_type (type), null_pointer_node, @@ -6506,10 +6535,10 @@ cp_parser_builtin_offsetof (cp_parser *parser) /* Parse the offsetof-member-designator. We begin as if we saw "expr->". */ expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, expr, - true, &dummy); + true, &dummy, token->location); while (true) { - cp_token *token = cp_lexer_peek_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); switch (token->type) { case CPP_OPEN_SQUARE: @@ -6521,7 +6550,8 @@ cp_parser_builtin_offsetof (cp_parser *parser) /* offsetof-member-designator "." identifier */ cp_lexer_consume_token (parser->lexer); expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, expr, - true, &dummy); + true, &dummy, + token->location); break; case CPP_CLOSE_PAREN: @@ -6883,7 +6913,8 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) if (parser->in_switch_statement_p) finish_case_label (expr, expr_hi); else - error ("case label %qE not within a switch statement", expr); + error ("%Hcase label %qE not within a switch statement", + &token->location, expr); } break; @@ -6894,7 +6925,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser) if (parser->in_switch_statement_p) finish_case_label (NULL_TREE, NULL_TREE); else - error ("case label not within a switch statement"); + error ("%Hcase label not within a switch statement", &token->location); break; default: @@ -7012,7 +7043,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr) else { 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) switch (in_statement) { case 0: - error ("break statement not within loop or switch"); + error ("%Hbreak statement not within loop or switch", &token->location); break; default: gcc_assert ((in_statement & IN_SWITCH_STMT) @@ -7522,10 +7553,10 @@ cp_parser_jump_statement (cp_parser* parser) statement = finish_break_stmt (); break; case IN_OMP_BLOCK: - error ("invalid exit from OpenMP structured block"); + error ("%Hinvalid exit from OpenMP structured block", &token->location); break; case IN_OMP_FOR: - error ("break statement used with OpenMP for loop"); + error ("%Hbreak statement used with OpenMP for loop", &token->location); break; } cp_parser_require (parser, CPP_SEMICOLON, "%<;%>"); @@ -7535,14 +7566,14 @@ cp_parser_jump_statement (cp_parser* parser) switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT)) { case 0: - error ("continue statement not within a loop"); + error ("%Hcontinue statement not within a loop", &token->location); break; case IN_ITERATION_STMT: case IN_OMP_FOR: statement = finish_continue_stmt (); break; case IN_OMP_BLOCK: - error ("invalid exit from OpenMP structured block"); + error ("%Hinvalid exit from OpenMP structured block", &token->location); break; default: gcc_unreachable (); @@ -7579,7 +7610,7 @@ cp_parser_jump_statement (cp_parser* parser) { /* Issue a warning about this use of a GNU extension. */ if (pedantic) - pedwarn ("ISO C++ forbids computed gotos"); + pedwarn ("%HISO C++ forbids computed gotos", &token->location); /* Consume the '*' token. */ cp_lexer_consume_token (parser->lexer); /* Parse the dependent expression. */ @@ -7940,7 +7971,7 @@ cp_parser_block_declaration (cp_parser *parser, else if (token1->keyword == RID_LABEL) { 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); /* If the next token is now a `;', consume it. */ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) @@ -8074,7 +8105,11 @@ cp_parser_simple_declaration (cp_parser* parser, which is erroneous. */ 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. */ else { @@ -8170,6 +8205,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, int* declares_class_or_enum) { bool constructor_possible_p = !parser->in_declarator_p; + cp_token *start_token = NULL; /* Clear DECL_SPECS. */ clear_decl_specs (decl_specs); @@ -8186,6 +8222,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser, /* Peek at the next token. */ 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. */ if (token->keyword == RID_ATTRIBUTE) { @@ -8262,15 +8303,17 @@ cp_parser_decl_specifier_seq (cp_parser* parser, we're complaining about C++0x compatibility. */ warning (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. */ - cp_parser_set_storage_class (parser, decl_specs, RID_AUTO); + cp_parser_set_storage_class (parser, decl_specs, RID_AUTO, + token->location); } else /* We do not yet support the use of `auto' as a type-specifier. */ - error ("C++0x %<auto%> specifier not supported"); + error ("%HC++0x %<auto%> specifier not supported", &token->location); break; case RID_REGISTER: @@ -8279,7 +8322,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, case RID_MUTABLE: /* Consume the token. */ 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; case RID_THREAD: /* Consume the token. */ @@ -8315,7 +8359,6 @@ cp_parser_decl_specifier_seq (cp_parser* parser, /*is_declaration=*/true, &decl_spec_declares_class_or_enum, &is_cv_qualifier); - *declares_class_or_enum |= decl_spec_declares_class_or_enum; /* If this type-specifier referenced a user-defined type @@ -8375,12 +8418,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser, 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. */ if (decl_specs->specs[(int) ds_friend] != 0 && (*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. @@ -8436,7 +8480,8 @@ static tree cp_parser_function_specifier_opt (cp_parser* parser, 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: if (decl_specs) @@ -8448,7 +8493,7 @@ cp_parser_function_specifier_opt (cp_parser* parser, A member function template shall not be virtual. */ if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - error ("templates may not be %<virtual%>"); + error ("%Htemplates may not be %<virtual%>", &token->location); else if (decl_specs) ++decl_specs->specs[(int) ds_virtual]; break; @@ -8602,6 +8647,7 @@ cp_parser_decltype (cp_parser *parser) const char *saved_message; bool saved_integral_constant_expression_p; bool saved_non_integral_constant_expression_p; + cp_token *id_expr_start_token; /* Look for the `decltype' token. */ if (!cp_parser_require_keyword (parser, RID_DECLTYPE, "%<decltype%>")) @@ -8631,6 +8677,7 @@ cp_parser_decltype (cp_parser *parser) return error_mark_node; /* First, try parsing an id-expression. */ + id_expr_start_token = cp_lexer_peek_token (parser->lexer); cp_parser_parse_tentatively (parser); expr = cp_parser_id_expression (parser, /*template_keyword_p=*/false, @@ -8653,7 +8700,8 @@ cp_parser_decltype (cp_parser *parser) /*is_template=*/false, /*is_namespace=*/false, /*check_dependency=*/true, - /*ambiguous_decls=*/NULL); + /*ambiguous_decls=*/NULL, + id_expr_start_token->location); if (expr && expr != error_mark_node @@ -8673,7 +8721,8 @@ cp_parser_decltype (cp_parser *parser) /*done=*/true, /*address_p=*/false, /*template_arg_p=*/false, - &error_msg)); + &error_msg, + id_expr_start_token->location)); if (expr == error_mark_node) /* We found an id-expression, but it was something that we @@ -8916,17 +8965,20 @@ static void cp_parser_mem_initializer_list (cp_parser* parser) { 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 mem-initializer-list. */ 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. */ while (true) { tree mem_initializer; + token = cp_lexer_peek_token (parser->lexer); /* Parse the mem-initializer. */ mem_initializer = cp_parser_mem_initializer (parser); /* If the next token is a `...', we're expanding member initializers. */ @@ -8940,8 +8992,8 @@ cp_parser_mem_initializer_list (cp_parser* parser) if (mem_initializer != error_mark_node && !TYPE_P (TREE_PURPOSE (mem_initializer))) { - error ("cannot expand initializer for member %<%D%>", - TREE_PURPOSE (mem_initializer)); + error ("%Hcannot expand initializer for member %<%D%>", + &token->location, TREE_PURPOSE (mem_initializer)); mem_initializer = error_mark_node; } @@ -8989,11 +9041,13 @@ cp_parser_mem_initializer (cp_parser* parser) tree mem_initializer_id; tree expression_list; tree member; + cp_token *token = cp_lexer_peek_token (parser->lexer); /* Find out what is being initialized. */ 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; } else @@ -9044,11 +9098,14 @@ cp_parser_mem_initializer_id (cp_parser* parser) bool template_p = false; tree id; + cp_token *token = cp_lexer_peek_token (parser->lexer); + /* `typename' is not allowed in this context ([temp.res]). */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME)) { - error ("keyword %<typename%> not allowed in this context (a qualified " - "member initializer is implicitly a type)"); + error ("%Hkeyword %<typename%> not allowed in this context (a qualified " + "member initializer is implicitly a type)", + &token->location); cp_lexer_consume_token (parser->lexer); } /* Look for the optional `::' operator. */ @@ -9565,6 +9622,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, appropriate diagnostic here. */ /* Consume the `='. */ + cp_token *start_token = cp_lexer_peek_token (parser->lexer); cp_lexer_consume_token (parser->lexer); /* Find the name of the parameter pack. */ @@ -9573,10 +9631,11 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, id_declarator = id_declarator->declarator; if (id_declarator && id_declarator->kind == cdk_id) - error ("template parameter pack %qD cannot have a default argument", - id_declarator->u.id.unqualified_name); + error ("%Htemplate parameter pack %qD cannot have a default argument", + &start_token->location, id_declarator->u.id.unqualified_name); 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. */ cp_parser_default_argument (parser, /*template_parm_p=*/true); @@ -9670,10 +9729,11 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) if (*is_parameter_pack) { if (identifier) - error ("template parameter pack %qD cannot have a default argument", - identifier); + error ("%Htemplate parameter pack %qD cannot have a " + "default argument", &token->location, identifier); else - error ("template parameter packs cannot have default arguments"); + error ("%Htemplate parameter packs cannot have " + "default arguments", &token->location); default_argument = NULL_TREE; } pop_deferring_access_checks (); @@ -9741,6 +9801,9 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) cp_lexer_consume_token (parser->lexer); /* Parse the id-expression. */ 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 = cp_parser_id_expression (parser, /*template_keyword_p=*/false, @@ -9761,7 +9824,8 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) /*is_template=*/is_template, /*is_namespace=*/false, /*check_dependency=*/true, - /*ambiguous_decls=*/NULL); + /*ambiguous_decls=*/NULL, + token->location); /* See if the default argument is valid. */ default_argument = check_template_template_default_arg (default_argument); @@ -9771,10 +9835,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack) if (*is_parameter_pack) { if (identifier) - error ("template parameter pack %qD cannot have a default argument", - identifier); + error ("%Htemplate parameter pack %qD cannot " + "have a default argument", + &token->location, identifier); else - error ("template parameter packs cannot have default arguments"); + error ("%Htemplate parameter packs cannot " + "have default arguments", + &token->location); default_argument = NULL_TREE; } pop_deferring_access_checks (); @@ -9823,7 +9890,7 @@ cp_parser_template_id (cp_parser *parser, cp_token_position start_of_id = 0; deferred_access_check *chk; 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; /* If the next token corresponds to a template-id, there is no need @@ -9871,6 +9938,7 @@ cp_parser_template_id (cp_parser *parser, /* Parse the template-name. */ is_identifier = false; + token = cp_lexer_peek_token (parser->lexer); template = cp_parser_template_name (parser, template_keyword_p, check_dependency_p, is_declaration, @@ -9897,6 +9965,7 @@ cp_parser_template_id (cp_parser *parser, /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is CPP_LESS. */ cp_lexer_consume_token (parser->lexer); + /* Parse the arguments. */ arguments = cp_parser_enclosed_template_argument_list (parser); if (!cp_parser_parse_definitely (parser)) @@ -9911,15 +9980,18 @@ cp_parser_template_id (cp_parser *parser, } /* Otherwise, emit an error about the invalid digraph, but continue parsing because we got our argument list. */ - permerror ("%<<::%> cannot begin a template-argument list"); - inform ("%<<:%> is an alternate spelling for %<[%>. Insert whitespace " - "between %<<%> and %<::%>"); + permerror ("%H%<<::%> cannot begin a template-argument list", + &next_token->location); + inform ("%H%<<:%> is an alternate spelling for %<[%>. Insert whitespace " + "between %<<%> and %<::%>", + &next_token->location); if (!flag_permissive) { static bool 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; } } @@ -9992,7 +10064,8 @@ cp_parser_template_id (cp_parser *parser, user, as opposed to simply marking the tentative parse as failed? */ 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 (); @@ -10046,6 +10119,7 @@ cp_parser_template_name (cp_parser* parser, tree identifier; tree decl; tree fns; + cp_token *token = cp_lexer_peek_token (parser->lexer); /* If the next token is `operator', then we have either an operator-function-id or a conversion-function-id. */ @@ -10105,7 +10179,8 @@ cp_parser_template_name (cp_parser* parser, cp_token_position start = 0; /* 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", parser->scope, identifier); /* If parsing tentatively, find the location of the "<" token. */ @@ -10149,7 +10224,8 @@ cp_parser_template_name (cp_parser* parser, /*is_template=*/false, /*is_namespace=*/false, check_dependency_p, - /*ambiguous_decls=*/NULL); + /*ambiguous_decls=*/NULL, + token->location); decl = maybe_get_template_decl_from_type_decl (decl); /* If DECL is a template, then the name was a template-name. */ @@ -10295,7 +10371,7 @@ cp_parser_template_argument (cp_parser* parser) bool template_p; bool address_p; bool maybe_type_id = false; - cp_token *token; + cp_token *token = NULL, *argument_start_token = NULL; cp_id_kind idk; /* 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) /* We're still not sure what the argument will be. */ cp_parser_parse_tentatively (parser); /* Try a template. */ + argument_start_token = cp_lexer_peek_token (parser->lexer); argument = cp_parser_id_expression (parser, /*template_keyword_p=*/false, /*check_dependency_p=*/true, @@ -10364,7 +10441,8 @@ cp_parser_template_argument (cp_parser* parser) /*is_template=*/template_p, /*is_namespace=*/false, /*check_dependency=*/true, - /*ambiguous_decls=*/NULL); + /*ambiguous_decls=*/NULL, + argument_start_token->location); if (TREE_CODE (argument) != TEMPLATE_DECL && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE) cp_parser_error (parser, "expected template-name"); @@ -10616,6 +10694,8 @@ static void cp_parser_explicit_specialization (cp_parser* parser) { bool need_lang_pop; + cp_token *token = cp_lexer_peek_token (parser->lexer); + /* Look for the `template' keyword. */ cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"); /* Look for the `<'. */ @@ -10630,7 +10710,7 @@ cp_parser_explicit_specialization (cp_parser* parser) linkage. */ 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 front end. */ push_lang_context (lang_name_cplusplus); @@ -10955,7 +11035,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_lexer_consume_token (parser->lexer); /* We do not yet support the use of `auto' as a type-specifier. */ - error ("C++0x %<auto%> specifier not supported"); + error ("%HC++0x %<auto%> specifier not supported", &token->location); } break; @@ -11168,12 +11248,13 @@ cp_parser_nonclass_name (cp_parser* parser) tree type_decl; tree identifier; + cp_token *token = cp_lexer_peek_token (parser->lexer); identifier = cp_parser_identifier (parser); if (identifier == error_mark_node) return error_mark_node; /* 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 && (objc_is_id (identifier) || objc_is_class_name (identifier))) @@ -11190,7 +11271,7 @@ cp_parser_nonclass_name (cp_parser* parser) { if (!cp_parser_simulate_error (parser)) cp_parser_name_lookup_error (parser, identifier, type_decl, - "is not a type"); + "is not a type", token->location); return error_mark_node; } /* Remember that the name was used in the definition of the @@ -11239,6 +11320,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, tree identifier; tree type = NULL_TREE; tree attributes = NULL_TREE; + cp_token *token = NULL; /* See if we're looking at the `enum' keyword. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM)) @@ -11308,6 +11390,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (!template_p) cp_parser_parse_tentatively (parser); /* Parse the template-id. */ + token = cp_lexer_peek_token (parser->lexer); decl = cp_parser_template_id (parser, template_p, /*check_dependency_p=*/true, is_declaration); @@ -11329,6 +11412,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (!type) { + token = cp_lexer_peek_token (parser->lexer); identifier = cp_parser_identifier (parser); if (identifier == error_mark_node) @@ -11341,7 +11425,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (tag_type == typename_type && TREE_CODE (parser->scope) != NAMESPACE_DECL) return cp_parser_make_typename_type (parser, parser->scope, - identifier); + identifier, + token->location); /* Look up a qualified name in the usual way. */ if (parser->scope) { @@ -11353,7 +11438,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, /*is_template=*/false, /*is_namespace=*/false, /*check_dependency=*/true, - &ambiguous_decls); + &ambiguous_decls, + token->location); /* If the lookup was ambiguous, an error will already have been issued. */ @@ -11389,7 +11475,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, { cp_parser_diagnose_invalid_type_name (parser, parser->scope, - identifier); + identifier, + token->location); return error_mark_node; } @@ -11489,7 +11576,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, /* An unqualified name was used to reference this type, so there were no qualifying templates. */ if (!cp_parser_check_template_parameters (parser, - /*num_templates=*/0)) + /*num_templates=*/0, + token->location)) return error_mark_node; type = xref_tag (tag_type, identifier, ts, template_p); } @@ -11692,6 +11780,8 @@ cp_parser_namespace_name (cp_parser* parser) tree identifier; tree namespace_decl; + cp_token *token = cp_lexer_peek_token (parser->lexer); + /* Get the name of the namespace. */ identifier = cp_parser_identifier (parser); if (identifier == error_mark_node) @@ -11720,13 +11810,14 @@ cp_parser_namespace_name (cp_parser* parser) /*is_template=*/false, /*is_namespace=*/true, /*check_dependency=*/true, - /*ambiguous_decls=*/NULL); + /*ambiguous_decls=*/NULL, + token->location); /* If it's not a namespace, issue an error. */ if (namespace_decl == error_mark_node || TREE_CODE (namespace_decl) != NAMESPACE_DECL) { 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"); namespace_decl = error_mark_node; } @@ -11841,6 +11932,8 @@ cp_parser_namespace_alias_definition (cp_parser* parser) tree identifier; tree namespace_specifier; + cp_token *token = cp_lexer_peek_token (parser->lexer); + /* Look for the `namespace' keyword. */ cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>"); /* Look for the identifier. */ @@ -11851,7 +11944,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser) if (!cp_parser_uncommitted_to_tentative_parse_p (parser) && 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. */ cp_lexer_consume_token (parser->lexer); if (cp_parser_skip_to_closing_brace (parser)) @@ -11966,6 +12059,7 @@ cp_parser_using_declaration (cp_parser* parser, cp_parser_parse_definitely will be false, as required. */ return cp_parser_parse_definitely (parser); + token = cp_lexer_peek_token (parser->lexer); /* Parse the unqualified-id. */ identifier = cp_parser_unqualified_id (parser, /*template_keyword_p=*/false, @@ -11990,7 +12084,8 @@ cp_parser_using_declaration (cp_parser* parser, /* [namespace.udecl] 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 { if (at_class_scope_p ()) @@ -12006,9 +12101,13 @@ cp_parser_using_declaration (cp_parser* parser, } else { - decl = cp_parser_lookup_name_simple (parser, identifier); + decl = cp_parser_lookup_name_simple (parser, + identifier, + token->location); 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)) return false; else if (!at_namespace_scope_p ()) @@ -12258,7 +12357,8 @@ cp_parser_init_declarator (cp_parser* parser, int declares_class_or_enum, bool* function_definition_p) { - cp_token *token; + cp_token *token = NULL, *asm_spec_start_token = NULL, + *attributes_start_token = NULL; cp_declarator *declarator; tree prefix_attributes; tree attributes; @@ -12292,6 +12392,7 @@ cp_parser_init_declarator (cp_parser* parser, resume_deferring_access_checks (); /* Parse the declarator. */ + token = cp_lexer_peek_token (parser->lexer); declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, @@ -12306,7 +12407,8 @@ cp_parser_init_declarator (cp_parser* parser, return error_mark_node; /* 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; if (declares_class_or_enum & 2) @@ -12323,8 +12425,10 @@ cp_parser_init_declarator (cp_parser* parser, if (cp_parser_allow_gnu_extensions_p (parser)) { /* Look for an asm-specification. */ + asm_spec_start_token = cp_lexer_peek_token (parser->lexer); asm_specification = cp_parser_asm_specification_opt (parser); /* And attributes. */ + attributes_start_token = cp_lexer_peek_token (parser->lexer); attributes = cp_parser_attributes_opt (parser); } else @@ -12353,9 +12457,12 @@ cp_parser_init_declarator (cp_parser* parser, /* Neither attributes nor an asm-specification are allowed on a function-definition. */ 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) - 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. */ *function_definition_p = true; @@ -12481,6 +12588,7 @@ cp_parser_init_declarator (cp_parser* parser, { if (function_declarator_p (declarator)) { + cp_token *initializer_start_token = cp_lexer_peek_token (parser->lexer); if (initialization_kind == CPP_EQ) initializer = cp_parser_pure_specifier (parser); else @@ -12489,7 +12597,8 @@ cp_parser_init_declarator (cp_parser* parser, know what the user intended, so just silently consume the initializer. */ 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, /*recovering=*/true, /*or_comma=*/false, @@ -12891,7 +13000,8 @@ cp_parser_direct_declarator (cp_parser* parser, in function scopes. */ 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; } } @@ -12913,6 +13023,7 @@ cp_parser_direct_declarator (cp_parser* parser, special_function_kind sfk; bool abstract_ok; bool pack_expansion_p = false; + cp_token *declarator_id_start_token; /* Parse a declarator-id */ abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); @@ -12931,6 +13042,7 @@ cp_parser_direct_declarator (cp_parser* parser, } } + declarator_id_start_token = cp_lexer_peek_token (parser->lexer); unqualified_name = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); qualifying_scope = parser->scope; @@ -13000,7 +13112,8 @@ cp_parser_direct_declarator (cp_parser* parser, /*only_current_p=*/false); /* If that failed, the declarator is invalid. */ 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_IDENTIFIER (qualifying_scope)); qualifying_scope = type; @@ -13026,7 +13139,8 @@ cp_parser_direct_declarator (cp_parser* parser, if (qualifying_scope && 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 " "name the constructor in a qualified name", class_type, @@ -13185,6 +13299,7 @@ cp_parser_ptr_operator (cp_parser* parser, cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false); /* Look for the nested-name specifier. */ + token = cp_lexer_peek_token (parser->lexer); cp_parser_nested_name_specifier (parser, /*typename_keyword_p=*/false, /*check_dependency_p=*/true, @@ -13199,7 +13314,7 @@ cp_parser_ptr_operator (cp_parser* parser, code = INDIRECT_REF; 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 { /* 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) if (cv_quals & cv_qualifier) { - error ("duplicate cv-qualifier"); + error ("%Hduplicate cv-qualifier", &token->location); cp_lexer_purge_token (parser->lexer); } else @@ -13384,6 +13499,7 @@ cp_parser_type_specifier_seq (cp_parser* parser, { bool seen_type_specifier = false; cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL; + cp_token *start_token = NULL; /* Clear the TYPE_SPECIFIER_SEQ. */ clear_decl_specs (type_specifier_seq); @@ -13403,6 +13519,11 @@ cp_parser_type_specifier_seq (cp_parser* parser, 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. */ type_specifier = cp_parser_type_specifier (parser, flags, @@ -13446,7 +13567,7 @@ cp_parser_type_specifier_seq (cp_parser* parser, 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. @@ -13673,7 +13794,7 @@ cp_parser_parameter_declaration (cp_parser *parser, cp_decl_specifier_seq decl_specifiers; cp_declarator *declarator; tree default_argument; - cp_token *token; + cp_token *token = NULL, *declarator_token_start = NULL; const char *saved_message; /* In a template parameter, `>' is not an operator. @@ -13742,6 +13863,7 @@ cp_parser_parameter_declaration (cp_parser *parser, && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) cp_parser_commit_to_tentative_parse (parser); /* Parse the declarator. */ + declarator_token_start = token; declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER, /*ctor_dtor_or_conv_p=*/NULL, @@ -13900,7 +14022,7 @@ cp_parser_parameter_declaration (cp_parser *parser, /* If we run out of tokens, issue an error message. */ case CPP_EOF: case CPP_PRAGMA_EOL: - error ("file ends in default argument"); + error ("%Hfile ends in default argument", &token->location); done = true; break; @@ -13937,8 +14059,11 @@ cp_parser_parameter_declaration (cp_parser *parser, /* Outside of a class definition, we can just parse the assignment-expression. */ else - default_argument - = cp_parser_default_argument (parser, template_parm_p); + { + token = cp_lexer_peek_token (parser->lexer); + default_argument + = cp_parser_default_argument (parser, template_parm_p); + } if (!parser->default_arg_ok_p) { @@ -13946,7 +14071,9 @@ cp_parser_parameter_declaration (cp_parser *parser, warning (0, "deprecated use of default argument for parameter of non-function"); 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; } } @@ -13962,11 +14089,12 @@ cp_parser_parameter_declaration (cp_parser *parser, id_declarator = id_declarator->declarator; 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); else - error ("%sparameter pack cannot have a default argument", - kind); + error ("%H%sparameter pack cannot have a default argument", + &declarator_token_start->location, kind); default_argument = NULL_TREE; } @@ -14377,10 +14505,12 @@ cp_parser_class_name (cp_parser *parser, /*is_template=*/false, /*is_namespace=*/false, check_dependency_p, - &ambiguous_decls); + &ambiguous_decls, + identifier_token->location); if (ambiguous_decls) { - error ("reference to %qD is ambiguous", identifier); + error ("%Hreference to %qD is ambiguous", + &identifier_token->location, identifier); print_candidates (ambiguous_decls); if (cp_parser_parsing_tentatively (parser)) { @@ -14671,7 +14801,7 @@ cp_parser_class_head (cp_parser* parser, bool invalid_explicit_specialization_p = false; tree pushed_scope = NULL_TREE; unsigned num_templates; - + cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL; /* Assume no nested-name-specifier will be present. */ *nested_name_specifier_p = false; /* Assume no template parameter lists will be used in defining the @@ -14704,6 +14834,7 @@ cp_parser_class_head (cp_parser* parser, /* Determine the name of the class. Begin by looking for an optional nested-name-specifier. */ + nested_name_specifier_token_start = cp_lexer_peek_token (parser->lexer); nested_name_specifier = cp_parser_nested_name_specifier_opt (parser, /*typename_keyword_p=*/false, @@ -14714,6 +14845,7 @@ cp_parser_class_head (cp_parser* parser, identifier. */ if (nested_name_specifier) { + type_start_token = cp_lexer_peek_token (parser->lexer); /* Although the grammar says `identifier', it really means `class-name' or `template-name'. You are only allowed to define a class that has already been declared with this @@ -14777,6 +14909,7 @@ cp_parser_class_head (cp_parser* parser, an identifier, or nothing at all. */ cp_parser_parse_tentatively (parser); /* Check for a template-id. */ + type_start_token = cp_lexer_peek_token (parser->lexer); id = cp_parser_template_id (parser, /*template_keyword_p=*/false, /*check_dependency_p=*/true, @@ -14828,7 +14961,8 @@ cp_parser_class_head (cp_parser* parser, /* Reject typedef-names in class heads. */ 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; goto done; } @@ -14840,10 +14974,13 @@ cp_parser_class_head (cp_parser* parser, if (scope && !is_ancestor (scope, nested_name_specifier)) { if (at_namespace_scope_p ()) - error ("declaration of %qD in namespace %qD which does not " - "enclose %qD", type, scope, nested_name_specifier); + error ("%Hdeclaration of %qD in namespace %qD which does not " + "enclose %qD", + &type_start_token->location, + type, scope, nested_name_specifier); 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 = NULL_TREE; goto done; @@ -14856,7 +14993,8 @@ cp_parser_class_head (cp_parser* parser, class member of a namespace outside of its namespace. */ 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; num_templates = 0; } @@ -14867,7 +15005,8 @@ cp_parser_class_head (cp_parser* parser, && parser->num_template_parameter_lists == 0 && 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; /* Take the same action that would have been taken by cp_parser_explicit_specialization. */ @@ -14879,7 +15018,8 @@ cp_parser_class_head (cp_parser* parser, use "goto done;" to return. */ /* Make sure that the right number of template parameters were 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 process the class-definition. */ @@ -14894,7 +15034,8 @@ cp_parser_class_head (cp_parser* parser, && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0)) || 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; } else @@ -14975,8 +15116,10 @@ cp_parser_class_head (cp_parser* parser, that's an error. */ if (type != error_mark_node && COMPLETE_TYPE_P (type)) { - error ("redefinition of %q#T", type); - error ("previous definition of %q+#T", type); + error ("%Hredefinition of %q#T", + &type_start_token->location, type); + error ("%Hprevious definition of %q+#T", + &type_start_token->location, type); type = NULL_TREE; goto done; } @@ -15131,7 +15274,9 @@ cp_parser_member_declaration (cp_parser* parser) tree decl; int declares_class_or_enum; 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; /* Check for the `__extension__' keyword. */ @@ -15195,6 +15340,7 @@ cp_parser_member_declaration (cp_parser* parser) return; /* Parse the decl-specifier-seq. */ + decl_spec_token_start = cp_lexer_peek_token (parser->lexer); cp_parser_decl_specifier_seq (parser, CP_PARSER_FLAGS_OPTIONAL, &decl_specifiers, @@ -15240,7 +15386,8 @@ cp_parser_member_declaration (cp_parser* parser) /* If the `friend' keyword was present, the friend must be introduced with a class-key. */ 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: template <typename T> struct A { @@ -15254,8 +15401,8 @@ cp_parser_member_declaration (cp_parser* parser) && TYPE_P (decl_specifiers.type)) type = decl_specifiers.type; if (!type || !TYPE_P (type)) - error ("friend declaration does not name a class or " - "function"); + error ("%Hfriend declaration does not name a class or " + "function", &decl_spec_token_start->location); else make_friend_class (current_class_type, type, /*complain=*/true); @@ -15278,7 +15425,9 @@ cp_parser_member_declaration (cp_parser* parser) finish_member_declaration (decl); } 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 @@ -15406,6 +15555,7 @@ cp_parser_member_declaration (cp_parser* parser) for a pure-specifier; otherwise, we look for a constant-initializer. When we call `grokfield', it will perform more stringent semantics checks. */ + initializer_token_start = cp_lexer_peek_token (parser->lexer); if (function_declarator_p (declarator)) initializer = cp_parser_pure_specifier (parser); else @@ -15430,7 +15580,8 @@ cp_parser_member_declaration (cp_parser* parser) standard, since a pure function may be defined outside of the class-specifier. */ 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_specifiers, declarator, @@ -15521,7 +15672,7 @@ cp_parser_pure_specifier (cp_parser* parser) } if (PROCESSING_REAL_TEMPLATE_DECL_P ()) { - error ("templates may not be %<virtual%>"); + error ("%Htemplates may not be %<virtual%>", &token->location); return error_mark_node; } @@ -15723,11 +15874,14 @@ cp_parser_base_specifier (cp_parser* parser) as base classes. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME)) { + token = cp_lexer_peek_token (parser->lexer); if (!processing_template_decl) - error ("keyword %<typename%> not allowed outside of templates"); + error ("%Hkeyword %<typename%> not allowed outside of templates", + &token->location); else - error ("keyword %<typename%> not allowed in this context " - "(the base class is implicitly a type)"); + error ("%Hkeyword %<typename%> not allowed in this context " + "(the base class is implicitly a type)", + &token->location); cp_lexer_consume_token (parser->lexer); } @@ -16428,7 +16582,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool is_template, bool is_namespace, bool check_dependency, - tree *ambiguous_decls) + tree *ambiguous_decls, + location_t name_location) { int flags = 0; tree decl; @@ -16609,7 +16764,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cp_parser_error, so we incorporate its actions directly. */ 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); } return error_mark_node; @@ -16639,14 +16795,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name, IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */ 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, none_type, /*is_template=*/false, /*is_namespace=*/false, /*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 @@ -16699,7 +16856,8 @@ cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p) static bool cp_parser_check_declarator_template_parameters (cp_parser* parser, - cp_declarator *declarator) + cp_declarator *declarator, + location_t declarator_location) { unsigned num_templates; @@ -16749,7 +16907,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ++num_templates; return cp_parser_check_template_parameters (parser, - num_templates); + num_templates, + declarator_location); case cdk_function: case cdk_array: @@ -16757,7 +16916,7 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, case cdk_reference: case cdk_ptrmem: return (cp_parser_check_declarator_template_parameters - (parser, declarator->declarator)); + (parser, declarator->declarator, declarator_location)); case cdk_error: return true; @@ -16774,7 +16933,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, static bool 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 something like: @@ -16782,7 +16942,7 @@ cp_parser_check_template_parameters (cp_parser* parser, template <class T> void S<T>::R<T>::f (); */ if (parser->num_template_parameter_lists < num_templates) { - error ("too few template-parameter-lists"); + error ("%Htoo few template-parameter-lists", &location); return false; } /* If there are the same number of template classes and parameter @@ -16797,7 +16957,7 @@ cp_parser_check_template_parameters (cp_parser* parser, something like: template <class T> template <class U> void S::f(); */ - error ("too many template-parameter-lists"); + error ("%Htoo many template-parameter-lists", &location); return false; } @@ -17055,12 +17215,14 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, bool saved_in_unbraced_linkage_specification_p; bool saved_in_function_body; unsigned saved_num_template_parameter_lists; + cp_token *token; saved_in_function_body = parser->in_function_body; parser->in_function_body = true; /* 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 support. */ + token = cp_lexer_peek_token (parser->lexer); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN)) { /* Consume the `return' keyword. */ @@ -17069,7 +17231,8 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, returned. */ cp_parser_identifier (parser); /* 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. */ while (true) { @@ -17128,8 +17291,10 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) tree parameter_list; bool friend_p = false; bool need_lang_pop; + cp_token *token; /* Look for the `template' keyword. */ + token = cp_lexer_peek_token (parser->lexer); if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>")) return; @@ -17141,7 +17306,8 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) /* 14.5.2.2 [temp.mem] 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); return; } @@ -17150,7 +17316,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) A template ... shall not have C linkage. */ 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 front end. */ push_lang_context (lang_name_cplusplus); @@ -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 know if a specialization will be a friend. */ push_deferring_access_checks (dk_no_check); + token = cp_lexer_peek_token (parser->lexer); decl = cp_parser_single_declaration (parser, checks, 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 (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); } @@ -17273,6 +17440,7 @@ cp_parser_single_declaration (cp_parser* parser, tree decl = NULL_TREE; cp_decl_specifier_seq decl_specifiers; bool function_definition_p = false; + cp_token *decl_spec_token_start; /* This function is only used when processing a template declaration. */ @@ -17284,6 +17452,7 @@ cp_parser_single_declaration (cp_parser* parser, /* Try the `decl-specifier-seq [opt] init-declarator [opt]' alternative. */ + decl_spec_token_start = cp_lexer_peek_token (parser->lexer); cp_parser_decl_specifier_seq (parser, CP_PARSER_FLAGS_OPTIONAL, &decl_specifiers, @@ -17294,7 +17463,8 @@ cp_parser_single_declaration (cp_parser* parser, /* There are no template typedefs. */ 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; } @@ -17357,7 +17527,8 @@ cp_parser_single_declaration (cp_parser* parser, && explicit_specialization_p && 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; } } @@ -17586,9 +17757,9 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) is a typo for '>'. Emit an error message and continue. Same deal about the token location, but here we can get it right by consuming the '>>' before issuing the diagnostic. */ - cp_lexer_consume_token (parser->lexer); - error ("spurious %<>>%>, use %<>%> to terminate " - "a template argument list"); + cp_token *token = cp_lexer_consume_token (parser->lexer); + error ("%Hspurious %<>>%>, use %<>%> to terminate " + "a template argument list", &token->location); } } else @@ -17909,14 +18080,15 @@ cp_parser_declares_only_class_p (cp_parser *parser) static void cp_parser_set_storage_class (cp_parser *parser, cp_decl_specifier_seq *decl_specs, - enum rid keyword) + enum rid keyword, + location_t location) { cp_storage_class storage_class; if (parser->in_unbraced_linkage_specification_p) { - error ("invalid use of %qD in linkage specification", - ridpointers[keyword]); + error ("%Hinvalid use of %qD in linkage specification", + &location, ridpointers[keyword]); return; } else if (decl_specs->storage_class != sc_none) @@ -17928,7 +18100,7 @@ cp_parser_set_storage_class (cp_parser *parser, if ((keyword == RID_EXTERN || keyword == RID_STATIC) && 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; } @@ -18258,7 +18430,7 @@ cp_parser_check_class_key (enum tag_types class_key, tree type) [class.mem/1]. */ 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))) return; @@ -18267,7 +18439,7 @@ cp_parser_check_access_in_redeclaration (tree decl) != (current_access_specifier == access_private_node)) || (TREE_PROTECTED (decl) != (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. @@ -18284,8 +18456,9 @@ cp_parser_optional_template_keyword (cp_parser *parser) template and what is not. */ if (!processing_template_decl) { - error ("%<template%> (as a disambiguator) is only allowed " - "within templates"); + cp_token *token = cp_lexer_peek_token (parser->lexer); + error ("%H%<template%> (as a disambiguator) is only allowed " + "within templates", &token->location); /* If this part of the token stream is rescanned, the same error message would be generated. So, we purge the token from the stream. */ @@ -18550,7 +18723,8 @@ cp_parser_objc_expression (cp_parser* parser) break; } 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); } @@ -18683,15 +18857,18 @@ static tree cp_parser_objc_encode_expression (cp_parser* parser) { tree type; + cp_token *token; cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */ cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"); + token = cp_lexer_peek_token (parser->lexer); type = complete_type (cp_parser_type_id (parser)); cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"); 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; } @@ -19006,7 +19183,7 @@ cp_parser_objc_selector (cp_parser* parser) 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; } @@ -19336,7 +19513,8 @@ cp_parser_objc_protocol_declaration (cp_parser* parser) cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ 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; } @@ -19472,7 +19650,8 @@ cp_parser_objc_declaration (cp_parser* parser) cp_parser_objc_end_implementation (parser); break; 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); } } @@ -19603,7 +19782,8 @@ cp_parser_objc_statement (cp_parser * parser) { case RID_AT_THROW: return cp_parser_objc_throw_statement (parser); 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); } @@ -19687,14 +19867,15 @@ cp_parser_omp_clause_name (cp_parser *parser) /* Validate that a clause of the given type does not already exist. */ 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; for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == code) { - error ("too many %qs clauses", name); + error ("%Htoo many %qs clauses", &location, name); break; } } @@ -19717,10 +19898,12 @@ static tree cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, tree list) { + cp_token *token; while (1) { tree name, decl; + token = cp_lexer_peek_token (parser->lexer); name = cp_parser_id_expression (parser, /*template_p=*/false, /*check_dependency_p=*/true, /*template_p=*/NULL, @@ -19729,9 +19912,9 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, if (name == error_mark_node) 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) - cp_parser_name_lookup_error (parser, name, decl, NULL); + cp_parser_name_lookup_error (parser, name, decl, NULL, token->location); else if (kind != 0) { 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) collapse ( constant-expression ) */ 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; location_t loc; @@ -19806,11 +19989,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list) || (n = tree_low_cst (num, 0)) <= 0 || (int) n != n) { - error ("%Hcollapse argument needs positive constant integer expression", &loc); + error ("%Hcollapse argument needs positive constant integer expression", + &loc); 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); OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_COLLAPSE_EXPR (c) = num; @@ -19822,7 +20006,7 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list) default ( shared | none ) */ 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; tree c; @@ -19868,7 +20052,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list) if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) 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); OMP_CLAUSE_CHAIN (c) = list; OMP_CLAUSE_DEFAULT_KIND (c) = kind; @@ -19880,7 +20064,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list) if ( expression ) */ 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; @@ -19895,7 +20079,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list) /*or_comma=*/false, /*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); OMP_CLAUSE_IF_EXPR (c) = t; @@ -19908,11 +20092,12 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list) nowait */ 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; - 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); OMP_CLAUSE_CHAIN (c) = list; @@ -19923,7 +20108,8 @@ cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED, tree list) num_threads ( expression ) */ 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; @@ -19938,7 +20124,8 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list) /*or_comma=*/false, /*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); OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; @@ -19951,11 +20138,13 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list) ordered */ 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; - 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); OMP_CLAUSE_CHAIN (c) = list; @@ -20032,7 +20221,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list) static | dynamic | guided | runtime | auto */ 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; @@ -20080,18 +20269,20 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list) if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) { + cp_token *token; cp_lexer_consume_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); t = cp_parser_assignment_expression (parser, false); if (t == error_mark_node) goto resync_fail; else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) - error ("schedule %<runtime%> does not take " - "a %<chunk_size%> parameter"); + error ("%Hschedule %<runtime%> does not take " + "a %<chunk_size%> parameter", &token->location); else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO) - error ("schedule %<auto%> does not take " - "a %<chunk_size%> parameter"); + error ("%Hschedule %<auto%> does not take " + "a %<chunk_size%> parameter", &token->location); else OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; @@ -20101,7 +20292,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list) else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>")) 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; return c; @@ -20118,11 +20309,12 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list) untied */ 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; - 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); OMP_CLAUSE_CHAIN (c) = list; @@ -20139,6 +20331,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, { tree clauses = NULL; bool first = true; + cp_token *token = NULL; 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, if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) cp_lexer_consume_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); c_kind = cp_parser_omp_clause_name (parser); first = false; switch (c_kind) { 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"; break; case PRAGMA_OMP_CLAUSE_COPYIN: @@ -20168,7 +20363,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, c_name = "copyprivate"; break; 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"; break; case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: @@ -20177,7 +20373,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, c_name = "firstprivate"; break; 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"; break; case PRAGMA_OMP_CLAUSE_LASTPRIVATE: @@ -20186,15 +20382,17 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, c_name = "lastprivate"; break; 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"; break; 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"; break; 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"; break; case PRAGMA_OMP_CLAUSE_PRIVATE: @@ -20207,7 +20405,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, c_name = "reduction"; break; 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"; break; case PRAGMA_OMP_CLAUSE_SHARED: @@ -20216,7 +20415,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, c_name = "shared"; break; 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"; break; default: @@ -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 confusing the rest of the compiler. */ 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: @@ -21315,10 +21515,11 @@ cp_parser_initial_pragma (cp_token *first_token) cp_lexer_get_preprocessor_token (NULL, first_token); 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 - error ("expected string literal"); + error ("%Hexpected string literal", &first_token->location); /* Skip to the end of the pragma. */ 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) switch (id) { 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; case PRAGMA_OMP_BARRIER: @@ -21361,8 +21563,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) cp_parser_omp_barrier (parser, pragma_tok); return false; case pragma_stmt: - error ("%<#pragma omp barrier%> may only be " - "used in compound statements"); + error ("%H%<#pragma omp barrier%> may only be " + "used in compound statements", &pragma_tok->location); break; default: goto bad_stmt; @@ -21376,8 +21578,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) cp_parser_omp_flush (parser, pragma_tok); return false; case pragma_stmt: - error ("%<#pragma omp flush%> may only be " - "used in compound statements"); + error ("%H%<#pragma omp flush%> may only be " + "used in compound statements", &pragma_tok->location); break; default: goto bad_stmt; @@ -21418,8 +21620,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) return true; case PRAGMA_OMP_SECTION: - error ("%<#pragma omp section%> may only be used in " - "%<#pragma omp sections%> construct"); + error ("%H%<#pragma omp section%> may only be used in " + "%<#pragma omp sections%> construct", &pragma_tok->location); break; default: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b54c9d1..1378e56 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9743,7 +9743,7 @@ tsubst_qualified_id (tree qualified_id, tree args, if (complain & tf_error) qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1), - expr); + expr, input_location); return error_mark_node; } @@ -9752,7 +9752,7 @@ tsubst_qualified_id (tree qualified_id, tree args, if (expr == error_mark_node && complain & tf_error) qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1), - expr); + expr, input_location); else if (TYPE_P (scope)) { expr = (adjust_result_of_qualified_name_lookup @@ -10484,7 +10484,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, /*is_type_p=*/false, /*complain=*/false); 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 do_local_using_decl (decl, scope, name); } @@ -10931,7 +10931,8 @@ tsubst_copy_and_build (tree t, /*done=*/true, /*address_p=*/false, /*template_arg_p=*/false, - &error_msg); + &error_msg, + input_location); if (error_msg) error (error_msg); if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE) @@ -11460,7 +11461,8 @@ tsubst_copy_and_build (tree t, } else { - qualified_name_lookup_error (object_type, tmpl, member); + qualified_name_lookup_error (object_type, tmpl, member, + input_location); return error_mark_node; } } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fa65e9b..17b1e5d 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 - 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 -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) ; /* We already complained. */ else if (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) { - error ("reference to %<%T::%D%> is ambiguous", scope, name); + error ("%Hreference to %<%T::%D%> is ambiguous", &location, scope, name); print_candidates (decl); } 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) - error ("%qD is not a member of %qD", name, scope); + error ("%H%qD is not a member of %qD", &location, name, scope); 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 @@ -2589,7 +2593,6 @@ baselink_for_fns (tree fns) the use of "this" explicit. Upon return, *IDK will be filled in appropriately. */ - tree finish_id_expression (tree id_expression, tree decl, @@ -2602,7 +2605,8 @@ finish_id_expression (tree id_expression, bool done, bool address_p, bool template_arg_p, - const char **error_msg) + const char **error_msg, + location_t location) { /* Initialize the output parameters. */ *idk = CP_ID_KIND_NONE; @@ -2632,7 +2636,7 @@ finish_id_expression (tree id_expression, /* If the qualifying type is non-dependent (and the name does not name a conversion operator to a dependent 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; } else if (!scope) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f26bcbf..c558bb6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +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> PR tree-optimization/36765 diff --git a/gcc/testsuite/g++.dg/parse/constructor1.C b/gcc/testsuite/g++.dg/parse/constructor1.C index 3011862..8f222f8 100644 --- a/gcc/testsuite/g++.dg/parse/constructor1.C +++ b/gcc/testsuite/g++.dg/parse/constructor1.C @@ -1,4 +1,7 @@ +// { dg-do compile } +// { dg-options "-fshow-column" } + ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "" } - process_ (0) + process_ (0) // { dg-error "3: error: only constructors take base initializers" } { } diff --git a/gcc/testsuite/g++.dg/parse/error-column.C b/gcc/testsuite/g++.dg/parse/error-column.C new file mode 100644 index 0000000..812a499 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error-column.C @@ -0,0 +1,9 @@ +// { 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'" } +} diff --git a/gcc/testsuite/g++.dg/parse/error1.C b/gcc/testsuite/g++.dg/parse/error1.C index 8756df6..60e7d65 100644 --- a/gcc/testsuite/g++.dg/parse/error1.C +++ b/gcc/testsuite/g++.dg/parse/error1.C @@ -1,6 +1,7 @@ +// { dg-options "-fshow-column" } struct INCOMPLETE; template <int> struct X { 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" } diff --git a/gcc/testsuite/g++.dg/parse/error10.C b/gcc/testsuite/g++.dg/parse/error10.C index 242c421..6e46922 100644 --- a/gcc/testsuite/g++.dg/parse/error10.C +++ b/gcc/testsuite/g++.dg/parse/error10.C @@ -1,5 +1,5 @@ // PR c++/3478 -// { dg-options "" } +// { dg-options "-fshow-column" } template <typename> struct A { @@ -11,5 +11,9 @@ template <typename T> void foo() enum A<void>::E e1; typename A<T>::E e2; 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 } } diff --git a/gcc/testsuite/g++.dg/parse/error11.C b/gcc/testsuite/g++.dg/parse/error11.C index 0a8e2e4..f7093a8 100644 --- a/gcc/testsuite/g++.dg/parse/error11.C +++ b/gcc/testsuite/g++.dg/parse/error11.C @@ -1,4 +1,5 @@ // { dg-do compile } +// { dg-options "-fshow-column" }" // 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 // correctly to avoid cascaded errors. @@ -15,16 +16,16 @@ struct Foo }; 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(); // { 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(); // { 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 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; @@ -32,22 +33,28 @@ void func(void) { Foo<::B> f; // { dg-error "cannot begin|alternate spelling" } 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 // was no digraph or whitespaces in the middle, so we should not emit // the special error message. 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" } -// { dg-error "" "" { target *-*-* } 40 } -// { dg-error "" "" { target *-*-* } 41 } - +// { dg-error "6: error: missing template arguments before" "" { 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]; 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 // -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 } diff --git a/gcc/testsuite/g++.dg/parse/error12.C b/gcc/testsuite/g++.dg/parse/error12.C index ea04fd0..b002588 100644 --- a/gcc/testsuite/g++.dg/parse/error12.C +++ b/gcc/testsuite/g++.dg/parse/error12.C @@ -1,7 +1,7 @@ // { dg-do compile } // Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> // Make sure the error about '<:' can be turned into a warning -// { dg-options "-fpermissive" } +// { dg-options "-fpermissive -fshow-column" } struct B; @@ -9,4 +9,5 @@ template <class A> struct Foo {}; 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 } diff --git a/gcc/testsuite/g++.dg/parse/error13.C b/gcc/testsuite/g++.dg/parse/error13.C index 15642e3..94ddae8 100644 --- a/gcc/testsuite/g++.dg/parse/error13.C +++ b/gcc/testsuite/g++.dg/parse/error13.C @@ -1,13 +1,14 @@ +// { dg-options "-fshow-column" } // PR c++/13975 -public: // { dg-error "" } +public: // { dg-error "1: error: expected unqualified-id before 'public'" } int i; -protected: // { dg-error "" } +protected: // { dg-error "1: error: expected unqualified-id before 'protected'" } int j; -private: // { dg-error "" } +private: // { dg-error "1: error: expected unqualified-id before 'private'" } int k; diff --git a/gcc/testsuite/g++.dg/parse/error14.C b/gcc/testsuite/g++.dg/parse/error14.C index 4b23045..906b98f8 100644 --- a/gcc/testsuite/g++.dg/parse/error14.C +++ b/gcc/testsuite/g++.dg/parse/error14.C @@ -1,3 +1,4 @@ +// { dg-options "-fshow-column" } // PR c++/13970 struct X @@ -18,5 +19,5 @@ struct X 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" } diff --git a/gcc/testsuite/g++.dg/parse/error15.C b/gcc/testsuite/g++.dg/parse/error15.C index b343970..b65175c 100644 --- a/gcc/testsuite/g++.dg/parse/error15.C +++ b/gcc/testsuite/g++.dg/parse/error15.C @@ -1,5 +1,6 @@ // { dg-do compile } // 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. namespace N @@ -9,29 +10,29 @@ namespace N int K; } -N::A f2; // { dg-error "without an argument list" } -N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" } -N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" } -N::K f6; // { dg-error "in namespace 'N' does not name a type" } -typename N::A f7; // { dg-error "without an argument list|outside of template" } +N::A f2; // { dg-error "4: error: invalid use of template-name 'N::A' without an argument list" } +N::INVALID f3; // { dg-error "4: error: 'INVALID' in namespace 'N' 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 "4: error: 'K' in namespace 'N' does not name a type" } +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 { - N::A f2; // { dg-error "without an argument list" } - N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" } - N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" } - N::K f6; // { dg-error "in namespace 'N' does not name a type" } - typename N::A f7; // { dg-error "without an argument list|outside of template" } + N::A f2; // { dg-error "6: error: invalid use of template-name 'N::A' without an argument list" } + N::INVALID f3; // { dg-error "6: error: 'INVALID' in namespace 'N' 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 "6: error: 'K' in namespace 'N' does not name a type" } + 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> struct C { - N::A f2; // { dg-error "without an argument list" } - N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" } - N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" } - N::K f6; // { dg-error "in namespace 'N' does not name a type" } - typename N::A f7; // { 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 "6: error: 'INVALID' in namespace 'N' 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 "6: error: 'K' in namespace 'N' does not name a type" } + 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 } diff --git a/gcc/testsuite/g++.dg/parse/error16.C b/gcc/testsuite/g++.dg/parse/error16.C index 3dc58ad..ddc302c 100644 --- a/gcc/testsuite/g++.dg/parse/error16.C +++ b/gcc/testsuite/g++.dg/parse/error16.C @@ -1,8 +1,9 @@ +// { dg-options "-fshow-column" } // PR c++/16964 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'" } diff --git a/gcc/testsuite/g++.dg/parse/error17.C b/gcc/testsuite/g++.dg/parse/error17.C index 2a8f3f8..0e05217 100644 --- a/gcc/testsuite/g++.dg/parse/error17.C +++ b/gcc/testsuite/g++.dg/parse/error17.C @@ -1,8 +1,9 @@ +// { dg-options "-fshow-column" } // PR c++/16965 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> {}; -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" } diff --git a/gcc/testsuite/g++.dg/parse/error18.C b/gcc/testsuite/g++.dg/parse/error18.C index 363aae9..926af11 100644 --- a/gcc/testsuite/g++.dg/parse/error18.C +++ b/gcc/testsuite/g++.dg/parse/error18.C @@ -1,7 +1,8 @@ +// { dg-options "-fshow-column" } // PR c++/16002 void f() { - double Q *= 5.0; // { dg-error "initializer" } + double Q *= 5.0; // { dg-error "12: error: expected initializer before '..' token" } } diff --git a/gcc/testsuite/g++.dg/parse/error19.C b/gcc/testsuite/g++.dg/parse/error19.C index 24a66af..b22156a 100644 --- a/gcc/testsuite/g++.dg/parse/error19.C +++ b/gcc/testsuite/g++.dg/parse/error19.C @@ -1,7 +1,8 @@ +// { dg-options "-fshow-column -fmessage-length=0 -ansi -pedantic-errors -Wno-long-long " } // PR C++/17867 struct A -{ // { dg-error "candidate" } +{ // { dg-error "1: note: candidates are:" } A(int); }; @@ -9,5 +10,5 @@ const A& foo(); void bar() { - foo()=A(0); // { dg-error "A" } + foo()=A(0); // { dg-error "12: error: no match for 'operator='" } } diff --git a/gcc/testsuite/g++.dg/parse/error2.C b/gcc/testsuite/g++.dg/parse/error2.C index 8dd1e9d..075dcc2 100644 --- a/gcc/testsuite/g++.dg/parse/error2.C +++ b/gcc/testsuite/g++.dg/parse/error2.C @@ -1,4 +1,5 @@ // { dg-do compile } +// { dg-options "-fshow-column" } // Properly print CALL_EXPRs while dumping expressions double g; @@ -7,4 +8,8 @@ int func(double); template <int> 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 } } diff --git a/gcc/testsuite/g++.dg/parse/error20.C b/gcc/testsuite/g++.dg/parse/error20.C index ee7390a..9564fab 100644 --- a/gcc/testsuite/g++.dg/parse/error20.C +++ b/gcc/testsuite/g++.dg/parse/error20.C @@ -1,3 +1,4 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/17821 struct A { @@ -11,7 +12,7 @@ struct C { }; int main() { 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; } diff --git a/gcc/testsuite/g++.dg/parse/error21.C b/gcc/testsuite/g++.dg/parse/error21.C index 6e24ae2..f60bf2b 100644 --- a/gcc/testsuite/g++.dg/parse/error21.C +++ b/gcc/testsuite/g++.dg/parse/error21.C @@ -1,5 +1,5 @@ // PR c++/17393 -// { dg-options "-Wall" } +// { dg-options "-Wall -fshow-column" } struct A { }; @@ -7,6 +7,6 @@ void foo() { // Check that we do not complain about an unused // 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" } } diff --git a/gcc/testsuite/g++.dg/parse/error22.C b/gcc/testsuite/g++.dg/parse/error22.C index da3a62f..3014121 100644 --- a/gcc/testsuite/g++.dg/parse/error22.C +++ b/gcc/testsuite/g++.dg/parse/error22.C @@ -1,5 +1,6 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/15786 struct A { - void foo(bar* p); /* { dg-error "declared" } */ + void foo(bar* p); /* { dg-error "12: error: 'bar' has not been declared" } */ }; diff --git a/gcc/testsuite/g++.dg/parse/error23.C b/gcc/testsuite/g++.dg/parse/error23.C index 7d6fda2..21b2434 100644 --- a/gcc/testsuite/g++.dg/parse/error23.C +++ b/gcc/testsuite/g++.dg/parse/error23.C @@ -1,7 +1,9 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/19149 struct QChar { QChar( char 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" } }; diff --git a/gcc/testsuite/g++.dg/parse/error24.C b/gcc/testsuite/g++.dg/parse/error24.C index c072250..e341c34 100644 --- a/gcc/testsuite/g++.dg/parse/error24.C +++ b/gcc/testsuite/g++.dg/parse/error24.C @@ -1,7 +1,8 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/19395 struct A { - typedef int ::X; // { dg-error "" } + typedef int ::X; // { dg-error "17: error: typedef name may not be a nested-name-specifier" } }; diff --git a/gcc/testsuite/g++.dg/parse/error25.C b/gcc/testsuite/g++.dg/parse/error25.C index 360b40f..b5cb57e 100644 --- a/gcc/testsuite/g++.dg/parse/error25.C +++ b/gcc/testsuite/g++.dg/parse/error25.C @@ -1,4 +1,5 @@ // { dg-do compile } +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // Origin: Steven Bosscher <steven at gcc dot gnu dot org> // PR c++/17401: ICE with invalid pure specifier @@ -8,10 +9,10 @@ class foo { virtual void bar1 () = 0; - virtual void bar2 () = __null; // { dg-error "invalid pure specifier" } - virtual void bar3 () = 4; // { dg-error "invalid pure specifier" } - virtual void bar4 () = A::f; // { dg-error "invalid pure specifier" } - virtual void bar5 () = 0l; // { dg-error "invalid pure specifier" } - virtual void bar6 () = 00; // { dg-error "invalid pure specifier" } - virtual void bar7 () = 0x0; // { dg-error "invalid pure specifier" } + virtual void bar2 () = __null; // { dg-error "32: error: invalid pure specifier" } + virtual void bar3 () = 4; // { dg-error "27: error: invalid pure specifier" } + virtual void bar4 () = A::f; // { dg-error "27: error: invalid pure specifier" } + virtual void bar5 () = 0l; // { dg-error "28: error: invalid pure specifier" } + virtual void bar6 () = 00; // { dg-error "28: error: invalid pure specifier" } + virtual void bar7 () = 0x0; // { dg-error "29: error: invalid pure specifier" } }; diff --git a/gcc/testsuite/g++.dg/parse/error26.C b/gcc/testsuite/g++.dg/parse/error26.C index 6e2b897..81f7ba6 100644 --- a/gcc/testsuite/g++.dg/parse/error26.C +++ b/gcc/testsuite/g++.dg/parse/error26.C @@ -1,12 +1,12 @@ // PR c++/20148 -// { dg-options "" } +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } 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() { - if (({})); // { dg-error "\{\.\.\.\}" } + if (({})); // { dg-error "7: error: ISO C.. forbids|11: error: could not convert" } } diff --git a/gcc/testsuite/g++.dg/parse/error27.C b/gcc/testsuite/g++.dg/parse/error27.C index f52d3ce..f1fd537 100644 --- a/gcc/testsuite/g++.dg/parse/error27.C +++ b/gcc/testsuite/g++.dg/parse/error27.C @@ -1,7 +1,8 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/20152 -struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "previous definition" } -struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "previous definition" } -struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "" } -struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "" } +struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "24: error: previous definition of 'struct KrSelectionMode'" } +struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "52: error: previous definition of 'struct KrKDESelectionMode'" } +struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "8: error: redefinition of 'struct KrSelectionMode'" } +struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "8: error: redefinition of 'struct KrKDESelectionMode'" } KrKDESelectionMode krKDESelectionMode; diff --git a/gcc/testsuite/g++.dg/parse/error28.C b/gcc/testsuite/g++.dg/parse/error28.C index 046cc50..fd202a1 100644 --- a/gcc/testsuite/g++.dg/parse/error28.C +++ b/gcc/testsuite/g++.dg/parse/error28.C @@ -1,10 +1,11 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/21908 struct virt { virt () {} virt (int i) {} }; -struct der : public virtual virt { // { dg-error "der" } - der (int i) : virt(i) {} // { dg-error "der" } +struct der : public virtual virt { // { dg-error "34: note: der::der" } + der (int i) : virt(i) {} // { dg-error "13: note: candidates are: der" } }; struct top : public der { - // { dg-error "der\\(\\)" "" { target *-*-* } 9 } top () {} // { dg-bogus "der\\(const" } }; +// { dg-error "10: error: no matching function for call to 'der" "" { target *-*-* } 9 } diff --git a/gcc/testsuite/g++.dg/parse/error29.C b/gcc/testsuite/g++.dg/parse/error29.C index b50b275..fcd091b 100644 --- a/gcc/testsuite/g++.dg/parse/error29.C +++ b/gcc/testsuite/g++.dg/parse/error29.C @@ -1,3 +1,4 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/25637 struct A { @@ -6,7 +7,7 @@ struct A { void operator delete(void *); }; struct B { - friend void A::foo() {} // { dg-error "define" } - friend void A::operator delete(void*) {} // { dg-error "define" } - friend A::A() {} // { 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 "39: error: cannot define member function 'A::operator delete' within 'B'" } + friend A::A() {} // { dg-error "15: error: cannot define member function 'A::A' within 'B'" } }; diff --git a/gcc/testsuite/g++.dg/parse/error3.C b/gcc/testsuite/g++.dg/parse/error3.C index a052346..1f337e9 100644 --- a/gcc/testsuite/g++.dg/parse/error3.C +++ b/gcc/testsuite/g++.dg/parse/error3.C @@ -1,6 +1,19 @@ +// { dg-options "-fshow-column" } // PR c++/10779 static void InstantiateConstraint(const float&, unsigned, - void(*AddFunction)(const TYPE&,bool&, // { dg-error "" } + void(*AddFunction)(const TYPE&,bool&, 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 } } diff --git a/gcc/testsuite/g++.dg/parse/error30.C b/gcc/testsuite/g++.dg/parse/error30.C index 734a255..5c52d1e 100644 --- a/gcc/testsuite/g++.dg/parse/error30.C +++ b/gcc/testsuite/g++.dg/parse/error30.C @@ -1,5 +1,6 @@ // PR c++/30854 // { dg-do compile } +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } struct A { @@ -7,5 +8,5 @@ struct A A(int); }; -A a = -A(); // { dg-error "no match for.*operator-.*in.*-A\\(\\)" } -A b = -A(5); // { dg-error "no match for.*operator-.*in.*-A\\(5\\)" } +A a = -A(); // { dg-error "10: error: no match for.*operator-.*in.*-A\\(\\)" } +A b = -A(5); // { dg-error "11: error: no match for.*operator-.*in.*-A\\(5\\)" } diff --git a/gcc/testsuite/g++.dg/parse/error31.C b/gcc/testsuite/g++.dg/parse/error31.C index 5264f44..d354cc3 100644 --- a/gcc/testsuite/g++.dg/parse/error31.C +++ b/gcc/testsuite/g++.dg/parse/error31.C @@ -1,10 +1,12 @@ +// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" } // PR c++/32190 template<typename T> class foo{ }; int main() { 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 l; foo<int> m; diff --git a/gcc/testsuite/g++.dg/parse/error4.C b/gcc/testsuite/g++.dg/parse/error4.C index aa1bfad..790e5c9 100644 --- a/gcc/testsuite/g++.dg/parse/error4.C +++ b/gcc/testsuite/g++.dg/parse/error4.C @@ -1,7 +1,10 @@ // PR c++/12160 +// { dg-options "-fshow-column" } -struct X { - virtual void f(int, - itn, // { dg-error "declared" } +struct X { + virtual void f(int, + itn, int); -}; +}; + +// { dg-error "4: error: 'itn' has not been declared" "" { target *-*-* } { 6 } } diff --git a/gcc/testsuite/g++.dg/parse/error5.C b/gcc/testsuite/g++.dg/parse/error5.C index 81356ce..8c9a039 100644 --- a/gcc/testsuite/g++.dg/parse/error5.C +++ b/gcc/testsuite/g++.dg/parse/error5.C @@ -1,4 +1,19 @@ // 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 } } diff --git a/gcc/testsuite/g++.dg/parse/error6.C b/gcc/testsuite/g++.dg/parse/error6.C index 3a16669..cd1b6b8 100644 --- a/gcc/testsuite/g++.dg/parse/error6.C +++ b/gcc/testsuite/g++.dg/parse/error6.C @@ -1,6 +1,11 @@ // PR c++/10603 +// { dg-options "-fshow-column" } -int f(int not) { // { dg-error "!" } - return 1-not; // { dg-error "" } +int f(int not) { + return 1-not; } +// { dg-error "11: error: expected ',' or '...' before '!' token" "" { target *-*-* } { 4 } } + +// { dg-error "15: error: expected primary\\-expression before ';' token" "" { target *-*-* } { 5 } } + diff --git a/gcc/testsuite/g++.dg/parse/error7.C b/gcc/testsuite/g++.dg/parse/error7.C index 50e7f84..f71c9aa 100644 --- a/gcc/testsuite/g++.dg/parse/error7.C +++ b/gcc/testsuite/g++.dg/parse/error7.C @@ -1,4 +1,7 @@ // PR c++/12827 +// { dg-options "-fshow-column" } void f(int x - int y); // { dg-error "," } + int y); + +// { dg-error "8: error: expected ',' or '...' before 'int'" "" { target *-*-* } { 5 } } diff --git a/gcc/testsuite/g++.dg/parse/error8.C b/gcc/testsuite/g++.dg/parse/error8.C index 125f2e4..a399cfe 100644 --- a/gcc/testsuite/g++.dg/parse/error8.C +++ b/gcc/testsuite/g++.dg/parse/error8.C @@ -1,4 +1,10 @@ // 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 } } diff --git a/gcc/testsuite/g++.dg/parse/error9.C b/gcc/testsuite/g++.dg/parse/error9.C index aa9109f..c1be6979 100644 --- a/gcc/testsuite/g++.dg/parse/error9.C +++ b/gcc/testsuite/g++.dg/parse/error9.C @@ -1,5 +1,9 @@ // PR c++/12613 -// { dg-options "" } +// { dg-options "-fshow-column" } 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 } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C b/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C index 42a21fc..7fe07a2 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C @@ -1,8 +1,9 @@ // { dg-do assemble } +// { dg-options "-fshow-column" } 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; - }; // { dg-error "" } class definition cannot be a friend + }; // { dg-error "class definition may not be declared a friend" "" { target *-*-* } { 5 } } int y; }; diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp index c188824..7ca5b73 100644 --- a/gcc/testsuite/lib/g++.exp +++ b/gcc/testsuite/lib/g++.exp @@ -273,7 +273,6 @@ proc g++_target_compile { source dest type options } { } lappend options "additional_flags=[libio_include_flags]" - lappend options "additional_flags=-fno-show-column" lappend options "compiler=$GXX_UNDER_TEST" set options [concat $gpp_compile_options $options] |