This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] PR 31754/C++ - make -fshow-column produce more accurate column numbers


Hello,

I have not heard anything from the patch I sent earlier at http://gcc.gnu.org/ml/gcc-patches/2008-06/msg01677.html.

So I went forward and wrote a second patch that stacks on top of that first one I sent earlier.

The second patch goes forward in making all the calls to error() in gcc/cp/parser.c carry somewhat more precise location information. That eventually produces error message with more accurate column information, when the parsed tokens context is still available to the parser.

As usual, the patch also updates some relevant tests of the testsuite to catch future regressions that might happen around this column number thing.

I have also refreshed the patches against "current" trunk.

Cheers,

Dodji.
gcc/cp/ChangeLog:
2008-06-30 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.

gcc/testsuite/ChangeLog:
2008-06-30 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.


diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d090d8f..afea188 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4632,13 +4632,15 @@ extern void finish_template_decl		(tree);
 extern tree finish_template_type		(tree, tree, int);
 extern tree finish_base_specifier		(tree, tree, bool);
 extern void finish_member_declaration		(tree);
-extern void qualified_name_lookup_error		(tree, tree, tree);
+extern void qualified_name_lookup_error		(tree, tree, tree,
+						 location_t);
 extern void check_template_keyword		(tree);
 extern tree finish_id_expression		(tree, tree, tree,
 						 cp_id_kind *,
 						 bool, bool, bool *,
 						 bool, bool, bool, bool,
-						 const char **);
+						 const char **,
+                                                 location_t);
 extern tree finish_typeof			(tree);
 extern tree finish_offsetof			(tree);
 extern void finish_decl_cleanup			(tree, tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7d530f5..184b9ec 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1585,7 +1585,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
@@ -1894,15 +1894,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
@@ -1938,7 +1938,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
@@ -1960,7 +1960,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
@@ -1982,7 +1982,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
@@ -1994,7 +1994,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
@@ -2020,7 +2020,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 *);
 
@@ -2069,7 +2069,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;
 	}
@@ -2092,33 +2092,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
@@ -2139,7 +2140,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;
 
@@ -2152,10 +2154,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)
 	{
@@ -2175,7 +2178,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]);
 	}
     }
 }
@@ -2291,13 +2294,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.  */
@@ -2382,6 +2387,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,
@@ -2405,7 +2411,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);
@@ -2693,7 +2700,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)
@@ -2701,7 +2709,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);
@@ -2919,7 +2927,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));
@@ -3098,7 +3107,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;
@@ -3196,7 +3205,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:
@@ -3207,8 +3217,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;
 	      }
@@ -3265,7 +3276,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.  */
@@ -3365,6 +3377,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.  */
@@ -3377,6 +3390,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
@@ -3400,7 +3414,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)
@@ -3447,8 +3462,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;
 		  }
 	      }
@@ -3462,7 +3477,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;
@@ -3746,7 +3762,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);
@@ -3847,8 +3864,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;
 	  }
@@ -3861,8 +3878,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));
       }
@@ -4066,20 +4083,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;
@@ -4731,7 +4751,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;
@@ -4845,7 +4866,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;
@@ -4877,7 +4899,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
@@ -4933,6 +4955,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,
@@ -4960,7 +4983,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
@@ -5514,18 +5537,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);
 	}
@@ -5702,6 +5728,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
@@ -5717,8 +5744,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;
 		}
 	    }
@@ -6445,6 +6472,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
@@ -6460,6 +6488,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,
@@ -6467,10 +6496,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:
@@ -6482,7 +6511,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:
@@ -6844,7 +6874,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;
 
@@ -6855,7 +6886,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:
@@ -6973,7 +7004,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);
 	    }
 	}
 
@@ -7457,7 +7488,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)
@@ -7465,10 +7496,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, "%<;%>");
@@ -7478,14 +7509,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 ();
@@ -7516,7 +7547,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.  */
@@ -7877,7 +7908,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))
@@ -8010,7 +8041,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
 	    {
@@ -8106,6 +8141,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);
@@ -8122,6 +8158,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)
 	{
@@ -8198,15 +8239,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:
@@ -8215,7 +8258,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.  */
@@ -8251,7 +8295,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
@@ -8311,12 +8354,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.
@@ -8372,7 +8416,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)
@@ -8384,7 +8429,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;
@@ -8538,6 +8583,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%>"))
@@ -8567,6 +8613,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,
@@ -8589,7 +8636,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
@@ -8609,7 +8657,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
@@ -8852,17 +8901,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. */
@@ -8876,8 +8928,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;
             }
 
@@ -8924,11 +8976,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
@@ -8970,11 +9024,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.  */
@@ -9491,6 +9548,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.  */     
@@ -9499,10 +9557,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);
@@ -9596,10 +9655,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 ();
@@ -9667,6 +9727,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,
@@ -9687,7 +9750,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);
@@ -9697,10 +9761,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 ();
@@ -9749,7 +9816,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
@@ -9797,6 +9864,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,
@@ -9823,6 +9891,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))
@@ -9837,15 +9906,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;
 	    }
 	}
