This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, C] PR18249
- From: Shujing Zhao <pearly dot zhao at oracle dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, Paolo Carlini <paolo dot carlini at oracle dot com>
- Date: Wed, 19 May 2010 18:30:06 +0800
- Subject: [PATCH, C] PR18249
Hi,
This patch is to try to fix the c++ parser i18n problems. The parameter of
cp_parser_error is change from "message" to "gmsgid".
At cp_parser_require, it uses the argument of "type" to classify the
"token_desc". If "type" is CPP_KEYWORD, it uses strcmp to branch the messages.
If "token_desc" includes " or ", such as "%<:%> or %<::%>", it would translate
"expected " and "%<:%> or %<::%>" respectively.
cp_parser_require_keyword is changes to keep consistently with cp_parser_require.
To fix the problem at cp_parser_name_lookup_error, a translated 'desired' would
be passed to error_at.
An enum type non_integral_constant is defined to solve the problem of
at cp_parser_non_integral_constant_expression.
For the problem of 18248, the entire message still can't appear in gcc.pot. This
patch is only to fix the c++ end.
Is it ok?
Thanks
Pearly
2010-05-19 Shujing Zhao <pearly.zhao@oracle.com>
* parser.c (non_integral_constant): New enum.
(cp_parser_error): Use gmsgid instead of message as parameter.
(cp_parser_name_lookup_error): Wrapped desired message with _();
(cp_parser_non_integral_constant_expression): Change the type of the
last parameter to non_integral_constant and put the diagnostics in
full sentences for easy translation. Change caller.
(cp_parser_require): Put the diagnostics in full sentences for easy
translation or pass the translated diagnostic to output.
(cp_parser_require_keyword): Pass a translated diagnostic output.
Index: parser.c
===================================================================
--- parser.c (revision 159555)
+++ parser.c (working copy)
@@ -149,6 +149,62 @@ typedef struct GTY(()) cp_token_cache {
cp_token * GTY ((skip)) last;
} cp_token_cache;
+/* The various kinds of non integral constant we encounter. */
+typedef enum non_integral_constant {
+ /* floating-point literal */
+ NIC_FLOAT = 1,
+ /* %<this%> */
+ NIC_THIS,
+ /* %<__FUNCTION__%> */
+ NIC_FUNC_NAME,
+ /* %<__PRETTY_FUNCTION__%> */
+ NIC_PRETTY_FUNC,
+ /* %<__func__%> */
+ NIC_C99_FUNC,
+ /* "%<va_arg%> */
+ NIC_VA_ARG,
+ /* a cast */
+ NIC_CAST,
+ /* %<typeid%> operator */
+ NIC_TYPEID,
+ /* non-constant compound literals */
+ NIC_NCC,
+ /* a function call */
+ NIC_FUNC_CALL,
+ /* an increment */
+ NIC_INC,
+ /* an decrement */
+ NIC_DEC,
+ /* an array reference */
+ NIC_ARRAY_REF,
+ /* %<->%> */
+ NIC_ARROW,
+ /* %<.%> */
+ NIC_POINT,
+ /* the address of a label */
+ NIC_ADDR_LABEL,
+ /* %<*%> */
+ NIC_STAR,
+ /* %<&%> */
+ NIC_ADDR,
+ /* %<++%> */
+ NIC_PREINCREMENT,
+ /* %<--%> */
+ NIC_PREDECREMENT,
+ /* %<new%> */
+ NIC_NEW,
+ /* %<delete%> */
+ NIC_DEL,
+ /* calls to overloaded operators */
+ NIC_OVERLOADED,
+ /* an assignment */
+ NIC_ASSIGNMENT,
+ /* a comma operator */
+ NIC_COMMA,
+ /* a call to a constructor */
+ NIC_CONSTRUCTOR
+} non_integral_constant;
+
/* Prototypes. */
static cp_lexer *cp_lexer_new_main
@@ -2021,7 +2077,7 @@ static void cp_parser_check_for_definiti
static void cp_parser_check_for_invalid_template_id
(cp_parser *, tree, location_t location);
static bool cp_parser_non_integral_constant_expression
- (cp_parser *, const char *);
+ (cp_parser *, non_integral_constant);
static void cp_parser_diagnose_invalid_type_name
(cp_parser *, tree, tree, location_t);
static bool cp_parser_parse_and_diagnose_invalid_type_name
@@ -2088,7 +2144,7 @@ cp_parser_is_keyword (cp_token* token, e
OTHER-TOKEN". */
static void
-cp_parser_error (cp_parser* parser, const char* message)
+cp_parser_error (cp_parser* parser, const char* gmsgid)
{
if (!cp_parser_simulate_error (parser))
{
@@ -2105,7 +2161,7 @@ cp_parser_error (cp_parser* parser, cons
return;
}
- c_parse_error (message,
+ c_parse_error (gmsgid,
/* Because c_parser_error does not understand
CPP_KEYWORD, keywords are treated like
identifiers. */
@@ -2146,11 +2202,11 @@ cp_parser_name_lookup_error (cp_parser*
error_at (location, "%qE has not been declared", name);
}
else if (parser->scope && parser->scope != global_namespace)
- error_at (location, "%<%E::%E%> %s", parser->scope, name, desired);
+ error_at (location, "%<%E::%E%> %s", parser->scope, name, _(desired));
else if (parser->scope == global_namespace)
- error_at (location, "%<::%E%> %s", name, desired);
+ error_at (location, "%<::%E%> %s", name, _(desired));
else
- error_at (location, "%qE %s", name, desired);
+ error_at (location, "%qE %s", name, _(desired));
}
/* If we are parsing tentatively, remember that an error has occurred
@@ -2302,20 +2358,112 @@ cp_parser_check_for_invalid_template_id
static bool
cp_parser_non_integral_constant_expression (cp_parser *parser,
- const char *thing)
+ non_integral_constant thing)
{
parser->non_integral_constant_expression_p = true;
if (parser->integral_constant_expression_p)
{
if (!parser->allow_non_integral_constant_expression_p)
{
- /* Don't use `%s' to print THING, because quotations (`%<', `%>')
- in the message need to be interpreted. */
- char *message = concat (thing,
- " cannot appear in a constant-expression",
- NULL);
- error (message);
- free (message);
+ const char *msg = NULL;
+ switch (thing)
+ {
+ case NIC_FLOAT:
+ error ("floating-point literal "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_CAST:
+ error ("a cast to a type other than an integral or "
+ "enumeration type cannot appear in a "
+ "constant-expression");
+ return true;
+ case NIC_TYPEID:
+ error ("%<typeid%> operator "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_NCC:
+ error ("non-constant compound literals "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_FUNC_CALL:
+ error ("a function call "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_INC:
+ error ("an increment "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_DEC:
+ error ("an decrement "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_ARRAY_REF:
+ error ("an array reference "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_ADDR_LABEL:
+ error ("the address of a label "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_OVERLOADED:
+ error ("calls to overloaded operators "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_ASSIGNMENT:
+ error ("an assignment cannot appear in a constant-expression");
+ return true;
+ case NIC_COMMA:
+ error ("a comma operator "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_CONSTRUCTOR:
+ error ("a call to a constructor "
+ "cannot appear in a constant-expression");
+ return true;
+ case NIC_THIS:
+ msg = "this";
+ break;
+ case NIC_FUNC_NAME:
+ msg = "__FUNCTION__";
+ break;
+ case NIC_PRETTY_FUNC:
+ msg = "__PRETTY_FUNCTION__";
+ break;
+ case NIC_C99_FUNC:
+ msg = "__func__";
+ break;
+ case NIC_VA_ARG:
+ msg = "va_arg";
+ break;
+ case NIC_ARROW:
+ msg = "->";
+ break;
+ case NIC_POINT:
+ msg = ".";
+ break;
+ case NIC_STAR:
+ msg = "*";
+ break;
+ case NIC_ADDR:
+ msg = "&";
+ break;
+ case NIC_PREINCREMENT:
+ msg = "++";
+ break;
+ case NIC_PREDECREMENT:
+ msg = "--";
+ break;
+ case NIC_NEW:
+ msg = "new";
+ break;
+ case NIC_DEL:
+ msg = "delete";
+ break;
+ default:
+ break;
+ }
+ if (msg)
+ error ("%qs cannot appear in a constant-expression", msg);
return true;
}
}
@@ -3253,8 +3401,7 @@ cp_parser_primary_expression (cp_parser
checked at that point. If we are not within a cast, then
this code is invalid. */
if (!cast_p)
- cp_parser_non_integral_constant_expression
- (parser, "floating-point literal");
+ cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
}
return token->u.value;
@@ -3383,7 +3530,7 @@ cp_parser_primary_expression (cp_parser
return error_mark_node;
}
/* Pointers cannot appear in constant-expressions. */
- if (cp_parser_non_integral_constant_expression (parser, "%<this%>"))
+ if (cp_parser_non_integral_constant_expression (parser, NIC_THIS))
return error_mark_node;
return finish_this_expr ();
@@ -3396,7 +3543,7 @@ cp_parser_primary_expression (cp_parser
case RID_PRETTY_FUNCTION_NAME:
case RID_C99_FUNCTION_NAME:
{
- const char *name;
+ non_integral_constant name;
/* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
__func__ are the names of variables -- but they are
@@ -3410,13 +3557,13 @@ cp_parser_primary_expression (cp_parser
switch (token->keyword)
{
case RID_FUNCTION_NAME:
- name = "%<__FUNCTION__%>";
+ name = NIC_FUNC_NAME;
break;
case RID_PRETTY_FUNCTION_NAME:
- name = "%<__PRETTY_FUNCTION__%>";
+ name = NIC_PRETTY_FUNC;
break;
case RID_C99_FUNCTION_NAME:
- name = "%<__func__%>";
+ name = NIC_C99_FUNC;
break;
default:
gcc_unreachable ();
@@ -3450,8 +3597,7 @@ cp_parser_primary_expression (cp_parser
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
/* Using `va_arg' in a constant-expression is not
allowed. */
- if (cp_parser_non_integral_constant_expression (parser,
- "%<va_arg%>"))
+ if (cp_parser_non_integral_constant_expression (parser,NIC_VA_ARG))
return error_mark_node;
return build_x_va_arg (expression, type);
}
@@ -4576,10 +4722,7 @@ cp_parser_postfix_expression (cp_parser
/* Only type conversions to integral or enumeration types
can be used in constant-expressions. */
if (!cast_valid_in_integral_constant_expression_p (type)
- && (cp_parser_non_integral_constant_expression
- (parser,
- "a cast to a type other than an integral or "
- "enumeration type")))
+ && (cp_parser_non_integral_constant_expression (parser, NIC_CAST)))
return error_mark_node;
switch (keyword)
@@ -4651,8 +4794,7 @@ cp_parser_postfix_expression (cp_parser
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
/* `typeid' may not appear in an integral constant expression. */
- if (cp_parser_non_integral_constant_expression(parser,
- "%<typeid%> operator"))
+ if (cp_parser_non_integral_constant_expression(parser, NIC_TYPEID))
return error_mark_node;
}
break;
@@ -4740,8 +4882,8 @@ cp_parser_postfix_expression (cp_parser
currently accepted programs. (Of course, as
compound literals are not part of ISO C++, the
standard has nothing to say.) */
- if (cp_parser_non_integral_constant_expression
- (parser, "non-constant compound literals"))
+ if (cp_parser_non_integral_constant_expression (parser,
+ NIC_NCC))
{
postfix_expression = error_mark_node;
break;
@@ -4833,7 +4975,7 @@ cp_parser_postfix_expression (cp_parser
constant-expressions. */
if (! builtin_valid_in_constant_expr_p (postfix_expression)
&& cp_parser_non_integral_constant_expression (parser,
- "a function call"))
+ NIC_FUNC_CALL))
{
postfix_expression = error_mark_node;
release_tree_vector (args);
@@ -4971,8 +5113,7 @@ cp_parser_postfix_expression (cp_parser
= finish_increment_expr (postfix_expression,
POSTINCREMENT_EXPR);
/* Increments may not appear in constant-expressions. */
- if (cp_parser_non_integral_constant_expression (parser,
- "an increment"))
+ if (cp_parser_non_integral_constant_expression (parser, NIC_INC))
postfix_expression = error_mark_node;
idk = CP_ID_KIND_NONE;
is_member_access = false;
@@ -4987,8 +5128,7 @@ cp_parser_postfix_expression (cp_parser
= finish_increment_expr (postfix_expression,
POSTDECREMENT_EXPR);
/* Decrements may not appear in constant-expressions. */
- if (cp_parser_non_integral_constant_expression (parser,
- "a decrement"))
+ if (cp_parser_non_integral_constant_expression (parser, NIC_DEC))
postfix_expression = error_mark_node;
idk = CP_ID_KIND_NONE;
is_member_access = false;
@@ -5049,8 +5189,7 @@ cp_parser_postfix_open_square_expression
/* When not doing offsetof, array references are not permitted in
constant-expressions. */
if (!for_offsetof
- && (cp_parser_non_integral_constant_expression
- (parser, "an array reference")))
+ && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
postfix_expression = error_mark_node;
return postfix_expression;
@@ -5225,7 +5364,7 @@ cp_parser_postfix_dot_deref_expression (
constant-expressions. */
if (!for_offsetof
&& (cp_parser_non_integral_constant_expression
- (parser, token_type == CPP_DEREF ? "%<->%>" : "%<.%>")))
+ (parser, token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT)))
postfix_expression = error_mark_node;
return postfix_expression;
@@ -5627,7 +5766,7 @@ cp_parser_unary_expression (cp_parser *p
/* Create an expression representing the address. */
expression = finish_label_address_expr (identifier, loc);
if (cp_parser_non_integral_constant_expression (parser,
- "the address of a label"))
+ NIC_ADDR_LABEL))
expression = error_mark_node;
return expression;
}
@@ -5636,7 +5775,7 @@ cp_parser_unary_expression (cp_parser *p
{
tree cast_expression;
tree expression = error_mark_node;
- const char *non_constant_p = NULL;
+ non_integral_constant non_constant_p = 0;
/* Consume the operator token. */
token = cp_lexer_consume_token (parser->lexer);
@@ -5649,13 +5788,13 @@ cp_parser_unary_expression (cp_parser *p
switch (unary_operator)
{
case INDIRECT_REF:
- non_constant_p = "%<*%>";
+ non_constant_p = NIC_STAR;
expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR,
tf_warning_or_error);
break;
case ADDR_EXPR:
- non_constant_p = "%<&%>";
+ non_constant_p = NIC_ADDR;
/* Fall through. */
case BIT_NOT_EXPR:
expression = build_x_unary_op (unary_operator, cast_expression,
@@ -5664,8 +5803,8 @@ cp_parser_unary_expression (cp_parser *p
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
- non_constant_p = (unary_operator == PREINCREMENT_EXPR
- ? "%<++%>" : "%<--%>");
+ non_constant_p = unary_operator == PREINCREMENT_EXPR
+ ? NIC_PREINCREMENT : NIC_PREDECREMENT;
/* Fall through. */
case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
@@ -5797,7 +5936,7 @@ cp_parser_new_expression (cp_parser* par
/* A new-expression may not appear in an integral constant
expression. */
- if (cp_parser_non_integral_constant_expression (parser, "%<new%>"))
+ if (cp_parser_non_integral_constant_expression (parser, NIC_NEW))
ret = error_mark_node;
else
{
@@ -6082,7 +6221,7 @@ cp_parser_delete_expression (cp_parser*
/* A delete-expression may not appear in an integral constant
expression. */
- if (cp_parser_non_integral_constant_expression (parser, "%<delete%>"))
+ if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
return error_mark_node;
return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
@@ -6244,10 +6383,8 @@ cp_parser_cast_expression (cp_parser *pa
/* Only type conversions to integral or enumeration types
can be used in constant-expressions. */
if (!cast_valid_in_integral_constant_expression_p (type)
- && (cp_parser_non_integral_constant_expression
- (parser,
- "a cast to a type other than an integral or "
- "enumeration type")))
+ && (cp_parser_non_integral_constant_expression (parser,
+ NIC_CAST)))
return error_mark_node;
/* Perform the cast. */
@@ -6482,8 +6619,8 @@ cp_parser_binary_expression (cp_parser*
least one of the operands is of enumeration type. */
if (overloaded_p
- && (cp_parser_non_integral_constant_expression
- (parser, "calls to overloaded operators")))
+ && (cp_parser_non_integral_constant_expression (parser,
+ NIC_OVERLOADED)))
return error_mark_node;
}
@@ -6595,7 +6732,7 @@ cp_parser_assignment_expression (cp_pars
/* An assignment may not appear in a
constant-expression. */
if (cp_parser_non_integral_constant_expression (parser,
- "an assignment"))
+ NIC_ASSIGNMENT))
return error_mark_node;
/* Build the assignment expression. */
expr = build_x_modify_expr (expr,
@@ -6730,8 +6867,7 @@ cp_parser_expression (cp_parser* parser,
/* Consume the `,'. */
cp_lexer_consume_token (parser->lexer);
/* A comma operator cannot appear in a constant-expression. */
- if (cp_parser_non_integral_constant_expression (parser,
- "a comma operator"))
+ if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
expression = error_mark_node;
}
@@ -6817,7 +6953,7 @@ cp_parser_constant_expression (cp_parser
offsetof-member-designator:
id-expression
| offsetof-member-designator "." id-expression
- | offsetof-member-designator "[" expression "]"
+ | offsetof-member-designator "%<*>%"[" expression "]"
| offsetof-member-designator "->" id-expression */
static tree
@@ -13168,7 +13304,7 @@ cp_parser_using_directive (cp_parser* pa
/* Look for the `using' keyword. */
cp_parser_require_keyword (parser, RID_USING, "%<using%>");
/* And the `namespace' keyword. */
- cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>");
+ cp_parser_require_keyword (parser, RID_NAMESPACE, "namespace");
/* Look for the optional `::' operator. */
cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
/* And the optional nested-name-specifier. */
@@ -13348,10 +13484,10 @@ cp_parser_asm_definition (cp_parser* par
}
if (goto_p && !labels_p)
- missing = clobbers_p ? "%<:%>" : "%<:%> or %<::%>";
+ missing = clobbers_p ? "%<:%>" : _("%<:%> or %<::%>");
}
else if (goto_p)
- missing = "%<:%> or %<::%>";
+ missing = _("%<:%> or %<::%>");
/* Look for the closing `)'. */
if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
@@ -19003,8 +19139,8 @@ cp_parser_functional_cast (cp_parser* pa
type = TREE_TYPE (type);
if (cast != error_mark_node
&& !cast_valid_in_integral_constant_expression_p (type)
- && (cp_parser_non_integral_constant_expression
- (parser, "a call to a constructor")))
+ && (cp_parser_non_integral_constant_expression (parser,
+ NIC_CONSTRUCTOR)))
return error_mark_node;
return cast;
}
@@ -19634,9 +19770,40 @@ cp_parser_require (cp_parser* parser,
/* Output the MESSAGE -- unless we're parsing tentatively. */
if (!cp_parser_simulate_error (parser))
{
- char *message = concat ("expected ", token_desc, NULL);
- cp_parser_error (parser, message);
- free (message);
+ switch (type)
+ {
+ case CPP_PRAGMA_EOL:
+ cp_parser_error (parser, "expected end of line");
+ break;
+ case CPP_NAME:
+ cp_parser_error (parser, "expected identifier");
+ break;
+ case CPP_KEYWORD:
+ if (strcmp (token_desc, "selection-statement"))
+ cp_parser_error (parser, "expected selection-statement");
+ else if (strcmp (token_desc, "iteration-statement"))
+ cp_parser_error (parser, "expected iteration-statement");
+ else if (strcmp (token_desc, "jump-statement"))
+ cp_parser_error (parser, "expected jump-statement");
+ else if (strcmp (token_desc, "class-key"))
+ cp_parser_error (parser, "expected class-key");
+ else if (strcmp (token_desc, " or "))
+ cp_parser_error (parser,
+ "expected %<class%>, %<typename%>, or %<template%>");
+ else
+ {
+ char *message = concat (_("expected "), token_desc, NULL);
+ cp_parser_error (parser, message);
+ free (message);
+ }
+ break;
+ default:
+ {
+ char *message = concat (_("expected "), token_desc, NULL);
+ cp_parser_error (parser, message);
+ free (message);
+ }
+ }
}
return NULL;
}
@@ -19738,14 +19905,9 @@ cp_parser_require_keyword (cp_parser* pa
if (token && token->keyword != keyword)
{
- dyn_string_t error_msg;
-
- /* Format the error message. */
- error_msg = dyn_string_new (0);
- dyn_string_append_cstr (error_msg, "expected ");
- dyn_string_append_cstr (error_msg, token_desc);
- cp_parser_error (parser, error_msg->s);
- dyn_string_delete (error_msg);
+ char *message = concat (_("expected "), token_desc, NULL);
+ cp_parser_error (parser, message);
+ free (message);
return NULL;
}
@@ -21720,7 +21882,7 @@ cp_parser_omp_clause_schedule (cp_parser
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
goto resync_fail;
}
- else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>"))
+ else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, _("%<,%> or %<)%>")))
goto resync_fail;
check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);