diff mbox series

[C++] Make some type forbidden diagnostics translatable (PR translation/90035)

Message ID 20190411075026.GX21066@tucnak
State New
Headers show
Series [C++] Make some type forbidden diagnostics translatable (PR translation/90035) | expand

Commit Message

Jakub Jelinek April 11, 2019, 7:50 a.m. UTC
Hi!

While looking into another PR, I've noticed that in two spots the
parser->type_definition_forbidden_message messages are untranslatable,
we construct them at runtime from 3 strings using concat.

The following patch fixes it by adding a const char * member
to the parser structure and passing that as another argument to error,
in the more usual case where the argument string only contains %< and %>
and not %qs added in this patch it will be just ignored.

I believe this patch is more friendly to the translators (as well as
less expensive at compile time because it doesn't have to concat/allocate
anything).

Another possibility would be to just use in cp_parser_has_attribute_expression
G_("types may not be defined in %<__builtin_has_attribute%> expressions")
and in cp_parser_sizeof_operand use a switch based on the 3 possible keyword
values and use
G_("types may not be defined in %<sizeof%> expressions")
G_("types may not be defined in %<__alignof__%> expressions")
G_("types may not be defined in %<alignof%> expressions")
G_("types may not be defined in %<typeof%> expressions")
depending on that (and C++ mode which determines which alignof spelling is
in ridpointers).  We wouldn't need to add an extra member, on the other side
the translators would need to translate 5 messages instead of just one.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR translation/90035
	* parser.h (struct cp_parser): Add
	type_definition_forbidden_message_arg member.
	* parser.c (cp_debug_parser): Print it.
	(cp_parser_check_type_definition): Pass
	parser->type_definition_forbidden_message_arg as second argument to
	error.
	(cp_parser_has_attribute_expression, cp_parser_sizeof_operand): Set
	parser->type_definition_forbidden_message_arg and use G_() with
	%qs for parser->type_definition_forbidden_message instead of
	building untranslatable message using concat.


	Jakub

Comments

Jason Merrill April 11, 2019, 3:14 p.m. UTC | #1
On 4/11/19 3:50 AM, Jakub Jelinek wrote:
> Hi!
> 
> While looking into another PR, I've noticed that in two spots the
> parser->type_definition_forbidden_message messages are untranslatable,
> we construct them at runtime from 3 strings using concat.
> 
> The following patch fixes it by adding a const char * member
> to the parser structure and passing that as another argument to error,
> in the more usual case where the argument string only contains %< and %>
> and not %qs added in this patch it will be just ignored.
> 
> I believe this patch is more friendly to the translators (as well as
> less expensive at compile time because it doesn't have to concat/allocate
> anything).
> 
> Another possibility would be to just use in cp_parser_has_attribute_expression
> G_("types may not be defined in %<__builtin_has_attribute%> expressions")
> and in cp_parser_sizeof_operand use a switch based on the 3 possible keyword
> values and use
> G_("types may not be defined in %<sizeof%> expressions")
> G_("types may not be defined in %<__alignof__%> expressions")
> G_("types may not be defined in %<alignof%> expressions")
> G_("types may not be defined in %<typeof%> expressions")
> depending on that (and C++ mode which determines which alignof spelling is
> in ridpointers).  We wouldn't need to add an extra member, on the other side
> the translators would need to translate 5 messages instead of just one.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Jason
diff mbox series

Patch