@@ -9918,7 +9990,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 ();
@@ -9972,6 +10045,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.  */
@@ -10031,7 +10105,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.  */
@@ -10075,7 +10150,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.  */
@@ -10221,7 +10297,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
@@ -10268,6 +10344,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,
@@ -10290,7 +10367,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");
@@ -10542,6 +10620,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 `<'.  */
@@ -10556,7 +10636,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);
@@ -10881,7 +10961,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;
 
@@ -11094,12 +11174,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)))
@@ -11116,7 +11197,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
@@ -11165,6 +11246,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))
@@ -11234,6 +11316,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);
@@ -11255,6 +11338,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)
@@ -11267,7 +11351,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)
 	{
@@ -11279,7 +11364,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.  */
@@ -11315,7 +11401,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;
 	    }
 
@@ -11415,7 +11502,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);
 	}
@@ -11618,6 +11706,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)
@@ -11646,13 +11736,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;
     }
@@ -11767,6 +11858,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.  */
@@ -11777,7 +11870,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))
@@ -11892,6 +11985,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,
@@ -11916,7 +12010,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 ())
@@ -11932,9 +12027,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 ())
@@ -12184,7 +12283,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;
@@ -12218,6 +12318,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,
@@ -12232,7 +12333,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)
@@ -12249,8 +12351,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
@@ -12278,9 +12382,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;
 
@@ -12405,6 +12512,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
@@ -12413,7 +12521,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,
@@ -12814,7 +12923,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;
 		}
 	    }
@@ -12836,6 +12946,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);
@@ -12854,6 +12965,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;
@@ -12923,7 +13035,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;
@@ -12949,7 +13062,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,
@@ -13108,6 +13222,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,
@@ -13122,7 +13237,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
@@ -13197,7 +13312,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
@@ -13307,6 +13422,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);
@@ -13326,6 +13442,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,
@@ -13369,7 +13490,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.
@@ -13596,7 +13717,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.
@@ -13665,6 +13786,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,
@@ -13823,7 +13945,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;
 
@@ -13860,8 +13982,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)
 	{
@@ -13869,7 +13994,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;
 	    }
 	}
@@ -13885,11 +14012,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;
 	}
@@ -14279,10 +14407,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))
 		{
@@ -14573,7 +14703,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
@@ -14606,6 +14736,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,
@@ -14616,6 +14747,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
@@ -14679,6 +14811,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,
@@ -14730,7 +14863,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;
 	}
@@ -14742,10 +14876,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;
@@ -14758,7 +14895,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;
 	}
@@ -14769,7 +14907,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.  */
@@ -14781,7 +14920,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.  */
@@ -14796,7 +14936,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
@@ -14877,8 +15018,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;
     }
@@ -15033,7 +15176,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.  */
@@ -15097,6 +15242,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,
@@ -15142,7 +15288,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 {
@@ -15156,8 +15303,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);
@@ -15180,7 +15327,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
@@ -15308,6 +15457,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
@@ -15332,7 +15482,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,
@@ -15423,7 +15574,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;
     }
 
@@ -15625,11 +15776,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);
     }
 
@@ -16330,7 +16484,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;
@@ -16511,7 +16666,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;
@@ -16541,14 +16697,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
@@ -16601,7 +16758,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;
 
@@ -16651,7 +16809,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:
@@ -16659,7 +16818,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;
@@ -16676,7 +16835,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:
@@ -16684,7 +16844,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
@@ -16699,7 +16859,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;
 }
 
@@ -16957,12 +17117,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.  */
@@ -16971,7 +17133,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)
 	{
@@ -17030,8 +17193,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;
 
@@ -17043,7 +17208,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;
     }
@@ -17052,7 +17218,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);
@@ -17099,6 +17265,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,
@@ -17111,7 +17278,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);
 	}
@@ -17175,6 +17342,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.  */
@@ -17186,6 +17354,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,
@@ -17196,7 +17365,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;
     }
 
@@ -17259,7 +17429,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;
       }
     }
@@ -17461,9 +17632,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
@@ -17784,14 +17955,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)
@@ -17803,7 +17975,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;
     }
 
@@ -18133,7 +18305,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;
@@ -18142,7 +18314,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.
@@ -18159,8 +18331,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.  */
@@ -18412,7 +18585,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);
     }
 
@@ -18545,15 +18719,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;
     }
 
@@ -18868,7 +19045,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;
     }
 
@@ -19198,7 +19375,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;
     }
 
@@ -19334,7 +19512,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);
     }
 }
@@ -19465,7 +19644,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);
     }
 
@@ -19549,14 +19729,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;
       }
 }
@@ -19579,10 +19760,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,
@@ -19591,9 +19774,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);
@@ -19643,7 +19826,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;
@@ -19668,11 +19851,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;
@@ -19684,7 +19868,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;
@@ -19730,7 +19914,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;
@@ -19742,7 +19926,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;
 
@@ -19757,7 +19941,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;
@@ -19770,11 +19954,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;
@@ -19785,7 +19970,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;
 
@@ -19800,7 +19986,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;
@@ -19813,11 +20000,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;
@@ -19894,7 +20083,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;
 
@@ -19942,18 +20131,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;
 
@@ -19963,7 +20154,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;
 
@@ -19980,11 +20171,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;
@@ -20001,6 +20193,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))
     {
@@ -20011,13 +20204,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:
@@ -20030,7 +20225,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:
@@ -20039,7 +20235,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:
@@ -20048,15 +20244,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:
@@ -20069,7 +20267,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:
@@ -20078,7 +20277,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:
@@ -20091,7 +20291,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:
@@ -21177,10 +21377,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)
@@ -21213,7 +21414,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:
@@ -21223,8 +21425,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;
@@ -21238,8 +21440,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;
@@ -21280,8 +21482,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
       return true;
 
     case PRAGMA_OMP_SECTION:
-      error ("%<#pragma omp section%> may only be used in "
-	     "%<#pragma omp sections%> construct");
+      error ("%H%<#pragma omp section%> may only be used in "
+	     "%<#pragma omp sections%> construct", &pragma_tok->location);
       break;
 
     default:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f24b6ff..f95ae07 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -9750,7 +9750,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;
     }
 
@@ -9759,7 +9759,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
@@ -10491,7 +10491,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);
 	  }
@@ -10938,7 +10938,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)
@@ -11467,7 +11468,8 @@ tsubst_copy_and_build (tree t,
 	      }
 	    else
 	      {
-		qualified_name_lookup_error (object_type, tmpl, member);
+		qualified_name_lookup_error (object_type, tmpl, member,
+					     input_location);
 		return error_mark_node;
 	      }
 	  }
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2400aeb..4ac585b 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2482,29 +2482,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
@@ -2569,7 +2573,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,
@@ -2582,7 +2585,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;
@@ -2612,7 +2616,7 @@ finish_id_expression (tree id_expression,
 	      /* If the qualifying type is non-dependent (and the name
 		 does not name a conversion operator to a dependent
 		 type), issue an error.  */
-	      qualified_name_lookup_error (scope, id_expression, decl);
+	      qualified_name_lookup_error (scope, id_expression, decl, location);
 	      return error_mark_node;
 	    }
 	  else if (!scope)
diff --git a/gcc/testsuite/g++.dg/parse/constructor1.C b/gcc/testsuite/g++.dg/parse/constructor1.C
index 3011862..8f222f8 100644
--- a/gcc/testsuite/g++.dg/parse/constructor1.C
+++ b/gcc/testsuite/g++.dg/parse/constructor1.C
@@ -1,4 +1,7 @@
+// { dg-do compile }
+// { dg-options "-fshow-column" }
+
 ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "" }
-  process_ (0)
+  process_ (0) // { dg-error "3: error: only constructors take base initializers" }
 {
 }
diff --git a/gcc/testsuite/g++.dg/parse/error-column.C b/gcc/testsuite/g++.dg/parse/error-column.C
new file mode 100644
index 0000000..812a499
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/error-column.C
@@ -0,0 +1,9 @@
+// { dg-do compile }
+// Make sure column information is correctly shown in error reporting
+// { dg-options "-fshow-column" }
+
+
+void foo ()
+{
+  cout << "blah"; // { dg-error "3: error: 'cout'" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/error1.C b/gcc/testsuite/g++.dg/parse/error1.C
index 8756df6..60e7d65 100644
--- a/gcc/testsuite/g++.dg/parse/error1.C
+++ b/gcc/testsuite/g++.dg/parse/error1.C
@@ -1,6 +1,7 @@
+// { dg-options "-fshow-column" }
 struct INCOMPLETE;
 template <int> struct X {
     static INCOMPLETE value;
 };
-template <> INCOMPLETE X<1>::value = 0; // { dg-error "" }
+template <> INCOMPLETE X<1>::value = 0; // { dg-error "30: error: variable 'INCOMPLETE X<1>::value' has initializer but incomplete type" }
 
diff --git a/gcc/testsuite/g++.dg/parse/error10.C b/gcc/testsuite/g++.dg/parse/error10.C
index 242c421..6e46922 100644
--- a/gcc/testsuite/g++.dg/parse/error10.C
+++ b/gcc/testsuite/g++.dg/parse/error10.C
@@ -1,5 +1,5 @@
 // PR c++/3478
-// { dg-options "" }
+// { dg-options "-fshow-column" }
 
 template <typename> struct A
 {
@@ -11,5 +11,9 @@ template <typename T> void foo()
   enum          A<void>::E e1;
   typename      A<T>::E    e2;
   enum          A<T>::E    e3;
-  enum typename A<T>::E    e4; // { dg-error "" }
+  enum typename A<T>::E    e4;
 }
+
+// Here, columns nums are not very accurate either. Still acceptable though
+// { dg-error "30: error: invalid type in declaration before ';' token" "" { target *-*-* } { 14 } }
+// { dg-error "30: error: two or more data types in declaration of 'e4'" "" { target *-*-* } { 14 } }
diff --git a/gcc/testsuite/g++.dg/parse/error11.C b/gcc/testsuite/g++.dg/parse/error11.C
index 0a8e2e4..f7093a8 100644
--- a/gcc/testsuite/g++.dg/parse/error11.C
+++ b/gcc/testsuite/g++.dg/parse/error11.C
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-options "-fshow-column" }"
 // Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
 // Try to find out when the digraph '<:' is used as a mistake, and parse it
 //  correctly to avoid cascaded errors.
@@ -15,16 +16,16 @@ struct Foo
   };
 
   void method(void) {
-    typename Foo<::B>::template Nested<::B> n; // { dg-error "cannot begin|alternate spelling" }
+    typename Foo<::B>::template Nested<::B> n; // { dg-error "17: error: '<::' cannot begin|17: note: '<:' is an alternate spelling|39: error: '<::' cannot begin|39: note: '<:' is an alternate" }
     n.template Nested<B>::method();
-    n.template Nested<::B>::method();  // { dg-error "cannot begin|alternate spelling" }
+    n.template Nested<::B>::method();  // { dg-error "22: error: '<::' cannot begin|22: note: '<:' is an alternate" }
     Nested<B>::method();
-    Nested<::B>::method(); // { dg-error "cannot begin|alternate spelling" }
+    Nested<::B>::method(); // { dg-error "11: error: '<::' cannot begin|11: note: '<:' is an alternate" }
   }
 };
 
 template <int N> struct Foo2 {};
-template struct Foo2<::B>;  // { dg-error "cannot begin|alternate spelling|type/value mismatch|expected a constant" }
+template struct Foo2<::B>;  // { dg-error "21: error: '<::' cannot begin|21: note: '<:' is an alternate|25: error: type/value mismatch|25: error:   expected a constant" }
 
 int value = 0;
 
@@ -32,22 +33,28 @@ void func(void)
 {
   Foo<::B> f; // { dg-error "cannot begin|alternate spelling" }
   f.Foo<B>::method();
-  f.Foo<::B>::method(); // { dg-error "cannot begin|alternate spelling" }
+  f.Foo<::B>::method(); // { dg-error "8: error|8: note" }
 
   // Check cases where we the token sequence is the correct one, but there
   //  was no digraph or whitespaces in the middle, so we should not emit
   //  the special error message.
   Foo<: :B> k2;     // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
   Foo[:B> k1;       // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" } 
-// { dg-error "" "" { target *-*-* } 40 }
-// { dg-error "" "" { target *-*-* } 41 }
-
+// { dg-error "6: error: missing template arguments before" "" { target *-*-* } { 41 } }
+// { dg-error "9: error: expected primary-expression before ':' token" "" { target *-*-* } 41 }
+// { dg-error "9: error: expected '\]' before ':' token" "" { target *-*-* } 41 }
+// { dg-error "9: error: expected ';' before ':' token" "" { target *-*-* } 41 }
+// { dg-error "6: error: missing template arguments before" "" { target *-*-* } 42 }
+// { dg-error "7: error: expected primary-expression before ':' token" "" { target *-*-* } 42 }
+// { dg-error "7: error: expected '\]' before ':' token" "" { target *-*-* } 42 }
+// { dg-error "7: error: expected ';' before ':' token" "" { target *-*-* } 42 }
+//
   int Foo[2];
   Foo[::value] = 0;
 }
 
-template struct Foo<::B>; // { dg-error "cannot begin|alternate spelling" }
+template struct Foo<::B>; // { dg-error "20: error: '<::' cannot begin|20: note: '<:' is an alternate" }
 
 // On the first error message, an additional note about the use of 
 //  -fpermissive should be present
-// { dg-error "-fpermissive" "-fpermissive" { target *-*-* } 18 }
+// { dg-error "17: note: \\(if you use '-fpermissive' G\\+\\+ will accept your code\\)" "-fpermissive" { target *-*-* } 19 }
diff --git a/gcc/testsuite/g++.dg/parse/error12.C b/gcc/testsuite/g++.dg/parse/error12.C
index ea04fd0..b002588 100644
--- a/gcc/testsuite/g++.dg/parse/error12.C
+++ b/gcc/testsuite/g++.dg/parse/error12.C
@@ -1,7 +1,7 @@
 // { dg-do compile }
 // Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
 // Make sure the error about '<:' can be turned into a warning
-// { dg-options "-fpermissive" }
+// { dg-options "-fpermissive -fshow-column" }
 
 struct B;
 
@@ -9,4 +9,5 @@ template <class A>
 struct Foo {};
 
 Foo<::B> foo;   // { dg-bogus "error" "error in place of warning" }
-// { dg-error "" "" { target *-*-* } 11 }
+// { dg-error "4: warning: '<::' cannot begin a template-argument list" "warning <::" { target *-*-* } 11 }
+// { dg-error "4: note: '<:' is an alternate spelling for '.'. Insert whitespace between '<' and '::'" "note <:" { target *-*-* } 11 }
diff --git a/gcc/testsuite/g++.dg/parse/error13.C b/gcc/testsuite/g++.dg/parse/error13.C
index 15642e3..94ddae8 100644
--- a/gcc/testsuite/g++.dg/parse/error13.C
+++ b/gcc/testsuite/g++.dg/parse/error13.C
@@ -1,13 +1,14 @@
+// { dg-options "-fshow-column" }
 // PR c++/13975
 
-public: // { dg-error "" }
+public: // { dg-error "1: error: expected unqualified-id before 'public'" }
 
 int i;
 
-protected: // { dg-error "" }
+protected: // { dg-error "1: error: expected unqualified-id before 'protected'" }
 
 int j;
 
-private: // { dg-error "" }
+private: // { dg-error "1: error: expected unqualified-id before 'private'" }
 
 int k;
diff --git a/gcc/testsuite/g++.dg/parse/error14.C b/gcc/testsuite/g++.dg/parse/error14.C
index 4b23045..906b98f 100644
--- a/gcc/testsuite/g++.dg/parse/error14.C
+++ b/gcc/testsuite/g++.dg/parse/error14.C
@@ -1,3 +1,4 @@
+// { dg-options "-fshow-column" }
 // PR c++/13970
 
 struct X
@@ -18,5 +19,5 @@ struct X
         Zinc<int>( //);
 		  //    }
 
-}; // { dg-error "" }
+}; // { dg-error "2: error: expected '.' at end of input|1: error: expected primary-expression before '.' token|1: error: expected ';' before '.' token|1: error: expected unqualified-id at end of input" }
 
diff --git a/gcc/testsuite/g++.dg/parse/error15.C b/gcc/testsuite/g++.dg/parse/error15.C
index b343970..b65175c 100644
--- a/gcc/testsuite/g++.dg/parse/error15.C
+++ b/gcc/testsuite/g++.dg/parse/error15.C
@@ -1,5 +1,6 @@
 // { dg-do compile }
 // Contributed by Volker Reichelt <reichelt at gcc dot gnu dot org> 
+// { dg-options "-fshow-column" }
 // PR c++/14008: Improve diagnostic on invalid types in declarators.
 
 namespace N
@@ -9,29 +10,29 @@ namespace N
   int K;
 }
 
-N::A f2;              // { dg-error "without an argument list" }
-N::INVALID f3;        // { dg-error "in namespace 'N' does not name a type" }
-N::C::INVALID f4;     // { dg-error "in class 'N::C' does not name a type" }
-N::K f6;              // { dg-error "in namespace 'N' does not name a type" }
-typename N::A f7;     // { dg-error "without an argument list|outside of template" }
+N::A f2;              // { dg-error "4: error: invalid use of template-name 'N::A' without an argument list" }
+N::INVALID f3;        // { dg-error "4: error: 'INVALID' in namespace 'N' does not name a type" }
+N::C::INVALID f4;     // { dg-error "7: error: 'INVALID' in class 'N::C' does not name a type" }
+N::K f6;              // { dg-error "4: error: 'K' in namespace 'N' does not name a type" }
+typename N::A f7;     // { dg-error "1: error: using 'typename' outside of template|13: error: invalid use of template-name 'N::A' without an argument list|17: error: invalid type in declaration before ';' token" }
 
 struct B
 {
-  N::A f2;            // { dg-error "without an argument list" }
-  N::INVALID f3;      // { dg-error "in namespace 'N' does not name a type" }
-  N::C::INVALID f4;   // { dg-error "in class 'N::C' does not name a type" }
-  N::K f6;            // { dg-error "in namespace 'N' does not name a type" }
-  typename N::A f7;   // { dg-error "without an argument list|outside of template" }
+  N::A f2;            // { dg-error "6: error: invalid use of template-name 'N::A' without an argument list" }
+  N::INVALID f3;      // { dg-error "6: error: 'INVALID' in namespace 'N' does not name a type" }
+  N::C::INVALID f4;   // { dg-error "9: error: 'INVALID' in class 'N::C' does not name a type" }
+  N::K f6;            // { dg-error "6: error: 'K' in namespace 'N' does not name a type" }
+  typename N::A f7;   // { dg-error "3: error: using 'typename' outside of template|15: error: invalid use of template-name 'N::A' without an argument list" }
 };
 
 template <int>
 struct C
 {
-  N::A f2;            // { dg-error "without an argument list" }
-  N::INVALID f3;      // { dg-error "in namespace 'N' does not name a type" }
-  N::C::INVALID f4;   // { dg-error "in class 'N::C' does not name a type" }
-  N::K f6;            // { dg-error "in namespace 'N' does not name a type" }
-  typename N::A f7;   // { dg-error "without an argument list" }
+  N::A f2;            // { dg-error "6: error: invalid use of template-name 'N::A' without an argument list" }
+  N::INVALID f3;      // { dg-error "6: error: 'INVALID' in namespace 'N' does not name a type" }
+  N::C::INVALID f4;   // { dg-error "9: error: 'INVALID' in class 'N::C' does not name a type" }
+  N::K f6;            // { dg-error "6: error: 'K' in namespace 'N' does not name a type" }
+  typename N::A f7;   // { dg-error "15: error: invalid use of template-name 'N::A' without an argument list" }
 };
 
-// { dg-bogus "" "bogus excess errors in declaration" { xfail *-*-* } 16 }
+// { dg-bogus "bogus excess errors in declaration" "bogus excess errors in declaration" { xfail *-*-* } 17 }
diff --git a/gcc/testsuite/g++.dg/parse/error16.C b/gcc/testsuite/g++.dg/parse/error16.C
index 3dc58ad..ddc302c 100644
--- a/gcc/testsuite/g++.dg/parse/error16.C
+++ b/gcc/testsuite/g++.dg/parse/error16.C
@@ -1,8 +1,9 @@
+// { dg-options "-fshow-column" }
 // PR c++/16964
 
 struct A
 {
-  struct B {}; // { dg-error "previous" }
+  struct B {}; // { dg-error "12: error: previous definition of 'struct A::B'" }
 };
 
-struct A::B{}; // { dg-error "redefinition" }
+struct A::B{}; // { dg-error "11: error: redefinition of 'struct A::B'" }
diff --git a/gcc/testsuite/g++.dg/parse/error17.C b/gcc/testsuite/g++.dg/parse/error17.C
index 2a8f3f8..0e05217 100644
--- a/gcc/testsuite/g++.dg/parse/error17.C
+++ b/gcc/testsuite/g++.dg/parse/error17.C
@@ -1,8 +1,9 @@
+// { dg-options "-fshow-column" }
 // PR c++/16965
 
 template <typename T> struct B { 
-  static int Bar(T); // { dg-error "" }
+  static int Bar(T); // { dg-error "19: error: candidates are: |19: error:  " }
 }; 
 struct D : B<int>, B<char> {}; 
  
-int i2 = D::Bar(2); // { dg-error "" }
+int i2 = D::Bar(2); // { dg-error "13: error: reference to 'Bar' is ambiguous|10: error: reference to 'Bar' is ambiguous" }
diff --git a/gcc/testsuite/g++.dg/parse/error18.C b/gcc/testsuite/g++.dg/parse/error18.C
index 363aae9..926af11 100644
--- a/gcc/testsuite/g++.dg/parse/error18.C
+++ b/gcc/testsuite/g++.dg/parse/error18.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column" }
 // PR c++/16002
 
 void f()
 {
-  double Q *= 5.0; // { dg-error "initializer" }
+  double Q *= 5.0; // { dg-error "12: error: expected initializer before '..' token" }
 }
 
diff --git a/gcc/testsuite/g++.dg/parse/error19.C b/gcc/testsuite/g++.dg/parse/error19.C
index 24a66af..b22156a 100644
--- a/gcc/testsuite/g++.dg/parse/error19.C
+++ b/gcc/testsuite/g++.dg/parse/error19.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column -fmessage-length=0   -ansi -pedantic-errors -Wno-long-long " }
 // PR C++/17867
 
 struct A
-{  // { dg-error "candidate" }
+{  // { dg-error "1: note: candidates are:" }
   A(int);
 };
 
@@ -9,5 +10,5 @@ const A& foo();
 
 void bar()
 {
-  foo()=A(0); // { dg-error "A" }
+  foo()=A(0); // { dg-error "12: error: no match for 'operator='" }
 }
diff --git a/gcc/testsuite/g++.dg/parse/error2.C b/gcc/testsuite/g++.dg/parse/error2.C
index 8dd1e9d..075dcc2 100644
--- a/gcc/testsuite/g++.dg/parse/error2.C
+++ b/gcc/testsuite/g++.dg/parse/error2.C
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-options "-fshow-column" }
 // Properly print CALL_EXPRs while dumping expressions
 
 double g;
@@ -7,4 +8,8 @@ int func(double);
 template <int>
 struct Foo {};
 
-Foo<func(g)> f; // { dg-error "" "func(g)" }
+Foo<func(g)> f; // { dg-error "5: error: 'int func.double.' cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
+// { dg-error "10: error: 'g' cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
+// { dg-error "11: error: a function call cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
+// { dg-error "12: error: template argument 1 is invalid" "" { target *-*-* } { 11 } }
+// { dg-error "15: error: invalid type in declaration before ';' token" "" { target *-*-* } { 11 } }
diff --git a/gcc/testsuite/g++.dg/parse/error20.C b/gcc/testsuite/g++.dg/parse/error20.C
index ee7390a..9564fab 100644
--- a/gcc/testsuite/g++.dg/parse/error20.C
+++ b/gcc/testsuite/g++.dg/parse/error20.C
@@ -1,3 +1,4 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/17821
 
 struct A {
@@ -11,7 +12,7 @@ struct C {
 };
 int main() {
   C c;
-  A(c.p.i); // { dg-error "member.*non-class" }
+  A(c.p.i); // { dg-error "9: error: request for member 'i' in 'c.C::p', which is of non-class type 'B" }
   return 0;
 }
 
diff --git a/gcc/testsuite/g++.dg/parse/error21.C b/gcc/testsuite/g++.dg/parse/error21.C
index 6e24ae2..f60bf2b 100644
--- a/gcc/testsuite/g++.dg/parse/error21.C
+++ b/gcc/testsuite/g++.dg/parse/error21.C
@@ -1,5 +1,5 @@
 // PR c++/17393
-// { dg-options "-Wall" }
+// { dg-options "-Wall -fshow-column" }
 
 struct A { };
 
@@ -7,6 +7,6 @@ void foo()
 {
   // Check that we do not complain about an unused
   // compiler-generated variable.
-  A& = a; // { dg-error "token|declarator|not declared" }
+  A& = a; // { dg-error "6: error: expected unqualified-id before '=' token|8: error: 'a' was not declared in this scope" }
 }
 
diff --git a/gcc/testsuite/g++.dg/parse/error22.C b/gcc/testsuite/g++.dg/parse/error22.C
index da3a62f..3014121 100644
--- a/gcc/testsuite/g++.dg/parse/error22.C
+++ b/gcc/testsuite/g++.dg/parse/error22.C
@@ -1,5 +1,6 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/15786
 
 struct A {
-  void foo(bar* p); /* { dg-error "declared" } */
+  void foo(bar* p); /* { dg-error "12: error: 'bar' has not been declared" } */
 };
diff --git a/gcc/testsuite/g++.dg/parse/error23.C b/gcc/testsuite/g++.dg/parse/error23.C
index 7d6fda2..21b2434 100644
--- a/gcc/testsuite/g++.dg/parse/error23.C
+++ b/gcc/testsuite/g++.dg/parse/error23.C
@@ -1,7 +1,9 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/19149
 
 struct QChar {
   QChar( char c );
   QChar( const QChar& c );
-  static const ; // { dg-error "" }
+  //following column number is not accurate enough but will make it for now
+  static const ; // { dg-error "10: error: declaration does not declare anything" }
 };
diff --git a/gcc/testsuite/g++.dg/parse/error24.C b/gcc/testsuite/g++.dg/parse/error24.C
index c072250..e341c34 100644
--- a/gcc/testsuite/g++.dg/parse/error24.C
+++ b/gcc/testsuite/g++.dg/parse/error24.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/19395
 
 struct A {
-  typedef int ::X; // { dg-error "" }
+  typedef int ::X; // { dg-error "17: error: typedef name may not be a nested-name-specifier" }
 };
 
 
diff --git a/gcc/testsuite/g++.dg/parse/error25.C b/gcc/testsuite/g++.dg/parse/error25.C
index 360b40f..b5cb57e 100644
--- a/gcc/testsuite/g++.dg/parse/error25.C
+++ b/gcc/testsuite/g++.dg/parse/error25.C
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // Origin: Steven Bosscher <steven at gcc dot gnu dot org>
 // PR c++/17401: ICE with invalid pure specifier
 
@@ -8,10 +9,10 @@
 class foo
 {
   virtual void bar1 () = 0;
-  virtual void bar2 () = __null;  // { dg-error "invalid pure specifier" }
-  virtual void bar3 () = 4;       // { dg-error "invalid pure specifier" }
-  virtual void bar4 () = A::f;    // { dg-error "invalid pure specifier" }
-  virtual void bar5 () = 0l;      // { dg-error "invalid pure specifier" }
-  virtual void bar6 () = 00;      // { dg-error "invalid pure specifier" }
-  virtual void bar7 () = 0x0;     // { dg-error "invalid pure specifier" }
+  virtual void bar2 () = __null;  // { dg-error "32: error: invalid pure specifier" }
+  virtual void bar3 () = 4;       // { dg-error "27: error: invalid pure specifier" }
+  virtual void bar4 () = A::f;    // { dg-error "27: error: invalid pure specifier" }
+  virtual void bar5 () = 0l;      // { dg-error "28: error: invalid pure specifier" }
+  virtual void bar6 () = 00;      // { dg-error "28: error: invalid pure specifier" }
+  virtual void bar7 () = 0x0;     // { dg-error "29: error: invalid pure specifier" }
 };
diff --git a/gcc/testsuite/g++.dg/parse/error26.C b/gcc/testsuite/g++.dg/parse/error26.C
index 6e2b897..81f7ba6 100644
--- a/gcc/testsuite/g++.dg/parse/error26.C
+++ b/gcc/testsuite/g++.dg/parse/error26.C
@@ -1,12 +1,12 @@
 // PR c++/20148
-// { dg-options "" }
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 
 void foo()
 {
-  if (({int c[2];})) ; // { dg-error "\{\.\.\.\}" }
+  if (({int c[2];})) ; // { dg-error "7: error: ISO C.. forbids|20: error: could not convert" }
 }
 
 void bar()
 {
-  if (({})); // { dg-error "\{\.\.\.\}" }
+  if (({})); // { dg-error "7: error: ISO C.. forbids|11: error: could not convert" }
 }
diff --git a/gcc/testsuite/g++.dg/parse/error27.C b/gcc/testsuite/g++.dg/parse/error27.C
index f52d3ce..f1fd537 100644
--- a/gcc/testsuite/g++.dg/parse/error27.C
+++ b/gcc/testsuite/g++.dg/parse/error27.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/20152
 
-struct KrSelectionMode {  virtual void init() = 0; }; // { dg-error "previous definition" }
-struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "previous definition" }
-struct KrSelectionMode {  virtual void init() = 0; }; // { dg-error "" }
-struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "" }
+struct KrSelectionMode {  virtual void init() = 0; }; // { dg-error "24: error: previous definition of 'struct KrSelectionMode'" }
+struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "52: error: previous definition of 'struct KrKDESelectionMode'" }
+struct KrSelectionMode {  virtual void init() = 0; }; // { dg-error "8: error: redefinition of 'struct KrSelectionMode'" }
+struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "8: error: redefinition of 'struct KrKDESelectionMode'" }
 KrKDESelectionMode krKDESelectionMode;
diff --git a/gcc/testsuite/g++.dg/parse/error28.C b/gcc/testsuite/g++.dg/parse/error28.C
index 046cc50..fd202a1 100644
--- a/gcc/testsuite/g++.dg/parse/error28.C
+++ b/gcc/testsuite/g++.dg/parse/error28.C
@@ -1,10 +1,11 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/21908
 
 struct virt { virt () {} virt (int i) {} };
-struct der : public virtual virt { // { dg-error "der" }
-  der (int i) : virt(i) {} // { dg-error "der" }
+struct der : public virtual virt { // { dg-error "34: note:                 der::der" }
+  der (int i) : virt(i) {} // { dg-error "13: note: candidates are: der" }
 };
 struct top : public der { 
-  // { dg-error "der\\(\\)" "" { target *-*-* } 9 } 
   top () {} // { dg-bogus "der\\(const" }
 };
+// { dg-error "10: error: no matching function for call to 'der" "" { target *-*-* } 9 }
diff --git a/gcc/testsuite/g++.dg/parse/error29.C b/gcc/testsuite/g++.dg/parse/error29.C
index b50b275..fcd091b 100644
--- a/gcc/testsuite/g++.dg/parse/error29.C
+++ b/gcc/testsuite/g++.dg/parse/error29.C
@@ -1,3 +1,4 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/25637
 
 struct A { 
@@ -6,7 +7,7 @@ struct A {
   void operator delete(void *);
 };
 struct B { 
-  friend void A::foo() {} // { dg-error "define" }
-  friend void A::operator delete(void*) {} // { dg-error "define" }
-  friend A::A() {} // { dg-error "define" }
+  friend void A::foo() {} // { dg-error "22: error: cannot define member function 'A::foo' within 'B'" }
+  friend void A::operator delete(void*) {} // { dg-error "39: error: cannot define member function 'A::operator delete' within 'B'" }
+  friend A::A() {} // { dg-error "15: error: cannot define member function 'A::A' within 'B'" }
 };
diff --git a/gcc/testsuite/g++.dg/parse/error3.C b/gcc/testsuite/g++.dg/parse/error3.C
index a052346..1f337e9 100644
--- a/gcc/testsuite/g++.dg/parse/error3.C
+++ b/gcc/testsuite/g++.dg/parse/error3.C
@@ -1,6 +1,19 @@
+// { dg-options "-fshow-column" }
 // PR c++/10779
 
 static void InstantiateConstraint(const float&, unsigned,
-                                  void(*AddFunction)(const TYPE&,bool&, // { dg-error "" }
+                                  void(*AddFunction)(const TYPE&,bool&,
                                                      char*, char*,
-                                                     unsigned*)); // { dg-error "" }
+                                                     unsigned*));
+// { dg-error "64: error: expected ',' or '...' before '&' token" "" { target *-*-* }  { 5 } }
+
+/// in the coming test, the column information is broken as it points to
+//  the end of the declaration instead of pointing to the begining of the
+//  'TYPE' identifier. This is due to the warning being generated by the
+//  declaration groking code (gcc/cp/decl.c) and not the parser. So in that
+//  code, the exact token location information is lost as the declaration
+//  groking code manipulates TREEs only. The token location used is then
+//  the global one that is not accurate enough. Anyway, let's say it is
+//  good enough for now, until we find a way to propagate token location to
+//  code paths that manipulate TREEs only.
+// { dg-error "64: error: ISO C\\+\\+ forbids declaration of 'TYPE' with no type" "" { target *-*-* } { 7 } }
diff --git a/gcc/testsuite/g++.dg/parse/error30.C b/gcc/testsuite/g++.dg/parse/error30.C
index 734a255..5c52d1e 100644
--- a/gcc/testsuite/g++.dg/parse/error30.C
+++ b/gcc/testsuite/g++.dg/parse/error30.C
@@ -1,5 +1,6 @@
 // PR c++/30854
 // { dg-do compile }
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 
 struct A
 {
@@ -7,5 +8,5 @@ struct A
   A(int);
 };
 
-A a = -A();	// { dg-error "no match for.*operator-.*in.*-A\\(\\)" }
-A b = -A(5);	// { dg-error "no match for.*operator-.*in.*-A\\(5\\)" }
+A a = -A();	// { dg-error "10: error: no match for.*operator-.*in.*-A\\(\\)" }
+A b = -A(5);	// { dg-error "11: error: no match for.*operator-.*in.*-A\\(5\\)" }
diff --git a/gcc/testsuite/g++.dg/parse/error31.C b/gcc/testsuite/g++.dg/parse/error31.C
index 5264f44..d354cc3 100644
--- a/gcc/testsuite/g++.dg/parse/error31.C
+++ b/gcc/testsuite/g++.dg/parse/error31.C
@@ -1,10 +1,12 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
 // PR c++/32190
 
 template<typename T> class foo{ };
 
 int main() {
     foo<int> i;
-    foo<foo<int> j; // { dg-error "template argument" }
+    // this column number is not accurate yet, but that will make it for now.
+    foo<foo<int> j; // { dg-error "18: error: template argument 1 is invalid" }
     int k;
     int l;
     foo<int> m;
diff --git a/gcc/testsuite/g++.dg/parse/error4.C b/gcc/testsuite/g++.dg/parse/error4.C
index aa1bfad..790e5c9 100644
--- a/gcc/testsuite/g++.dg/parse/error4.C
+++ b/gcc/testsuite/g++.dg/parse/error4.C
@@ -1,7 +1,10 @@
 // PR c++/12160
+// { dg-options "-fshow-column" }
 
-struct X { 
-  virtual void f(int, 
-		 itn,        // { dg-error "declared" }
+struct X {
+  virtual void f(int,
+		 itn,
 		 int);
-}; 
+};
+
+// { dg-error "4: error: 'itn' has not been declared" "" { target *-*-* } { 6 } }
diff --git a/gcc/testsuite/g++.dg/parse/error5.C b/gcc/testsuite/g++.dg/parse/error5.C
index 81356ce..8c9a039 100644
--- a/gcc/testsuite/g++.dg/parse/error5.C
+++ b/gcc/testsuite/g++.dg/parse/error5.C
@@ -1,4 +1,19 @@
 // PR c++/13269
+// { dg-options "-fshow-column" }
 
-class Foo { int foo() return 0; } }; // { dg-error "" }
+class Foo { int foo() return 0; } };
+
+// { dg-error "30: error: expected identifier before numeric constant" "" { target *-*-* } { 4 } }
+
+// { dg-error "23: error: named return values are no longer supported" "" { target *-*-* } { 4 } }
+
+// the column number info of this error output is still wrong because the error
+// message has been generated by cp_parser_error() which does not
+// necessarily allow accurate column number display. At some point, we will
+// need make cp_parser_error() report more accurate column numbers.
+// { dg-error "30: error: expected '\{' at end of input" "" { target *-*-* } { 4 } }
+
+// { dg-error "35: error: expected unqualified-id before '\}' token" "" {target *-*-*  } { 4 } }
+
+// { dg-error "35: error: expected declaration before '\}' token" "" {target *-*-*  } { 4 } }
 
diff --git a/gcc/testsuite/g++.dg/parse/error6.C b/gcc/testsuite/g++.dg/parse/error6.C
index 3a16669..cd1b6b8 100644
--- a/gcc/testsuite/g++.dg/parse/error6.C
+++ b/gcc/testsuite/g++.dg/parse/error6.C
@@ -1,6 +1,11 @@
 // PR c++/10603
+// { dg-options "-fshow-column" }
 
-int f(int not) { // { dg-error "!" }
-  return 1-not; // { dg-error "" }
+int f(int not) {
+  return 1-not;
 } 
 
+// { dg-error "11: error: expected ',' or '...' before '!' token" "" { target *-*-* } { 4 } }
+
+// { dg-error "15: error: expected primary\\-expression before ';' token" "" { target *-*-* }  { 5 } }
+
diff --git a/gcc/testsuite/g++.dg/parse/error7.C b/gcc/testsuite/g++.dg/parse/error7.C
index 50e7f84..f71c9aa 100644
--- a/gcc/testsuite/g++.dg/parse/error7.C
+++ b/gcc/testsuite/g++.dg/parse/error7.C
@@ -1,4 +1,7 @@
 // PR c++/12827
+// { dg-options "-fshow-column" }
 
 void f(int x
-       int y); // { dg-error "," }
+       int y);
+
+// { dg-error "8: error: expected ',' or '...' before 'int'" "" { target *-*-* } { 5 } }
diff --git a/gcc/testsuite/g++.dg/parse/error8.C b/gcc/testsuite/g++.dg/parse/error8.C
index 125f2e4..a399cfe 100644
--- a/gcc/testsuite/g++.dg/parse/error8.C
+++ b/gcc/testsuite/g++.dg/parse/error8.C
@@ -1,4 +1,10 @@
 // PR c++/13438
+// {  dg-options "-fshow-column" }
 
-struct A { friend typename struct B; };  // { dg-error "" }
-  
+struct A { friend typename struct B; };
+
+
+// { dg-error "19: error: using 'typename' outside of template" "" { target *-*-* } { 4 } }
+// { dg-error "28: error: expected nested-name-specifier before 'struct'" "" { target *-*-* } { 4 } }
+// { dg-error "35: error: multiple types in one declaration" "" { target *-*-* } { 4 } }
+// { dg-error "12: error: friend declaration does not name a class or function" "" { target *-*-* } { 4 } }
diff --git a/gcc/testsuite/g++.dg/parse/error9.C b/gcc/testsuite/g++.dg/parse/error9.C
index aa9109f..c1be697 100644
--- a/gcc/testsuite/g++.dg/parse/error9.C
+++ b/gcc/testsuite/g++.dg/parse/error9.C
@@ -1,5 +1,9 @@
 // PR c++/12613
-// { dg-options "" }
+// { dg-options "-fshow-column" }
 
 enum { FOO = 1, BAR = 2 };
-int a[] = { FOO: 1, BAR: 2 }; // { dg-error "" }
+int a[] = { FOO: 1, BAR: 2 };
+
+// the following 2 column locations are still not accurate enough
+// { dg-error "28: error: name 'FOO' used in a GNU-style designated initializer for an array" "" { target *-*-* }  { 5 } }
+// { dg-error "28: error: name 'BAR' used in a GNU-style designated initializer for an array" "" { target *-*-* }  { 5 } }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C b/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
index 42a21fc..7fe07a2 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
@@ -1,8 +1,9 @@
 // { dg-do assemble  }
+// { dg-options "-fshow-column" }
 
 struct A { // { dg-error "" } forward declaration
-  friend struct B : A {		// { dg-error "" } 
+  friend struct B : A {		// { dg-error "invalid use of incomplete type 'struct A'" }
     int x;
-  };	// { dg-error "" } class definition cannot be a friend
+  };	// { dg-error "class definition may not be declared a friend" ""  { target *-*-* } { 5 } }
   int y;
 };
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index c188824..7ca5b73 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -273,7 +273,6 @@ proc g++_target_compile { source dest type options } {
     }
 
     lappend options "additional_flags=[libio_include_flags]"
-    lappend options "additional_flags=-fno-show-column"
     lappend options "compiler=$GXX_UNDER_TEST"
 
     set options [concat $gpp_compile_options $options]
gcc/cp/ChangeLog:
2008-06-30 Dodji Seketeli <dseketel@redhat.com>

 	PR c++/31754
	* cp-tree.h (struct cp_decl_specifier_seq): add a location field. It
	carries the location of the primary type.
	* parser.c (cp_parser_check_type_definition): update documentation.
	(cp_parser_check_for_definition_in_return_type,
	cp_parser_check_for_invalid_template_id,
	cp_parser_set_decl_spec_type,
	cp_parser_check_for_definition_in_return_type,
	cp_parser_diagnose_invalid_type_name,
	cp_parser_new_expression, cp_parser_explicit_instantiation,
	cp_parser_type_specifier, cp_parser_simple_type_specifier,
	cp_parser_omp_for_loop, cp_parser_pragma): use location in error messages.

gcc/testsuite/ChangeLog:
2008-06-30 Dodji Seketeli <dseketel@redhat.com>

	* g++.dg/other/semicolon.C: Tighten this test, making it column aware.
	* g++.dg/parse/error15.C: update this because of more accurate column
	numbers in error reporting.
	* g++.old-deja/g++.brendan/crash16.C: Tighten the test, making it
	column aware.
	* g++.old-deja/g++.law/ctors5.C: Likewise.
	* g++.old-deja/g++.other/crash25.C: Likewise.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index afea188..9cd84f3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3910,6 +3910,9 @@ typedef struct cp_decl_specifier_seq {
      reflected here.  This field will be a TYPE, unless a typedef-name
      was used, in which case it will be a TYPE_DECL.  */
   tree type;
+  /* The location of the primary type. Mainly used for error
+     reporting.  */
+  location_t type_location;
   /* The attributes, if any, provided with the specifier sequence.  */
   tree attributes;
   /* If non-NULL, a built-in type that the user attempted to redefine
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 184b9ec..c859bae 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1940,7 +1940,7 @@ static bool cp_parser_declares_only_class_p
 static void cp_parser_set_storage_class
   (cp_parser *, cp_decl_specifier_seq *, enum rid, location_t);
 static void cp_parser_set_decl_spec_type
-  (cp_decl_specifier_seq *, tree, bool);
+  (cp_decl_specifier_seq *, tree, location_t, bool);
 static bool cp_parser_friend_p
   (const cp_decl_specifier_seq *);
 static cp_token *cp_parser_require
@@ -1988,9 +1988,9 @@ static bool cp_parser_simulate_error
 static bool cp_parser_check_type_definition
   (cp_parser *);
 static void cp_parser_check_for_definition_in_return_type
-  (cp_declarator *, tree);
+  (cp_declarator *, tree, location_t type_location);
 static void cp_parser_check_for_invalid_template_id
-  (cp_parser *, tree);
+  (cp_parser *, tree, location_t location);
 static bool cp_parser_non_integral_constant_expression
   (cp_parser *, const char *);
 static void cp_parser_diagnose_invalid_type_name
@@ -2204,11 +2204,12 @@ cp_parser_check_type_definition (cp_parser* parser)
 /* This function is called when the DECLARATOR is processed.  The TYPE
    was a type defined in the decl-specifiers.  If it is invalid to
    define a type in the decl-specifiers for DECLARATOR, an error is
-   issued.  */
+   issued. TYPE_LOCATION is the location of TYPE and is used
+   for error reporting.  */
 
 static void
 cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
-					       tree type)
+					       tree type, location_t type_location)
 {
   /* [dcl.fct] forbids type definitions in return types.
      Unfortunately, it's not easy to know whether or not we are
@@ -2221,31 +2222,32 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
   if (declarator
       && declarator->kind == cdk_function)
     {
-      error ("new types may not be defined in a return type");
-      inform ("(perhaps a semicolon is missing after the definition of %qT)",
-	      type);
+      error ("%Hnew types may not be defined in a return type", &type_location);
+      inform ("%H(perhaps a semicolon is missing after the definition of %qT)",
+	      &type_location, type);
     }
 }
 
 /* A type-specifier (TYPE) has been parsed which cannot be followed by
    "<" in any valid C++ program.  If the next token is indeed "<",
    issue a message warning the user about what appears to be an
-   invalid attempt to form a template-id.  */
+   invalid attempt to form a template-id. LOCATION is the location
+   of the type-specifier (TYPE) */
 
 static void
 cp_parser_check_for_invalid_template_id (cp_parser* parser,
-					 tree type)
+					 tree type, location_t location)
 {
   cp_token_position start = 0;
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
     {
       if (TYPE_P (type))
-	error ("%qT is not a template", type);
+	error ("%H%qT is not a template", &location, type);
       else if (TREE_CODE (type) == IDENTIFIER_NODE)
-	error ("%qE is not a template", type);
+	error ("%H%qE is not a template", &location, type);
       else
-	error ("invalid template-id");
+	error ("%Hinvalid template-id", &location);
       /* Remember the location of the invalid "<".  */
       if (cp_parser_uncommitted_to_tentative_parse_p (parser))
 	start = cp_lexer_token_position (parser->lexer, true);
@@ -2291,32 +2293,34 @@ cp_parser_non_integral_constant_expression (cp_parser  *parser,
    qualifying scope (or NULL, if none) for ID.  This function commits
    to the current active tentative parse, if any.  (Otherwise, the
    problematic construct might be encountered again later, resulting
-   in duplicate error messages.)  */
+   in duplicate error messages.) LOCATION is the location of ID.  */
 
 static void
 cp_parser_diagnose_invalid_type_name (cp_parser *parser,
 				      tree scope, tree id,
-				      location_t id_location)
+				      location_t 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, id_location);
+  decl = cp_parser_lookup_name_simple (parser, 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.  */
   if (TREE_CODE (decl) == TEMPLATE_DECL)
-    error ("invalid use of template-name %qE without an argument list", decl);
+    error ("%Hinvalid use of template-name %qE without an argument list",
+           &location, decl);
   else if (TREE_CODE (id) == BIT_NOT_EXPR)
-    error ("invalid use of destructor %qD as a type", id);
+    error ("%Hinvalid use of destructor %qD as a type", &location, id);
   else if (TREE_CODE (decl) == TYPE_DECL)
     /* Something like 'unsigned A a;'  */
-    error ("invalid combination of multiple type-specifiers");
+    error ("%Hinvalid combination of multiple type-specifiers",
+           &location);
   else if (!parser->scope)
     {
       /* Issue an error message.  */
-      error ("%qE does not name a type", id);
+      error ("%H%qE does not name a type", &location, id);
       /* If we're in a template class, it's possible that the user was
 	 referring to a type from a base class.  For example:
 
@@ -2348,8 +2352,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
 		    if (TREE_CODE (field) == TYPE_DECL
 			&& DECL_NAME (field) == id)
 		      {
-			inform ("(perhaps %<typename %T::%E%> was intended)",
-				BINFO_TYPE (b), id);
+			inform ("%H(perhaps %<typename %T::%E%> was intended)",
+				&location, BINFO_TYPE (b), id);
 			break;
 		      }
 		  if (field)
@@ -2363,10 +2367,11 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
   else if (parser->scope != error_mark_node)
     {
       if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
-	error ("%qE in namespace %qE does not name a type",
-	       id, parser->scope);
+	error ("%H%qE in namespace %qE does not name a type",
+	       &location, id, parser->scope);
       else if (TYPE_P (parser->scope))
-	error ("%qE in class %qT does not name a type", id, parser->scope);
+	error ("%H%qE in class %qT does not name a type",
+               &location, id, parser->scope);
       else
 	gcc_unreachable ();
     }
@@ -5552,7 +5557,8 @@ cp_parser_new_expression (cp_parser* parser)
 	{
 	  error ("%Harray bound forbidden after parenthesized type-id",
 		 &token->location);
-	  inform ("try removing the parentheses around the type-id");
+	  inform ("%Htry removing the parentheses around the type-id",
+		 &token->location);
 	  cp_parser_direct_new_declarator (parser);
 	}
       nelts = NULL_TREE;
@@ -10525,6 +10531,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
   int declares_class_or_enum;
   cp_decl_specifier_seq decl_specifiers;
   tree extension_specifier = NULL_TREE;
+  cp_token *token;
 
   /* Look for an (optional) storage-class-specifier or
      function-specifier.  */
@@ -10547,6 +10554,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
      control while processing explicit instantiation directives.  */
   push_deferring_access_checks (dk_no_check);
   /* Parse a decl-specifier-seq.  */
+  token = cp_lexer_peek_token (parser->lexer);
   cp_parser_decl_specifier_seq (parser,
 				CP_PARSER_FLAGS_OPTIONAL,
 				&decl_specifiers,
@@ -10579,7 +10587,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
 				/*member_p=*/false);
       if (declares_class_or_enum & 2)
 	cp_parser_check_for_definition_in_return_type (declarator,
-						       decl_specifiers.type);
+						       decl_specifiers.type,
+						       decl_specifiers.type_location);
       if (declarator != cp_error_declarator)
 	{
 	  decl = grokdeclarator (declarator, &decl_specifiers,
@@ -10751,6 +10760,7 @@ cp_parser_type_specifier (cp_parser* parser,
 	  if (decl_specs)
 	    cp_parser_set_decl_spec_type (decl_specs,
 					  type_spec,
+					  token->location,
 					  /*user_defined_p=*/true);
 	  return type_spec;
 	}
@@ -10775,6 +10785,7 @@ cp_parser_type_specifier (cp_parser* parser,
 	  if (decl_specs)
 	    cp_parser_set_decl_spec_type (decl_specs,
 					  type_spec,
+					  token->location,
 					  /*user_defined_p=*/true);
 	  return type_spec;
 	}
@@ -10796,6 +10807,7 @@ cp_parser_type_specifier (cp_parser* parser,
       if (decl_specs)
 	cp_parser_set_decl_spec_type (decl_specs,
 				      type_spec,
+				      token->location,
 				      /*user_defined_p=*/true);
       return type_spec;
 
@@ -10971,6 +10983,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 
       if (decl_specs)
 	cp_parser_set_decl_spec_type (decl_specs, type,
+				      token->location,
 				      /*user_defined_p=*/true);
 
       return type;
@@ -10986,6 +10999,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 
       if (decl_specs)
 	cp_parser_set_decl_spec_type (decl_specs, type,
+				      token->location,
 				      /*user_defined_p=*/true);
 
       return type;
@@ -11007,6 +11021,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	      && token->keyword != RID_LONG))
 	cp_parser_set_decl_spec_type (decl_specs,
 				      type,
+				      token->location,
 				      /*user_defined=*/false);
       if (decl_specs)
 	decl_specs->any_specifiers_p = true;
@@ -11017,7 +11032,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       /* There is no valid C++ program where a non-template type is
 	 followed by a "<".  That usually indicates that the user thought
 	 that the type was a template.  */
-      cp_parser_check_for_invalid_template_id (parser, type);
+      cp_parser_check_for_invalid_template_id (parser, type, token->location);
 
       return TYPE_NAME (type);
     }
@@ -11046,6 +11061,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 						/*type_p=*/false,
 						/*is_declaration=*/false)
 	   != NULL_TREE);
+      token = cp_lexer_peek_token (parser->lexer);
       /* If we have seen a nested-name-specifier, and the next token
 	 is `template', then we are using the template-id production.  */
       if (parser->scope
@@ -11080,6 +11096,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	type = NULL_TREE;
       if (type && decl_specs)
 	cp_parser_set_decl_spec_type (decl_specs, type,
+				      token->location,
 				      /*user_defined=*/true);
     }
 
