FreeBSD/contrib/gcc/cp/parser.c
/* Parse a sequence of adjacent string constants.  Returns a
   TREE_STRING representing the combined, nul-terminated string
   constant.  If TRANSLATE is true, translate the string to the
   execution character set.  If WIDE_OK is true, a wide string is
   invalid here.

   C++98 [lex.string] says that if a narrow string literal token is
   adjacent to a wide string literal token, the behavior is undefined.
   However, C99 6.4.5p4 says that this results in a wide string literal.
   We follow C99 here, for consistency with the C front end.

   This code is largely lifted from lex_string() in c-lex.c.

   FUTURE: ObjC++ will need to handle @-strings here.  */
Parse a sequence of adjacent string constants.  Returns a
TREE_STRING representing the combined, nul-terminated string
constant.  If TRANSLATE is true, translate the string to the
execution character set.  If WIDE_OK is true, a wide string is
invalid here.

C++98 [lex.string] says that if a narrow string literal token is
adjacent to a wide string literal token, the behavior is undefined.
However, C99 6.4.5p4 says that this results in a wide string literal.
We follow C99 here, for consistency with the C front end.

This code is largely lifted from lex_string() in c-lex.c.

ObjC++ will need to handle @-strings here.
Parse a sequence of adjacent string constants . Returns a TREE_STRING representing the combined nul - terminated string constant . If TRANSLATE is true translate the string to the execution character set . If WIDE_OK is true a wide string is invalid here . C ++ 98 [ lex . string ] says that if a narrow string literal token is adjacent to a wide string literal token the behavior is undefined . However C99 6 . 4 . 5p4 says that this results in a wide string literal . We follow C99 here for consistency with the C front end . This code is largely lifted from lex_string () in c - lex . c . ObjC ++ will need to handle @ - strings here .
static tree
cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
{
  tree value;
  bool wide = false;
  size_t count;
  struct obstack str_ob;
  cpp_string str, istr, *strs;
  cp_token *tok;
  tok = cp_lexer_peek_token (parser->lexer);
  if (!cp_parser_is_string_literal (tok))
    {
      cp_parser_error (parser, "expected string-literal");
      return error_mark_node;
    }
  if (!cp_parser_is_string_literal
      (cp_lexer_peek_nth_token (parser->lexer, 2)))
    {
      cp_lexer_consume_token (parser->lexer);
      str.text = (const unsigned char *)TREE_STRING_POINTER (tok->u.value);
      str.len = TREE_STRING_LENGTH (tok->u.value);
      count = 1;
      if (tok->type == CPP_WSTRING)
	wide = true;
      strs = &str;
    }
  else
    {
      gcc_obstack_init (&str_ob);
      count = 0;
      do
	{
	  cp_lexer_consume_token (parser->lexer);
	  count++;
	  str.text = (unsigned char *)TREE_STRING_POINTER (tok->u.value);
	  str.len = TREE_STRING_LENGTH (tok->u.value);
	  if (tok->type == CPP_WSTRING)
	    wide = true;
	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
	  tok = cp_lexer_peek_token (parser->lexer);
	}
      while (cp_parser_is_string_literal (tok));
      strs = (cpp_string *) obstack_finish (&str_ob);
    }
  if (wide && !wide_ok)
    {
      cp_parser_error (parser, "a wide string is invalid in this context");
      wide = false;
    }
  if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
      (parse_in, strs, count, &istr, wide))
    {
      value = build_string (istr.len, (char *)istr.text);
      free ((void *)istr.text);
      TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
      value = fix_string_type (value);
    }
  else
    value = error_mark_node;
  if (count > 1)
    obstack_free (&str_ob, 0);
  return value;
}
static tree cp_parser_string_literal ( cp_parser * parser , bool translate , bool wide_ok ) { tree value ; bool wide = false ; size_t count ; struct obstack str_ob ; cpp_string str , istr , * strs ; cp_token * tok ; tok = cp_lexer_peek_token ( parser -> lexer ) ; if ( ! cp_parser_is_string_literal ( tok ) ) { cp_parser_error ( parser , " " ) ; return error_mark_node ; } if ( ! cp_parser_is_string_literal ( cp_lexer_peek_nth_token ( parser -> lexer , 2 ) ) ) { cp_lexer_consume_token ( parser -> lexer ) ; str . text = ( const unsigned char * ) TREE_STRING_POINTER ( tok -> u . value ) ; str . len = TREE_STRING_LENGTH ( tok -> u . value ) ; count = 1 ; if ( tok -> type == CPP_WSTRING ) wide = true ; strs = & str ; } else { gcc_obstack_init ( & str_ob ) ; count = 0 ; do { cp_lexer_consume_token ( parser -> lexer ) ; count ++ ; str . text = ( unsigned char * ) TREE_STRING_POINTER ( tok -> u . value ) ; str . len = TREE_STRING_LENGTH ( tok -> u . value ) ; if ( tok -> type == CPP_WSTRING ) wide = true ; obstack_grow ( & str_ob , & str , sizeof ( cpp_string ) ) ; tok = cp_lexer_peek_token ( parser -> lexer ) ; } while ( cp_parser_is_string_literal ( tok ) ) ; strs = ( cpp_string * ) obstack_finish ( & str_ob ) ; } if ( wide && ! wide_ok ) { cp_parser_error ( parser , " " ) ; wide = false ; } if ( ( translate ? cpp_interpret_string : cpp_interpret_string_notranslate ) ( parse_in , strs , count , & istr , wide ) ) { value = build_string ( istr . len , ( char * ) istr . text ) ; free ( ( void * ) istr . text ) ; TREE_TYPE ( value ) = wide ? wchar_array_type_node : char_array_type_node ; value = fix_string_type ( value ) ; } else value = error_mark_node ; if ( count > 1 ) obstack_free ( & str_ob , 0 ) ; return value ; }
Parse a sequence of adjacent string constants.
Parse a sequence of adjacent string constants .
/* Try to avoid the overhead of creating and destroying an obstack
     for the common case of just one string.  */ /* cpp_interpret_string has issued an error.  */