lexer_token.string.string = identify_string(string, size);
}
-/**
- * Parse a wide character constant and set lexer_token.
- */
-static void parse_wide_character_constant(void)
-{
- eat('\'');
-
- while (true) {
- switch (c) {
- case '\\': {
- const utf32 tc = parse_escape_sequence();
- obstack_grow_symbol(&symbol_obstack, tc);
- break;
- }
-
- MATCH_NEWLINE(
- parse_error("newline while parsing character constant");
- break;
- )
-
- case '\'':
- next_char();
- goto end_of_wide_char_constant;
-
- case EOF:
- errorf(&lexer_token.base.source_position, "EOF while parsing character constant");
- goto end_of_wide_char_constant;
-
- default:
- obstack_grow_symbol(&symbol_obstack, c);
- next_char();
- break;
- }
- }
-
-end_of_wide_char_constant:;
- obstack_1grow(&symbol_obstack, '\0');
- size_t size = (size_t) obstack_object_size(&symbol_obstack) - 1;
- char *string = obstack_finish(&symbol_obstack);
-
- lexer_token.kind = T_WIDE_CHARACTER_CONSTANT;
- lexer_token.string.string = identify_string(string, size);
-
- if (size == 0) {
- errorf(&lexer_token.base.source_position, "empty character constant");
- }
-}
-
/**
* Parse a character constant and set lexer_token.
*/
-static void parse_character_constant(void)
+static void parse_character_constant(string_encoding_t const enc)
{
eat('\'');
switch (c) {
case '\\': {
utf32 const tc = parse_escape_sequence();
- if (tc >= 0x100) {
- warningf(WARN_OTHER, &lexer_pos, "escape sequence out of range");
+ if (enc == STRING_ENCODING_CHAR) {
+ if (tc >= 0x100) {
+ warningf(WARN_OTHER, &lexer_pos, "escape sequence out of range");
+ }
+ obstack_1grow(&symbol_obstack, tc);
+ } else {
+ obstack_grow_symbol(&symbol_obstack, tc);
}
- obstack_1grow(&symbol_obstack, tc);
break;
}
const size_t size = (size_t)obstack_object_size(&symbol_obstack)-1;
char *const string = obstack_finish(&symbol_obstack);
- lexer_token.kind = T_CHARACTER_CONSTANT;
- lexer_token.string.string = identify_string(string, size);
+ lexer_token.kind = T_CHARACTER_CONSTANT;
+ lexer_token.string.encoding = enc;
+ lexer_token.string.string = identify_string(string, size);
if (size == 0) {
errorf(&lexer_token.base.source_position, "empty character constant");
string_encoding_t const enc = STRING_ENCODING_WIDE;
if (lexer_token.base.symbol == symbol_L) {
switch (c) {
- case '"': parse_string_literal(enc); break;
- case '\'': parse_wide_character_constant(); break;
+ case '"': parse_string_literal(enc); break;
+ case '\'': parse_character_constant(enc); break;
}
}
return;
return;
case '\'':
- parse_character_constant();
+ parse_character_constant(STRING_ENCODING_CHAR);
return;
case '.':
case T_MINUSMINUS: \
case T_PLUSPLUS: \
case T_STRING_LITERAL: \
- case T_WIDE_CHARACTER_CONSTANT: \
case T___FUNCDNAME__: \
case T___FUNCSIG__: \
case T___FUNCTION__: \
*/
static expression_t *parse_character_constant(void)
{
- expression_t *literal = allocate_expression_zero(EXPR_LITERAL_CHARACTER);
- literal->base.type = c_mode & _CXX ? type_char : type_int;
- literal->literal.value = token.string.string;
-
- size_t len = literal->literal.value.size;
- if (len > 1) {
- if (!GNU_MODE && !(c_mode & _C99)) {
- errorf(HERE, "more than 1 character in character constant");
- } else {
- literal->base.type = type_int;
- warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
+ expression_t *literal;
+ switch (token.string.encoding) {
+ case STRING_ENCODING_CHAR: {
+ literal = allocate_expression_zero(EXPR_LITERAL_CHARACTER);
+ literal->base.type = c_mode & _CXX ? type_char : type_int;
+ literal->literal.value = token.string.string;
+
+ size_t len = literal->literal.value.size;
+ if (len > 1) {
+ if (!GNU_MODE && !(c_mode & _C99)) {
+ errorf(HERE, "more than 1 character in character constant");
+ } else {
+ literal->base.type = type_int;
+ warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
+ }
}
+ break;
}
- eat(T_CHARACTER_CONSTANT);
- return literal;
-}
+ case STRING_ENCODING_WIDE: {
+ literal = allocate_expression_zero(EXPR_LITERAL_WIDE_CHARACTER);
+ literal->base.type = type_int;
+ literal->literal.value = token.string.string;
-/**
- * Parse a wide character constant.
- */
-static expression_t *parse_wide_character_constant(void)
-{
- expression_t *literal = allocate_expression_zero(EXPR_LITERAL_WIDE_CHARACTER);
- literal->base.type = type_int;
- literal->literal.value = token.string.string;
-
- size_t len = wstrlen(&literal->literal.value);
- if (len > 1) {
- warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
+ size_t len = wstrlen(&literal->literal.value);
+ if (len > 1) {
+ warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
+ }
+ break;
+ }
}
- eat(T_WIDE_CHARACTER_CONSTANT);
+ eat(T_CHARACTER_CONSTANT);
return literal;
}
case T_INTEGER:
case T_FLOATINGPOINT: return parse_number_literal();
case T_CHARACTER_CONSTANT: return parse_character_constant();
- case T_WIDE_CHARACTER_CONSTANT: return parse_wide_character_constant();
case T_STRING_LITERAL: return parse_string_literal();
case T___FUNCTION__:
case T___func__: return parse_function_keyword(FUNCNAME_FUNCTION);
add_anchor_token(T_MINUSMINUS);
add_anchor_token(T_PLUSPLUS);
add_anchor_token(T_STRING_LITERAL);
- add_anchor_token(T_WIDE_CHARACTER_CONSTANT);
add_anchor_token(T__Bool);
add_anchor_token(T__Complex);
add_anchor_token(T__Imaginary);
rem_anchor_token(T__Imaginary);
rem_anchor_token(T__Complex);
rem_anchor_token(T__Bool);
- rem_anchor_token(T_WIDE_CHARACTER_CONSTANT);
rem_anchor_token(T_STRING_LITERAL);
rem_anchor_token(T_PLUSPLUS);
rem_anchor_token(T_MINUSMINUS);