@@ -11112,7 +11129,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	  return qual_type;
 	}
 
-      cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type));
+      cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
+					       token->location);
     }
 
   return type;
@@ -11534,7 +11552,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
   /* A "<" cannot follow an elaborated type specifier.  If that
      happens, the user was probably trying to form a template-id.  */
-  cp_parser_check_for_invalid_template_id (parser, type);
+  cp_parser_check_for_invalid_template_id (parser, type, token->location);
 
   return type;
 }
@@ -12339,7 +12357,8 @@ cp_parser_init_declarator (cp_parser* parser,
 
   if (declares_class_or_enum & 2)
     cp_parser_check_for_definition_in_return_type (declarator,
-						   decl_specifiers->type);
+						   decl_specifiers->type,
+						   decl_specifiers->type_location);
 
   /* Figure out what scope the entity declared by the DECLARATOR is
      located in.  `grokdeclarator' sometimes changes the scope, so
@@ -14777,6 +14796,7 @@ cp_parser_class_head (cp_parser* parser,
       if (!cp_parser_parse_definitely (parser))
 	{
 	  invalid_nested_name_p = true;
+	  type_start_token = cp_lexer_peek_token (parser->lexer);
 	  id = cp_parser_identifier (parser);
 	  if (id == error_mark_node)
 	    id = NULL_TREE;
@@ -14820,7 +14840,10 @@ cp_parser_class_head (cp_parser* parser,
       if (!cp_parser_parse_definitely (parser))
 	{
 	  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
-	    id = cp_parser_identifier (parser);
+	    {
+	      type_start_token = cp_lexer_peek_token (parser->lexer);
+	      id = cp_parser_identifier (parser);
+	    }
 	  else
 	    id = NULL_TREE;
 	}
@@ -14834,7 +14857,8 @@ cp_parser_class_head (cp_parser* parser,
   pop_deferring_access_checks ();
 
   if (id)
-    cp_parser_check_for_invalid_template_id (parser, id);
+    cp_parser_check_for_invalid_template_id (parser, id,
+					     type_start_token->location);
 
   /* If it's not a `:' or a `{' then we can't really be looking at a
      class-head, since a class-head only appears as part of a
@@ -15423,7 +15447,8 @@ cp_parser_member_declaration (cp_parser* parser)
 
 	      if (declares_class_or_enum & 2)
 		cp_parser_check_for_definition_in_return_type
-		  (declarator, decl_specifiers.type);
+					    (declarator, decl_specifiers.type,
+					     decl_specifiers.type_location);
 
 	      /* Look for an asm-specification.  */
 	      asm_specification = cp_parser_asm_specification_opt (parser);
