re PR c++/31754 (Improve column number accuracy in error messages)
authorDodji Seketeli <dseketel@redhat.com>
Fri, 11 Jul 2008 12:54:22 +0000 (12:54 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Fri, 11 Jul 2008 12:54:22 +0000 (14:54 +0200)
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

41 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/constructor1.C
gcc/testsuite/g++.dg/parse/error-column.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/error1.C
gcc/testsuite/g++.dg/parse/error10.C
gcc/testsuite/g++.dg/parse/error11.C
gcc/testsuite/g++.dg/parse/error12.C
gcc/testsuite/g++.dg/parse/error13.C
gcc/testsuite/g++.dg/parse/error14.C
gcc/testsuite/g++.dg/parse/error15.C
gcc/testsuite/g++.dg/parse/error16.C
gcc/testsuite/g++.dg/parse/error17.C
gcc/testsuite/g++.dg/parse/error18.C
gcc/testsuite/g++.dg/parse/error19.C
gcc/testsuite/g++.dg/parse/error2.C
gcc/testsuite/g++.dg/parse/error20.C
gcc/testsuite/g++.dg/parse/error21.C
gcc/testsuite/g++.dg/parse/error22.C
gcc/testsuite/g++.dg/parse/error23.C
gcc/testsuite/g++.dg/parse/error24.C
gcc/testsuite/g++.dg/parse/error25.C
gcc/testsuite/g++.dg/parse/error26.C
gcc/testsuite/g++.dg/parse/error27.C
gcc/testsuite/g++.dg/parse/error28.C
gcc/testsuite/g++.dg/parse/error29.C
gcc/testsuite/g++.dg/parse/error3.C
gcc/testsuite/g++.dg/parse/error30.C
gcc/testsuite/g++.dg/parse/error31.C
gcc/testsuite/g++.dg/parse/error4.C
gcc/testsuite/g++.dg/parse/error5.C
gcc/testsuite/g++.dg/parse/error6.C
gcc/testsuite/g++.dg/parse/error7.C
gcc/testsuite/g++.dg/parse/error8.C
gcc/testsuite/g++.dg/parse/error9.C
gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
gcc/testsuite/lib/g++.exp

index 2143fe22808e3551fcd72358e8711c8bf3462f37..0161f2e8c10855cb0f202925c01cb14d7c48f4dc 100644 (file)
@@ -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
index ed6ae0e810a6163198d89e4f0ee29d4aa24be5ce..10eba33ea3eb9ab906819082f772b4dbe615d224 100644 (file)
@@ -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);
index 767d14d2a6199cb92f9b3d0d6a125da7f54ee077..2429bfc20a8c1f3f60a8ab71b28846888a67de8c 100644 (file)
@@ -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:
index b54c9d13e94fcd66b76bcc805c8730cdb37837f6..1378e5618dc783aabd4ecd1394704d5dca7d3c54 100644 (file)
@@ -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;
              }
          }
index fa65e9b28048a99a606cdc4f182723bef4b31d80..17b1e5dee498afba533b4d3670f275ca618d260d 100644 (file)
@@ -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)
index f26bcbf46e6d6bf9180f9da5353c1ad9fad470c2..c558bb675a89d1e6916f2987a3f4b4240c5081ad 100644 (file)
@@ -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
index 3011862ffbc9d409df056526615e1ff39dc2cfa6..8f222f80b10f293e29a7b5864f43b89ec2d6ab15 100644 (file)
@@ -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 (file)
index 0000000..812a499
--- /dev/null
@@ -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'" }
+}
index 8756df64592177270927048aa41e410f3bd5f1b9..60e7d6587b3b2b2e05b9fe198032324a8f97f529 100644 (file)
@@ -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" }
 
index 242c421c46323a05445c265de40fe4a6483e8f6a..6e46922a115188e91ad292bbd5289e994b92f666 100644 (file)
@@ -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 } }
index 0a8e2e4fc3d64b53ae589d11d4ff6071b008c659..f7093a8f987557e16705dffa4a2f6beb79a797c2 100644 (file)
@@ -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 }
index ea04fd06d11efbc2d366c8720e8f4598b7b8cdae..b0025885bf4e0a5d97c9cbdc2a459628385e6063 100644 (file)
@@ -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 }
index 15642e39ed7bb2d65f916a29f5e8bf2a469e7738..94ddae89705dfe6f3592dfe770b36c84b7c2b1c4 100644 (file)
@@ -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;
index 4b230453867488b45658c9cebed84abfc2f51b93..906b98f87e218ea492b4d8ea7d3a4891322f4881 100644 (file)
@@ -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" }
 
