[EXPR_LITERAL_INTEGER] = sizeof(literal_expression_t),
[EXPR_LITERAL_FLOATINGPOINT] = sizeof(literal_expression_t),
[EXPR_LITERAL_CHARACTER] = sizeof(string_literal_expression_t),
- [EXPR_LITERAL_WIDE_CHARACTER] = sizeof(string_literal_expression_t),
[EXPR_STRING_LITERAL] = sizeof(string_literal_expression_t),
[EXPR_COMPOUND_LITERAL] = sizeof(compound_literal_expression_t),
[EXPR_CALL] = sizeof(call_expression_t),
static const size_t sizes[] = {
[INITIALIZER_VALUE] = sizeof(initializer_value_t),
[INITIALIZER_STRING] = sizeof(initializer_string_t),
- [INITIALIZER_WIDE_STRING] = sizeof(initializer_wide_string_t),
[INITIALIZER_LIST] = sizeof(initializer_list_t),
[INITIALIZER_DESIGNATOR] = sizeof(initializer_designator_t)
};
case EXPR_LITERAL_CASES:
case EXPR_LITERAL_CHARACTER:
- case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_ERROR:
case EXPR_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO init?
}
}
-static initializer_t *initializer_from_string(array_type_t *const type,
- const string_t *const string)
+static initializer_t *initializer_from_string(array_type_t *const type, string_encoding_t const enc, string_t const *const string)
{
/* TODO: check len vs. size of array type */
(void) type;
initializer_t *initializer = allocate_initializer_zero(INITIALIZER_STRING);
- initializer->string.string = *string;
-
- return initializer;
-}
-
-static initializer_t *initializer_from_wide_string(array_type_t *const type,
- const string_t *const string)
-{
- /* TODO: check len vs. size of array type */
- (void) type;
-
- initializer_t *const initializer =
- allocate_initializer_zero(INITIALIZER_WIDE_STRING);
- initializer->wide_string.string = *string;
+ initializer->string.encoding = enc;
+ initializer->string.string = *string;
return initializer;
}
{
/* TODO check that expression is a constant expression */
- /* §6.7.8.14/15 char array may be initialized by string literals */
- type_t *type = skip_typeref(orig_type);
- type_t *expr_type_orig = expression->base.type;
- type_t *expr_type = skip_typeref(expr_type_orig);
+ type_t *const type = skip_typeref(orig_type);
- if (is_type_array(type) && expr_type->kind == TYPE_POINTER) {
+ /* §6.7.8.14/15 char array may be initialized by string literals */
+ if (expression->kind == EXPR_STRING_LITERAL && is_type_array(type)) {
array_type_t *const array_type = &type->array;
type_t *const element_type = skip_typeref(array_type->element_type);
-
- if (element_type->kind == TYPE_ATOMIC && expression->kind == EXPR_STRING_LITERAL) {
- switch (expression->string_literal.encoding) {
- case STRING_ENCODING_CHAR: {
- atomic_type_kind_t const akind = element_type->atomic.akind;
- if (akind == ATOMIC_TYPE_CHAR
- || akind == ATOMIC_TYPE_SCHAR
- || akind == ATOMIC_TYPE_UCHAR) {
- return initializer_from_string(array_type,
- &expression->string_literal.value);
- }
- break;
+ switch (expression->string_literal.encoding) {
+ case STRING_ENCODING_CHAR: {
+ if (is_type_atomic(element_type, ATOMIC_TYPE_CHAR) ||
+ is_type_atomic(element_type, ATOMIC_TYPE_SCHAR) ||
+ is_type_atomic(element_type, ATOMIC_TYPE_UCHAR)) {
+ goto make_string_init;
}
+ break;
+ }
- case STRING_ENCODING_WIDE: {
- type_t *bare_wchar_type = skip_typeref(type_wchar_t);
- if (get_unqualified_type(element_type) == bare_wchar_type) {
- return initializer_from_wide_string(array_type,
- &expression->string_literal.value);
- }
- break;
- }
+ case STRING_ENCODING_WIDE: {
+ type_t *bare_wchar_type = skip_typeref(type_wchar_t);
+ if (get_unqualified_type(element_type) == bare_wchar_type) {
+make_string_init:
+ return initializer_from_string(array_type, expression->string_literal.encoding, &expression->string_literal.value);
}
+ break;
+ }
}
}
break;
case INITIALIZER_STRING:
- size = result->string.string.size + 1;
- break;
-
- case INITIALIZER_WIDE_STRING:
- size = result->wide_string.string.size;
+ size = get_string_len(result->string.encoding, &result->string.string) + 1;
break;
case INITIALIZER_DESIGNATOR:
case EXPR_ENUM_CONSTANT:
case EXPR_LITERAL_CASES:
case EXPR_LITERAL_CHARACTER:
- case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO descend into initialisers
case EXPR_LABEL_ADDRESS:
}
case INITIALIZER_STRING:
- case INITIALIZER_WIDE_STRING:
case INITIALIZER_DESIGNATOR: // designators have no payload
return true;
}
*/
static expression_t *parse_character_constant(void)
{
- 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->string_literal.value = token.string.string;
+ expression_t *const literal = allocate_expression_zero(EXPR_LITERAL_CHARACTER);
+ literal->string_literal.encoding = token.string.encoding;
+ literal->string_literal.value = token.string.string;
- if (literal->string_literal.value.size > 1) {
+ size_t const size = get_string_len(token.string.encoding, &token.string.string);
+ switch (token.string.encoding) {
+ case STRING_ENCODING_CHAR:
+ literal->base.type = c_mode & _CXX ? type_char : type_int;
+ if (size > 1) {
if (!GNU_MODE && !(c_mode & _C99)) {
errorf(HERE, "more than 1 character in character constant");
} else {
}
}
break;
- }
-
- case STRING_ENCODING_WIDE: {
- literal = allocate_expression_zero(EXPR_LITERAL_WIDE_CHARACTER);
- literal->base.type = type_int;
- literal->string_literal.value = token.string.string;
- if (wstrlen(&literal->string_literal.value) > 1) {
+ case STRING_ENCODING_WIDE:
+ literal->base.type = type_int;
+ if (size > 1) {
warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
}
break;
}
- }
eat(T_CHARACTER_CONSTANT);
return literal;
}
case EXPR_STRING_LITERAL: {
- size_t const size = expression->string_literal.value.size + 1;
+ size_t const size = get_string_len(expression->string_literal.encoding, &expression->string_literal.value) + 1;
type_t *const elem = get_unqualified_type(expression->base.type->pointer.points_to);
return make_array_type(elem, size, TYPE_QUALIFIER_NONE);
}
case EXPR_LITERAL_MS_NOOP: return true;
case EXPR_LITERAL_BOOLEAN:
case EXPR_LITERAL_CHARACTER:
- case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_LITERAL_INTEGER:
case EXPR_LITERAL_FLOATINGPOINT:
case EXPR_STRING_LITERAL: return false;
{
expression_parser_function_t *entry = &expression_parsers[token_kind];
- if (entry->parser != NULL) {
- diagnosticf("for token '%k'\n", (token_kind_t)token_kind);
- panic("trying to register multiple expression parsers for a token");
- }
+ assert(!entry->parser);
entry->parser = parser;
}
{
expression_parser_function_t *entry = &expression_parsers[token_kind];
- if (entry->infix_parser != NULL) {
- diagnosticf("for token '%k'\n", (token_kind_t)token_kind);
- panic("trying to register multiple infix expression parsers for a "
- "token");
- }
+ assert(!entry->infix_parser);
entry->infix_parser = parser;
entry->infix_precedence = precedence;
}
{
environment_stack = NEW_ARR_F(stack_entry_t, 0);
label_stack = NEW_ARR_F(stack_entry_t, 0);
- diagnostic_count = 0;
error_count = 0;
warning_count = 0;