@@ -18016,6 +18041,7 @@ cp_parser_set_storage_class (cp_parser *parser,
 static void
 cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
 			      tree type_spec,
+			      location_t location,
 			      bool user_defined_p)
 {
   decl_specs->any_specifiers_p = true;
@@ -18042,6 +18068,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
 	{
 	  decl_specs->type = type_spec;
 	  decl_specs->user_defined_type_p = false;
+	  decl_specs->type_location = location;
 	}
     }
   else if (decl_specs->type)
@@ -18051,6 +18078,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
       decl_specs->type = type_spec;
       decl_specs->user_defined_type_p = user_defined_p;
       decl_specs->redefined_builtin_type = NULL_TREE;
+      decl_specs->type_location = location;
     }
 }
 
@@ -20967,7 +20995,10 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
       else
 	{
 	  if (!collapse_err)
-	    error ("collapsed loops not perfectly nested");
+	    {
+	      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+	      error ("%Hcollapsed loops not perfectly nested", &loc);
+	    }
 	  collapse_err = true;
 	  cp_parser_statement_seq_opt (parser, NULL);
 	  cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
@@ -21455,8 +21486,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
 	  cp_parser_omp_taskwait (parser, pragma_tok);
 	  return false;
 	case pragma_stmt:
-	  error ("%<#pragma omp taskwait%> may only be "
-		 "used in compound statements");
+	  error ("%H%<#pragma omp taskwait%> may only be "
+		 "used in compound statements",
+		 &pragma_tok->location);
 	  break;
 	default:
 	  goto bad_stmt;
diff --git a/gcc/testsuite/g++.dg/other/semicolon.C b/gcc/testsuite/g++.dg/other/semicolon.C
index 6bc3d95..542d3b7 100644
--- a/gcc/testsuite/g++.dg/other/semicolon.C
+++ b/gcc/testsuite/g++.dg/other/semicolon.C
@@ -1,9 +1,10 @@
 // PR c++/18368
 // Origin: Chris Lattner <sabre@nondot.org>
 // { dg-do compile }
+// { dg-options "-fshow-column" }
 
 struct A
 {
-  struct B { int i; }
-  void foo();   // { dg-error "two or more|return type" }
-};              // { dg-error "semicolon is missing" "" { target *-*-* } 8 }
+  struct B { int i; } // { dg-error "3: error: new types may not be defined in a return type|note: \\(perhaps a semicolon is missing" }
+  void foo();   // { dg-error "12: error: two or more|return type" }
+};
diff --git a/gcc/testsuite/g++.dg/parse/error15.C b/gcc/testsuite/g++.dg/parse/error15.C
index b65175c..5903a58 100644
--- a/gcc/testsuite/g++.dg/parse/error15.C
+++ b/gcc/testsuite/g++.dg/parse/error15.C
@@ -10,28 +10,28 @@ namespace N
   int K;
 }
 
