public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
@ 2009-11-17 10:42 Shujing Zhao
  2009-11-18  2:50 ` Gabriel Dos Reis
  0 siblings, 1 reply; 12+ messages in thread
From: Shujing Zhao @ 2009-11-17 10:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Gabriel Dos Reis, Paolo Carlini

[-- Attachment #1: Type: text/plain, Size: 701 bytes --]

Hi,

This patch is to adjust the function maybe_warn_cpp0x to make the 
warning messages can be extracted by exgettext for translation. As the 
commenter of pr40892 suggested, I have made two candidate patches. One 
is to pass an enum to this function and the other is pass the complete 
diagnostic text to it. I'm not sure which one is better for trunk, so 
both of them are submitted to be selected.
Some of test cases are also changed to add the detailed error messages 
to match the output messages.
Both of the candidates are tested on i686-pc-linux-gnu and the 
diagnostic sentences can be extracted to gcc.pot by execute "make 
gcc.pot" at objdir/gcc.
Which one is ok for trunk?

Thanks
Pearly

[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 795 bytes --]

2009-11-17  Shujing Zhao  <pearly.zhao@oracle.com>

	PR c++/40892
	* error.c (maybe_warn_cpp0x): Move the diagnostic details to the
	caller and use gmsgid as argument name.
	(maybe_warn_variadic_templates): Use the complete diagnostic text for
	easier translation.
	* call.c (reference_binding): Likewise.
	* decl.c (reshape_init_r, check_initializer, grokdeclarator):
	Likewise.
	* parser.c (cp_parser_primary_expression)
	(cp_parser_parenthesized_expression_list, cp_parser_new_initializer)
	(cp_parser_assignment_expression, cp_parser_condition)
	(cp_parser_jump_statement, cp_parser_mem_initializer)
	(cp_parser_simple_type_specifier, cp_parser_elaborated_type_specifier)
	(cp_parser_enum_specifier, cp_parser_initializer,
	(cp_parser_pure_specifier, cp_parser_functional_cast): Likewise.
	

[-- Attachment #3: 40892.patch --]
[-- Type: text/x-patch, Size: 10112 bytes --]

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 154234)
+++ cp/decl.c	(working copy)
@@ -4926,7 +4926,8 @@ reshape_init_r (tree type, reshape_iter 
 	      init = error_mark_node;
 	    }
 	  else
-	    maybe_warn_cpp0x ("extended initializer lists");
+	    maybe_warn_cpp0x ("extended initializer lists "
+			      "only available with -std=c++0x or -std=gnu++0x");
 	}
 
       d->cur++;
@@ -5170,7 +5171,8 @@ check_initializer (tree decl, tree init,
 	{
 	  if (init_len == 0)
 	    {
-	      maybe_warn_cpp0x ("extended initializer lists");
+	      maybe_warn_cpp0x ("extended initializer lists only "
+			 	"available with -std=c++0x or -std=gnu++0x");
 	      init = build_zero_init (type, NULL_TREE, false);
 	    }
 	  else if (init_len != 1)
@@ -8523,7 +8525,9 @@ grokdeclarator (const cp_declarator *dec
 	      {
 		if (explicitp == 1)
 		  {
-		    maybe_warn_cpp0x ("explicit conversion operators");
+		    maybe_warn_cpp0x ("explicit conversion operators only "
+				      "available with -std=c++0x or "
+				      "-std=gnu++0x");
 		    explicitp = 2;
 		  }
 	      }
Index: cp/error.c
===================================================================
--- cp/error.c	(revision 154234)
+++ cp/error.c	(working copy)
@@ -2885,20 +2885,21 @@ cp_printer (pretty_printer *pp, text_inf
 \f
 /* Warn about the use of C++0x features when appropriate.  */
 void
-maybe_warn_cpp0x (const char* str)
+maybe_warn_cpp0x (const char* gmsgid)
 {
   if ((cxx_dialect == cxx98) && !in_system_header)
     /* We really want to suppress this warning in system headers,
        because libstdc++ uses variadic templates even when we aren't
        in C++0x mode. */
-    pedwarn (input_location, 0, "%s only available with -std=c++0x or -std=gnu++0x", str);
+    pedwarn (input_location, 0, gmsgid);
 }
 
 /* Warn about the use of variadic templates when appropriate.  */
 void
 maybe_warn_variadic_templates (void)
 {
-  maybe_warn_cpp0x ("variadic templates");
+  maybe_warn_cpp0x ("variadic templates "
+		    "only available with -std=c++0x or -std=gnu++0x");
 }
 
 
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 154234)
+++ cp/parser.c	(working copy)
@@ -3329,7 +3329,8 @@ cp_parser_primary_expression (cp_parser 
       if (c_dialect_objc ())
         /* We have an Objective-C++ message. */
         return cp_parser_objc_expression (parser);
-      maybe_warn_cpp0x ("lambda expressions");
+      maybe_warn_cpp0x ("lambda expressions "
+			"only available with -std=c++0x or -std=gnu++0x");
       return cp_parser_lambda_expression (parser);
 
     case CPP_OBJC_STRING:
@@ -5275,7 +5276,8 @@ cp_parser_parenthesized_expression_list 
 	    if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 	      {
 		/* A braced-init-list.  */
-		maybe_warn_cpp0x ("extended initializer lists");
+		maybe_warn_cpp0x ("extended initializer lists only "
+				  "available with -std=c++0x or -std=gnu++0x");
 		expr = cp_parser_braced_list (parser, &expr_non_constant_p);
 		if (non_constant_p && expr_non_constant_p)
 		  *non_constant_p = true;
@@ -5992,7 +5994,8 @@ cp_parser_new_initializer (cp_parser* pa
     {
       tree t;
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x ("extended initializer lists "
+			"only available with -std=c++0x or -std=gnu++0x");
       t = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
       expression_list = make_tree_vector_single (t);
@@ -6553,7 +6556,8 @@ cp_parser_assignment_expression (cp_pars
 	      tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
 
 	      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
-		maybe_warn_cpp0x ("extended initializer lists");
+		maybe_warn_cpp0x ("extended initializer lists only "
+				  "available with -std=c++0x or -std=gnu++0x");
 
 	      /* An assignment may not appear in a
 		 constant-expression.  */
@@ -8143,7 +8147,8 @@ cp_parser_condition (cp_parser* parser)
 	      initializer = cp_parser_initializer_clause (parser, &non_constant_p);
 	    }
 	  if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
-	    maybe_warn_cpp0x ("extended initializer lists");
+	    maybe_warn_cpp0x ("extended initializer lists "
+			      "only available with -std=c++0x or -std=gnu++0x");
 
 	  if (!non_constant_p)
 	    initializer = fold_non_dependent_expr (initializer);
@@ -8407,7 +8412,8 @@ cp_parser_jump_statement (cp_parser* par
 
 	if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 	  {
-	    maybe_warn_cpp0x ("extended initializer lists");
+	    maybe_warn_cpp0x ("extended initializer lists "
+			      "only available with -std=c++0x or -std=gnu++0x");
 	    expr = cp_parser_braced_list (parser, &expr_non_constant_p);
 	  }
 	else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -9922,7 +9928,8 @@ cp_parser_mem_initializer (cp_parser* pa
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x ("extended initializer lists "
+			"only available with -std=c++0x or -std=gnu++0x");
       expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       expression_list = build_tree_list (NULL_TREE, expression_list);
@@ -11933,7 +11940,8 @@ cp_parser_simple_type_specifier (cp_pars
       break;
       
     case RID_AUTO:
-      maybe_warn_cpp0x ("C++0x auto");
+      maybe_warn_cpp0x ("C++0x auto "
+			"only available with -std=c++0x or -std=gnu++0x");
       type = make_auto ();
       break;
 
@@ -12240,7 +12248,8 @@ cp_parser_elaborated_type_specifier (cp_
           || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
         {
           if (cxx_dialect == cxx98)
-            maybe_warn_cpp0x ("scoped enums");
+            maybe_warn_cpp0x ("scoped enums only "
+			      "available with -std=c++0x or -std=gnu++0x");
 
           /* Consume the `struct' or `class'.  */
           cp_lexer_consume_token (parser->lexer);
