*/
static void print_quoted_string(const string_t *const string, char border)
{
+ print_string(get_string_encoding_prefix(string->encoding));
+
print_char(border);
const char *end = string->begin + string->size;
for (const char *c = string->begin; c != end; ++c) {
static void print_string_literal(string_literal_expression_t const *const literal, char const delimiter)
{
- print_string(get_string_encoding_prefix(literal->encoding));
print_quoted_string(&literal->value, delimiter);
}
* @param id_prefix a prefix for the name of the generated string constant
* @param value the value of the string constant
*/
-static ir_node *string_to_firm(source_position_t const *const src_pos, char const *const id_prefix, string_encoding_t const enc, string_t const *const value)
+static ir_node *string_to_firm(source_position_t const *const src_pos, char const *const id_prefix, string_t const *const value)
{
- size_t const slen = get_string_len(enc, value) + 1;
+ size_t const slen = get_string_len(value) + 1;
ir_initializer_t *const initializer = create_initializer_compound(slen);
ir_type * elem_type;
- switch (enc) {
+ switch (value->encoding) {
case STRING_ENCODING_CHAR: {
elem_type = ir_type_char;
size_t size = literal->value.size;
ir_tarval *tv;
- switch (literal->encoding) {
+ switch (literal->value.encoding) {
case STRING_ENCODING_WIDE: {
utf32 v = read_utf8_char(&string);
char buf[128];
case FUNCNAME_PRETTY_FUNCTION:
case FUNCNAME_FUNCDNAME:
if (current_function_name == NULL) {
- const source_position_t *const src_pos = &expr->base.source_position;
- const char *name = current_function_entity->base.symbol->string;
- const string_t string = { name, strlen(name) };
- current_function_name = string_to_firm(src_pos, "__func__.%u", STRING_ENCODING_CHAR, &string);
+ source_position_t const *const src_pos = &expr->base.source_position;
+ char const *const name = current_function_entity->base.symbol->string;
+ string_t const string = { name, strlen(name), STRING_ENCODING_CHAR };
+ current_function_name = string_to_firm(src_pos, "__func__.%u", &string);
}
return current_function_name;
case FUNCNAME_FUNCSIG:
if (current_funcsig == NULL) {
- const source_position_t *const src_pos = &expr->base.source_position;
- ir_entity *ent = get_irg_entity(current_ir_graph);
- const char *const name = get_entity_ld_name(ent);
- const string_t string = { name, strlen(name) };
- current_funcsig = string_to_firm(src_pos, "__FUNCSIG__.%u", STRING_ENCODING_CHAR, &string);
+ source_position_t const *const src_pos = &expr->base.source_position;
+ ir_entity *const ent = get_irg_entity(current_ir_graph);
+ char const *const name = get_entity_ld_name(ent);
+ string_t const string = { name, strlen(name), STRING_ENCODING_CHAR };
+ current_funcsig = string_to_firm(src_pos, "__FUNCSIG__.%u", &string);
}
return current_funcsig;
}
case EXPR_VA_COPY: return va_copy_expression_to_firm( &expr->va_copye);
case EXPR_VA_START: return va_start_expression_to_firm( &expr->va_starte);
- case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.source_position, "str.%u", expr->string_literal.encoding, &expr->string_literal.value);
+ case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.source_position, "str.%u", &expr->string_literal.value);
case EXPR_ERROR: break;
}
ir_initializer_t *const irinit = create_initializer_compound(arr_len);
ir_mode *const mode = get_ir_mode_storage(type->array.element_type);
char const * p = str->value.begin;
- switch (str->encoding) {
+ switch (str->value.encoding) {
case STRING_ENCODING_CHAR:
for (size_t i = 0; i != arr_len; ++i) {
char const c = i < str_len ? *p++ : 0;
* string and character literals
*/
struct string_literal_expression_t {
- expression_base_t base;
- string_encoding_t encoding;
- string_t value;
+ expression_base_t base;
+ string_t value;
};
struct funcname_expression_t {
}
}
-static string_t sym_make_string(void)
+static string_t sym_make_string(string_encoding_t const enc)
{
obstack_1grow(&symbol_obstack, '\0');
size_t const len = obstack_object_size(&symbol_obstack) - 1;
#else
const char *result = string;
#endif
- return (string_t) {result, len};
+ return (string_t){ result, len, enc };
}
/**
return;
}
- lexer_token.number.suffix = sym_make_string();
+ lexer_token.number.suffix = sym_make_string(STRING_ENCODING_CHAR);
}
static void parse_exponent(void)
"hexadecimal floatingpoint constant requires an exponent");
}
- lexer_token.number.number = sym_make_string();
+ lexer_token.number.number = sym_make_string(STRING_ENCODING_CHAR);
lexer_token.kind = is_float ? T_FLOATINGPOINT : T_INTEGER;
next_char();
}
- lexer_token.number.number = sym_make_string();
+ lexer_token.number.number = sym_make_string(STRING_ENCODING_CHAR);
lexer_token.kind = T_INTEGER;
if (!has_digits) {
parse_exponent();
}
- lexer_token.number.number = sym_make_string();
+ lexer_token.number.number = sym_make_string(STRING_ENCODING_CHAR);
if (is_float) {
lexer_token.kind = T_FLOATINGPOINT;
string_t make_string(const char *string)
{
obstack_grow(&symbol_obstack, string, strlen(string));
- return sym_make_string();
+ return sym_make_string(STRING_ENCODING_CHAR);
}
static void parse_string(utf32 const delim, token_kind_t const kind, string_encoding_t const enc, char const *const context)
}
end_of_string:
- lexer_token.kind = kind;
- lexer_token.string.encoding = enc;
- lexer_token.string.string = sym_make_string();
+ lexer_token.kind = kind;
+ lexer_token.string.string = sym_make_string(enc);
}
/**
lexer_pos.lineno = atoi(pp_token.number.number.begin) - 1;
next_pp_token();
}
- if (pp_token.kind == T_STRING_LITERAL && pp_token.string.encoding == STRING_ENCODING_CHAR) {
- lexer_pos.input_name = pp_token.string.string.begin;
+ if (pp_token.kind == T_STRING_LITERAL && pp_token.string.string.encoding == STRING_ENCODING_CHAR) {
+ lexer_pos.input_name = pp_token.string.string.begin;
lexer_pos.is_system_header = false;
next_pp_token();
obstack_grow(&ast_obstack, s->begin, s->size);
}
-static string_t finish_string(void)
+static string_t finish_string(string_encoding_t const enc)
{
obstack_1grow(&ast_obstack, '\0');
size_t const size = obstack_object_size(&ast_obstack) - 1;
char const *const string = obstack_finish(&ast_obstack);
- return (string_t){ string, size };
+ return (string_t){ string, size, enc };
}
-static string_t concat_string_literals(string_encoding_t *const out_enc)
+static string_t concat_string_literals(void)
{
assert(token.kind == T_STRING_LITERAL);
- string_t result;
- string_encoding_t enc = token.string.encoding;
+ string_t result;
if (look_ahead(1)->kind == T_STRING_LITERAL) {
append_string(&token.string.string);
eat(T_STRING_LITERAL);
warningf(WARN_TRADITIONAL, HERE, "traditional C rejects string constant concatenation");
+ string_encoding_t enc = token.string.string.encoding;
do {
- if (token.string.encoding != STRING_ENCODING_CHAR) {
- enc = token.string.encoding;
+ if (token.string.string.encoding != STRING_ENCODING_CHAR) {
+ enc = token.string.string.encoding;
}
append_string(&token.string.string);
eat(T_STRING_LITERAL);
} while (token.kind == T_STRING_LITERAL);
- result = finish_string();
+ result = finish_string(enc);
} else {
result = token.string.string;
eat(T_STRING_LITERAL);
}
- *out_enc = enc;
return result;
}
static string_t parse_string_literals(char const *const context)
{
if (!skip_till(T_STRING_LITERAL, context))
- return (string_t){ "", 0 };
+ return (string_t){ "", 0, STRING_ENCODING_CHAR };
- string_encoding_t enc;
source_position_t const pos = *HERE;
- string_t const res = concat_string_literals(&enc);
+ string_t const res = concat_string_literals();
- if (enc != STRING_ENCODING_CHAR) {
+ if (res.encoding != STRING_ENCODING_CHAR) {
errorf(&pos, "expected plain string literal, got wide string literal");
}
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);
- switch (expression->string_literal.encoding) {
+ switch (expression->string_literal.value.encoding) {
case STRING_ENCODING_CHAR: {
if (is_type_atomic(element_type, ATOMIC_TYPE_CHAR) ||
is_type_atomic(element_type, ATOMIC_TYPE_SCHAR) ||
break;
case INITIALIZER_STRING: {
- string_literal_expression_t const *const str = get_init_string(result);
- size = get_string_len(str->encoding, &str->value) + 1;
+ size = get_string_len(&get_init_string(result)->value) + 1;
break;
}
static expression_t *parse_string_literal(void)
{
expression_t *const expr = allocate_expression_zero(EXPR_STRING_LITERAL);
- expr->string_literal.value = concat_string_literals(&expr->string_literal.encoding);
- expr->base.type = get_string_type(expr->string_literal.encoding);
+ expr->string_literal.value = concat_string_literals();
+ expr->base.type = get_string_type(expr->string_literal.value.encoding);
return expr;
}
static expression_t *parse_character_constant(void)
{
expression_t *const literal = allocate_expression_zero(EXPR_LITERAL_CHARACTER);
- literal->string_literal.encoding = token.string.encoding;
- literal->string_literal.value = token.string.string;
+ literal->string_literal.value = token.string.string;
- size_t const size = get_string_len(token.string.encoding, &token.string.string);
- switch (token.string.encoding) {
+ size_t const size = get_string_len(&token.string.string);
+ switch (token.string.string.encoding) {
case STRING_ENCODING_CHAR:
literal->base.type = c_mode & _CXX ? type_char : type_int;
if (size > 1) {
}
case EXPR_STRING_LITERAL: {
- size_t const size = get_string_len(expression->string_literal.encoding, &expression->string_literal.value) + 1;
+ size_t const size = get_string_len(&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);
}
return result;
}
-static string_t sym_make_string(void)
+static string_t sym_make_string(string_encoding_t const enc)
{
obstack_1grow(&symbol_obstack, '\0');
size_t const len = obstack_object_size(&symbol_obstack) - 1;
char *const string = obstack_finish(&symbol_obstack);
char const *const result = identify_string(string);
- return (string_t) {result, len};
+ return (string_t){ result, len, enc };
}
static void parse_string(utf32 const delimiter, preprocessor_token_kind_t const kind, string_encoding_t const enc, char const *const context)
}
end_of_string:
- pp_token.kind = kind;
- pp_token.string.encoding = enc;
- pp_token.string.string = sym_make_string();
+ pp_token.kind = kind;
+ pp_token.string.string = sym_make_string(enc);
}
static void parse_string_literal(string_encoding_t const enc)
end_number:
pp_token.kind = TP_NUMBER;
- pp_token.number.number = sym_make_string();
+ pp_token.number.number = sym_make_string(STRING_ENCODING_CHAR);
}
break;
case TP_STRING_LITERAL:
- fputs(get_string_encoding_prefix(pp_token.string.encoding), out);
+ fputs(get_string_encoding_prefix(pp_token.string.string.encoding), out);
fputc('"', out);
fputs(pp_token.string.string.begin, out);
fputc('"', out);
break;
case TP_CHARACTER_CONSTANT:
- fputs(get_string_encoding_prefix(pp_token.string.encoding), out);
+ fputs(get_string_encoding_prefix(pp_token.string.string.encoding), out);
fputc('\'', out);
fputs(pp_token.string.string.begin, out);
fputc('\'', out);
static void parse_headername(void)
{
const source_position_t start_position = input.position;
- string_t string = {NULL, 0};
+ string_t string = { NULL, 0, STRING_ENCODING_CHAR };
assert(obstack_object_size(&symbol_obstack) == 0);
/* behind an #include we can have the special headername lexems.
}
finished_headername:
- string = sym_make_string();
+ string = sym_make_string(STRING_ENCODING_CHAR);
finish_error:
pp_token.base.source_position = start_position;
return result;
}
-size_t get_string_len(string_encoding_t const enc, string_t const *const str)
+size_t get_string_len(string_t const *const str)
{
- switch (enc) {
+ switch (str->encoding) {
case STRING_ENCODING_CHAR: return str->size;
case STRING_ENCODING_WIDE: return wstrlen(str);
}
typedef enum string_encoding_t string_encoding_t;
typedef struct string_t {
- const char *begin; /**< UTF-8 encoded string, the last character is
- * guaranteed to be 0 */
- size_t size; /**< size of string in bytes (not characters) */
+ char const *begin; /**< UTF-8 encoded string, the last character is guaranteed to be \0. */
+ size_t size; /**< size of string in bytes (not characters), without terminating \0. */
+ string_encoding_t encoding;
} string_t;
-size_t get_string_len(string_encoding_t enc, string_t const *str);
+size_t get_string_len(string_t const *str);
#endif
case T_CHARACTER_CONSTANT: delim = '\''; goto print_string;
print_string:
print_token_kind(f, (token_kind_t)token->kind);
- fprintf(f, " %s%c", get_string_encoding_prefix(token->string.encoding), delim);
+ fprintf(f, " %s%c", get_string_encoding_prefix(token->string.string.encoding), delim);
print_stringrep(&token->string.string, f);
fputc(delim, f);
break;
};
struct string_literal_t {
- token_base_t base;
- string_encoding_t encoding;
- string_t string;
+ token_base_t base;
+ string_t string;
};
struct number_literal_t {