-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" }
+N::A f2;              // { dg-error "1: error: invalid use of template-name 'N::A' without an argument list" }
+N::INVALID f3;        // { dg-error "1: error: 'INVALID' in namespace 'N' does not name a type" }
+N::C::INVALID f4;     // { dg-error "1: error: 'INVALID' in class 'N::C' does not name a type" }
+N::K f6;              // { dg-error "1: 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 "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" }
+  N::A f2;            // { dg-error "3: error: invalid use of template-name 'N::A' without an argument list" }
+  N::INVALID f3;      // { dg-error "3: error: 'INVALID' in namespace 'N' does not name a type" }
+  N::C::INVALID f4;   // { dg-error "3: error: 'INVALID' in class 'N::C' does not name a type" }
+  N::K f6;            // { dg-error "3: 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 "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" }
+  N::A f2;            // { dg-error "3: error: invalid use of template-name 'N::A' without an argument list" }
+  N::INVALID f3;      // { dg-error "3: error: 'INVALID' in namespace 'N' does not name a type" }
+  N::C::INVALID f4;   // { dg-error "3: error: 'INVALID' in class 'N::C' does not name a type" }
+  N::K f6;            // { dg-error "3: 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" }
 };
 
diff --git a/gcc/testsuite/g++.dg/parse/non-templ2.C b/gcc/testsuite/g++.dg/parse/non-templ2.C
new file mode 100644
index 0000000..169006a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/non-templ2.C
@@ -0,0 +1,16 @@
+// Origin : Dodji Seketeli <dseketel@redhat.com>
+// { dg-do compile }
+// { dg-options "-fshow-column" }
+
+struct Outer {
+    struct Inner {int m;};
+};
+
+template <typename T>
+struct S {
+    T m;
+    static int sm;
+    class Outer::Inner<char> b0; // { dg-error "18: error: 'Inner' is not a template" }
+    class Outer<int>::Inner<char> b1; // { dg-error "11: error: 'Outer' is not a template|23: error: 'Outer::Inner' is not a template|35: error: declaration of 'Outer::Inner S<T>::b0"  }
+};
+
diff --git a/gcc/testsuite/g++.dg/parse/nontype2.C b/gcc/testsuite/g++.dg/parse/nontype2.C
new file mode 100644
index 0000000..8141443
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/nontype2.C
@@ -0,0 +1,13 @@
+// Origin: Dodji Seketeli <dseketel@redhat.com>
+// { dg-compile }
+// { dg-options "-fshow-column" }
+
+void
+foo ()
+{   
+    unsigned
+      A         // { dg-error "7: error: 'A' does not name a type" }
+         a;
+}
+
+
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
index 7151eb1..ddcae3c 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
@@ -1,12 +1,14 @@
 // { dg-do compile }
