Make diagnosticvf() slightly more efficient by using fwrite() instead of printing...
[cparser] / parser.c
index 5d7f6ac..9dadbf6 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -254,7 +254,6 @@ static void semantic_comparison(binary_expression_t *expression);
        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:   \
@@ -326,8 +325,7 @@ static size_t get_expression_struct_size(expression_kind_t kind)
                [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),
@@ -1076,8 +1074,11 @@ static string_t concat_string_literals(string_encoding_t *const out_enc)
        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);
@@ -1487,6 +1488,7 @@ unary:
                        return;
 
                case EXPR_LITERAL_CASES:
+               case EXPR_LITERAL_CHARACTER:
                case EXPR_ERROR:
                case EXPR_STRING_LITERAL:
                case EXPR_COMPOUND_LITERAL: // TODO init?
@@ -4648,6 +4650,7 @@ static bool expression_returns(expression_t const *const expr)
                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:
@@ -5852,15 +5855,14 @@ static expression_t *parse_number_literal(void)
  */
 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 {
@@ -5869,20 +5871,14 @@ static expression_t *parse_character_constant(void)
                        }
                }
                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;
@@ -6671,7 +6667,6 @@ static expression_t *parse_primary_expression(void)
        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);
@@ -8306,7 +8301,6 @@ static bool expression_has_effect(const expression_t *const expr)
                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;
@@ -8636,7 +8630,7 @@ static asm_argument_t *parse_asm_arguments(bool is_out)
                                return NULL;
                }
 
-               argument->constraints = parse_string_literals();
+               argument->constraints = parse_string_literals("asm argument");
                add_anchor_token(')');
                expect('(');
                expression_t *expression = parse_expression();
@@ -8723,7 +8717,7 @@ static asm_clobber_t *parse_asm_clobbers(void)
 
        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;
@@ -8744,40 +8738,27 @@ static statement_t *parse_asm_statement(void)
        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(';');
@@ -9424,22 +9405,6 @@ static bool expression_is_local_variable(const expression_t *expression)
        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) {
@@ -9809,7 +9774,6 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        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__);
@@ -9977,7 +9941,6 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        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);
@@ -10054,7 +10017,7 @@ static void parse_global_asm(void)
        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;
 
@@ -10069,7 +10032,7 @@ static void parse_linkage_specification(void)
        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;