case T_STRING_LITERAL: \
case T___FUNCDNAME__: \
case T___FUNCSIG__: \
- case T___FUNCTION__: \
case T___PRETTY_FUNCTION__: \
case T___alignof__: \
case T___builtin_classify_type: \
[EXPR_LITERAL_BOOLEAN] = sizeof(literal_expression_t),
[EXPR_LITERAL_INTEGER] = sizeof(literal_expression_t),
[EXPR_LITERAL_FLOATINGPOINT] = sizeof(literal_expression_t),
- [EXPR_LITERAL_CHARACTER] = sizeof(literal_expression_t),
- [EXPR_LITERAL_WIDE_CHARACTER] = sizeof(literal_expression_t),
+ [EXPR_LITERAL_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),
return result;
}
-static string_t parse_string_literals(void)
+static string_t parse_string_literals(char const *const context)
{
+ if (!skip_till(T_STRING_LITERAL, context))
+ return (string_t){ "", 0 };
+
string_encoding_t enc;
source_position_t const pos = *HERE;
string_t const res = concat_string_literals(&enc);
return;
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
case EXPR_ERROR:
case EXPR_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO init?
case EXPR_REFERENCE:
case EXPR_ENUM_CONSTANT:
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
case EXPR_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO descend into initialisers
case EXPR_LABEL_ADDRESS:
*/
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->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;
- size_t len = literal->literal.value.size;
- if (len > 1) {
+ 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 (!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->literal.value = token.string.string;
-
- size_t len = wstrlen(&literal->literal.value);
- if (len > 1) {
+ case STRING_ENCODING_WIDE:
+ literal->base.type = type_int;
+ if (wstrlen(&literal->string_literal.value) > 1) {
warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
}
break;
}
- }
eat(T_CHARACTER_CONSTANT);
return literal;
case T_FLOATINGPOINT: return parse_number_literal();
case T_CHARACTER_CONSTANT: return parse_character_constant();
case T_STRING_LITERAL: return parse_string_literal();
- case T___FUNCTION__:
case T___func__: return parse_function_keyword(FUNCNAME_FUNCTION);
case T___PRETTY_FUNCTION__: return parse_function_keyword(FUNCNAME_PRETTY_FUNCTION);
case T___FUNCSIG__: return parse_function_keyword(FUNCNAME_FUNCSIG);
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;
return NULL;
}
- argument->constraints = parse_string_literals();
+ argument->constraints = parse_string_literals("asm argument");
add_anchor_token(')');
expect('(');
expression_t *expression = parse_expression();
while (token.kind == T_STRING_LITERAL) {
asm_clobber_t *clobber = allocate_ast_zero(sizeof(clobber[0]));
- clobber->clobber = parse_string_literals();
+ clobber->clobber = parse_string_literals(NULL);
*anchor = clobber;
anchor = &clobber->next;
asm_statement_t *asm_statement = &statement->asms;
eat(T_asm);
+ add_anchor_token(')');
+ add_anchor_token(':');
+ add_anchor_token(T_STRING_LITERAL);
if (next_if(T_volatile))
asm_statement->is_volatile = true;
expect('(');
- add_anchor_token(')');
- if (token.kind != T_STRING_LITERAL) {
- parse_error_expected("after asm(", T_STRING_LITERAL, NULL);
- goto end_of_asm;
- }
- asm_statement->asm_text = parse_string_literals();
+ rem_anchor_token(T_STRING_LITERAL);
+ asm_statement->asm_text = parse_string_literals("asm statement");
- add_anchor_token(':');
- if (!next_if(':')) {
- rem_anchor_token(':');
- goto end_of_asm;
- }
+ if (next_if(':'))
+ asm_statement->outputs = parse_asm_arguments(true);
- asm_statement->outputs = parse_asm_arguments(true);
- if (!next_if(':')) {
- rem_anchor_token(':');
- goto end_of_asm;
- }
+ if (next_if(':'))
+ asm_statement->inputs = parse_asm_arguments(false);
- asm_statement->inputs = parse_asm_arguments(false);
- if (!next_if(':')) {
- rem_anchor_token(':');
- goto end_of_asm;
- }
rem_anchor_token(':');
+ if (next_if(':'))
+ asm_statement->clobbers = parse_asm_clobbers();
- asm_statement->clobbers = parse_asm_clobbers();
-
-end_of_asm:
rem_anchor_token(')');
expect(')');
expect(';');
return is_local_variable(entity);
}
-/**
- * Check if a given expression represents a local variable and
- * return its declaration then, else return NULL.
- */
-entity_t *expression_is_variable(const expression_t *expression)
-{
- if (expression->base.kind != EXPR_REFERENCE) {
- return NULL;
- }
- entity_t *entity = expression->reference.entity;
- if (entity->kind != ENTITY_VARIABLE)
- return NULL;
-
- return entity;
-}
-
static void err_or_warn(source_position_t const *const pos, char const *const msg)
{
if (c_mode & _CXX || strict_mode) {
add_anchor_token(T__Bool);
add_anchor_token(T__Complex);
add_anchor_token(T__Imaginary);
- add_anchor_token(T___FUNCTION__);
add_anchor_token(T___PRETTY_FUNCTION__);
add_anchor_token(T___alignof__);
add_anchor_token(T___attribute__);
rem_anchor_token(T___attribute__);
rem_anchor_token(T___alignof__);
rem_anchor_token(T___PRETTY_FUNCTION__);
- rem_anchor_token(T___FUNCTION__);
rem_anchor_token(T__Imaginary);
rem_anchor_token(T__Complex);
rem_anchor_token(T__Bool);
expect('(');
rem_anchor_token(T_STRING_LITERAL);
- statement->asms.asm_text = parse_string_literals();
+ statement->asms.asm_text = parse_string_literals("global asm");
statement->base.next = unit->global_asm;
unit->global_asm = statement;
eat(T_extern);
source_position_t const pos = *HERE;
- char const *const linkage = parse_string_literals().begin;
+ char const *const linkage = parse_string_literals(NULL).begin;
linkage_kind_t old_linkage = current_linkage;
linkage_kind_t new_linkage;