Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.2
gcc43
sap303956-utf16-1.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File sap303956-utf16-1.diff of Package gcc43
This is r134438. gcc/ 2008-04-18 Kris Van Hees <kris.van.hees@oracle.com> * c-common.c (CHAR16_TYPE, CHAR32_TYPE): New macros. (fname_as_string): Match updated cpp_interpret_string prototype. (fix_string_type): Support char16_t* and char32_t*. (c_common_nodes_and_builtins): Add char16_t and char32_t (and derivative) nodes. Register as builtin if C++0x. (c_parse_error): Support CPP_CHAR{16,32}. * c-common.h (RID_CHAR16, RID_CHAR32): New elements. (enum c_tree_index) <CTI_CHAR16_TYPE, CTI_SIGNED_CHAR16_TYPE, CTI_UNSIGNED_CHAR16_TYPE, CTI_CHAR32_TYPE, CTI_SIGNED_CHAR32_TYPE, CTI_UNSIGNED_CHAR32_TYPE, CTI_CHAR16_ARRAY_TYPE, CTI_CHAR32_ARRAY_TYPE>: New elements. (char16_type_node, signed_char16_type_node, unsigned_char16_type_node, char32_type_node, signed_char32_type_node, char16_array_type_node, char32_array_type_node): New defines. * c-lex.c (cb_ident): Match updated cpp_interpret_string prototype. (c_lex_with_flags): Support CPP_CHAR{16,32} and CPP_STRING{16,32}. (lex_string): Support CPP_STRING{16,32}, match updated cpp_interpret_string and cpp_interpret_string_notranslate prototypes. (lex_charconst): Support CPP_CHAR{16,32}. * c-parser.c (c_parser_postfix_expression): Support CPP_CHAR{16,32} and CPP_STRING{16,32}. gcc/testsuite 2008-04-18 Kris Van Hees <kris.van.hees@oracle.com> Tests for char16_t and char32_t support. * g++.dg/ext/utf-cvt.C: New * g++.dg/ext/utf-cxx0x.C: New * g++.dg/ext/utf-cxx98.C: New * g++.dg/ext/utf-dflt.C: New * g++.dg/ext/utf-gnuxx0x.C: New * g++.dg/ext/utf-gnuxx98.C: New * g++.dg/ext/utf-mangle.C: New * g++.dg/ext/utf-typedef-cxx0x.C: New * g++.dg/ext/utf-typedef-cxx98.C: New * g++.dg/ext/utf-typespec.C: New * g++.dg/ext/utf16-1.C: New * g++.dg/ext/utf16-2.C: New * g++.dg/ext/utf16-3.C: New * g++.dg/ext/utf16-4.C: New * g++.dg/ext/utf32-1.C: New * g++.dg/ext/utf32-2.C: New * g++.dg/ext/utf32-3.C: New * g++.dg/ext/utf32-4.C: New * gcc.dg/utf-cvt.c: New * gcc.dg/utf-dflt.c: New * gcc.dg/utf16-1.c: New * gcc.dg/utf16-2.c: New * gcc.dg/utf16-3.c: New * gcc.dg/utf16-4.c: New * gcc.dg/utf32-1.c: New * gcc.dg/utf32-2.c: New * gcc.dg/utf32-3.c: New * gcc.dg/utf32-4.c: New gcc/cp 2008-04-18 Kris Van Hees <kris.van.hees@oracle.com> * cvt.c (type_promotes_to): Support char16_t and char32_t. * decl.c (grokdeclarator): Disallow signed/unsigned/short/long on char16_t and char32_t. * lex.c (reswords): Add char16_t and char32_t (for c++0x). * mangle.c (write_builtin_type): Mangle char16_t/char32_t as vendor extended builtin type "u8char{16,32}_t". * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Support RID_CHAR{16,32}. (cp_lexer_print_token): Support CPP_STRING{16,32}. (cp_parser_is_string_literal): Idem. (cp_parser_string_literal): Idem. (cp_parser_primary_expression): Support CPP_CHAR{16,32} and CPP_STRING{16,32}. (cp_parser_simple_type_specifier): Support RID_CHAR{16,32}. * tree.c (char_type_p): Support char16_t and char32_t as char types. * typeck.c (string_conv_p): Support char16_t and char32_t. libiberty/ 2008-04-18 Kris Van Hees <kris.van.hees@oracle.com> * testsuite/demangle-expected: Added tests for char16_t and char32_t. libcpp/ 2008-04-18 Kris Van Hees <kris.van.hees@oracle.com> * include/cpp-id-data.h (UC): Was U, conflicts with U"..." literal. * include/cpplib.h (CHAR16, CHAR32, STRING16, STRING32): New tokens. (struct cpp_options): Added uliterals. (cpp_interpret_string): Update prototype. (cpp_interpret_string_notranslate): Idem. * charset.c (init_iconv_desc): New width member in cset_converter. (cpp_init_iconv): Add support for char{16,32}_cset_desc. (convert_ucn): Idem. (emit_numeric_escape): Idem. (convert_hex): Idem. (convert_oct): Idem. (convert_escape): Idem. (converter_for_type): New function. (cpp_interpret_string): Use converter_for_type, support u and U prefix. (cpp_interpret_string_notranslate): Match changed prototype. (wide_str_to_charconst): Use converter_for_type. (cpp_interpret_charconst): Add support for CPP_CHAR{16,32}. * directives.c (linemarker_dir): Macro U changed to UC. (parse_include): Idem. (register_pragma_1): Idem. (restore_registered_pragmas): Idem. (get__Pragma_string): Support CPP_STRING{16,32}. * expr.c (eval_token): Support CPP_CHAR{16,32}. * init.c (struct lang_flags): Added uliterals. (lang_defaults): Idem. * internal.h (struct cset_converter) <width>: New field. (struct cpp_reader) <char16_cset_desc>: Idem. (struct cpp_reader) <char32_cset_desc>: Idem. * lex.c (digraph_spellings): Macro U changed to UC. (OP, TK): Idem. (lex_string): Add support for u'...', U'...', u"..." and U"...". (_cpp_lex_direct): Idem. * macro.c (_cpp_builtin_macro_text): Macro U changed to UC. (stringify_arg): Support CPP_CHAR{16,32} and CPP_STRING{16,32}. Index: gcc/c-lex.c =================================================================== *** gcc/c-lex.c (revision 134437) --- gcc/c-lex.c (revision 134438) *************** cb_ident (cpp_reader * ARG_UNUSED (pfile *** 174,180 **** { /* Convert escapes in the string. */ cpp_string cstr = { 0, 0 }; ! if (cpp_interpret_string (pfile, str, 1, &cstr, false)) { ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text); free (CONST_CAST (unsigned char *, cstr.text)); --- 174,180 ---- { /* Convert escapes in the string. */ cpp_string cstr = { 0, 0 }; ! if (cpp_interpret_string (pfile, str, 1, &cstr, CPP_STRING)) { ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text); free (CONST_CAST (unsigned char *, cstr.text)); *************** c_lex_with_flags (tree *value, location_ *** 361,366 **** --- 361,368 ---- case CPP_STRING: case CPP_WSTRING: + case CPP_STRING16: + case CPP_STRING32: type = lex_string (tok, value, true, true); break; *************** c_lex_with_flags (tree *value, location_ *** 410,420 **** --- 412,426 ---- case CPP_CHAR: case CPP_WCHAR: + case CPP_CHAR16: + case CPP_CHAR32: *value = lex_charconst (tok); break; case CPP_STRING: case CPP_WSTRING: + case CPP_STRING16: + case CPP_STRING32: if ((lex_flags & C_LEX_RAW_STRINGS) == 0) { type = lex_string (tok, value, false, *************** interpret_fixed (const cpp_token *token, *** 822,833 **** return value; } ! /* Convert a series of STRING and/or WSTRING tokens into a tree, ! performing string constant concatenation. TOK is the first of ! these. VALP is the location to write the string into. OBJC_STRING ! indicates whether an '@' token preceded the incoming token. Returns the CPP token type of the result (CPP_STRING, CPP_WSTRING, ! or CPP_OBJC_STRING). This is unfortunately more work than it should be. If any of the strings in the series has an L prefix, the result is a wide string --- 828,839 ---- return value; } ! /* Convert a series of STRING, WSTRING, STRING16 and/or STRING32 tokens ! into a tree, performing string constant concatenation. TOK is the ! first of these. VALP is the location to write the string into. ! OBJC_STRING indicates whether an '@' token preceded the incoming token. Returns the CPP token type of the result (CPP_STRING, CPP_WSTRING, ! CPP_STRING32, CPP_STRING16, or CPP_OBJC_STRING). This is unfortunately more work than it should be. If any of the strings in the series has an L prefix, the result is a wide string *************** static enum cpp_ttype *** 842,860 **** lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate) { tree value; - bool wide = false; size_t concats = 0; struct obstack str_ob; cpp_string istr; /* Try to avoid the overhead of creating and destroying an obstack for the common case of just one string. */ cpp_string str = tok->val.str; cpp_string *strs = &str; - if (tok->type == CPP_WSTRING) - wide = true; - retry: tok = cpp_get_token (parse_in); switch (tok->type) --- 848,863 ---- lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate) { tree value; size_t concats = 0; struct obstack str_ob; cpp_string istr; + enum cpp_ttype type = tok->type; /* Try to avoid the overhead of creating and destroying an obstack for the common case of just one string. */ cpp_string str = tok->val.str; cpp_string *strs = &str; retry: tok = cpp_get_token (parse_in); switch (tok->type) *************** lex_string (const cpp_token *tok, tree * *** 873,880 **** break; case CPP_WSTRING: ! wide = true; ! /* FALLTHROUGH */ case CPP_STRING: if (!concats) --- 876,890 ---- break; case CPP_WSTRING: ! case CPP_STRING16: ! case CPP_STRING32: ! if (type != tok->type) ! { ! if (type == CPP_STRING) ! type = tok->type; ! else ! error ("unsupported non-standard concatenation of string literals"); ! } case CPP_STRING: if (!concats) *************** lex_string (const cpp_token *tok, tree * *** 899,905 **** if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate) ! (parse_in, strs, concats + 1, &istr, wide)) { value = build_string (istr.len, (const char *) istr.text); free (CONST_CAST (unsigned char *, istr.text)); --- 909,915 ---- if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate) ! (parse_in, strs, concats + 1, &istr, type)) { value = build_string (istr.len, (const char *) istr.text); free (CONST_CAST (unsigned char *, istr.text)); *************** lex_string (const cpp_token *tok, tree * *** 909,930 **** /* Callers cannot generally handle error_mark_node in this context, so return the empty string instead. cpp_interpret_string has issued an error. */ ! if (wide) ! value = build_string (TYPE_PRECISION (wchar_type_node) ! / TYPE_PRECISION (char_type_node), ! "\0\0\0"); /* widest supported wchar_t ! is 32 bits */ ! else ! value = build_string (1, ""); } ! TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node; *valp = fix_string_type (value); if (concats) obstack_free (&str_ob, 0); ! return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING; } /* Converts a (possibly wide) character constant token into a tree. */ --- 919,970 ---- /* Callers cannot generally handle error_mark_node in this context, so return the empty string instead. cpp_interpret_string has issued an error. */ ! switch (type) ! { ! default: ! case CPP_STRING: ! value = build_string (1, ""); ! break; ! case CPP_STRING16: ! value = build_string (TYPE_PRECISION (char16_type_node) ! / TYPE_PRECISION (char_type_node), ! "\0"); /* char16_t is 16 bits */ ! break; ! case CPP_STRING32: ! value = build_string (TYPE_PRECISION (char32_type_node) ! / TYPE_PRECISION (char_type_node), ! "\0\0\0"); /* char32_t is 32 bits */ ! break; ! case CPP_WSTRING: ! value = build_string (TYPE_PRECISION (wchar_type_node) ! / TYPE_PRECISION (char_type_node), ! "\0\0\0"); /* widest supported wchar_t ! is 32 bits */ ! break; ! } } ! switch (type) ! { ! default: ! case CPP_STRING: ! TREE_TYPE (value) = char_array_type_node; ! break; ! case CPP_STRING16: ! TREE_TYPE (value) = char16_array_type_node; ! break; ! case CPP_STRING32: ! TREE_TYPE (value) = char32_array_type_node; ! break; ! case CPP_WSTRING: ! TREE_TYPE (value) = wchar_array_type_node; ! } *valp = fix_string_type (value); if (concats) obstack_free (&str_ob, 0); ! return objc_string ? CPP_OBJC_STRING : type; } /* Converts a (possibly wide) character constant token into a tree. */ *************** lex_charconst (const cpp_token *token) *** 941,946 **** --- 981,990 ---- if (token->type == CPP_WCHAR) type = wchar_type_node; + else if (token->type == CPP_CHAR32) + type = char32_type_node; + else if (token->type == CPP_CHAR16) + type = char16_type_node; /* In C, a character constant has type 'int'. In C++ 'char', but multi-char charconsts have type 'int'. */ else if (!c_dialect_cxx () || chars_seen > 1) Index: gcc/testsuite/gcc.dg/utf32-2.c =================================================================== *** gcc/testsuite/gcc.dg/utf32-2.c (revision 0) --- gcc/testsuite/gcc.dg/utf32-2.c (revision 134438) *************** *** 0 **** --- 1,31 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char32_t* string constants. */ + /* { dg-do run } */ + /* { dg-options "-std=gnu99 -Wall -Werror" } */ + + typedef unsigned int char32_t; + + extern void abort (void); + + char32_t *s0 = U"ab"; + char32_t *s1 = U"a\u0024"; + char32_t *s2 = U"a\u2029"; + char32_t *s3 = U"a\U00064321"; + + #define A 0x00000061 + #define B 0x00000062 + #define D 0x00000024 + #define X 0x00002029 + #define Y 0x00064321 + + int main () + { + if (s0[0] != A || s0[1] != B || s0[2] != 0x00000000) + abort (); + if (s1[0] != A || s1[1] != D || s0[2] != 0x00000000) + abort (); + if (s2[0] != A || s2[1] != X || s0[2] != 0x00000000) + abort (); + if (s3[0] != A || s3[1] != Y || s3[2] != 0x00000000) + abort (); + } Index: gcc/testsuite/gcc.dg/utf32-4.c =================================================================== *** gcc/testsuite/gcc.dg/utf32-4.c (revision 0) --- gcc/testsuite/gcc.dg/utf32-4.c (revision 134438) *************** *** 0 **** --- 1,20 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char32_t character constants. */ + /* { dg-do compile } */ + /* { dg-options "-std=gnu99" } */ + + typedef unsigned int char32_t; + + char32_t c0 = U''; /* { dg-error "empty character" } */ + char32_t c1 = U'ab'; /* { dg-warning "constant too long" } */ + char32_t c2 = U'\U00064321'; + + char32_t c3 = 'a'; + char32_t c4 = u'a'; + char32_t c5 = u'\u2029'; + char32_t c6 = u'\U00064321'; /* { dg-warning "constant too long" } */ + char32_t c7 = L'a'; + char32_t c8 = L'\u2029'; + char32_t c9 = L'\U00064321'; + + int main () {} Index: gcc/testsuite/gcc.dg/utf16-2.c =================================================================== *** gcc/testsuite/gcc.dg/utf16-2.c (revision 0) --- gcc/testsuite/gcc.dg/utf16-2.c (revision 134438) *************** *** 0 **** --- 1,32 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char16_t* string literals. */ + /* { dg-do run } */ + /* { dg-options "-std=gnu99 -Wall -Werror" } */ + + typedef short unsigned int char16_t; + + extern void abort (void); + + char16_t *s0 = u"ab"; + char16_t *s1 = u"a\u0024"; + char16_t *s2 = u"a\u2029"; + char16_t *s3 = u"a\U00064321"; + + #define A 0x0061 + #define B 0x0062 + #define D 0x0024 + #define X 0x2029 + #define Y1 0xD950 + #define Y2 0xDF21 + + int main () + { + if (s0[0] != A || s0[1] != B || s0[2] != 0x0000) + abort (); + if (s1[0] != A || s1[1] != D || s0[2] != 0x0000) + abort (); + if (s2[0] != A || s2[1] != X || s0[2] != 0x0000) + abort (); + if (s3[0] != A || s3[1] != Y1 || s3[2] != Y2 || s3[3] != 0x0000) + abort (); + } Index: gcc/testsuite/gcc.dg/utf16-4.c =================================================================== *** gcc/testsuite/gcc.dg/utf16-4.c (revision 0) --- gcc/testsuite/gcc.dg/utf16-4.c (revision 134438) *************** *** 0 **** --- 1,20 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char16_t character constants. */ + /* { dg-do compile } */ + /* { dg-options "-std=gnu99" } */ + + typedef short unsigned int char16_t; + + char16_t c0 = u''; /* { dg-error "empty character" } */ + char16_t c1 = u'ab'; /* { dg-warning "constant too long" } */ + char16_t c2 = u'\U00064321'; /* { dg-warning "constant too long" } */ + + char16_t c3 = 'a'; + char16_t c4 = U'a'; + char16_t c5 = U'\u2029'; + char16_t c6 = U'\U00064321'; /* { dg-warning "implicitly truncated" } */ + char16_t c7 = L'a'; + char16_t c8 = L'\u2029'; + char16_t c9 = L'\U00064321'; /* { dg-warning "implicitly truncated" } */ + + int main () {} Index: gcc/testsuite/gcc.dg/utf-badconcat.c =================================================================== *** gcc/testsuite/gcc.dg/utf-badconcat.c (revision 0) --- gcc/testsuite/gcc.dg/utf-badconcat.c (revision 134438) *************** *** 0 **** --- 1,22 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test unsupported concatenation of char16_t/char32_t* string literals. */ + /* { dg-do compile } */ + /* { dg-options "-std=gnu99" } */ + + void *s0 = u"a" "b"; + void *s1 = "a" u"b"; + void *s2 = u"a" U"b"; /* { dg-error "non-standard concatenation" } */ + void *s3 = U"a" u"b"; /* { dg-error "non-standard concatenation" } */ + void *s4 = u"a" L"b"; /* { dg-error "non-standard concatenation" } */ + void *s5 = L"a" u"b"; /* { dg-error "non-standard concatenation" } */ + void *s6 = u"a" u"b"; + void *s7 = U"a" "b"; + void *s8 = "a" U"b"; + void *s9 = U"a" L"b"; /* { dg-error "non-standard concatenation" } */ + void *sa = L"a" U"b"; /* { dg-error "non-standard concatenation" } */ + void *sb = U"a" U"b"; + void *sc = L"a" "b"; + void *sd = "a" L"b"; + void *se = L"a" L"b"; + + int main () {} Index: gcc/testsuite/gcc.dg/utf32-1.c =================================================================== *** gcc/testsuite/gcc.dg/utf32-1.c (revision 0) --- gcc/testsuite/gcc.dg/utf32-1.c (revision 134438) *************** *** 0 **** --- 1,44 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char32_t character constants. */ + /* { dg-do run } */ + /* { dg-options "-std=gnu99 -Wall -Werror" } */ + + typedef unsigned int char32_t; + + extern void abort (void); + + char32_t c0 = U'a'; + char32_t c1 = U'\0'; + char32_t c2 = U'\u0024'; + char32_t c3 = U'\u2029'; + char32_t c4 = U'\U00064321'; + + #define A 0x00000061 + #define D 0x00000024 + #define X 0x00002029 + #define Y 0x00064321 + + int main () + { + if (sizeof (U'a') != sizeof (char32_t)) + abort (); + if (sizeof (U'\0') != sizeof (char32_t)) + abort (); + if (sizeof (U'\u0024') != sizeof (char32_t)) + abort (); + if (sizeof (U'\u2029') != sizeof (char32_t)) + abort (); + if (sizeof (U'\U00064321') != sizeof (char32_t)) + abort (); + + if (c0 != A) + abort (); + if (c1 != 0x0000) + abort (); + if (c2 != D) + abort (); + if (c3 != X) + abort (); + if (c4 != Y) + abort (); + } Index: gcc/testsuite/gcc.dg/utf32-3.c =================================================================== *** gcc/testsuite/gcc.dg/utf32-3.c (revision 0) --- gcc/testsuite/gcc.dg/utf32-3.c (revision 134438) *************** *** 0 **** --- 1,48 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test concatenation of char32_t* string literals. */ + /* { dg-do run } */ + /* { dg-options "-std=gnu99 -Wall -Werror" } */ + + typedef unsigned int char32_t; + + extern void abort (void); + + char32_t *s0 = U"a" U"b"; + + char32_t *s1 = U"a" "b"; + char32_t *s2 = "a" U"b"; + char32_t *s3 = U"a" "\u2029"; + char32_t *s4 = "\u2029" U"b"; + char32_t *s5 = U"a" "\U00064321"; + char32_t *s6 = "\U00064321" U"b"; + + #define A 0x00000061 + #define B 0x00000062 + #define X 0x00002029 + #define Y 0x00064321 + + int main () + { + if (sizeof ((U"a" U"b")[0]) != sizeof (char32_t)) + abort (); + if (sizeof ((U"a" "b")[0]) != sizeof (char32_t)) + abort (); + if (sizeof (( "a" U"b")[0]) != sizeof (char32_t)) + abort (); + + if (s0[0] != A || s0[1] != B || s0[2] != 0x00000000) + abort (); + + if (s1[0] != A || s1[1] != B || s1[2] != 0x00000000) + abort (); + if (s2[0] != A || s2[1] != B || s2[2] != 0x00000000) + abort (); + if (s3[0] != A || s3[1] != X || s3[2] != 0x00000000) + abort (); + if (s4[0] != X || s4[1] != B || s4[2] != 0x00000000) + abort (); + if (s5[0] != A || s5[1] != Y || s5[2] != 0x00000000) + abort (); + if (s6[0] != Y || s6[1] != B || s6[2] != 0x00000000) + abort (); + } Index: gcc/testsuite/gcc.dg/utf16-1.c =================================================================== *** gcc/testsuite/gcc.dg/utf16-1.c (revision 0) --- gcc/testsuite/gcc.dg/utf16-1.c (revision 134438) *************** *** 0 **** --- 1,67 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char16_t character constants. */ + /* { dg-do run } */ + /* { dg-options "-std=gnu99 -Wall -Werror" } */ + + typedef short unsigned int char16_t; + + extern void abort (void); + + char16_t c0 = u'a'; + char16_t c1 = u'\0'; + char16_t c2 = u'\u0024'; + char16_t c3 = u'\u2029'; + char16_t c4 = u'\u8010'; + + char16_t c5 = 'a'; + char16_t c6 = U'a'; + char16_t c7 = U'\u2029'; + char16_t c8 = U'\u8010'; + char16_t c9 = L'a'; + char16_t ca = L'\u2029'; + char16_t cb = L'\u8010'; + + #define A 0x0061 + #define D 0x0024 + #define X 0x2029 + #define Y 0x8010 + + int main () + { + if (sizeof (u'a') != sizeof (char16_t)) + abort (); + if (sizeof (u'\0') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u0024') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u2029') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u8010') != sizeof (char16_t)) + abort (); + + if (c0 != A) + abort (); + if (c1 != 0x0000) + abort (); + if (c2 != D) + abort (); + if (c3 != X) + abort (); + if (c4 != Y) + abort (); + + if (c5 != A) + abort (); + if (c6 != A) + abort (); + if (c7 != X) + abort (); + if (c8 != Y) + abort (); + if (c9 != A) + abort (); + if (ca != X) + abort (); + if (cb != Y) + abort (); + } Index: gcc/testsuite/gcc.dg/utf16-3.c =================================================================== *** gcc/testsuite/gcc.dg/utf16-3.c (revision 0) --- gcc/testsuite/gcc.dg/utf16-3.c (revision 134438) *************** *** 0 **** --- 1,49 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test concatenation of char16_t* string literals. */ + /* { dg-do run } */ + /* { dg-options "-std=gnu99 -Wall -Werror" } */ + + typedef short unsigned int char16_t; + + extern void abort (void); + + char16_t *s0 = u"a" u"b"; + + char16_t *s1 = u"a" "b"; + char16_t *s2 = "a" u"b"; + char16_t *s3 = u"a" "\u2029"; + char16_t *s4 = "\u2029" u"b"; + char16_t *s5 = u"a" "\U00064321"; + char16_t *s6 = "\U00064321" u"b"; + + #define A 0x0061 + #define B 0x0062 + #define X 0x2029 + #define Y1 0xD950 + #define Y2 0xDF21 + + int main () + { + if (sizeof ((u"a" u"b")[0]) != sizeof (char16_t)) + abort (); + if (sizeof ((u"a" "b")[0]) != sizeof (char16_t)) + abort (); + if (sizeof (( "a" u"b")[0]) != sizeof (char16_t)) + abort (); + + if (s0[0] != A || s0[1] != B || s0[2] != 0x0000) + abort (); + + if (s1[0] != A || s1[1] != B || s1[2] != 0x0000) + abort (); + if (s2[0] != A || s2[1] != B || s2[2] != 0x0000) + abort (); + if (s3[0] != A || s3[1] != X || s3[2] != 0x0000) + abort (); + if (s4[0] != X || s4[1] != B || s4[2] != 0x0000) + abort (); + if (s5[0] != A || s5[1] != Y1 || s5[2] != Y2 || s5[3] != 0x0000) + abort (); + if (s6[0] != Y1 || s6[1] != Y2 || s6[2] != B || s6[3] != 0x0000) + abort (); + } Index: gcc/testsuite/gcc.dg/utf-cvt.c =================================================================== *** gcc/testsuite/gcc.dg/utf-cvt.c (revision 0) --- gcc/testsuite/gcc.dg/utf-cvt.c (revision 134438) *************** *** 0 **** --- 1,49 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the char16_t and char32_t promotion rules. */ + /* { dg-do compile } */ + /* { dg-options "-std=gnu99 -Wall -Wconversion -Wsign-conversion" } */ + + typedef unsigned short char16_t; + typedef unsigned int char32_t; + + extern void f_c (char); + extern void fsc (signed char); + extern void fuc (unsigned char); + extern void f_s (short); + extern void fss (signed short); + extern void fus (unsigned short); + extern void f_i (int); + extern void fsi (signed int); + extern void fui (unsigned int); + extern void f_l (long); + extern void fsl (signed long); + extern void ful (unsigned long); + + void m (char16_t c0, char32_t c1) + { + f_c (c0); /* { dg-warning "alter its value" } */ + fsc (c0); /* { dg-warning "alter its value" } */ + fuc (c0); /* { dg-warning "alter its value" } */ + f_s (c0); /* { dg-warning "change the sign" } */ + fss (c0); /* { dg-warning "change the sign" } */ + fus (c0); + f_i (c0); + fsi (c0); + fui (c0); + f_l (c0); + fsl (c0); + ful (c0); + + f_c (c1); /* { dg-warning "alter its value" } */ + fsc (c1); /* { dg-warning "alter its value" } */ + fuc (c1); /* { dg-warning "alter its value" } */ + f_s (c1); /* { dg-warning "alter its value" } */ + fss (c1); /* { dg-warning "alter its value" } */ + fus (c1); /* { dg-warning "alter its value" } */ + f_i (c1); /* { dg-warning "change the sign" } */ + fsi (c1); /* { dg-warning "change the sign" } */ + fui (c1); + f_l (c1); /* { dg-warning "change the sign" } */ + fsl (c1); /* { dg-warning "change the sign" } */ + ful (c1); + } Index: gcc/testsuite/gcc.dg/utf-dflt.c =================================================================== *** gcc/testsuite/gcc.dg/utf-dflt.c (revision 0) --- gcc/testsuite/gcc.dg/utf-dflt.c (revision 134438) *************** *** 0 **** --- 1,25 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* If not gnu99, the u and U prefixes should be parsed as separate tokens. */ + /* { dg-do compile } */ + /* { dg-options "" } */ + + const unsigned short c0 = u'a'; /* { dg-error "undeclared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 6 } */ + const unsigned long c1 = U'a'; /* { dg-error "undeclared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 8 } */ + + #define u 1 + + #define U 2 + + + const unsigned short c2 = u'a'; + const unsigned long c3 = U'a'; + + #undef u + #undef U + #define u "a" + #define U "b" + + const void *s0 = u"a"; + const void *s1 = U"a"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf16-1.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf16-1.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf16-1.C (revision 134438) *************** *** 0 **** --- 1,65 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char16_t character constants. */ + /* { dg-do run } */ + /* { dg-options "-std=c++0x -Wall -Werror" } */ + + extern "C" void abort (void); + + const static char16_t c0 = u'a'; + const static char16_t c1 = u'\0'; + const static char16_t c2 = u'\u0024'; + const static char16_t c3 = u'\u2029'; + const static char16_t c4 = u'\u8010'; + + const static char16_t c5 = 'a'; + const static char16_t c6 = U'a'; + const static char16_t c7 = U'\u2029'; + const static char16_t c8 = U'\u8010'; + const static char16_t c9 = L'a'; + const static char16_t ca = L'\u2029'; + const static char16_t cb = L'\u8010'; + + #define A 0x0061 + #define D 0x0024 + #define X 0x2029 + #define Y 0x8010 + + int main () + { + if (sizeof (u'a') != sizeof (char16_t)) + abort (); + if (sizeof (u'\0') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u0024') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u2029') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u8010') != sizeof (char16_t)) + abort (); + + if (c0 != A) + abort (); + if (c1 != 0x0000) + abort (); + if (c2 != D) + abort (); + if (c3 != X) + abort (); + if (c4 != Y) + abort (); + + if (c5 != A) + abort (); + if (c6 != A) + abort (); + if (c7 != X) + abort (); + if (c8 != Y) + abort (); + if (c9 != A) + abort (); + if (ca != X) + abort (); + if (cb != Y) + abort (); + } Index: gcc/testsuite/g++.dg/ext/utf32-4.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf32-4.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf32-4.C (revision 134438) *************** *** 0 **** --- 1,18 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char32_t character constants. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x" } */ + + const static char32_t c0 = U''; /* { dg-error "empty character" } */ + const static char32_t c1 = U'ab'; /* { dg-warning "constant too long" } */ + const static char32_t c2 = U'\U00064321'; + + const static char32_t c3 = 'a'; + const static char32_t c4 = u'a'; + const static char32_t c5 = u'\u2029'; + const static char32_t c6 = u'\U00064321'; /* { dg-warning "constant too long" } */ + const static char32_t c7 = L'a'; + const static char32_t c8 = L'\u2029'; + const static char32_t c9 = L'\U00064321'; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf-cxx98.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-cxx98.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-cxx98.C (revision 134438) *************** *** 0 **** --- 1,29 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char16_t/char32_t in c++98. */ + /* Ensure u and U prefixes are parsed as separate tokens in c++98. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++98" } */ + + const static char16_t c0 = 'a'; /* { dg-error "not name a type" } */ + const static char32_t c1 = 'a'; /* { dg-error "not name a type" } */ + + const unsigned short c2 = u'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 10 } */ + const unsigned long c3 = U'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 12 } */ + + #define u 1 + + #define U 2 + + + const unsigned short c5 = u'a'; + const unsigned long c6 = U'a'; + + #undef u + #undef U + #define u "a" + #define U "b" + + const void *s0 = u"a"; + const void *s1 = U"a"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf16-2.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf16-2.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf16-2.C (revision 134438) *************** *** 0 **** --- 1,30 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char16_t* string literals. */ + /* { dg-do run } */ + /* { dg-options "-std=c++0x -Wall -Werror" } */ + + extern "C" void abort (void); + + const static char16_t *s0 = u"ab"; + const static char16_t *s1 = u"a\u0024"; + const static char16_t *s2 = u"a\u2029"; + const static char16_t *s3 = u"a\U00064321"; + + #define A 0x0061 + #define B 0x0062 + #define D 0x0024 + #define X 0x2029 + #define Y1 0xD950 + #define Y2 0xDF21 + + int main () + { + if (s0[0] != A || s0[1] != B || s0[2] != 0x0000) + abort (); + if (s1[0] != A || s1[1] != D || s0[2] != 0x0000) + abort (); + if (s2[0] != A || s2[1] != X || s0[2] != 0x0000) + abort (); + if (s3[0] != A || s3[1] != Y1 || s3[2] != Y2 || s3[3] != 0x0000) + abort (); + } Index: gcc/testsuite/g++.dg/ext/utf16-3.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf16-3.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf16-3.C (revision 134438) *************** *** 0 **** --- 1,47 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test concatenation of char16_t* string literals. */ + /* { dg-do run } */ + /* { dg-options "-std=c++0x -Wall -Werror" } */ + + extern "C" void abort (void); + + const static char16_t *s0 = u"a" u"b"; + + const static char16_t *s1 = u"a" "b"; + const static char16_t *s2 = "a" u"b"; + const static char16_t *s3 = u"a" "\u2029"; + const static char16_t *s4 = "\u2029" u"b"; + const static char16_t *s5 = u"a" "\U00064321"; + const static char16_t *s6 = "\U00064321" u"b"; + + #define A 0x0061 + #define B 0x0062 + #define X 0x2029 + #define Y1 0xD950 + #define Y2 0xDF21 + + int main () + { + if (sizeof ((u"a" u"b")[0]) != sizeof (char16_t)) + abort (); + if (sizeof ((u"a" "b")[0]) != sizeof (char16_t)) + abort (); + if (sizeof (( "a" u"b")[0]) != sizeof (char16_t)) + abort (); + + if (s0[0] != A || s0[1] != B || s0[2] != 0x0000) + abort (); + + if (s1[0] != A || s1[1] != B || s1[2] != 0x0000) + abort (); + if (s2[0] != A || s2[1] != B || s2[2] != 0x0000) + abort (); + if (s3[0] != A || s3[1] != X || s3[2] != 0x0000) + abort (); + if (s4[0] != X || s4[1] != B || s4[2] != 0x0000) + abort (); + if (s5[0] != A || s5[1] != Y1 || s5[2] != Y2 || s5[3] != 0x0000) + abort (); + if (s6[0] != Y1 || s6[1] != Y2 || s6[2] != B || s6[3] != 0x0000) + abort (); + } Index: gcc/testsuite/g++.dg/ext/utf-badconcat.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-badconcat.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-badconcat.C (revision 134438) *************** *** 0 **** --- 1,22 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test unsupported concatenation of char16_t/char32_t* string literals. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x" } */ + + const void *s0 = u"a" "b"; + const void *s1 = "a" u"b"; + const void *s2 = u"a" U"b"; /* { dg-error "non-standard concatenation" } */ + const void *s3 = U"a" u"b"; /* { dg-error "non-standard concatenation" } */ + const void *s4 = u"a" L"b"; /* { dg-error "non-standard concatenation" } */ + const void *s5 = L"a" u"b"; /* { dg-error "non-standard concatenation" } */ + const void *s6 = u"a" u"b"; + const void *s7 = U"a" "b"; + const void *s8 = "a" U"b"; + const void *s9 = U"a" L"b"; /* { dg-error "non-standard concatenation" } */ + const void *sa = L"a" U"b"; /* { dg-error "non-standard concatenation" } */ + const void *sb = U"a" U"b"; + const void *sc = L"a" "b"; + const void *sd = "a" L"b"; + const void *se = L"a" L"b"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf-typedef-cxx0x.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-typedef-cxx0x.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-typedef-cxx0x.C (revision 134438) *************** *** 0 **** --- 1,7 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Ensure that a typedef to char16_t/char32_t issues a warning in c++0x. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x" } */ + + typedef short unsigned int char16_t; /* { dg-warning "redeclaration" } */ + typedef unsigned int char32_t; /* { dg-warning "redeclaration" } */ Index: gcc/testsuite/g++.dg/ext/utf16-4.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf16-4.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf16-4.C (revision 134438) *************** *** 0 **** --- 1,18 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char16_t character constants. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x" } */ + + const static char16_t c0 = u''; /* { dg-error "empty character" } */ + const static char16_t c1 = u'ab'; /* { dg-warning "constant too long" } */ + const static char16_t c2 = u'\U00064321'; /* { dg-warning "constant too long" } */ + + const static char16_t c3 = 'a'; + const static char16_t c4 = U'a'; + const static char16_t c5 = U'\u2029'; + const static char16_t c6 = U'\U00064321'; /* { dg-warning "implicitly truncated" } */ + const static char16_t c7 = L'a'; + const static char16_t c8 = L'\u2029'; + const static char16_t c9 = L'\U00064321'; /* { dg-warning "implicitly truncated" } */ + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf-gnuxx98.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-gnuxx98.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-gnuxx98.C (revision 134438) *************** *** 0 **** --- 1,29 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char16_t/char32_t in gnu++98. */ + /* Ensure u and U prefixes are parsed as separate tokens in gnu++98. */ + /* { dg-do compile } */ + /* { dg-options "-std=gnu++98" } */ + + const static char16_t c0 = 'a'; /* { dg-error "not name a type" } */ + const static char32_t c1 = 'a'; /* { dg-error "not name a type" } */ + + const unsigned short c2 = u'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 10 } */ + const unsigned long c3 = U'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 12 } */ + + #define u 1 + + #define U 2 + + + const unsigned short c5 = u'a'; + const unsigned long c6 = U'a'; + + #undef u + #undef U + #define u "a" + #define U "b" + + const void *s0 = u"a"; + const void *s1 = U"a"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf-cvt.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-cvt.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-cvt.C (revision 134438) *************** *** 0 **** --- 1,46 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the char16_t and char32_t promotion rules. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x -Wall -Wconversion -Wsign-conversion -Wsign-promo" } */ + + extern void f_c (char); + extern void fsc (signed char); + extern void fuc (unsigned char); + extern void f_s (short); + extern void fss (signed short); + extern void fus (unsigned short); + extern void f_i (int); + extern void fsi (signed int); + extern void fui (unsigned int); + extern void f_l (long); + extern void fsl (signed long); + extern void ful (unsigned long); + + void m(char16_t c0, char32_t c1) + { + f_c (c0); /* { dg-warning "alter its value" } */ + fsc (c0); /* { dg-warning "alter its value" } */ + fuc (c0); /* { dg-warning "alter its value" } */ + f_s (c0); /* { dg-warning "change the sign" } */ + fss (c0); /* { dg-warning "change the sign" } */ + fus (c0); + f_i (c0); + fsi (c0); + fui (c0); + f_l (c0); + fsl (c0); + ful (c0); + + f_c (c1); /* { dg-warning "alter its value" } */ + fsc (c1); /* { dg-warning "alter its value" } */ + fuc (c1); /* { dg-warning "alter its value" } */ + f_s (c1); /* { dg-warning "alter its value" } */ + fss (c1); /* { dg-warning "alter its value" } */ + fus (c1); /* { dg-warning "alter its value" } */ + f_i (c1); /* { dg-warning "change the sign" } */ + fsi (c1); /* { dg-warning "change the sign" } */ + fui (c1); + f_l (c1); /* { dg-warning "change the sign" } */ + fsl (c1); /* { dg-warning "change the sign" } */ + ful (c1); + } Index: gcc/testsuite/g++.dg/ext/utf-dflt.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-dflt.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-dflt.C (revision 134438) *************** *** 0 **** --- 1,29 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Expected errors for char16_t/char32_t in default std. */ + /* Ensure u and U prefixes are parsed as separate tokens in default std. */ + /* { dg-do compile } */ + /* { dg-options "" } */ + + const static char16_t c0 = 'a'; /* { dg-error "not name a type" } */ + const static char32_t c1 = 'a'; /* { dg-error "not name a type" } */ + + const unsigned short c2 = u'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 10 } */ + const unsigned long c3 = U'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 12 } */ + + #define u 1 + + #define U 2 + + + const unsigned short c4 = u'a'; + const unsigned long c5 = U'a'; + + #undef u + #undef U + #define u "a" + #define U "b" + + const void *s0 = u"a"; + const void *s1 = U"a"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf-cxx0x.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-cxx0x.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-cxx0x.C (revision 134438) *************** *** 0 **** --- 1,14 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test parsing of u and U prefixes when also used as macros. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x" } */ + + #define u L + #define U L + + const unsigned short c2 = u'a'; + const unsigned long c3 = U'a'; + const void *s0 = u"a"; + const void *s1 = U"a"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf32-1.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf32-1.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf32-1.C (revision 134438) *************** *** 0 **** --- 1,42 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char32_t character constants. */ + /* { dg-do run } */ + /* { dg-options "-std=c++0x -Wall -Werror" } */ + + extern "C" void abort (void); + + const static char32_t c0 = U'a'; + const static char32_t c1 = U'\0'; + const static char32_t c2 = U'\u0024'; + const static char32_t c3 = U'\u2029'; + const static char32_t c4 = U'\U00064321'; + + #define A 0x00000061 + #define D 0x00000024 + #define X 0x00002029 + #define Y 0x00064321 + + int main () + { + if (sizeof (U'a') != sizeof (char32_t)) + abort (); + if (sizeof (U'\0') != sizeof (char32_t)) + abort (); + if (sizeof (U'\u0024') != sizeof (char32_t)) + abort (); + if (sizeof (U'\u2029') != sizeof (char32_t)) + abort (); + if (sizeof (U'\U00064321') != sizeof (char32_t)) + abort (); + + if (c0 != A) + abort (); + if (c1 != 0x0000) + abort (); + if (c2 != D) + abort (); + if (c3 != X) + abort (); + if (c4 != Y) + abort (); + } Index: gcc/testsuite/g++.dg/ext/utf-typespec.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-typespec.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-typespec.C (revision 134438) *************** *** 0 **** --- 1,25 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Ensure that type specifiers are not allowed for char16_t/char32_t. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++0x" } */ + + signed char16_t c0; /* { dg-error "signed" } */ + signed char32_t c1; /* { dg-error "signed" } */ + unsigned char16_t c2; /* { dg-error "unsigned" } */ + unsigned char32_t c3; /* { dg-error "unsigned" } */ + + short char16_t c4; /* { dg-error "short" } */ + long char16_t c5; /* { dg-error "long" } */ + short char32_t c6; /* { dg-error "short" } */ + long char32_t c7; /* { dg-error "long" } */ + + signed short char16_t c8; /* { dg-error "signed" } */ + signed short char32_t c9; /* { dg-error "signed" } */ + signed long char16_t ca; /* { dg-error "signed" } */ + signed long char32_t cb; /* { dg-error "signed" } */ + unsigned short char16_t cc; /* { dg-error "unsigned" } */ + unsigned short char32_t cd; /* { dg-error "unsigned" } */ + unsigned long char16_t ce; /* { dg-error "unsigned" } */ + unsigned long char32_t cf; /* { dg-error "unsigned" } */ + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf32-2.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf32-2.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf32-2.C (revision 134438) *************** *** 0 **** --- 1,29 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test the support for char32_t* string constants. */ + /* { dg-do run } */ + /* { dg-options "-std=c++0x -Wall -Werror" } */ + + extern "C" void abort (void); + + const static char32_t *s0 = U"ab"; + const static char32_t *s1 = U"a\u0024"; + const static char32_t *s2 = U"a\u2029"; + const static char32_t *s3 = U"a\U00064321"; + + #define A 0x00000061 + #define B 0x00000062 + #define D 0x00000024 + #define X 0x00002029 + #define Y 0x00064321 + + int main () + { + if (s0[0] != A || s0[1] != B || s0[2] != 0x00000000) + abort (); + if (s1[0] != A || s1[1] != D || s0[2] != 0x00000000) + abort (); + if (s2[0] != A || s2[1] != X || s0[2] != 0x00000000) + abort (); + if (s3[0] != A || s3[1] != Y || s3[2] != 0x00000000) + abort (); + } Index: gcc/testsuite/g++.dg/ext/utf-gnuxx0x.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-gnuxx0x.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-gnuxx0x.C (revision 134438) *************** *** 0 **** --- 1,14 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test parsing of u and U prefixes when also used as macros. */ + /* { dg-do compile } */ + /* { dg-options "-std=gnu++0x" } */ + + #define u L + #define U L + + const unsigned short c2 = u'a'; + const unsigned long c3 = U'a'; + const void *s0 = u"a"; + const void *s1 = U"a"; + + int main () {} Index: gcc/testsuite/g++.dg/ext/utf32-3.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf32-3.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf32-3.C (revision 134438) *************** *** 0 **** --- 1,46 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Test concatenation of char32_t* string literals. */ + /* { dg-do run } */ + /* { dg-options "-std=c++0x -Wall -Werror" } */ + + extern "C" void abort (void); + + const static char32_t *s0 = U"a" U"b"; + + const static char32_t *s1 = U"a" "b"; + const static char32_t *s2 = "a" U"b"; + const static char32_t *s3 = U"a" "\u2029"; + const static char32_t *s4 = "\u2029" U"b"; + const static char32_t *s5 = U"a" "\U00064321"; + const static char32_t *s6 = "\U00064321" U"b"; + + #define A 0x00000061 + #define B 0x00000062 + #define X 0x00002029 + #define Y 0x00064321 + + int main () + { + if (sizeof ((U"a" U"b")[0]) != sizeof (char32_t)) + abort (); + if (sizeof ((U"a" "b")[0]) != sizeof (char32_t)) + abort (); + if (sizeof (( "a" U"b")[0]) != sizeof (char32_t)) + abort (); + + if (s0[0] != A || s0[1] != B || s0[2] != 0x00000000) + abort (); + + if (s1[0] != A || s1[1] != B || s1[2] != 0x00000000) + abort (); + if (s2[0] != A || s2[1] != B || s2[2] != 0x00000000) + abort (); + if (s3[0] != A || s3[1] != X || s3[2] != 0x00000000) + abort (); + if (s4[0] != X || s4[1] != B || s4[2] != 0x00000000) + abort (); + if (s5[0] != A || s5[1] != Y || s5[2] != 0x00000000) + abort (); + if (s6[0] != Y || s6[1] != B || s6[2] != 0x00000000) + abort (); + } Index: gcc/testsuite/g++.dg/ext/utf-typedef-cxx98.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-typedef-cxx98.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-typedef-cxx98.C (revision 134438) *************** *** 0 **** --- 1,7 ---- + /* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ + /* Ensure that a typedef to char16_t/char32_t is fine in c++98. */ + /* { dg-do compile } */ + /* { dg-options "-std=c++98" } */ + + typedef short unsigned int char16_t; + typedef unsigned int char32_t; Index: gcc/testsuite/g++.dg/ext/utf-mangle.C =================================================================== *** gcc/testsuite/g++.dg/ext/utf-mangle.C (revision 0) --- gcc/testsuite/g++.dg/ext/utf-mangle.C (revision 134438) *************** *** 0 **** --- 1,14 ---- + // Contributed by Kris Van Hees <kris.van.hees@oracle.com> + // Test the support for char16_t character constants. + // { dg-do compile } + // { dg-options "-std=c++0x" } + + void f0 (char16_t c) {} + void f1 (char32_t c) {} + void f2 (char16_t *s) {} + void f3 (char32_t *s) {} + + // { dg-final { scan-assembler "_Z2f0u8char16_t:" } } + // { dg-final { scan-assembler "_Z2f1u8char32_t:" } } + // { dg-final { scan-assembler "_Z2f2Pu8char16_t:" } } + // { dg-final { scan-assembler "_Z2f3Pu8char32_t:" } } Index: gcc/cp/typeck.c =================================================================== *** gcc/cp/typeck.c (revision 134437) --- gcc/cp/typeck.c (revision 134438) *************** string_conv_p (const_tree totype, const_ *** 1722,1733 **** t = TREE_TYPE (totype); if (!same_type_p (t, char_type_node) && !same_type_p (t, wchar_type_node)) return 0; if (TREE_CODE (exp) == STRING_CST) { ! /* Make sure that we don't try to convert between char and wchar_t. */ if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t)) return 0; } --- 1722,1735 ---- t = TREE_TYPE (totype); if (!same_type_p (t, char_type_node) + && !same_type_p (t, char16_type_node) + && !same_type_p (t, char32_type_node) && !same_type_p (t, wchar_type_node)) return 0; if (TREE_CODE (exp) == STRING_CST) { ! /* Make sure that we don't try to convert between char and wide chars. */ if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))), t)) return 0; } Index: gcc/cp/decl.c =================================================================== *** gcc/cp/decl.c (revision 134437) --- gcc/cp/decl.c (revision 134438) *************** grokdeclarator (const cp_declarator *dec *** 7732,7737 **** --- 7732,7744 ---- error ("%<long%> or %<short%> specified with char for %qs", name); else if (long_p && short_p) error ("%<long%> and %<short%> specified together for %qs", name); + else if (type == char16_type_node || type == char32_type_node) + { + if (signed_p || unsigned_p) + error ("%<signed%> or %<unsigned%> invalid for %qs", name); + else if (short_p || long_p) + error ("%<short%> or %<long%> invalid for %qs", name); + } else { ok = 1; Index: gcc/cp/cvt.c =================================================================== *** gcc/cp/cvt.c (revision 134437) --- gcc/cp/cvt.c (revision 134438) *************** type_promotes_to (tree type) *** 1219,1224 **** --- 1219,1226 ---- /* Normally convert enums to int, but convert wide enums to something wider. */ else if (TREE_CODE (type) == ENUMERAL_TYPE + || type == char16_type_node + || type == char32_type_node || type == wchar_type_node) { int precision = MAX (TYPE_PRECISION (type), Index: gcc/cp/tree.c =================================================================== *** gcc/cp/tree.c (revision 134437) --- gcc/cp/tree.c (revision 134438) *************** char_type_p (tree type) *** 2474,2479 **** --- 2474,2481 ---- return (same_type_p (type, char_type_node) || same_type_p (type, unsigned_char_type_node) || same_type_p (type, signed_char_type_node) + || same_type_p (type, char16_type_node) + || same_type_p (type, char32_type_node) || same_type_p (type, wchar_type_node)); } Index: gcc/cp/mangle.c =================================================================== *** gcc/cp/mangle.c (revision 134437) --- gcc/cp/mangle.c (revision 134438) *************** write_builtin_type (tree type) *** 1782,1791 **** break; case INTEGER_TYPE: ! /* TYPE may still be wchar_t, since that isn't in ! integer_type_nodes. */ if (type == wchar_type_node) write_char ('w'); else if (TYPE_FOR_JAVA (type)) write_java_integer_type_codes (type); else --- 1782,1795 ---- break; case INTEGER_TYPE: ! /* TYPE may still be wchar_t, char16_t, or char32_t, since that ! isn't in integer_type_nodes. */ if (type == wchar_type_node) write_char ('w'); + else if (type == char16_type_node) + write_string ("u8char16_t"); + else if (type == char32_type_node) + write_string ("u8char32_t"); else if (TYPE_FOR_JAVA (type)) write_java_integer_type_codes (type); else Index: gcc/cp/lex.c =================================================================== *** gcc/cp/lex.c (revision 134437) --- gcc/cp/lex.c (revision 134438) *************** static const struct resword reswords[] = *** 241,246 **** --- 241,248 ---- { "case", RID_CASE, 0 }, { "catch", RID_CATCH, 0 }, { "char", RID_CHAR, 0 }, + { "char16_t", RID_CHAR16, D_CXX0X }, + { "char32_t", RID_CHAR32, D_CXX0X }, { "class", RID_CLASS, 0 }, { "const", RID_CONST, 0 }, { "const_cast", RID_CONSTCAST, 0 }, Index: gcc/cp/parser.c =================================================================== *** gcc/cp/parser.c (revision 134437) --- gcc/cp/parser.c (revision 134438) *************** cp_lexer_next_token_is_decl_specifier_ke *** 556,561 **** --- 556,563 ---- case RID_TYPENAME: /* Simple type specifiers. */ case RID_CHAR: + case RID_CHAR16: + case RID_CHAR32: case RID_WCHAR: case RID_BOOL: case RID_SHORT: *************** cp_lexer_print_token (FILE * stream, cp_ *** 789,794 **** --- 791,798 ---- break; case CPP_STRING: + case CPP_STRING16: + case CPP_STRING32: case CPP_WSTRING: fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value)); break; *************** cp_parser_parsing_tentatively (cp_parser *** 2033,2039 **** static bool cp_parser_is_string_literal (cp_token* token) { ! return (token->type == CPP_STRING || token->type == CPP_WSTRING); } /* Returns nonzero if TOKEN is the indicated KEYWORD. */ --- 2037,2046 ---- static bool cp_parser_is_string_literal (cp_token* token) { ! return (token->type == CPP_STRING || ! token->type == CPP_STRING16 || ! token->type == CPP_STRING32 || ! token->type == CPP_WSTRING); } /* Returns nonzero if TOKEN is the indicated KEYWORD. */ *************** static tree *** 2867,2877 **** 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)) --- 2874,2884 ---- cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) { tree value; size_t count; struct obstack str_ob; cpp_string str, istr, *strs; cp_token *tok; + enum cpp_ttype type; tok = cp_lexer_peek_token (parser->lexer); if (!cp_parser_is_string_literal (tok)) *************** cp_parser_string_literal (cp_parser *par *** 2880,2885 **** --- 2887,2894 ---- return error_mark_node; } + type = tok->type; + /* Try to avoid the overhead of creating and destroying an obstack for the common case of just one string. */ if (!cp_parser_is_string_literal *************** cp_parser_string_literal (cp_parser *par *** 2890,2897 **** 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; } --- 2899,2904 ---- *************** cp_parser_string_literal (cp_parser *par *** 2906,2913 **** count++; str.text = (const 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)); --- 2913,2926 ---- count++; str.text = (const unsigned char *)TREE_STRING_POINTER (tok->u.value); str.len = TREE_STRING_LENGTH (tok->u.value); ! ! if (type != tok->type) ! { ! if (type == CPP_STRING) ! type = tok->type; ! else if (tok->type != CPP_STRING) ! error ("unsupported non-standard concatenation of string literals"); ! } obstack_grow (&str_ob, &str, sizeof (cpp_string)); *************** cp_parser_string_literal (cp_parser *par *** 2918,2936 **** 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, (const char *)istr.text); free (CONST_CAST (unsigned char *, istr.text)); ! TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node; value = fix_string_type (value); } else --- 2931,2965 ---- strs = (cpp_string *) obstack_finish (&str_ob); } ! if (type != CPP_STRING && !wide_ok) { cp_parser_error (parser, "a wide string is invalid in this context"); ! type = CPP_STRING; } if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate) ! (parse_in, strs, count, &istr, type)) { value = build_string (istr.len, (const char *)istr.text); free (CONST_CAST (unsigned char *, istr.text)); ! switch (type) ! { ! default: ! case CPP_STRING: ! TREE_TYPE (value) = char_array_type_node; ! break; ! case CPP_STRING16: ! TREE_TYPE (value) = char16_array_type_node; ! break; ! case CPP_STRING32: ! TREE_TYPE (value) = char32_array_type_node; ! break; ! case CPP_WSTRING: ! TREE_TYPE (value) = wchar_array_type_node; ! break; ! } ! value = fix_string_type (value); } else *************** cp_parser_primary_expression (cp_parser *** 3085,3090 **** --- 3114,3121 ---- string-literal boolean-literal */ case CPP_CHAR: + case CPP_CHAR16: + case CPP_CHAR32: case CPP_WCHAR: case CPP_NUMBER: token = cp_lexer_consume_token (parser->lexer); *************** cp_parser_primary_expression (cp_parser *** 3136,3141 **** --- 3167,3174 ---- return token->u.value; case CPP_STRING: + case CPP_STRING16: + case CPP_STRING32: case CPP_WSTRING: /* ??? Should wide strings be allowed when parser->translate_strings_p is false (i.e. in attributes)? If not, we can kill the third *************** cp_parser_type_specifier (cp_parser* par *** 10762,10767 **** --- 10795,10802 ---- simple-type-specifier: auto decltype ( expression ) + char16_t + char32_t GNU Extension: *************** cp_parser_simple_type_specifier (cp_pars *** 10791,10796 **** --- 10826,10837 ---- decl_specs->explicit_char_p = true; type = char_type_node; break; + case RID_CHAR16: + type = char16_type_node; + break; + case RID_CHAR32: + type = char32_type_node; + break; case RID_WCHAR: type = wchar_type_node; break; *************** cp_parser_set_decl_spec_type (cp_decl_sp *** 17754,17766 **** { decl_specs->any_specifiers_p = true; ! /* If the user tries to redeclare bool or wchar_t (with, for ! example, in "typedef int wchar_t;") we remember that this is what ! happened. In system headers, we ignore these declarations so ! that G++ can work with system headers that are not C++-safe. */ if (decl_specs->specs[(int) ds_typedef] && !user_defined_p && (type_spec == boolean_type_node || type_spec == wchar_type_node) && (decl_specs->type || decl_specs->specs[(int) ds_long] --- 17795,17810 ---- { decl_specs->any_specifiers_p = true; ! /* If the user tries to redeclare bool, char16_t, char32_t, or wchar_t ! (with, for example, in "typedef int wchar_t;") we remember that ! this is what happened. In system headers, we ignore these ! declarations so that G++ can work with system headers that are not ! C++-safe. */ if (decl_specs->specs[(int) ds_typedef] && !user_defined_p && (type_spec == boolean_type_node + || type_spec == char16_type_node + || type_spec == char32_type_node || type_spec == wchar_type_node) && (decl_specs->type || decl_specs->specs[(int) ds_long] Index: gcc/c-common.c =================================================================== *** gcc/c-common.c (revision 134437) --- gcc/c-common.c (revision 134438) *************** cpp_reader *parse_in; /* Declared in c- *** 66,71 **** --- 66,79 ---- #define PID_TYPE "int" #endif + #ifndef CHAR16_TYPE + #define CHAR16_TYPE "short unsigned int" + #endif + + #ifndef CHAR32_TYPE + #define CHAR32_TYPE "unsigned int" + #endif + #ifndef WCHAR_TYPE #define WCHAR_TYPE "int" #endif *************** cpp_reader *parse_in; /* Declared in c- *** 123,128 **** --- 131,139 ---- tree signed_wchar_type_node; tree unsigned_wchar_type_node; + tree char16_type_node; + tree char32_type_node; + tree float_type_node; tree double_type_node; tree long_double_type_node; *************** cpp_reader *parse_in; /* Declared in c- *** 174,179 **** --- 185,200 ---- tree wchar_array_type_node; + Type `char16_t[SOMENUMBER]' or something like it. + Used when a UTF-16 string literal is created. + + tree char16_array_type_node; + + Type `char32_t[SOMENUMBER]' or something like it. + Used when a UTF-32 string literal is created. + + tree char32_array_type_node; + Type `int ()' -- used for implicit declaration of functions. tree default_function_type; *************** fname_as_string (int pretty_p) *** 777,783 **** strname.text = (unsigned char *) namep; strname.len = len - 1; ! if (cpp_interpret_string (parse_in, &strname, 1, &cstr, false)) { XDELETEVEC (namep); return (const char *) cstr.text; --- 798,804 ---- strname.text = (unsigned char *) namep; strname.len = len - 1; ! if (cpp_interpret_string (parse_in, &strname, 1, &cstr, CPP_STRING)) { XDELETEVEC (namep); return (const char *) cstr.text; *************** fname_decl (unsigned int rid, tree id) *** 857,870 **** tree fix_string_type (tree value) { - const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; - const int wide_flag = TREE_TYPE (value) == wchar_array_type_node; int length = TREE_STRING_LENGTH (value); int nchars; tree e_type, i_type, a_type; /* Compute the number of elements, for the array type. */ ! nchars = wide_flag ? length / wchar_bytes : length; /* C89 2.2.4.1, C99 5.2.4.1 (Translation limits). The analogous limit in C++98 Annex B is very large (65536) and is not normative, --- 878,908 ---- tree fix_string_type (tree value) { int length = TREE_STRING_LENGTH (value); int nchars; tree e_type, i_type, a_type; /* Compute the number of elements, for the array type. */ ! if (TREE_TYPE (value) == char_array_type_node || !TREE_TYPE (value)) ! { ! nchars = length; ! e_type = char_type_node; ! } ! else if (TREE_TYPE (value) == char16_array_type_node) ! { ! nchars = length / (TYPE_PRECISION (char16_type_node) / BITS_PER_UNIT); ! e_type = char16_type_node; ! } ! else if (TREE_TYPE (value) == char32_array_type_node) ! { ! nchars = length / (TYPE_PRECISION (char32_type_node) / BITS_PER_UNIT); ! e_type = char32_type_node; ! } ! else ! { ! nchars = length / (TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT); ! e_type = wchar_type_node; ! } /* C89 2.2.4.1, C99 5.2.4.1 (Translation limits). The analogous limit in C++98 Annex B is very large (65536) and is not normative, *************** fix_string_type (tree value) *** 899,905 **** construct the matching unqualified array type first. The C front end does not require this, but it does no harm, so we do it unconditionally. */ - e_type = wide_flag ? wchar_type_node : char_type_node; i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1)); a_type = build_array_type (e_type, i_type); if (c_dialect_cxx() || warn_write_strings) --- 937,942 ---- *************** c_define_builtins (tree va_list_ref_type *** 3629,3634 **** --- 3666,3673 ---- void c_common_nodes_and_builtins (void) { + int char16_type_size; + int char32_type_size; int wchar_type_size; tree array_domain_type; tree va_list_ref_type_node; *************** c_common_nodes_and_builtins (void) *** 3878,3883 **** --- 3917,3954 ---- wchar_array_type_node = build_array_type (wchar_type_node, array_domain_type); + /* Define 'char16_t'. */ + char16_type_node = get_identifier (CHAR16_TYPE); + char16_type_node = TREE_TYPE (identifier_global_value (char16_type_node)); + char16_type_size = TYPE_PRECISION (char16_type_node); + if (c_dialect_cxx ()) + { + char16_type_node = make_unsigned_type (char16_type_size); + + if (cxx_dialect == cxx0x) + record_builtin_type (RID_CHAR16, "char16_t", char16_type_node); + } + + /* This is for UTF-16 string constants. */ + char16_array_type_node + = build_array_type (char16_type_node, array_domain_type); + + /* Define 'char32_t'. */ + char32_type_node = get_identifier (CHAR32_TYPE); + char32_type_node = TREE_TYPE (identifier_global_value (char32_type_node)); + char32_type_size = TYPE_PRECISION (char32_type_node); + if (c_dialect_cxx ()) + { + char32_type_node = make_unsigned_type (char32_type_size); + + if (cxx_dialect == cxx0x) + record_builtin_type (RID_CHAR32, "char32_t", char32_type_node); + } + + /* This is for UTF-32 string constants. */ + char32_array_type_node + = build_array_type (char32_type_node, array_domain_type); + wint_type_node = TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE))); *************** c_parse_error (const char *gmsgid, enum *** 6662,6681 **** if (token == CPP_EOF) message = catenate_messages (gmsgid, " at end of input"); ! else if (token == CPP_CHAR || token == CPP_WCHAR) { unsigned int val = TREE_INT_CST_LOW (value); ! const char *const ell = (token == CPP_CHAR) ? "" : "L"; if (val <= UCHAR_MAX && ISGRAPH (val)) message = catenate_messages (gmsgid, " before %s'%c'"); else message = catenate_messages (gmsgid, " before %s'\\x%x'"); ! error (message, ell, val); free (message); message = NULL; } ! else if (token == CPP_STRING || token == CPP_WSTRING) message = catenate_messages (gmsgid, " before string constant"); else if (token == CPP_NUMBER) message = catenate_messages (gmsgid, " before numeric constant"); --- 6733,6771 ---- if (token == CPP_EOF) message = catenate_messages (gmsgid, " at end of input"); ! else if (token == CPP_CHAR || token == CPP_WCHAR || token == CPP_CHAR16 ! || token == CPP_CHAR32) { unsigned int val = TREE_INT_CST_LOW (value); ! const char *prefix; ! ! switch (token) ! { ! default: ! prefix = ""; ! break; ! case CPP_WCHAR: ! prefix = "L"; ! break; ! case CPP_CHAR16: ! prefix = "u"; ! break; ! case CPP_CHAR32: ! prefix = "U"; ! break; ! } ! if (val <= UCHAR_MAX && ISGRAPH (val)) message = catenate_messages (gmsgid, " before %s'%c'"); else message = catenate_messages (gmsgid, " before %s'\\x%x'"); ! error (message, prefix, val); free (message); message = NULL; } ! else if (token == CPP_STRING || token == CPP_WSTRING || token == CPP_STRING16 ! || token == CPP_STRING32) message = catenate_messages (gmsgid, " before string constant"); else if (token == CPP_NUMBER) message = catenate_messages (gmsgid, " before numeric constant"); Index: gcc/c-common.h =================================================================== *** gcc/c-common.h (revision 134437) --- gcc/c-common.h (revision 134438) *************** enum rid *** 85,91 **** RID_NEW, RID_OFFSETOF, RID_OPERATOR, RID_THIS, RID_THROW, RID_TRUE, RID_TRY, RID_TYPENAME, RID_TYPEID, ! RID_USING, /* casts */ RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, --- 85,91 ---- RID_NEW, RID_OFFSETOF, RID_OPERATOR, RID_THIS, RID_THROW, RID_TRUE, RID_TRY, RID_TYPENAME, RID_TYPEID, ! RID_USING, RID_CHAR16, RID_CHAR32, /* casts */ RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, *************** extern GTY ((length ("(int) RID_MAX"))) *** 143,148 **** --- 143,150 ---- enum c_tree_index { + CTI_CHAR16_TYPE, + CTI_CHAR32_TYPE, CTI_WCHAR_TYPE, CTI_SIGNED_WCHAR_TYPE, CTI_UNSIGNED_WCHAR_TYPE, *************** enum c_tree_index *** 155,160 **** --- 157,164 ---- CTI_WIDEST_UINT_LIT_TYPE, CTI_CHAR_ARRAY_TYPE, + CTI_CHAR16_ARRAY_TYPE, + CTI_CHAR32_ARRAY_TYPE, CTI_WCHAR_ARRAY_TYPE, CTI_INT_ARRAY_TYPE, CTI_STRING_TYPE, *************** struct c_common_identifier GTY(()) *** 190,195 **** --- 194,201 ---- struct cpp_hashnode node; }; + #define char16_type_node c_global_trees[CTI_CHAR16_TYPE] + #define char32_type_node c_global_trees[CTI_CHAR32_TYPE] #define wchar_type_node c_global_trees[CTI_WCHAR_TYPE] #define signed_wchar_type_node c_global_trees[CTI_SIGNED_WCHAR_TYPE] #define unsigned_wchar_type_node c_global_trees[CTI_UNSIGNED_WCHAR_TYPE] *************** struct c_common_identifier GTY(()) *** 206,211 **** --- 212,219 ---- #define truthvalue_false_node c_global_trees[CTI_TRUTHVALUE_FALSE] #define char_array_type_node c_global_trees[CTI_CHAR_ARRAY_TYPE] + #define char16_array_type_node c_global_trees[CTI_CHAR16_ARRAY_TYPE] + #define char32_array_type_node c_global_trees[CTI_CHAR32_ARRAY_TYPE] #define wchar_array_type_node c_global_trees[CTI_WCHAR_ARRAY_TYPE] #define int_array_type_node c_global_trees[CTI_INT_ARRAY_TYPE] #define string_type_node c_global_trees[CTI_STRING_TYPE] Index: gcc/c-parser.c =================================================================== *** gcc/c-parser.c (revision 134437) --- gcc/c-parser.c (revision 134438) *************** c_parser_postfix_expression (c_parser *p *** 5163,5174 **** --- 5163,5178 ---- { case CPP_NUMBER: case CPP_CHAR: + case CPP_CHAR16: + case CPP_CHAR32: case CPP_WCHAR: expr.value = c_parser_peek_token (parser)->value; expr.original_code = ERROR_MARK; c_parser_consume_token (parser); break; case CPP_STRING: + case CPP_STRING16: + case CPP_STRING32: case CPP_WSTRING: expr.value = c_parser_peek_token (parser)->value; expr.original_code = STRING_CST; Index: libiberty/testsuite/demangle-expected =================================================================== *** libiberty/testsuite/demangle-expected (revision 134437) --- libiberty/testsuite/demangle-expected (revision 134438) *************** foo(char) *** 3399,3404 **** --- 3399,3424 ---- foo # --format=gnu-v3 --no-params + _Z2f0u8char16_t + f0(char16_t) + f0 + # + --format=gnu-v3 --no-params + _Z2f0Pu8char16_t + f0(char16_t*) + f0 + # + --format=gnu-v3 --no-params + _Z2f0u8char32_t + f0(char32_t) + f0 + # + --format=gnu-v3 --no-params + _Z2f0Pu8char32_t + f0(char32_t*) + f0 + # + --format=gnu-v3 --no-params 2CBIL_Z3foocEE CB<foo(char)> CB<foo(char)> Index: libcpp/directives.c =================================================================== *** libcpp/directives.c (revision 134437) --- libcpp/directives.c (revision 134438) *************** DIRECTIVE_TABLE *** 188,194 **** did use this notation in its preprocessed output. */ static const directive linemarker_dir = { ! do_linemarker, U"#", 1, KANDR, IN_I }; #define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF) --- 188,194 ---- did use this notation in its preprocessed output. */ static const directive linemarker_dir = { ! do_linemarker, UC"#", 1, KANDR, IN_I }; #define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF) *************** parse_include (cpp_reader *pfile, int *p *** 697,703 **** const unsigned char *dir; if (pfile->directive == &dtable[T_PRAGMA]) ! dir = U"pragma dependency"; else dir = pfile->directive->name; cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or <FILENAME>", --- 697,703 ---- const unsigned char *dir; if (pfile->directive == &dtable[T_PRAGMA]) ! dir = UC"pragma dependency"; else dir = pfile->directive->name; cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or <FILENAME>", *************** register_pragma_1 (cpp_reader *pfile, co *** 1085,1091 **** if (space) { ! node = cpp_lookup (pfile, U space, strlen (space)); entry = lookup_pragma_entry (*chain, node); if (!entry) { --- 1085,1091 ---- if (space) { ! node = cpp_lookup (pfile, UC space, strlen (space)); entry = lookup_pragma_entry (*chain, node); if (!entry) { *************** register_pragma_1 (cpp_reader *pfile, co *** 1114,1120 **** } /* Check for duplicates. */ ! node = cpp_lookup (pfile, U name, strlen (name)); entry = lookup_pragma_entry (*chain, node); if (entry == NULL) { --- 1114,1120 ---- } /* Check for duplicates. */ ! node = cpp_lookup (pfile, UC name, strlen (name)); entry = lookup_pragma_entry (*chain, node); if (entry == NULL) { *************** restore_registered_pragmas (cpp_reader * *** 1262,1268 **** { if (pe->is_nspace) sd = restore_registered_pragmas (pfile, pe->u.space, sd); ! pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd)); free (*sd); sd++; } --- 1262,1268 ---- { if (pe->is_nspace) sd = restore_registered_pragmas (pfile, pe->u.space, sd); ! pe->pragma = cpp_lookup (pfile, UC *sd, strlen (*sd)); free (*sd); sd++; } *************** get__Pragma_string (cpp_reader *pfile) *** 1491,1497 **** string = get_token_no_padding (pfile); if (string->type == CPP_EOF) _cpp_backup_tokens (pfile, 1); ! if (string->type != CPP_STRING && string->type != CPP_WSTRING) return NULL; paren = get_token_no_padding (pfile); --- 1491,1498 ---- string = get_token_no_padding (pfile); if (string->type == CPP_EOF) _cpp_backup_tokens (pfile, 1); ! if (string->type != CPP_STRING && string->type != CPP_WSTRING ! && string->type != CPP_STRING32 && string->type != CPP_STRING16) return NULL; paren = get_token_no_padding (pfile); Index: libcpp/macro.c =================================================================== *** libcpp/macro.c (revision 134437) --- libcpp/macro.c (revision 134438) *************** _cpp_builtin_macro_text (cpp_reader *pfi *** 158,164 **** { cpp_errno (pfile, CPP_DL_WARNING, "could not determine file timestamp"); ! pbuffer->timestamp = U"\"??? ??? ?? ??:??:?? ????\""; } } } --- 158,164 ---- { cpp_errno (pfile, CPP_DL_WARNING, "could not determine file timestamp"); ! pbuffer->timestamp = UC"\"??? ??? ?? ??:??:?? ????\""; } } } *************** _cpp_builtin_macro_text (cpp_reader *pfi *** 256,263 **** cpp_errno (pfile, CPP_DL_WARNING, "could not determine date and time"); ! pfile->date = U"\"??? ?? ????\""; ! pfile->time = U"\"??:??:??\""; } } --- 256,263 ---- cpp_errno (pfile, CPP_DL_WARNING, "could not determine date and time"); ! pfile->date = UC"\"??? ?? ????\""; ! pfile->time = UC"\"??:??:??\""; } } *************** stringify_arg (cpp_reader *pfile, macro_ *** 375,382 **** continue; } ! escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING ! || token->type == CPP_CHAR || token->type == CPP_WCHAR); /* Room for each char being written in octal, initial space and final quote and NUL. */ --- 375,384 ---- continue; } ! escape_it = (token->type == CPP_STRING || token->type == CPP_CHAR ! || token->type == CPP_WSTRING || token->type == CPP_STRING ! || token->type == CPP_STRING32 || token->type == CPP_CHAR32 ! || token->type == CPP_STRING16 || token->type == CPP_CHAR16); /* Room for each char being written in octal, initial space and final quote and NUL. */ Index: libcpp/include/cpplib.h =================================================================== *** libcpp/include/cpplib.h (revision 134437) --- libcpp/include/cpplib.h (revision 134438) *************** struct _cpp_file; *** 123,132 **** --- 123,136 ---- \ TK(CHAR, LITERAL) /* 'char' */ \ TK(WCHAR, LITERAL) /* L'char' */ \ + TK(CHAR16, LITERAL) /* u'char' */ \ + TK(CHAR32, LITERAL) /* U'char' */ \ TK(OTHER, LITERAL) /* stray punctuation */ \ \ TK(STRING, LITERAL) /* "string" */ \ TK(WSTRING, LITERAL) /* L"string" */ \ + TK(STRING16, LITERAL) /* u"string" */ \ + TK(STRING32, LITERAL) /* U"string" */ \ TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ TK(HEADER_NAME, LITERAL) /* <stdio.h> in #include */ \ \ *************** struct cpp_options *** 291,296 **** --- 295,303 ---- /* Nonzero means to allow hexadecimal floats and LL suffixes. */ unsigned char extended_numbers; + /* Nonzero means process u/U prefix literals (UTF-16/32). */ + unsigned char uliterals; + /* Nonzero means print names of header files (-H). */ unsigned char print_include_names; *************** extern cppchar_t cpp_interpret_charconst *** 712,721 **** /* Evaluate a vector of CPP_STRING or CPP_WSTRING tokens. */ extern bool cpp_interpret_string (cpp_reader *, const cpp_string *, size_t, ! cpp_string *, bool); extern bool cpp_interpret_string_notranslate (cpp_reader *, const cpp_string *, size_t, ! cpp_string *, bool); /* Convert a host character constant to the execution character set. */ extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t); --- 719,728 ---- /* Evaluate a vector of CPP_STRING or CPP_WSTRING tokens. */ extern bool cpp_interpret_string (cpp_reader *, const cpp_string *, size_t, ! cpp_string *, enum cpp_ttype); extern bool cpp_interpret_string_notranslate (cpp_reader *, const cpp_string *, size_t, ! cpp_string *, enum cpp_ttype); /* Convert a host character constant to the execution character set. */ extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t); Index: libcpp/include/cpp-id-data.h =================================================================== *** libcpp/include/cpp-id-data.h (revision 134437) --- libcpp/include/cpp-id-data.h (revision 134438) *************** Foundation, 51 Franklin Street, Fifth Fl *** 22,28 **** typedef unsigned char uchar; #endif ! #define U (const unsigned char *) /* Intended use: U"string" */ /* Chained list of answers to an assertion. */ struct answer GTY(()) --- 22,28 ---- typedef unsigned char uchar; #endif ! #define UC (const unsigned char *) /* Intended use: UC"string" */ /* Chained list of answers to an assertion. */ struct answer GTY(()) Index: libcpp/init.c =================================================================== *** libcpp/init.c (revision 134437) --- libcpp/init.c (revision 134438) *************** struct lang_flags *** 76,95 **** char std; char cplusplus_comments; char digraphs; }; static const struct lang_flags lang_defaults[] = ! { /* c99 c++ xnum xid std // digr */ ! /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 }, ! /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 }, ! /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 }, ! /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 }, ! /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 }, ! /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 }, ! /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 }, ! /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1 }, ! /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1 }, ! /* ASM */ { 0, 0, 1, 0, 0, 1, 0 } /* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and CXX0X when no longer experimental (when all uses of identifiers in the compiler have been audited for correct handling of --- 76,96 ---- char std; char cplusplus_comments; char digraphs; + char uliterals; }; static const struct lang_flags lang_defaults[] = ! { /* c99 c++ xnum xid std // digr ulit */ ! /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0 }, ! /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1 }, ! /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 }, ! /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0 }, ! /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0 }, ! /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0 }, ! /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0 }, ! /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1, 1 }, ! /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1, 1 }, ! /* ASM */ { 0, 0, 1, 0, 0, 1, 0, 0 } /* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and CXX0X when no longer experimental (when all uses of identifiers in the compiler have been audited for correct handling of *************** cpp_set_lang (cpp_reader *pfile, enum c_ *** 112,117 **** --- 113,119 ---- CPP_OPTION (pfile, trigraphs) = l->std; CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; CPP_OPTION (pfile, digraphs) = l->digraphs; + CPP_OPTION (pfile, uliterals) = l->uliterals; } /* Initialize library global state. */ Index: libcpp/expr.c =================================================================== *** libcpp/expr.c (revision 134437) --- libcpp/expr.c (revision 134438) *************** eval_token (cpp_reader *pfile, const cpp *** 705,710 **** --- 705,712 ---- case CPP_WCHAR: case CPP_CHAR: + case CPP_CHAR16: + case CPP_CHAR32: { cppchar_t cc = cpp_interpret_charconst (pfile, token, &temp, &unsignedp); *************** _cpp_parse_expr (cpp_reader *pfile) *** 863,868 **** --- 865,872 ---- case CPP_NUMBER: case CPP_CHAR: case CPP_WCHAR: + case CPP_CHAR16: + case CPP_CHAR32: case CPP_NAME: case CPP_HASH: if (!want_value) Index: libcpp/internal.h =================================================================== *** libcpp/internal.h (revision 134437) --- libcpp/internal.h (revision 134438) *************** struct cset_converter *** 48,53 **** --- 48,54 ---- { convert_f func; iconv_t cd; + int width; }; #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t)) *************** struct cpp_reader *** 399,404 **** --- 400,413 ---- struct cset_converter narrow_cset_desc; /* Descriptor for converting from the source character set to the + UTF-16 execution character set. */ + struct cset_converter char16_cset_desc; + + /* Descriptor for converting from the source character set to the + UTF-32 execution character set. */ + struct cset_converter char32_cset_desc; + + /* Descriptor for converting from the source character set to the wide execution character set. */ struct cset_converter wide_cset_desc; Index: libcpp/lex.c =================================================================== *** libcpp/lex.c (revision 134437) --- libcpp/lex.c (revision 134438) *************** struct token_spelling *** 39,48 **** }; static const unsigned char *const digraph_spellings[] = ! { U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" }; ! #define OP(e, s) { SPELL_OPERATOR, U s }, ! #define TK(e, s) { SPELL_ ## s, U #e }, static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; #undef OP #undef TK --- 39,48 ---- }; static const unsigned char *const digraph_spellings[] = ! { UC"%:", UC"%:%:", UC"<:", UC":>", UC"<%", UC"%>" }; ! #define OP(e, s) { SPELL_OPERATOR, UC s }, ! #define TK(e, s) { SPELL_ ## s, UC #e }, static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; #undef OP #undef TK *************** create_literal (cpp_reader *pfile, cpp_t *** 611,618 **** /* Lexes a string, character constant, or angle-bracketed header file name. The stored string contains the spelling, including opening ! quote and leading any leading 'L'. It returns the type of the ! literal, or CPP_OTHER if it was not properly terminated. The spelling is NUL-terminated, but it is not guaranteed that this is the first NUL since embedded NULs are preserved. */ --- 611,618 ---- /* Lexes a string, character constant, or angle-bracketed header file name. The stored string contains the spelling, including opening ! quote and leading any leading 'L', 'u' or 'U'. It returns the type ! of the literal, or CPP_OTHER if it was not properly terminated. The spelling is NUL-terminated, but it is not guaranteed that this is the first NUL since embedded NULs are preserved. */ *************** lex_string (cpp_reader *pfile, cpp_token *** 626,637 **** cur = base; terminator = *cur++; ! if (terminator == 'L') terminator = *cur++; if (terminator == '\"') ! type = *base == 'L' ? CPP_WSTRING: CPP_STRING; else if (terminator == '\'') ! type = *base == 'L' ? CPP_WCHAR: CPP_CHAR; else terminator = '>', type = CPP_HEADER_NAME; --- 626,641 ---- cur = base; terminator = *cur++; ! if (terminator == 'L' || terminator == 'u' || terminator == 'U') terminator = *cur++; if (terminator == '\"') ! type = (*base == 'L' ? CPP_WSTRING : ! *base == 'U' ? CPP_STRING32 : ! *base == 'u' ? CPP_STRING16 : CPP_STRING); else if (terminator == '\'') ! type = (*base == 'L' ? CPP_WCHAR : ! *base == 'U' ? CPP_CHAR32 : ! *base == 'u' ? CPP_CHAR16 : CPP_CHAR); else terminator = '>', type = CPP_HEADER_NAME; *************** _cpp_lex_direct (cpp_reader *pfile) *** 965,975 **** } case 'L': ! /* 'L' may introduce wide characters or strings. */ ! if (*buffer->cur == '\'' || *buffer->cur == '"') { ! lex_string (pfile, result, buffer->cur - 1); ! break; } /* Fall through. */ --- 969,984 ---- } case 'L': ! case 'u': ! case 'U': ! /* 'L', 'u' or 'U' may introduce wide characters or strings. */ ! if (c == 'L' || CPP_OPTION (pfile, uliterals)) { ! if (*buffer->cur == '\'' || *buffer->cur == '"') ! { ! lex_string (pfile, result, buffer->cur - 1); ! break; ! } } /* Fall through. */ *************** _cpp_lex_direct (cpp_reader *pfile) *** 977,988 **** case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': ! case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': ! case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': result->type = CPP_NAME; { --- 986,997 ---- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': ! case 's': case 't': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': ! case 'S': case 'T': case 'V': case 'W': case 'X': case 'Y': case 'Z': result->type = CPP_NAME; { Index: libcpp/charset.c =================================================================== *** libcpp/charset.c (revision 134437) --- libcpp/charset.c (revision 134438) *************** init_iconv_desc (cpp_reader *pfile, cons *** 642,647 **** --- 642,648 ---- { ret.func = convert_no_conversion; ret.cd = (iconv_t) -1; + ret.width = -1; return ret; } *************** init_iconv_desc (cpp_reader *pfile, cons *** 655,660 **** --- 656,662 ---- { ret.func = conversion_tab[i].func; ret.cd = conversion_tab[i].fake_cd; + ret.width = -1; return ret; } *************** init_iconv_desc (cpp_reader *pfile, cons *** 663,668 **** --- 665,671 ---- { ret.func = convert_using_iconv; ret.cd = iconv_open (to, from); + ret.width = -1; if (ret.cd == (iconv_t) -1) { *************** init_iconv_desc (cpp_reader *pfile, cons *** 683,688 **** --- 686,692 ---- from, to); ret.func = convert_no_conversion; ret.cd = (iconv_t) -1; + ret.width = -1; } return ret; } *************** cpp_init_iconv (cpp_reader *pfile) *** 716,722 **** --- 720,736 ---- wcset = default_wcset; pfile->narrow_cset_desc = init_iconv_desc (pfile, ncset, SOURCE_CHARSET); + pfile->narrow_cset_desc.width = CPP_OPTION (pfile, char_precision); + pfile->char16_cset_desc = init_iconv_desc (pfile, + be ? "UTF-16BE" : "UTF-16LE", + SOURCE_CHARSET); + pfile->char16_cset_desc.width = 16; + pfile->char32_cset_desc = init_iconv_desc (pfile, + be ? "UTF-32BE" : "UTF-32LE", + SOURCE_CHARSET); + pfile->char32_cset_desc.width = 32; pfile->wide_cset_desc = init_iconv_desc (pfile, wcset, SOURCE_CHARSET); + pfile->wide_cset_desc.width = CPP_OPTION (pfile, wchar_precision); } /* Destroy iconv(3) descriptors set up by cpp_init_iconv, if necessary. */ *************** _cpp_valid_ucn (cpp_reader *pfile, const *** 1051,1065 **** An advanced pointer is returned. Issues all relevant diagnostics. */ static const uchar * convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, bool wide) { cppchar_t ucn; uchar buf[6]; uchar *bufp = buf; size_t bytesleft = 6; int rval; - struct cset_converter cvt - = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc; struct normalize_state nst = INITIAL_NORMALIZE_STATE; from++; /* Skip u/U. */ --- 1065,1077 ---- An advanced pointer is returned. Issues all relevant diagnostics. */ static const uchar * convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, struct cset_converter cvt) { cppchar_t ucn; uchar buf[6]; uchar *bufp = buf; size_t bytesleft = 6; int rval; struct normalize_state nst = INITIAL_NORMALIZE_STATE; from++; /* Skip u/U. */ *************** convert_ucn (cpp_reader *pfile, const uc *** 1086,1099 **** function issues no diagnostics and never fails. */ static void emit_numeric_escape (cpp_reader *pfile, cppchar_t n, ! struct _cpp_strbuf *tbuf, bool wide) { ! if (wide) { /* We have to render this into the target byte order, which may not be our byte order. */ bool bigend = CPP_OPTION (pfile, bytes_big_endian); - size_t width = CPP_OPTION (pfile, wchar_precision); size_t cwidth = CPP_OPTION (pfile, char_precision); size_t cmask = width_to_mask (cwidth); size_t nbwc = width / cwidth; --- 1098,1112 ---- function issues no diagnostics and never fails. */ static void emit_numeric_escape (cpp_reader *pfile, cppchar_t n, ! struct _cpp_strbuf *tbuf, struct cset_converter cvt) { ! size_t width = cvt.width; ! ! if (width != CPP_OPTION (pfile, char_precision)) { /* We have to render this into the target byte order, which may not be our byte order. */ bool bigend = CPP_OPTION (pfile, bytes_big_endian); size_t cwidth = CPP_OPTION (pfile, char_precision); size_t cmask = width_to_mask (cwidth); size_t nbwc = width / cwidth; *************** emit_numeric_escape (cpp_reader *pfile, *** 1136,1147 **** number. You can, e.g. generate surrogate pairs this way. */ static const uchar * convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, bool wide) { cppchar_t c, n = 0, overflow = 0; int digits_found = 0; ! size_t width = (wide ? CPP_OPTION (pfile, wchar_precision) ! : CPP_OPTION (pfile, char_precision)); size_t mask = width_to_mask (width); if (CPP_WTRADITIONAL (pfile)) --- 1149,1159 ---- number. You can, e.g. generate surrogate pairs this way. */ static const uchar * convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, struct cset_converter cvt) { cppchar_t c, n = 0, overflow = 0; int digits_found = 0; ! size_t width = cvt.width; size_t mask = width_to_mask (width); if (CPP_WTRADITIONAL (pfile)) *************** convert_hex (cpp_reader *pfile, const uc *** 1174,1180 **** n &= mask; } ! emit_numeric_escape (pfile, n, tbuf, wide); return from; } --- 1186,1192 ---- n &= mask; } ! emit_numeric_escape (pfile, n, tbuf, cvt); return from; } *************** convert_hex (cpp_reader *pfile, const uc *** 1187,1198 **** number. */ static const uchar * convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, bool wide) { size_t count = 0; cppchar_t c, n = 0; ! size_t width = (wide ? CPP_OPTION (pfile, wchar_precision) ! : CPP_OPTION (pfile, char_precision)); size_t mask = width_to_mask (width); bool overflow = false; --- 1199,1209 ---- number. */ static const uchar * convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, struct cset_converter cvt) { size_t count = 0; cppchar_t c, n = 0; ! size_t width = cvt.width; size_t mask = width_to_mask (width); bool overflow = false; *************** convert_oct (cpp_reader *pfile, const uc *** 1213,1219 **** n &= mask; } ! emit_numeric_escape (pfile, n, tbuf, wide); return from; } --- 1224,1230 ---- n &= mask; } ! emit_numeric_escape (pfile, n, tbuf, cvt); return from; } *************** convert_oct (cpp_reader *pfile, const uc *** 1224,1230 **** pointer. Handles all relevant diagnostics. */ static const uchar * convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, bool wide) { /* Values of \a \b \e \f \n \r \t \v respectively. */ #if HOST_CHARSET == HOST_CHARSET_ASCII --- 1235,1241 ---- pointer. Handles all relevant diagnostics. */ static const uchar * convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, ! struct _cpp_strbuf *tbuf, struct cset_converter cvt) { /* Values of \a \b \e \f \n \r \t \v respectively. */ #if HOST_CHARSET == HOST_CHARSET_ASCII *************** convert_escape (cpp_reader *pfile, const *** 1236,1258 **** #endif uchar c; - struct cset_converter cvt - = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc; c = *from; switch (c) { /* UCNs, hex escapes, and octal escapes are processed separately. */ case 'u': case 'U': ! return convert_ucn (pfile, from, limit, tbuf, wide); case 'x': ! return convert_hex (pfile, from, limit, tbuf, wide); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': ! return convert_oct (pfile, from, limit, tbuf, wide); /* Various letter escapes. Get the appropriate host-charset value into C. */ --- 1247,1267 ---- #endif uchar c; c = *from; switch (c) { /* UCNs, hex escapes, and octal escapes are processed separately. */ case 'u': case 'U': ! return convert_ucn (pfile, from, limit, tbuf, cvt); case 'x': ! return convert_hex (pfile, from, limit, tbuf, cvt); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': ! return convert_oct (pfile, from, limit, tbuf, cvt); /* Various letter escapes. Get the appropriate host-charset value into C. */ *************** convert_escape (cpp_reader *pfile, const *** 1312,1317 **** --- 1321,1347 ---- return from + 1; } + /* TYPE is a token type. The return value is the conversion needed to + convert from source to execution character set for the given type. */ + static struct cset_converter + converter_for_type (cpp_reader *pfile, enum cpp_ttype type) + { + switch (type) + { + default: + return pfile->narrow_cset_desc; + case CPP_CHAR16: + case CPP_STRING16: + return pfile->char16_cset_desc; + case CPP_CHAR32: + case CPP_STRING32: + return pfile->char32_cset_desc; + case CPP_WCHAR: + case CPP_WSTRING: + return pfile->wide_cset_desc; + } + } + /* FROM is an array of cpp_string structures of length COUNT. These are to be converted from the source to the execution character set, escape sequences translated, and finally all are to be *************** convert_escape (cpp_reader *pfile, const *** 1320,1332 **** false for failure. */ bool cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, ! cpp_string *to, bool wide) { struct _cpp_strbuf tbuf; const uchar *p, *base, *limit; size_t i; ! struct cset_converter cvt ! = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc; tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len); tbuf.text = XNEWVEC (uchar, tbuf.asize); --- 1350,1361 ---- false for failure. */ bool cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, ! cpp_string *to, enum cpp_ttype type) { struct _cpp_strbuf tbuf; const uchar *p, *base, *limit; size_t i; ! struct cset_converter cvt = converter_for_type (pfile, type); tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len); tbuf.text = XNEWVEC (uchar, tbuf.asize); *************** cpp_interpret_string (cpp_reader *pfile, *** 1335,1341 **** for (i = 0; i < count; i++) { p = from[i].text; ! if (*p == 'L') p++; p++; /* Skip leading quote. */ limit = from[i].text + from[i].len - 1; /* Skip trailing quote. */ --- 1364,1370 ---- for (i = 0; i < count; i++) { p = from[i].text; ! if (*p == 'L' || *p == 'u' || *p == 'U') p++; p++; /* Skip leading quote. */ limit = from[i].text + from[i].len - 1; /* Skip trailing quote. */ *************** cpp_interpret_string (cpp_reader *pfile, *** 1354,1365 **** if (p == limit) break; ! p = convert_escape (pfile, p + 1, limit, &tbuf, wide); } } /* NUL-terminate the 'to' buffer and translate it to a cpp_string structure. */ ! emit_numeric_escape (pfile, 0, &tbuf, wide); tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len); to->text = tbuf.text; to->len = tbuf.len; --- 1383,1394 ---- if (p == limit) break; ! p = convert_escape (pfile, p + 1, limit, &tbuf, cvt); } } /* NUL-terminate the 'to' buffer and translate it to a cpp_string structure. */ ! emit_numeric_escape (pfile, 0, &tbuf, cvt); tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len); to->text = tbuf.text; to->len = tbuf.len; *************** cpp_interpret_string (cpp_reader *pfile, *** 1375,1381 **** in a string, but do not perform character set conversion. */ bool cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, ! size_t count, cpp_string *to, bool wide) { struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc; bool retval; --- 1404,1411 ---- in a string, but do not perform character set conversion. */ bool cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, ! size_t count, cpp_string *to, ! enum cpp_ttype type ATTRIBUTE_UNUSED) { struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc; bool retval; *************** cpp_interpret_string_notranslate (cpp_re *** 1383,1389 **** pfile->narrow_cset_desc.func = convert_no_conversion; pfile->narrow_cset_desc.cd = (iconv_t) -1; ! retval = cpp_interpret_string (pfile, from, count, to, wide); pfile->narrow_cset_desc = save_narrow_cset_desc; return retval; --- 1413,1419 ---- pfile->narrow_cset_desc.func = convert_no_conversion; pfile->narrow_cset_desc.cd = (iconv_t) -1; ! retval = cpp_interpret_string (pfile, from, count, to, CPP_STRING); pfile->narrow_cset_desc = save_narrow_cset_desc; return retval; *************** narrow_str_to_charconst (cpp_reader *pfi *** 1462,1474 **** /* Subroutine of cpp_interpret_charconst which performs the conversion to a number, for wide strings. STR is the string structure returned by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for ! cpp_interpret_charconst. */ static cppchar_t wide_str_to_charconst (cpp_reader *pfile, cpp_string str, ! unsigned int *pchars_seen, int *unsignedp) { bool bigend = CPP_OPTION (pfile, bytes_big_endian); ! size_t width = CPP_OPTION (pfile, wchar_precision); size_t cwidth = CPP_OPTION (pfile, char_precision); size_t mask = width_to_mask (width); size_t cmask = width_to_mask (cwidth); --- 1492,1505 ---- /* Subroutine of cpp_interpret_charconst which performs the conversion to a number, for wide strings. STR is the string structure returned by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for ! cpp_interpret_charconst. TYPE is the token type. */ static cppchar_t wide_str_to_charconst (cpp_reader *pfile, cpp_string str, ! unsigned int *pchars_seen, int *unsignedp, ! enum cpp_ttype type) { bool bigend = CPP_OPTION (pfile, bytes_big_endian); ! size_t width = converter_for_type (pfile, type).width; size_t cwidth = CPP_OPTION (pfile, char_precision); size_t mask = width_to_mask (width); size_t cmask = width_to_mask (cwidth); *************** wide_str_to_charconst (cpp_reader *pfile *** 1490,1496 **** /* Wide character constants have type wchar_t, and a single character exactly fills a wchar_t, so a multi-character wide character constant is guaranteed to overflow. */ ! if (off > 0) cpp_error (pfile, CPP_DL_WARNING, "character constant too long for its type"); --- 1521,1527 ---- /* Wide character constants have type wchar_t, and a single character exactly fills a wchar_t, so a multi-character wide character constant is guaranteed to overflow. */ ! if (str.len > nbwc * 2) cpp_error (pfile, CPP_DL_WARNING, "character constant too long for its type"); *************** wide_str_to_charconst (cpp_reader *pfile *** 1498,1510 **** sign- or zero-extend to the full width of cppchar_t. */ if (width < BITS_PER_CPPCHAR_T) { ! if (CPP_OPTION (pfile, unsigned_wchar) || !(result & (1 << (width - 1)))) result &= mask; else result |= ~mask; } ! *unsignedp = CPP_OPTION (pfile, unsigned_wchar); *pchars_seen = 1; return result; } --- 1529,1548 ---- sign- or zero-extend to the full width of cppchar_t. */ if (width < BITS_PER_CPPCHAR_T) { ! if (type == CPP_CHAR16 || type == CPP_CHAR32 ! || CPP_OPTION (pfile, unsigned_wchar) ! || !(result & (1 << (width - 1)))) result &= mask; else result |= ~mask; } ! if (type == CPP_CHAR16 || type == CPP_CHAR32 ! || CPP_OPTION (pfile, unsigned_wchar)) ! *unsignedp = 1; ! else ! *unsignedp = 0; ! *pchars_seen = 1; return result; } *************** cpp_interpret_charconst (cpp_reader *pfi *** 1518,1537 **** unsigned int *pchars_seen, int *unsignedp) { cpp_string str = { 0, 0 }; ! bool wide = (token->type == CPP_WCHAR); cppchar_t result; ! /* an empty constant will appear as L'' or '' */ if (token->val.str.len == (size_t) (2 + wide)) { cpp_error (pfile, CPP_DL_ERROR, "empty character constant"); return 0; } ! else if (!cpp_interpret_string (pfile, &token->val.str, 1, &str, wide)) return 0; if (wide) ! result = wide_str_to_charconst (pfile, str, pchars_seen, unsignedp); else result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp); --- 1556,1576 ---- unsigned int *pchars_seen, int *unsignedp) { cpp_string str = { 0, 0 }; ! bool wide = (token->type != CPP_CHAR); cppchar_t result; ! /* an empty constant will appear as L'', u'', U'' or '' */ if (token->val.str.len == (size_t) (2 + wide)) { cpp_error (pfile, CPP_DL_ERROR, "empty character constant"); return 0; } ! else if (!cpp_interpret_string (pfile, &token->val.str, 1, &str, token->type)) return 0; if (wide) ! result = wide_str_to_charconst (pfile, str, pchars_seen, unsignedp, ! token->type); else result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor