{
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_STRING] = sizeof(initializer_value_t),
[INITIALIZER_LIST] = sizeof(initializer_list_t),
[INITIALIZER_DESIGNATOR] = sizeof(initializer_designator_t)
};
}
}
-static initializer_t *initializer_from_string(array_type_t *const type,
- const string_t *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;
-
- return initializer;
-}
-
/**
* Build an initializer from a given expression.
*/
{
/* 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:;
+ initializer_t *const init = allocate_initializer_zero(INITIALIZER_STRING);
+ init->value.value = expression;
+ return init;
}
+ break;
+ }
}
}
size = max_index + 1;
break;
- case INITIALIZER_STRING:
- size = result->string.string.size + 1;
- break;
-
- case INITIALIZER_WIDE_STRING:
- size = result->wide_string.string.size;
+ case INITIALIZER_STRING: {
+ string_literal_expression_t const *const str = get_init_string(result);
+ size = get_string_len(str->encoding, &str->value) + 1;
break;
+ }
case INITIALIZER_DESIGNATOR:
case INITIALIZER_VALUE:
} else {
errorf(pos, "multiple datatypes in declaration");
}
- goto end_error;
+ specifiers->type = type_error_type;
+ return;
}
}
if (specifiers->attributes != NULL)
type = handle_type_attributes(specifiers->attributes, type);
specifiers->type = type;
- return;
-
-end_error:
- specifiers->type = type_error_type;
}
static type_qualifiers_t parse_type_qualifiers(void)
}
case INITIALIZER_STRING:
- case INITIALIZER_WIDE_STRING:
case INITIALIZER_DESIGNATOR: // designators have no payload
return true;
}
symbol_t *iter_symbol = iter->base.symbol;
if (iter_symbol == NULL) {
type_t *type = iter->declaration.type;
- if (type->kind != TYPE_COMPOUND_STRUCT
- && type->kind != TYPE_COMPOUND_UNION)
+ if (!is_type_compound(type))
continue;
compound_t *sub_compound = type->compound.compound;
literal->string_literal.encoding = token.string.encoding;
literal->string_literal.value = token.string.string;
+ 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 (literal->string_literal.value.size > 1) {
+ if (size > 1) {
if (!GNU_MODE && !(c_mode & _C99)) {
errorf(HERE, "more than 1 character in character constant");
} else {
case STRING_ENCODING_WIDE:
literal->base.type = type_int;
- if (wstrlen(&literal->string_literal.value) > 1) {
+ if (size > 1) {
warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
}
break;
}
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);
}
type_left = type;
}
- if (type_left->kind != TYPE_COMPOUND_STRUCT &&
- type_left->kind != TYPE_COMPOUND_UNION) {
-
+ if (!is_type_compound(type_left)) {
if (is_type_valid(type_left) && !saw_error) {
errorf(&pos,
"request for member '%Y' in something not a struct or union, but '%T'",