c-pragma.h (c_lex_string_translate): Change type to int.
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 15 Jun 2004 21:43:21 +0000 (21:43 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 15 Jun 2004 21:43:21 +0000 (21:43 +0000)
gcc/ChangeLog:
* 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.
gcc/cp/ChangeLog:
* 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.

From-SVN: r83201

gcc/ChangeLog
gcc/c-lex.c
gcc/c-parse.in
gcc/c-pragma.h
gcc/cp/ChangeLog
gcc/cp/parser.c

index b75748d49cf70a950eb86e3177b5a1a1c5fe293a..fdd411cd49150ef7593372f9efd1e28137d67321 100644 (file)
@@ -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
index 3a63a053b794f189fa0e0e645dc72f9f11f710ac..81723550b1371dd934889a66cc00785ba142bb96 100644 (file)
@@ -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
     {
index 08badedb0022c97a6e01ede2d9e08856792cf1f3..ad3fb6ef5d22a67dd3f914529f6f89c8c4392c9b 100644 (file)
@@ -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; }
         ;
 
 \f
index 397b02d684079c14ba33ddf93b7fb07c90f24213..6bb10f3af704f9e94d531192413a0ada06d34f0e 100644 (file)
@@ -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 */
index 5e2c20b8408489dbf0387f35bf9ce99cd1d6d32f..3889e75b7cf0540f84b7b2d0e843344744ff60e8 100644 (file)
@@ -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
index af732d99267a9064368d5ca609fbebecd2900ba4..bc736891feff284509329a124a8d4b92b1cd29d0 100644 (file)
@@ -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.  */