aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-lex.c29
-rw-r--r--gcc/c-parse.in4
-rw-r--r--gcc/c-pragma.h8
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/parser.c128
6 files changed, 155 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b75748d..fdd411c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2004-06-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-pragma.h (c_lex_string_translate): Change type to int.
+ * c-parse.in: Change all assignments of c_lex_string_translate
+ to true and false to 1 and 0.
+ * c-lex.c (c_lex_string_translate): Likewise.
+ (lex_string): Convert string without translation in the -1
+ case.
+
2004-06-15 Mark G. Adams <mark.g.adams@sympatico.ca>
* convert.h: Add include guards
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index 3a63a05..8172355 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -53,7 +53,12 @@ static splay_tree file_info_tree;
int pending_lang_change; /* If we need to switch languages - C++ only */
int c_header_level; /* depth in C headers - C++ only */
-bool c_lex_string_translate = true; /* If we need to translate characters received. */
+
+/* If we need to translate characters received. This is tri-state:
+ 0 means use only the untranslated string; 1 means use only
+ the translated string; -1 means chain the translated string
+ to the untranslated one. */
+int c_lex_string_translate = 1;
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
@@ -699,6 +704,28 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
{
value = build_string (istr.len, (char *)istr.text);
free ((void *)istr.text);
+
+ if (c_lex_string_translate == -1)
+ {
+ if (!cpp_interpret_string_notranslate (parse_in, strs, count,
+ &istr, wide))
+ /* Assume that, if we managed to translate the string
+ above, then the untranslated parsing will always
+ succeed. */
+ abort ();
+
+ if (TREE_STRING_LENGTH (value) != (int)istr.len
+ || 0 != strncmp (TREE_STRING_POINTER (value), (char *)istr.text,
+ istr.len))
+ {
+ /* Arrange for us to return the untranslated string in
+ *valp, but to set up the C type of the translated
+ one. */
+ *valp = build_string (istr.len, (char *)istr.text);
+ valp = &TREE_CHAIN (*valp);
+ }
+ free ((void *)istr.text);
+ }
}
else
{
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 08baded..ad3fb6e 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -2545,11 +2545,11 @@ asm_clobbers:
;
stop_string_translation:
- { c_lex_string_translate = false; }
+ { c_lex_string_translate = 0; }
;
start_string_translation:
- { c_lex_string_translate = true; }
+ { c_lex_string_translate = 1; }
;
diff --git a/gcc/c-pragma.h b/gcc/c-pragma.h
index 397b02d..6bb10f3 100644
--- a/gcc/c-pragma.h
+++ b/gcc/c-pragma.h
@@ -57,8 +57,10 @@ extern void add_to_renaming_pragma_list (tree, tree);
extern int c_lex (tree *);
extern int c_lex_with_flags (tree *, unsigned char *);
-/* If true, then lex strings into the execution character set.
- Otherwise, lex strings into the host character set. */
-extern bool c_lex_string_translate;
+/* If 1, then lex strings into the execution character set.
+ If 0, lex strings into the host character set.
+ If -1, lex both, and chain them together, such that the former
+ is the TREE_CHAIN of the latter. */
+extern int c_lex_string_translate;
#endif /* GCC_C_PRAGMA_H */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5e2c20b..3889e75 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2004-06-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * parser.c: Change all assignments of c_lex_string_translate
+ to true and false to 1 and 0.
+ (cp_lexer_read_token): Convert type of the translated string.
+ (cp_parser_skip_to_closing_parentheses): Preserve original
+ value of c_lex_string_translate, and set it to -1 while
+ running.
+ (cp_parser_cache_group): Likewise.
+ (cp_parser_cache_group_1): Renamed.
+ (cp_parser_asm_operand_list): Remove redundant setting of
+ c_lex_string_translate.
+ (cp_parser_primary_expression) [CPP_STRING, CPP_WSTRING]:
+ Handle chained strings.
+
2004-06-12 Andrew Pinski <apinski@apple.com>
PR c++/14639
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index af732d9..bc73689 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -501,15 +501,25 @@ cp_lexer_read_token (cp_lexer* lexer)
if ((token->type == CPP_STRING || token->type == CPP_WSTRING)
&& flag_const_strings)
{
- tree type;
+ if (c_lex_string_translate)
+ {
+ tree value = token->value;
+ tree type;
- /* Get the current type. It will be an ARRAY_TYPE. */
- type = TREE_TYPE (token->value);
- /* Use build_cplus_array_type to rebuild the array, thereby
- getting the right type. */
- type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type));
- /* Reset the type of the token. */
- TREE_TYPE (token->value) = type;
+ /* We might as well go ahead and release the chained
+ translated string such that we can reuse its memory. */
+ if (TREE_CHAIN (value))
+ value = TREE_CHAIN (token->value);
+
+ /* Get the current type. It will be an ARRAY_TYPE. */
+ type = TREE_TYPE (value);
+ /* Use build_cplus_array_type to rebuild the array, thereby
+ getting the right type. */
+ type = build_cplus_array_type (TREE_TYPE (type),
+ TYPE_DOMAIN (type));
+ /* Reset the type of the token. */
+ TREE_TYPE (value) = type;
+ }
}
return token;
@@ -2082,34 +2092,53 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
{
unsigned paren_depth = 0;
unsigned brace_depth = 0;
+ int saved_c_lex_string_translate = c_lex_string_translate;
+ int result;
if (recovering && !or_comma && cp_parser_parsing_tentatively (parser)
&& !cp_parser_committed_to_tentative_parse (parser))
return 0;
+ if (! recovering)
+ /* If we're looking ahead, keep both translated and untranslated
+ strings. */
+ c_lex_string_translate = -1;
+
while (true)
{
cp_token *token;
/* If we've run out of tokens, then there is no closing `)'. */
if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
- return 0;
+ {
+ result = 0;
+ break;
+ }
token = cp_lexer_peek_token (parser->lexer);
/* This matches the processing in skip_to_end_of_statement. */
if (token->type == CPP_SEMICOLON && !brace_depth)
- return 0;
+ {
+ result = 0;
+ break;
+ }
if (token->type == CPP_OPEN_BRACE)
++brace_depth;
if (token->type == CPP_CLOSE_BRACE)
{
if (!brace_depth--)
- return 0;
+ {
+ result = 0;
+ break;
+ }
}
if (recovering && or_comma && token->type == CPP_COMMA
&& !brace_depth && !paren_depth)
- return -1;
+ {
+ result = -1;
+ break;
+ }
if (!brace_depth)
{
@@ -2121,13 +2150,19 @@ cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
{
if (consume_paren)
cp_lexer_consume_token (parser->lexer);
- return 1;
+ {
+ result = 1;
+ break;
+ }
}
}
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
}
+
+ c_lex_string_translate = saved_c_lex_string_translate;
+ return result;
}
/* Consume tokens until we reach the end of the current statement.
@@ -2463,12 +2498,18 @@ cp_parser_primary_expression (cp_parser *parser,
boolean-literal */
case CPP_CHAR:
case CPP_WCHAR:
- case CPP_STRING:
- case CPP_WSTRING:
case CPP_NUMBER:
token = cp_lexer_consume_token (parser->lexer);
return token->value;
+ case CPP_STRING:
+ case CPP_WSTRING:
+ token = cp_lexer_consume_token (parser->lexer);
+ if (TREE_CHAIN (token->value))
+ return TREE_CHAIN (token->value);
+ else
+ return token->value;
+
case CPP_OPEN_PAREN:
{
tree expr;
@@ -6437,7 +6478,7 @@ cp_parser_declaration (cp_parser* parser)
/* Set this here since we can be called after
pushing the linkage specification. */
- c_lex_string_translate = true;
+ c_lex_string_translate = 1;
/* Check for the `__extension__' keyword. */
if (cp_parser_extension_opt (parser, &saved_pedantic))
@@ -6455,12 +6496,12 @@ cp_parser_declaration (cp_parser* parser)
/* Don't translate the CPP_STRING in extern "C". */
if (token1.keyword == RID_EXTERN)
- c_lex_string_translate = false;
+ c_lex_string_translate = 0;
if (token1.type != CPP_EOF)
token2 = *cp_lexer_peek_nth_token (parser->lexer, 2);
- c_lex_string_translate = true;
+ c_lex_string_translate = 1;
/* If the next token is `extern' and the following token is a string
literal, then we have a linkage specification. */
@@ -7086,6 +7127,10 @@ cp_parser_linkage_specification (cp_parser* parser)
/* Assume C++ linkage. */
linkage = get_identifier ("c++");
}
+ /* If the string is chained to another string, take the latter,
+ that's the untranslated string. */
+ else if (TREE_CHAIN (token->value))
+ linkage = get_identifier (TREE_STRING_POINTER (TREE_CHAIN (token->value)));
/* If it's a simple string constant, things are easier. */
else
linkage = get_identifier (TREE_STRING_POINTER (token->value));
@@ -9915,7 +9960,7 @@ cp_parser_asm_definition (cp_parser* parser)
/* Look for the opening `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
/* Look for the string. */
- c_lex_string_translate = false;
+ c_lex_string_translate = 0;
token = cp_parser_require (parser, CPP_STRING, "asm body");
if (!token)
goto finish;
@@ -10012,7 +10057,7 @@ cp_parser_asm_definition (cp_parser* parser)
assemble_asm (string);
finish:
- c_lex_string_translate = true;
+ c_lex_string_translate = 1;
}
/* Declarators [gram.dcl.decl] */
@@ -13447,8 +13492,6 @@ cp_parser_asm_operand_list (cp_parser* parser)
tree name;
cp_token *token;
- c_lex_string_translate = false;
-
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{
/* Consume the `[' token. */
@@ -13466,14 +13509,14 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the string-literal. */
token = cp_parser_require (parser, CPP_STRING, "string-literal");
string_literal = token ? token->value : error_mark_node;
- c_lex_string_translate = true;
+ c_lex_string_translate = 1;
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
/* Parse the expression. */
expression = cp_parser_expression (parser);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
- c_lex_string_translate = false;
+ c_lex_string_translate = 0;
/* Add this operand to the list. */
asm_operands = tree_cons (build_tree_list (name, string_literal),
expression,
@@ -13599,7 +13642,7 @@ cp_parser_attribute_list (cp_parser* parser)
{
tree attribute_list = NULL_TREE;
- c_lex_string_translate = false;
+ c_lex_string_translate = 0;
while (true)
{
cp_token *token;
@@ -13645,7 +13688,7 @@ cp_parser_attribute_list (cp_parser* parser)
/* Consume the comma and keep going. */
cp_lexer_consume_token (parser->lexer);
}
- c_lex_string_translate = true;
+ c_lex_string_translate = 1;
/* We built up the list in reverse order. */
return nreverse (attribute_list);
@@ -15343,10 +15386,10 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
/* Add tokens to CACHE until a non-nested END token appears. */
static void
-cp_parser_cache_group (cp_parser *parser,
- cp_token_cache *cache,
- enum cpp_ttype end,
- unsigned depth)
+cp_parser_cache_group_1 (cp_parser *parser,
+ cp_token_cache *cache,
+ enum cpp_ttype end,
+ unsigned depth)
{
while (true)
{
@@ -15366,17 +15409,38 @@ cp_parser_cache_group (cp_parser *parser,
/* See if it starts a new group. */
if (token->type == CPP_OPEN_BRACE)
{
- cp_parser_cache_group (parser, cache, CPP_CLOSE_BRACE, depth + 1);
+ cp_parser_cache_group_1 (parser, cache, CPP_CLOSE_BRACE, depth + 1);
if (depth == 0)
return;
}
else if (token->type == CPP_OPEN_PAREN)
- cp_parser_cache_group (parser, cache, CPP_CLOSE_PAREN, depth + 1);
+ cp_parser_cache_group_1 (parser, cache, CPP_CLOSE_PAREN, depth + 1);
else if (token->type == end)
return;
}
}
+/* Convenient interface for cp_parser_cache_group_1 that makes sure we
+ preserve string tokens in both translated and untranslated
+ forms. */
+
+static void
+cp_parser_cache_group (cp_parser *parser,
+ cp_token_cache *cache,
+ enum cpp_ttype end,
+ unsigned depth)
+{
+ int saved_c_lex_string_translate;
+
+ saved_c_lex_string_translate = c_lex_string_translate;
+ c_lex_string_translate = -1;
+
+ cp_parser_cache_group_1 (parser, cache, end, depth);
+
+ c_lex_string_translate = saved_c_lex_string_translate;
+}
+
+
/* Begin parsing tentatively. We always save tokens while parsing
tentatively so that if the tentative parsing fails we can restore the
tokens. */