@@ -12577,7 +12586,8 @@ cp_parser_enum_specifier (cp_parser* par
       || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
     {
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x ("scoped enums "
+			  "only available with -std=c++0x or -std=gnu++0x");
 
       /* Consume the `struct' or `class' token.  */
       cp_lexer_consume_token (parser->lexer);
@@ -12611,7 +12621,8 @@ cp_parser_enum_specifier (cp_parser* par
 	return NULL_TREE;
 
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x ("scoped enums "
+			  "only available with -std=c++0x or -std=gnu++0x");
 
       has_underlying_type = true;
 
@@ -15425,7 +15436,8 @@ cp_parser_initializer (cp_parser* parser
     }
   else if (token->type == CPP_OPEN_BRACE)
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x ("extended initializer lists "
+			"only available with -std=c++0x or -std=gnu++0x");
       init = cp_parser_braced_list (parser, non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
     }
@@ -16895,7 +16907,8 @@ cp_parser_pure_specifier (cp_parser* par
   if (token->keyword == RID_DEFAULT
       || token->keyword == RID_DELETE)
     {
-      maybe_warn_cpp0x ("defaulted and deleted functions");
+      maybe_warn_cpp0x ("defaulted and deleted functions "
+			"only available with -std=c++0x or -std=gnu++0x");
       return token->u.value;
     }
 
@@ -18895,7 +18908,8 @@ cp_parser_functional_cast (cp_parser* pa
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x ("extended initializer lists "
+			"only available with -std=c++0x or -std=gnu++0x");
       expression_list = cp_parser_braced_list (parser, &nonconst_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       if (TREE_CODE (type) == TYPE_DECL)
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 154234)
+++ cp/call.c	(working copy)
@@ -1228,7 +1228,8 @@ reference_binding (tree rto, tree rfrom,
 
   if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x ("extended initializer lists "
+			"only available with -std=c++0x or -std=gnu++0x");
       conv = implicit_conversion (to, from, expr, c_cast_p,
 				  flags);
       if (!CLASS_TYPE_P (to)
Index: testsuite/g++.old-deja/g++.other/crash28.C
===================================================================
--- testsuite/g++.old-deja/g++.other/crash28.C	(revision 154234)
+++ testsuite/g++.old-deja/g++.other/crash28.C	(working copy)
@@ -31,5 +31,5 @@ public:
 };
 void foo::x() throw(bar)
 {
-  if (!b) throw bar (static_cast<::N::X*>(this));	// { dg-error "" } parse error
+  if (!b) throw bar (static_cast<::N::X*>(this));	// { dg-error "lambda expressions|expected" } parse error
 }
Index: testsuite/g++.dg/inherit/error4.C
===================================================================
--- testsuite/g++.dg/inherit/error4.C	(revision 154234)
+++ testsuite/g++.dg/inherit/error4.C	(working copy)
@@ -2,7 +2,7 @@
 
 struct A { virtual ~A(); };
 
-struct B : A A {};		// { dg-error "" }
+struct B : A A {};		// { dg-error "expected|initializer|invalid" }
 
 A foo(const B &b)		// { dg-error "" }
 {
Index: testsuite/g++.dg/template/crash90.C
===================================================================
--- testsuite/g++.dg/template/crash90.C	(revision 154234)
+++ testsuite/g++.dg/template/crash90.C	(working copy)
@@ -4,5 +4,5 @@ template < unsigned >
 struct A ;
 template < typename >
 struct B ;
-template < typename T , A < B < T > // { dg-error "" }
+template < typename T , A < B < T > // { dg-error "initializer|parse error|valid type|expected" }
 { }

[-- Attachment #4: ChangeLog-2.patch --]
[-- Type: text/x-patch, Size: 888 bytes --]

2009-11-12  Shujing Zhao  <pearly.zhao@oracle.com>

	PR c++/40892
	* error.c (maybe_warn_cpp0x): Accept enum cpp0x_warn_str as argument.
	(maybe_warn_variadic_templates): Update the maybe_warn_cpp0x calls to
	match the new declaration.
	* cp-tree.h (cpp0x_warn_str): New type.
	(maybe_warn_cpp0x): Adjust prototype with new argument.
	* call.c (reference_binding): Update the maybe_warn_cpp0x calls.
	* decl.c (reshape_init_r, check_initializer, grokdeclarator):
	Likewise.
	* parser.c (cp_parser_primary_expression)
	(cp_parser_parenthesized_expression_list, cp_parser_new_initializer)
	(cp_parser_assignment_expression, cp_parser_condition)
	(cp_parser_jump_statement, cp_parser_mem_initializer)
	(cp_parser_simple_type_specifier, cp_parser_elaborated_type_specifier)
	(cp_parser_enum_specifier, cp_parser_initializer)
	(cp_parser_pure_specifier, cp_parser_functional_cast): Likewise.


[-- Attachment #5: 40892-2.patch --]
[-- Type: text/x-patch, Size: 11413 bytes --]

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 154234)
+++ cp/decl.c	(working copy)
@@ -4926,7 +4926,7 @@ reshape_init_r (tree type, reshape_iter 
 	      init = error_mark_node;
 	    }
 	  else
-	    maybe_warn_cpp0x ("extended initializer lists");
+	    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 	}
 
       d->cur++;
@@ -5170,7 +5170,7 @@ check_initializer (tree decl, tree init,
 	{
 	  if (init_len == 0)
 	    {
-	      maybe_warn_cpp0x ("extended initializer lists");
+	      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 	      init = build_zero_init (type, NULL_TREE, false);
 	    }
 	  else if (init_len != 1)
@@ -8523,7 +8523,7 @@ grokdeclarator (const cp_declarator *dec
 	      {
 		if (explicitp == 1)
 		  {
-		    maybe_warn_cpp0x ("explicit conversion operators");
+		    maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
 		    explicitp = 2;
 		  }
 	      }
Index: cp/error.c
===================================================================
--- cp/error.c	(revision 154234)
+++ cp/error.c	(working copy)
@@ -2885,20 +2885,57 @@ cp_printer (pretty_printer *pp, text_inf
 \f
 /* Warn about the use of C++0x features when appropriate.  */
 void
-maybe_warn_cpp0x (const char* str)
+maybe_warn_cpp0x (cpp0x_warn_str str)
 {
   if ((cxx_dialect == cxx98) && !in_system_header)
     /* We really want to suppress this warning in system headers,
        because libstdc++ uses variadic templates even when we aren't
        in C++0x mode. */
-    pedwarn (input_location, 0, "%s only available with -std=c++0x or -std=gnu++0x", str);
+    switch (str)
+      {
+      case CPP0X_INITIALIZER_LISTS:
+	pedwarn (input_location, 0, 
+		 "extended initializer lists "
+		 "only available with -std=c++0x or -std=gnu++0x");
+	break;
+      case CPP0X_EXPLICIT_CONVERSION:
+	pedwarn (input_location, 0,
+		 "explicit conversion operators "
+		 "only available with -std=c++0x or -std=gnu++0x"); 
+	break;
+      case CPP0X_VARIADIC_TEMPLATES:
+	pedwarn (input_location, 0,
+		 "variadic templates "
+		 "only available with -std=c++0x or -std=gnu++0x");
+	break;
+      case CPP0X_LAMBDA_EXPR:
+	pedwarn (input_location, 0,
+		 "lambda expressions "
+		  "only available with -std=c++0x or -std=gnu++0x");
+	break;
+      case CPP0X_AUTO:
+	pedwarn (input_location, 0,
+		 "C++0x auto only available with -std=c++0x or -std=gnu++0x");
+	break;
+      case CPP0X_SCOPED_ENUMS:
+	pedwarn (input_location, 0,
+		 "scoped enums only available with -std=c++0x or -std=gnu++0x");
+	break;
+      case CPP0X_DEFAULTED_DELETED:
+	pedwarn (input_location, 0,
+		 "defaulted and deleted functions "
+		 "only available with -std=c++0x or -std=gnu++0x");
+	break;	
+      default:
+	gcc_unreachable();
+      }
 }
 
 /* Warn about the use of variadic templates when appropriate.  */
 void
 maybe_warn_variadic_templates (void)
 {
-  maybe_warn_cpp0x ("variadic templates");
+  maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES);
 }
 
 
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 154234)
+++ cp/parser.c	(working copy)
@@ -3329,7 +3329,7 @@ cp_parser_primary_expression (cp_parser 
       if (c_dialect_objc ())
         /* We have an Objective-C++ message. */
         return cp_parser_objc_expression (parser);
-      maybe_warn_cpp0x ("lambda expressions");
+      maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR);
       return cp_parser_lambda_expression (parser);
 
     case CPP_OBJC_STRING:
@@ -5275,7 +5275,7 @@ cp_parser_parenthesized_expression_list 
 	    if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 	      {
 		/* A braced-init-list.  */
-		maybe_warn_cpp0x ("extended initializer lists");
+		maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 		expr = cp_parser_braced_list (parser, &expr_non_constant_p);
 		if (non_constant_p && expr_non_constant_p)
 		  *non_constant_p = true;
@@ -5992,7 +5992,7 @@ cp_parser_new_initializer (cp_parser* pa
     {
       tree t;
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       t = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
       expression_list = make_tree_vector_single (t);
@@ -6553,7 +6553,7 @@ cp_parser_assignment_expression (cp_pars
 	      tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
 
 	      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
-		maybe_warn_cpp0x ("extended initializer lists");
+		maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
 	      /* An assignment may not appear in a
 		 constant-expression.  */
@@ -8143,7 +8143,7 @@ cp_parser_condition (cp_parser* parser)
 	      initializer = cp_parser_initializer_clause (parser, &non_constant_p);
 	    }
 	  if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
-	    maybe_warn_cpp0x ("extended initializer lists");
+	    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 
 	  if (!non_constant_p)
 	    initializer = fold_non_dependent_expr (initializer);
@@ -8407,7 +8407,7 @@ cp_parser_jump_statement (cp_parser* par
 
 	if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 	  {
-	    maybe_warn_cpp0x ("extended initializer lists");
+	    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
 	    expr = cp_parser_braced_list (parser, &expr_non_constant_p);
 	  }
 	else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -9922,7 +9922,7 @@ cp_parser_mem_initializer (cp_parser* pa
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
       bool expr_non_constant_p;
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       expression_list = build_tree_list (NULL_TREE, expression_list);
@@ -11933,7 +11933,7 @@ cp_parser_simple_type_specifier (cp_pars
       break;
       
     case RID_AUTO:
-      maybe_warn_cpp0x ("C++0x auto");
+      maybe_warn_cpp0x (CPP0X_AUTO);
       type = make_auto ();
       break;
 
@@ -12240,7 +12240,7 @@ cp_parser_elaborated_type_specifier (cp_
           || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
         {
           if (cxx_dialect == cxx98)
-            maybe_warn_cpp0x ("scoped enums");
+            maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
           /* Consume the `struct' or `class'.  */
           cp_lexer_consume_token (parser->lexer);
@@ -12577,7 +12577,7 @@ cp_parser_enum_specifier (cp_parser* par
       || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
     {
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
       /* Consume the `struct' or `class' token.  */
       cp_lexer_consume_token (parser->lexer);
@@ -12611,7 +12611,7 @@ cp_parser_enum_specifier (cp_parser* par
 	return NULL_TREE;
 
       if (cxx_dialect == cxx98)
-        maybe_warn_cpp0x ("scoped enums");
+        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
 
       has_underlying_type = true;
 
@@ -15425,7 +15425,7 @@ cp_parser_initializer (cp_parser* parser
     }
   else if (token->type == CPP_OPEN_BRACE)
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       init = cp_parser_braced_list (parser, non_constant_p);
       CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
     }
@@ -16895,7 +16895,7 @@ cp_parser_pure_specifier (cp_parser* par
   if (token->keyword == RID_DEFAULT
       || token->keyword == RID_DELETE)
     {
-      maybe_warn_cpp0x ("defaulted and deleted functions");
+      maybe_warn_cpp0x (CPP0X_DEFAULTED_DELETED);
       return token->u.value;
     }
 
@@ -18895,7 +18895,7 @@ cp_parser_functional_cast (cp_parser* pa
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       expression_list = cp_parser_braced_list (parser, &nonconst_p);
       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
       if (TREE_CODE (type) == TYPE_DECL)
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 154234)
+++ cp/call.c	(working copy)
@@ -1228,7 +1228,7 @@ reference_binding (tree rto, tree rfrom,
 
   if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
     {
-      maybe_warn_cpp0x ("extended initializer lists");
+      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
       conv = implicit_conversion (to, from, expr, c_cast_p,
 				  flags);
       if (!CLASS_TYPE_P (to)
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 154234)
+++ cp/cp-tree.h	(working copy)
@@ -382,6 +382,28 @@ typedef enum cp_id_kind
   CP_ID_KIND_QUALIFIED
 } cp_id_kind;
 
+
+/* The various kinds of C++0x warnings we encounter. */
+
+typedef enum cpp0x_warn_str
+{
+  /* extended initializer lists */
+  CPP0X_INITIALIZER_LISTS,
+  /* explicit conversion operators */
+  CPP0X_EXPLICIT_CONVERSION,
+  /* variadic templates */
+  CPP0X_VARIADIC_TEMPLATES,
+  /* lambda expressions */
+  CPP0X_LAMBDA_EXPR,
+  /* C++0x auto */
+  CPP0X_AUTO,
+  /* scoped enums */
+  CPP0X_SCOPED_ENUMS,
+  /* defaulted and deleted functions */
+  CPP0X_DEFAULTED_DELETED
+} cpp0x_warn_str;
+  
+
 /* Macros for access to language-specific slots in an identifier.  */
 
 #define IDENTIFIER_NAMESPACE_BINDINGS(NODE)	\
@@ -4672,7 +4694,7 @@ extern const char *language_to_string		(
 extern const char *class_key_or_enum_as_string	(tree);
 extern void print_instantiation_context		(void);
 extern void maybe_warn_variadic_templates       (void);
-extern void maybe_warn_cpp0x			(const char *);
+extern void maybe_warn_cpp0x			(cpp0x_warn_str str);
 extern bool pedwarn_cxx98                       (location_t, int, const char *, ...) ATTRIBUTE_GCC_CXXDIAG(3,4);
 
 /* in except.c */
Index: testsuite/g++.old-deja/g++.other/crash28.C
===================================================================
--- testsuite/g++.old-deja/g++.other/crash28.C	(revision 154234)
+++ testsuite/g++.old-deja/g++.other/crash28.C	(working copy)
@@ -31,5 +31,5 @@ public:
 };
 void foo::x() throw(bar)
 {
-  if (!b) throw bar (static_cast<::N::X*>(this));	// { dg-error "" } parse error
+  if (!b) throw bar (static_cast<::N::X*>(this));	// { dg-error "lambda expressions|expected" } parse error
 }
Index: testsuite/g++.dg/inherit/error4.C
===================================================================
--- testsuite/g++.dg/inherit/error4.C	(revision 154234)
+++ testsuite/g++.dg/inherit/error4.C	(working copy)
@@ -2,7 +2,7 @@
 
 struct A { virtual ~A(); };
 
-struct B : A A {};		// { dg-error "" }
+struct B : A A {};		// { dg-error "expected|initializer|invalid" }
 
 A foo(const B &b)		// { dg-error "" }
 {
Index: testsuite/g++.dg/template/crash90.C
===================================================================
--- testsuite/g++.dg/template/crash90.C	(revision 154234)
+++ testsuite/g++.dg/template/crash90.C	(working copy)
@@ -4,5 +4,5 @@ template < unsigned >
 struct A ;
 template < typename >
 struct B ;
-template < typename T , A < B < T > // { dg-error "" }
+template < typename T , A < B < T > // { dg-error "initializer|parse error|valid type|expected" }
 { }

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-17 10:42 [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems Shujing Zhao
@ 2009-11-18  2:50 ` Gabriel Dos Reis
  2009-11-18  2:57   ` Shujing Zhao
  2009-11-18  3:42   ` Paolo Bonzini
  0 siblings, 2 replies; 12+ messages in thread
From: Gabriel Dos Reis @ 2009-11-18  2:50 UTC (permalink / raw)
  To: Shujing Zhao; +Cc: gcc-patches, Paolo Carlini

On Tue, Nov 17, 2009 at 2:15 AM, Shujing Zhao <pearly.zhao@oracle.com> wrote:
> Hi,
>
> This patch is to adjust the function maybe_warn_cpp0x to make the warning
> messages can be extracted by exgettext for translation. As the commenter of
> pr40892 suggested, I have made two candidate patches. One is to pass an enum
> to this function and the other is pass the complete diagnostic text to it.
> I'm not sure which one is better for trunk, so both of them are submitted to
> be selected.
> Some of test cases are also changed to add the detailed error messages to
> match the output messages.
> Both of the candidates are tested on i686-pc-linux-gnu and the diagnostic
> sentences can be extracted to gcc.pot by execute "make gcc.pot" at
> objdir/gcc.
> Which one is ok for trunk?

The second -- the one with enums.
I don't know whether it is my mailer or not, but make sure
you get the formatting right.

Thanks!

-- Gaby


>
> Thanks
> Pearly
>
> 2009-11-17  Shujing Zhao  <pearly.zhao@oracle.com>
>
>        PR c++/40892
>        * error.c (maybe_warn_cpp0x): Move the diagnostic details to the
>        caller and use gmsgid as argument name.
>        (maybe_warn_variadic_templates): Use the complete diagnostic text for
>        easier translation.
>        * call.c (reference_binding): Likewise.
>        * decl.c (reshape_init_r, check_initializer, grokdeclarator):
>        Likewise.
>        * parser.c (cp_parser_primary_expression)
>        (cp_parser_parenthesized_expression_list, cp_parser_new_initializer)
>        (cp_parser_assignment_expression, cp_parser_condition)
>        (cp_parser_jump_statement, cp_parser_mem_initializer)
>        (cp_parser_simple_type_specifier,
> cp_parser_elaborated_type_specifier)
>        (cp_parser_enum_specifier, cp_parser_initializer,
>        (cp_parser_pure_specifier, cp_parser_functional_cast): Likewise.
>
>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18  2:50 ` Gabriel Dos Reis
@ 2009-11-18  2:57   ` Shujing Zhao
  2009-11-18  3:42   ` Paolo Bonzini
  1 sibling, 0 replies; 12+ messages in thread
From: Shujing Zhao @ 2009-11-18  2:57 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: gcc-patches, Paolo Carlini

On 11/18/2009 10:16 AM, Gabriel Dos Reis wrote:
>
> The second -- the one with enums.
> I don't know whether it is my mailer or not, but make sure
> you get the formatting right.
>   
Ok. Thanks Gaby.

-- Pearly

> Thanks!
>
> -- Gaby
>
>
>   
>> Thanks
>> Pearly
>>
>> 2009-11-17  Shujing Zhao  <pearly.zhao@oracle.com>
>>
>>        PR c++/40892
>>        * error.c (maybe_warn_cpp0x): Move the diagnostic details to the
>>        caller and use gmsgid as argument name.
>>        (maybe_warn_variadic_templates): Use the complete diagnostic text for
>>        easier translation.
>>        * call.c (reference_binding): Likewise.
>>        * decl.c (reshape_init_r, check_initializer, grokdeclarator):
>>        Likewise.
>>        * parser.c (cp_parser_primary_expression)
>>        (cp_parser_parenthesized_expression_list, cp_parser_new_initializer)
>>        (cp_parser_assignment_expression, cp_parser_condition)
>>        (cp_parser_jump_statement, cp_parser_mem_initializer)
>>        (cp_parser_simple_type_specifier,
>> cp_parser_elaborated_type_specifier)
>>        (cp_parser_enum_specifier, cp_parser_initializer,
>>        (cp_parser_pure_specifier, cp_parser_functional_cast): Likewise.
>>
>>
>>
>>     

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18  2:50 ` Gabriel Dos Reis
  2009-11-18  2:57   ` Shujing Zhao
@ 2009-11-18  3:42   ` Paolo Bonzini
  2009-11-18  4:20     ` Joseph S. Myers
  1 sibling, 1 reply; 12+ messages in thread
From: Paolo Bonzini @ 2009-11-18  3:42 UTC (permalink / raw)
  To: GCC Patches, Gabriel Dos Reis

 >> I have made two candidate patches. One is to pass an enum
>> to this function and the other is pass the complete diagnostic text to it.
>> Which one is ok for trunk?
>
> The second -- the one with enums.

Since you like the enum approach, what would you think of something like 
http://gcc.gnu.org/ml/gcc-patches/2002-06/msg01620.html ?

Paolo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18  3:42   ` Paolo Bonzini
@ 2009-11-18  4:20     ` Joseph S. Myers
  2009-11-18  9:40       ` Gabriel Dos Reis
  0 siblings, 1 reply; 12+ messages in thread
From: Joseph S. Myers @ 2009-11-18  4:20 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: GCC Patches, Gabriel Dos Reis

On Wed, 18 Nov 2009, Paolo Bonzini wrote:

> >> I have made two candidate patches. One is to pass an enum
> > > to this function and the other is pass the complete diagnostic text to it.
> > > Which one is ok for trunk?
> > 
> > The second -- the one with enums.
> 
> Since you like the enum approach, what would you think of something like
> http://gcc.gnu.org/ml/gcc-patches/2002-06/msg01620.html ?

I agree with the preference for the enums, but would rather put in full 
sentences for translation instead of using fragments each of which is used 
in multiple places, unless something makes using full sentences 
infeasible.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18  4:20     ` Joseph S. Myers
@ 2009-11-18  9:40       ` Gabriel Dos Reis
  2009-11-18 10:02         ` Paolo Bonzini
  0 siblings, 1 reply; 12+ messages in thread
From: Gabriel Dos Reis @ 2009-11-18  9:40 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Paolo Bonzini, GCC Patches

On Tue, Nov 17, 2009 at 9:34 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> On Wed, 18 Nov 2009, Paolo Bonzini wrote:
>
>> >> I have made two candidate patches. One is to pass an enum
>> > > to this function and the other is pass the complete diagnostic text to it.
>> > > Which one is ok for trunk?
>> >
>> > The second -- the one with enums.
>>
>> Since you like the enum approach, what would you think of something like
>> http://gcc.gnu.org/ml/gcc-patches/2002-06/msg01620.html ?
>
> I agree with the preference for the enums, but would rather put in full
> sentences for translation instead of using fragments each of which is used
> in multiple places, unless something makes using full sentences
> infeasible.

I agree.

-- Gaby

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18  9:40       ` Gabriel Dos Reis
@ 2009-11-18 10:02         ` Paolo Bonzini
  2009-11-18 13:28           ` Joseph S. Myers
                             ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Paolo Bonzini @ 2009-11-18 10:02 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Joseph S. Myers, GCC Patches

On 11/18/2009 10:22 AM, Gabriel Dos Reis wrote:
>> >  I agree with the preference for the enums, but would rather put in full
>> >  sentences for translation instead of using fragments each of which is used
>> >  in multiple places, unless something makes using full sentences
>> >  infeasible.
> I agree.

The patch there uses full sentences when possible:

-      error ("%s for `%T [%T]' operator", problem,
+      if (match)
+        error ("ambiguous overload for `%T [%T]' operator",
+		error_type (arg1), error_type (arg2));
+      else
+        error ("no match for `%T [%T]' operator",
  		error_type (arg1), error_type (arg2));

The problem is that sometimes you have 10-20 possibilities for the 
"kind", for example in bad_specifiers

-      bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
-	bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
-	    bad_specifiers (decl, "field", virtualp, quals != NULL_TREE,
-	bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,

each of these four choices is used in three error messages, thus 
complicating the code.

I agree that though for something like check_for_new_type it would be 
possible to build the entire sentence in the function.  BTW note how 
there were two messages starting with inside, which were incorrect in 
English too:

-		  check_for_new_type ("sizeof", $3); }
-		  check_for_new_type ("alignof", $3); }
-		  check_for_new_type ("new", $2); }
-		  check_for_new_type ("cast", $2); }
-		  check_for_new_type ("__builtin_va_arg", $5); }
-		  check_for_new_type ("dynamic_cast", $3);
-		  check_for_new_type ("static_cast", $3);
-		  check_for_new_type ("reinterpret_cast", $3);
-		  check_for_new_type ("const_cast", $3);
-		  check_for_new_type ("typeid", $3);
-		{ check_for_new_type ("inside exception declarations", -		 
check_for_new_type ("inside parameter list", $1); }
-		  check_for_new_type ("exception specifier", $1);

Thanks for the quick impression.  There are definitely some changes to 
cherry pick in that patch (for example adding N_ here and there) now 
that I look at it again after years.

Paolo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18 10:02         ` Paolo Bonzini
@ 2009-11-18 13:28           ` Joseph S. Myers
  2009-11-18 15:20           ` Gabriel Dos Reis
  2009-11-20  8:30           ` Shujing Zhao
  2 siblings, 0 replies; 12+ messages in thread
From: Joseph S. Myers @ 2009-11-18 13:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Gabriel Dos Reis, GCC Patches

On Wed, 18 Nov 2009, Paolo Bonzini wrote:

> The problem is that sometimes you have 10-20 possibilities for the "kind", for
> example in bad_specifiers
> 
> -      bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
> -	bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
> -	    bad_specifiers (decl, "field", virtualp, quals != NULL_TREE,
> -	bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
> 
> each of these four choices is used in three error messages, thus complicating
> the code.

I don't see four choices in three error messages as being a problem at 
all.  In c-typeck.c there are ten calls to the WARN_FOR_ASSIGNMENT macro, 
each of which has four possible messages, for example.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18 10:02         ` Paolo Bonzini
  2009-11-18 13:28           ` Joseph S. Myers
@ 2009-11-18 15:20           ` Gabriel Dos Reis
  2009-11-20  8:30           ` Shujing Zhao
  2 siblings, 0 replies; 12+ messages in thread
From: Gabriel Dos Reis @ 2009-11-18 15:20 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, GCC Patches

On Wed, Nov 18, 2009 at 3:52 AM, Paolo Bonzini <bonzini@gnu.org> wrote:
> On 11/18/2009 10:22 AM, Gabriel Dos Reis wrote:
>>>
>>> >  I agree with the preference for the enums, but would rather put in
>>> > full
>>> >  sentences for translation instead of using fragments each of which is
>>> > used
>>> >  in multiple places, unless something makes using full sentences
>>> >  infeasible.
>>
>> I agree.
>
> The patch there uses full sentences when possible:
>
> -      error ("%s for `%T [%T]' operator", problem,
> +      if (match)
> +        error ("ambiguous overload for `%T [%T]' operator",
> +               error_type (arg1), error_type (arg2));
> +      else
> +        error ("no match for `%T [%T]' operator",
>                error_type (arg1), error_type (arg2));
>
> The problem is that sometimes you have 10-20 possibilities for the "kind",
> for example in bad_specifiers
>
> -      bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
> -       bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
> -           bad_specifiers (decl, "field", virtualp, quals != NULL_TREE,
> -       bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
>
> each of these four choices is used in three error messages, thus
> complicating the code.
>
> I agree that though for something like check_for_new_type it would be
> possible to build the entire sentence in the function.  BTW note how there
> were two messages starting with inside, which were incorrect in English too:
>
> -                 check_for_new_type ("sizeof", $3); }
> -                 check_for_new_type ("alignof", $3); }
> -                 check_for_new_type ("new", $2); }
> -                 check_for_new_type ("cast", $2); }
> -                 check_for_new_type ("__builtin_va_arg", $5); }
> -                 check_for_new_type ("dynamic_cast", $3);
> -                 check_for_new_type ("static_cast", $3);
> -                 check_for_new_type ("reinterpret_cast", $3);
> -                 check_for_new_type ("const_cast", $3);
> -                 check_for_new_type ("typeid", $3);
> -               { check_for_new_type ("inside exception declarations", -
>             check_for_new_type ("inside parameter list", $1); }
> -                 check_for_new_type ("exception specifier", $1);
>
> Thanks for the quick impression.  There are definitely some changes to
> cherry pick in that patch (for example adding N_ here and there) now that I
> look at it again after years.

I think there are good stuff there.  They just need to be structured in a way
that is more convenient for translation.

-- Gaby

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-18 10:02         ` Paolo Bonzini
  2009-11-18 13:28           ` Joseph S. Myers
  2009-11-18 15:20           ` Gabriel Dos Reis
@ 2009-11-20  8:30           ` Shujing Zhao
  2009-11-20  8:55             ` Paolo Bonzini
  2009-11-20 13:56             ` Joseph S. Myers
  2 siblings, 2 replies; 12+ messages in thread
From: Shujing Zhao @ 2009-11-20  8:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Gabriel Dos Reis, Joseph S. Myers, GCC Patches

On 11/18/2009 05:52 PM, Paolo Bonzini wrote:
> On 11/18/2009 10:22 AM, Gabriel Dos Reis wrote:
>>> >  I agree with the preference for the enums, but would rather put in 
>>> full
>>> >  sentences for translation instead of using fragments each of which 
>>> is used
>>> >  in multiple places, unless something makes using full sentences
>>> >  infeasible.
>> I agree.
> 
> 
Hi, Paolo
I'm working on the diagnostic issues of C++ front-end in 4.5.0 now. Since 4.5.0 
is in stage 3, your patch maybe is late for 4.5.0. Can I help you to refine and 
adjust it to 4.6.0 when the tree re-opens after branching?

Thanks
pearly

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-20  8:30           ` Shujing Zhao
@ 2009-11-20  8:55             ` Paolo Bonzini
  2009-11-20 13:56             ` Joseph S. Myers
  1 sibling, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2009-11-20  8:55 UTC (permalink / raw)
  To: Shujing Zhao; +Cc: Gabriel Dos Reis, Joseph S. Myers, GCC Patches

On 11/20/2009 09:14 AM, Shujing Zhao wrote:
> Can I help you to refine and adjust it to 4.6.0 when the tree re-opens
> after branching?

Yes, feel free to pick it up from me!

Paolo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems
  2009-11-20  8:30           ` Shujing Zhao
  2009-11-20  8:55             ` Paolo Bonzini
@ 2009-11-20 13:56             ` Joseph S. Myers
  1 sibling, 0 replies; 12+ messages in thread
From: Joseph S. Myers @ 2009-11-20 13:56 UTC (permalink / raw)
  To: Shujing Zhao; +Cc: Paolo Bonzini, Gabriel Dos Reis, GCC Patches

On Fri, 20 Nov 2009, Shujing Zhao wrote:

> On 11/18/2009 05:52 PM, Paolo Bonzini wrote:
> > On 11/18/2009 10:22 AM, Gabriel Dos Reis wrote:
> > > > >  I agree with the preference for the enums, but would rather put in
> > > > full
> > > > >  sentences for translation instead of using fragments each of which is
> > > > used
> > > > >  in multiple places, unless something makes using full sentences
> > > > >  infeasible.
> > > I agree.
> > 
> > 
> Hi, Paolo
> I'm working on the diagnostic issues of C++ front-end in 4.5.0 now. Since
> 4.5.0 is in stage 3, your patch maybe is late for 4.5.0. Can I help you to
> refine and adjust it to 4.6.0 when the tree re-opens after branching?

I think most such changes should be fine for 4.5, even after I submit a 
gcc.pot for 4.5 to the TP (probably when we move to regression-only mode) 
since we're dealing with messages that are not effectively translatable at 
present.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2009-11-20 13:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-17 10:42 [PATCH, PR c++/40892] Fix maybe_warn_cpp0x i18n problems Shujing Zhao
2009-11-18  2:50 ` Gabriel Dos Reis
2009-11-18  2:57   ` Shujing Zhao
2009-11-18  3:42   ` Paolo Bonzini
2009-11-18  4:20     ` Joseph S. Myers
2009-11-18  9:40       ` Gabriel Dos Reis
2009-11-18 10:02         ` Paolo Bonzini
2009-11-18 13:28           ` Joseph S. Myers
2009-11-18 15:20           ` Gabriel Dos Reis
2009-11-20  8:30           ` Shujing Zhao
2009-11-20  8:55             ` Paolo Bonzini
2009-11-20 13:56             ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).