+// { dg-options "-fshow-column" }
 // GROUPS passed old-abort
-class Graph {
+
+class Graph { // { dg-error "1: error: new types|1: note: \\(perhaps" }
 public:
       unsigned         char N;
-      Graph(void) {} // { dg-error "previously defined here" }
+      Graph(void) {} // { dg-error "17: error: 'Graph" }
 }
 
-Graph::Graph(void)    // { dg-error "return type|redefinition|semicolon" }
+Graph::Graph(void) // { dg-error "18: error: return type|18: error: redefinition" }
 {    N = 10;
 }
 
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors5.C b/gcc/testsuite/g++.old-deja/g++.law/ctors5.C
index 334b597..1f469cf 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors5.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors5.C
@@ -1,11 +1,12 @@
 // { dg-do assemble  }
+// { dg-options "-fshow-column" }
 // GROUPS passed constructors
 // ctors file
 // Subject: bug in handling static const object of the enclosing class
 // Date: Tue, 1 Sep 92 10:38:44 EDT
 
 class X
-{ // { dg-error "X::X" } implicit constructor
+{ // { dg-error "1: note:                 X::X\\(const X&\\)" } implicit constructor
   private:
     int x;
   public:
@@ -13,21 +14,21 @@ class X
     X( int );
 };
 
-class Y
+class Y // { dg-error "1: error: new types may not be defined in a return type|1: note: \\(perhaps a semicolon is missing after the definition of 'Y'\\)" }
 {
   private:
     X xx;
   public:
     Y();
 }
-X::X( int xi ) // { dg-error "return type|X::X|semicolon" }
+X::X( int xi ) // { dg-error "14: error: return type specification for constructor invalid|14: note: candidates are: X::X\\(int\\)" }
 {
     x = xi;
 }
 
 const X X::x0( 0 );
 
-Y::Y() // { dg-error "no match" }
+Y::Y() // { dg-error "6: error: no matching function for call to 'X::X\\(\\)'" }
 {
     xx = X::x0;
 }
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash25.C b/gcc/testsuite/g++.old-deja/g++.other/crash25.C
index b8417e8..517bac2 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/crash25.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash25.C
@@ -1,16 +1,17 @@
 // { dg-do assemble  }
+// { dg-options "-fshow-column" }
 // Origin: Jakub Jelinek <jakub@redhat.com>
 
-class X {
+class X { // { dg-error "1: error: new types may not be defined in a return type|1: note: \\(perhaps a semicolon is missing after the definition of 'X'\\)" }
 public:
   X();
   virtual ~X();
 }
 
-X::x()	// { dg-error "return type|member function|semicolon" }
+X::x()	// { dg-error "6: error: no 'X X::x\\(\\)' member function declared in class 'X'" }
 {
 }
 
-X::~x()	// { dg-error "expected class-name" }
+X::~x()	// { dg-error "6: error: expected class-name before '\\(' token" }
 {				
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]