--- gcc/cp/parser.h.jj	2019-01-08 22:33:34.255713665 +0100
+++ gcc/cp/parser.h	2019-04-10 15:19:37.672814432 +0200
@@ -350,6 +350,9 @@  struct GTY(()) cp_parser {
      issued as an error message if a type is defined.  */
   const char *type_definition_forbidden_message;
 
+  /* Argument for type_definition_forbidden_message if needed.  */
+  const char *type_definition_forbidden_message_arg;
+
   /* A stack used for member functions of local classes.  The lists
      contained in an individual entry can only be processed once the
      outermost class being defined is complete.  */
--- gcc/cp/parser.c.jj	2019-03-27 21:19:39.000045746 +0100
+++ gcc/cp/parser.c	2019-04-10 15:34:28.201322120 +0200
@@ -570,8 +570,10 @@  cp_debug_parser (FILE *file, cp_parser *
   cp_debug_print_flag (file, "Colon doesn't start a class definition",
 			      parser->colon_doesnt_start_class_def_p);
   if (parser->type_definition_forbidden_message)
-    fprintf (file, "Error message for forbidden type definitions: %s\n",
-	     parser->type_definition_forbidden_message);
+    fprintf (file, "Error message for forbidden type definitions: %s %s\n",
+	     parser->type_definition_forbidden_message,
+	     parser->type_definition_forbidden_message_arg
+	     ? parser->type_definition_forbidden_message_arg : "<none>");
   cp_debug_print_unparsed_queues (file, parser->unparsed_queues);
   fprintf (file, "Number of class definitions in progress: %u\n",
 	   parser->num_classes_being_defined);
@@ -3054,8 +3056,9 @@  cp_parser_check_type_definition (cp_pars
   if (parser->type_definition_forbidden_message)
     {
       /* Don't use `%s' to print the string, because quotations (`%<', `%>')
-	 in the message need to be interpreted.  */
-      error (parser->type_definition_forbidden_message);
+	 or %qs in the message need to be interpreted.  */
+      error (parser->type_definition_forbidden_message,
+	     parser->type_definition_forbidden_message_arg);
       return false;
     }
   return true;
@@ -8518,12 +8521,12 @@  cp_parser_has_attribute_expression (cp_p
   /* Types cannot be defined in a `sizeof' expression.  Save away the
      old message.  */
   const char *saved_message = parser->type_definition_forbidden_message;
-  /* And create the new one.  */
-  const int kwd = RID_BUILTIN_HAS_ATTRIBUTE;
-  char *tmp = concat ("types may not be defined in %<",
-		      IDENTIFIER_POINTER (ridpointers[kwd]),
-		      "%> expressions", NULL);
-  parser->type_definition_forbidden_message = tmp;
+  const char *saved_message_arg
+    = parser->type_definition_forbidden_message_arg;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in %qs expressions");
+  parser->type_definition_forbidden_message_arg
+    = IDENTIFIER_POINTER (ridpointers[RID_BUILTIN_HAS_ATTRIBUTE]);
 
   /* The restrictions on constant-expressions do not apply inside
      sizeof expressions.  */
@@ -8562,10 +8565,9 @@  cp_parser_has_attribute_expression (cp_p
   --cp_unevaluated_operand;
   --c_inhibit_evaluation_warnings;
 
-  /* Free the message we created.  */
-  free (tmp);
   /* And restore the old one.  */
   parser->type_definition_forbidden_message = saved_message;
+  parser->type_definition_forbidden_message_arg = saved_message_arg;
   parser->integral_constant_expression_p
     = saved_integral_constant_expression_p;
   parser->non_integral_constant_expression_p
@@ -28928,7 +28930,7 @@  cp_parser_sizeof_operand (cp_parser* par
 {
   tree expr = NULL_TREE;
   const char *saved_message;
-  char *tmp;
+  const char *saved_message_arg;
   bool saved_integral_constant_expression_p;
   bool saved_non_integral_constant_expression_p;
 
@@ -28941,11 +28943,11 @@  cp_parser_sizeof_operand (cp_parser* par
   /* Types cannot be defined in a `sizeof' expression.  Save away the
      old message.  */
   saved_message = parser->type_definition_forbidden_message;
-  /* And create the new one.  */
-  tmp = concat ("types may not be defined in %<",
-		IDENTIFIER_POINTER (ridpointers[keyword]),
-		"%> expressions", NULL);
-  parser->type_definition_forbidden_message = tmp;
+  saved_message_arg = parser->type_definition_forbidden_message_arg;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in %qs expressions");
+  parser->type_definition_forbidden_message_arg
+    = IDENTIFIER_POINTER (ridpointers[keyword]);
 
   /* The restrictions on constant-expressions do not apply inside
      sizeof expressions.  */
@@ -29002,10 +29004,9 @@  cp_parser_sizeof_operand (cp_parser* par
   --cp_unevaluated_operand;
   --c_inhibit_evaluation_warnings;
 
-  /* Free the message we created.  */
-  free (tmp);
   /* And restore the old one.  */
   parser->type_definition_forbidden_message = saved_message;
+  parser->type_definition_forbidden_message_arg = saved_message_arg;
   parser->integral_constant_expression_p
     = saved_integral_constant_expression_p;
   parser->non_integral_constant_expression_p