index b343970336f8d0033d5038245ca66a757249aefa..b65175cfc91cc17d4848f75e85e43648f2ce6558 100644 (file)
@@ -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 }
index 3dc58ad53c0684918439d1bc1e381a1392e82f1c..ddc302c7cd6aaa8d38cee7b5273b8717a8cb0300 100644 (file)
@@ -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'" }
index 2a8f3f829ca52f1e03d9f4b4dd56097fd3653868..0e05217c04ddcf971b760e57ac7b632423c51d43 100644 (file)
@@ -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" }
index 363aae99879840f918f9595bf56651423ebe7baa..926af11eb6a8f3ba106b20c4e864e5f1feb69e77 100644 (file)
@@ -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" }
 }
 
index 24a66affdaea8c176c95118ae2a6b80cf037b8ab..b22156a5d717f5594ea41b4e7ebfee0ab418f647 100644 (file)
@@ -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='" }
 }
index 8dd1e9d30da4a3ac80845eef7dae593a6b425901..075dcc2b0d15c86dc733c485fedf06090441d508 100644 (file)
@@ -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 } }
index ee7390a633c7716c3d6d45a1b69331d03a136af3..9564fab757b7ff89a8e9e2b1698fc7ff1957c9a9 100644 (file)
@@ -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;
 }
 
index 6e24ae2244ec7ab4753ad10df19208d941735271..f60bf2b9c54aed23d860a1ce55137fe86de2662c 100644 (file)
@@ -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" }
 }
 
index da3a62f788a6b1c6a8f50b3a7b5b89cc8bf56fff..30141219abc885e4250bcd23850d9a51af7be008 100644 (file)
@@ -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" } */
 };
index 7d6fda2cc4114fefce0da782fd7c6ebbbfb84a8d..21b24349608bb845714f1b3591819c408db88dc1 100644 (file)
@@ -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" }
 };
index c0722504271490234767c8d78b4068c92242fecc..e341c341291da3868f5bd7a34a06d726f7fee803 100644 (file)
@@ -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" }
 };
 
 
index 360b40f2e7effd8925e71e134c00aa2e1c4df694..b5cb57ee1f045de68f155929acddab39078a9347 100644 (file)
@@ -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" }
 };
index 6e2b897d92b5cce43c84c4f1cdcfe5a0e7b2e91c..81f7ba6d382f7362dc7143356b5ff9713cf5f02c 100644 (file)
@@ -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" }
 }
index f52d3cecce67b62105d0c4e466eb5ba66132b4bb..f1fd5376e5972e65c4bcdf638b07d65b6bd3e920 100644 (file)
@@ -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;
index 046cc501f0bac339200682fcec69ade1e7556da2..fd202a107672cb6b8527d3c1e9b58582c686d783 100644 (file)
@@ -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 }
index b50b275a9e622aba1cc7e4bb4f8228793f32a0c6..fcd091b0b6509c20256f8473b5b7653de982288b 100644 (file)
@@ -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'" }
 };
index a052346d8ca2d929e7c20a3ea27acb32031a20db..1f337e91cde4ac90a8ce95c922602f77db0afeff 100644 (file)
@@ -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 } }
index 734a2552cb4296367005f702a6422b6c3d450523..5c52d1ee67a706ddec09f2595f3966141a8fbe2b 100644 (file)
@@ -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\\)" }
index 5264f442b311764a77631732ab44928fda0f6b81..d354cc3e0dda8433cab6c54900802b06bf587a5d 100644 (file)
@@ -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;
index aa1bfad0dc9d09e5a7659eaf1e079d4508a3b10d..790e5c9a40b6d6097b0f5dc396147a5f431bbded 100644 (file)
@@ -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 } }
index 81356ced1b0da276841c8453566599555ab19897..8c9a039ac3ce65b15caf99af0d4bf0c70d2eeb60 100644 (file)
@@ -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 } }
 
index 3a1666995ebefb5b1aa64645839b466c300f069b..cd1b6b8cd33850c16cd00a7d2c235d2ed20a83a2 100644 (file)
@@ -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 } }
+
index 50e7f84dca510eb01cd7c4d3cf6025f07cd6148d..f71c9aa9fa0fdcccbf7022254dc6511e8aea6a5b 100644 (file)
@@ -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 } }
index 125f2e42c6b2cfa6b8c7af09e1a8db1b9295504c..a399cfe63f777bdd02aa10282551997d02642355 100644 (file)
@@ -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 } }
index aa9109fd22bf151d3e39aabb55739981dcc4d39e..c1be6979b47d7f96a044168dda09c7bd9e6d694e 100644 (file)
@@ -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 } }
index 42a21fcb0728d7e24326f8013af1038a962d6c08..7fe07a2df0ed93e2d92c7e5c100d94c6dd2c54c3 100644 (file)
@@ -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;
 };
index c188824b841512cd7936078519a3c14da84d03a3..7ca5b7397818d77df8c6f855776f1666389323f1 100644 (file)
@@ -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]