diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-lex.c | 29 | ||||
-rw-r--r-- | gcc/c-parse.in | 4 | ||||
-rw-r--r-- | gcc/c-pragma.h | 8 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/parser.c | 128 |
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. */ |