Augment MATCH_NEWLINE() in the preprocessor so its usage looks like an ordinary case...
[cparser] / ast.c
diff --git a/ast.c b/ast.c
index c62110a..2daa235 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -101,90 +101,87 @@ static int right_to_left(unsigned precedence)
 static unsigned get_expression_precedence(expression_kind_t kind)
 {
        static const unsigned prec[] = {
-               [EXPR_REFERENCE]                         = PREC_PRIMARY,
-               [EXPR_REFERENCE_ENUM_VALUE]              = PREC_PRIMARY,
-               [EXPR_LITERAL_INTEGER]                   = PREC_PRIMARY,
-               [EXPR_LITERAL_INTEGER_OCTAL]             = PREC_PRIMARY,
-               [EXPR_LITERAL_INTEGER_HEXADECIMAL]       = PREC_PRIMARY,
-               [EXPR_LITERAL_FLOATINGPOINT]             = PREC_PRIMARY,
-               [EXPR_LITERAL_FLOATINGPOINT_HEXADECIMAL] = PREC_PRIMARY,
-               [EXPR_LITERAL_CHARACTER]                 = PREC_PRIMARY,
-               [EXPR_LITERAL_WIDE_CHARACTER]            = PREC_PRIMARY,
-               [EXPR_LITERAL_MS_NOOP]                   = PREC_PRIMARY,
-               [EXPR_STRING_LITERAL]                    = PREC_PRIMARY,
-               [EXPR_WIDE_STRING_LITERAL]               = PREC_PRIMARY,
-               [EXPR_COMPOUND_LITERAL]                  = PREC_UNARY,
-               [EXPR_CALL]                              = PREC_POSTFIX,
-               [EXPR_CONDITIONAL]                       = PREC_CONDITIONAL,
-               [EXPR_SELECT]                            = PREC_POSTFIX,
-               [EXPR_ARRAY_ACCESS]                      = PREC_POSTFIX,
-               [EXPR_SIZEOF]                            = PREC_UNARY,
-               [EXPR_CLASSIFY_TYPE]                     = PREC_UNARY,
-               [EXPR_ALIGNOF]                           = PREC_UNARY,
-
-               [EXPR_FUNCNAME]                          = PREC_PRIMARY,
-               [EXPR_BUILTIN_CONSTANT_P]                = PREC_PRIMARY,
-               [EXPR_BUILTIN_TYPES_COMPATIBLE_P]        = PREC_PRIMARY,
-               [EXPR_OFFSETOF]                          = PREC_PRIMARY,
-               [EXPR_VA_START]                          = PREC_PRIMARY,
-               [EXPR_VA_ARG]                            = PREC_PRIMARY,
-               [EXPR_VA_COPY]                           = PREC_PRIMARY,
-               [EXPR_STATEMENT]                         = PREC_PRIMARY,
-               [EXPR_LABEL_ADDRESS]                     = PREC_PRIMARY,
-
-               [EXPR_UNARY_NEGATE]                      = PREC_UNARY,
-               [EXPR_UNARY_PLUS]                        = PREC_UNARY,
-               [EXPR_UNARY_BITWISE_NEGATE]              = PREC_UNARY,
-               [EXPR_UNARY_NOT]                         = PREC_UNARY,
-               [EXPR_UNARY_DEREFERENCE]                 = PREC_UNARY,
-               [EXPR_UNARY_TAKE_ADDRESS]                = PREC_UNARY,
-               [EXPR_UNARY_POSTFIX_INCREMENT]           = PREC_POSTFIX,
-               [EXPR_UNARY_POSTFIX_DECREMENT]           = PREC_POSTFIX,
-               [EXPR_UNARY_PREFIX_INCREMENT]            = PREC_UNARY,
-               [EXPR_UNARY_PREFIX_DECREMENT]            = PREC_UNARY,
-               [EXPR_UNARY_CAST]                        = PREC_UNARY,
-               [EXPR_UNARY_ASSUME]                      = PREC_PRIMARY,
-               [EXPR_UNARY_DELETE]                      = PREC_UNARY,
-               [EXPR_UNARY_DELETE_ARRAY]                = PREC_UNARY,
-               [EXPR_UNARY_THROW]                       = PREC_ASSIGNMENT,
-
-               [EXPR_BINARY_ADD]                        = PREC_ADDITIVE,
-               [EXPR_BINARY_SUB]                        = PREC_ADDITIVE,
-               [EXPR_BINARY_MUL]                        = PREC_MULTIPLICATIVE,
-               [EXPR_BINARY_DIV]                        = PREC_MULTIPLICATIVE,
-               [EXPR_BINARY_MOD]                        = PREC_MULTIPLICATIVE,
-               [EXPR_BINARY_EQUAL]                      = PREC_EQUALITY,
-               [EXPR_BINARY_NOTEQUAL]                   = PREC_EQUALITY,
-               [EXPR_BINARY_LESS]                       = PREC_RELATIONAL,
-               [EXPR_BINARY_LESSEQUAL]                  = PREC_RELATIONAL,
-               [EXPR_BINARY_GREATER]                    = PREC_RELATIONAL,
-               [EXPR_BINARY_GREATEREQUAL]               = PREC_RELATIONAL,
-               [EXPR_BINARY_BITWISE_AND]                = PREC_AND,
-               [EXPR_BINARY_BITWISE_OR]                 = PREC_OR,
-               [EXPR_BINARY_BITWISE_XOR]                = PREC_XOR,
-               [EXPR_BINARY_LOGICAL_AND]                = PREC_LOGICAL_AND,
-               [EXPR_BINARY_LOGICAL_OR]                 = PREC_LOGICAL_OR,
-               [EXPR_BINARY_SHIFTLEFT]                  = PREC_SHIFT,
-               [EXPR_BINARY_SHIFTRIGHT]                 = PREC_SHIFT,
-               [EXPR_BINARY_ASSIGN]                     = PREC_ASSIGNMENT,
-               [EXPR_BINARY_MUL_ASSIGN]                 = PREC_ASSIGNMENT,
-               [EXPR_BINARY_DIV_ASSIGN]                 = PREC_ASSIGNMENT,
-               [EXPR_BINARY_MOD_ASSIGN]                 = PREC_ASSIGNMENT,
-               [EXPR_BINARY_ADD_ASSIGN]                 = PREC_ASSIGNMENT,
-               [EXPR_BINARY_SUB_ASSIGN]                 = PREC_ASSIGNMENT,
-               [EXPR_BINARY_SHIFTLEFT_ASSIGN]           = PREC_ASSIGNMENT,
-               [EXPR_BINARY_SHIFTRIGHT_ASSIGN]          = PREC_ASSIGNMENT,
-               [EXPR_BINARY_BITWISE_AND_ASSIGN]         = PREC_ASSIGNMENT,
-               [EXPR_BINARY_BITWISE_XOR_ASSIGN]         = PREC_ASSIGNMENT,
-               [EXPR_BINARY_BITWISE_OR_ASSIGN]          = PREC_ASSIGNMENT,
-               [EXPR_BINARY_COMMA]                      = PREC_EXPRESSION,
-
-               [EXPR_BINARY_ISGREATER]                  = PREC_PRIMARY,
-               [EXPR_BINARY_ISGREATEREQUAL]             = PREC_PRIMARY,
-               [EXPR_BINARY_ISLESS]                     = PREC_PRIMARY,
-               [EXPR_BINARY_ISLESSEQUAL]                = PREC_PRIMARY,
-               [EXPR_BINARY_ISLESSGREATER]              = PREC_PRIMARY,
-               [EXPR_BINARY_ISUNORDERED]                = PREC_PRIMARY
+               [EXPR_ERROR]                      = PREC_PRIMARY,
+               [EXPR_REFERENCE]                  = PREC_PRIMARY,
+               [EXPR_ENUM_CONSTANT]              = PREC_PRIMARY,
+               [EXPR_LITERAL_INTEGER]            = PREC_PRIMARY,
+               [EXPR_LITERAL_FLOATINGPOINT]      = PREC_PRIMARY,
+               [EXPR_LITERAL_CHARACTER]          = PREC_PRIMARY,
+               [EXPR_LITERAL_WIDE_CHARACTER]     = PREC_PRIMARY,
+               [EXPR_LITERAL_MS_NOOP]            = PREC_PRIMARY,
+               [EXPR_STRING_LITERAL]             = PREC_PRIMARY,
+               [EXPR_COMPOUND_LITERAL]           = PREC_UNARY,
+               [EXPR_CALL]                       = PREC_POSTFIX,
+               [EXPR_CONDITIONAL]                = PREC_CONDITIONAL,
+               [EXPR_SELECT]                     = PREC_POSTFIX,
+               [EXPR_ARRAY_ACCESS]               = PREC_POSTFIX,
+               [EXPR_SIZEOF]                     = PREC_UNARY,
+               [EXPR_CLASSIFY_TYPE]              = PREC_UNARY,
+               [EXPR_ALIGNOF]                    = PREC_UNARY,
+
+               [EXPR_FUNCNAME]                   = PREC_PRIMARY,
+               [EXPR_BUILTIN_CONSTANT_P]         = PREC_PRIMARY,
+               [EXPR_BUILTIN_TYPES_COMPATIBLE_P] = PREC_PRIMARY,
+               [EXPR_OFFSETOF]                   = PREC_PRIMARY,
+               [EXPR_VA_START]                   = PREC_PRIMARY,
+               [EXPR_VA_ARG]                     = PREC_PRIMARY,
+               [EXPR_VA_COPY]                    = PREC_PRIMARY,
+               [EXPR_STATEMENT]                  = PREC_PRIMARY,
+               [EXPR_LABEL_ADDRESS]              = PREC_PRIMARY,
+
+               [EXPR_UNARY_NEGATE]               = PREC_UNARY,
+               [EXPR_UNARY_PLUS]                 = PREC_UNARY,
+               [EXPR_UNARY_BITWISE_NEGATE]       = PREC_UNARY,
+               [EXPR_UNARY_NOT]                  = PREC_UNARY,
+               [EXPR_UNARY_DEREFERENCE]          = PREC_UNARY,
+               [EXPR_UNARY_TAKE_ADDRESS]         = PREC_UNARY,
+               [EXPR_UNARY_POSTFIX_INCREMENT]    = PREC_POSTFIX,
+               [EXPR_UNARY_POSTFIX_DECREMENT]    = PREC_POSTFIX,
+               [EXPR_UNARY_PREFIX_INCREMENT]     = PREC_UNARY,
+               [EXPR_UNARY_PREFIX_DECREMENT]     = PREC_UNARY,
+               [EXPR_UNARY_CAST]                 = PREC_UNARY,
+               [EXPR_UNARY_ASSUME]               = PREC_PRIMARY,
+               [EXPR_UNARY_DELETE]               = PREC_UNARY,
+               [EXPR_UNARY_DELETE_ARRAY]         = PREC_UNARY,
+               [EXPR_UNARY_THROW]                = PREC_ASSIGNMENT,
+
+               [EXPR_BINARY_ADD]                 = PREC_ADDITIVE,
+               [EXPR_BINARY_SUB]                 = PREC_ADDITIVE,
+               [EXPR_BINARY_MUL]                 = PREC_MULTIPLICATIVE,
+               [EXPR_BINARY_DIV]                 = PREC_MULTIPLICATIVE,
+               [EXPR_BINARY_MOD]                 = PREC_MULTIPLICATIVE,
+               [EXPR_BINARY_EQUAL]               = PREC_EQUALITY,
+               [EXPR_BINARY_NOTEQUAL]            = PREC_EQUALITY,
+               [EXPR_BINARY_LESS]                = PREC_RELATIONAL,
+               [EXPR_BINARY_LESSEQUAL]           = PREC_RELATIONAL,
+               [EXPR_BINARY_GREATER]             = PREC_RELATIONAL,
+               [EXPR_BINARY_GREATEREQUAL]        = PREC_RELATIONAL,
+               [EXPR_BINARY_BITWISE_AND]         = PREC_AND,
+               [EXPR_BINARY_BITWISE_OR]          = PREC_OR,
+               [EXPR_BINARY_BITWISE_XOR]         = PREC_XOR,
+               [EXPR_BINARY_LOGICAL_AND]         = PREC_LOGICAL_AND,
+               [EXPR_BINARY_LOGICAL_OR]          = PREC_LOGICAL_OR,
+               [EXPR_BINARY_SHIFTLEFT]           = PREC_SHIFT,
+               [EXPR_BINARY_SHIFTRIGHT]          = PREC_SHIFT,
+               [EXPR_BINARY_ASSIGN]              = PREC_ASSIGNMENT,
+               [EXPR_BINARY_MUL_ASSIGN]          = PREC_ASSIGNMENT,
+               [EXPR_BINARY_DIV_ASSIGN]          = PREC_ASSIGNMENT,
+               [EXPR_BINARY_MOD_ASSIGN]          = PREC_ASSIGNMENT,
+               [EXPR_BINARY_ADD_ASSIGN]          = PREC_ASSIGNMENT,
+               [EXPR_BINARY_SUB_ASSIGN]          = PREC_ASSIGNMENT,
+               [EXPR_BINARY_SHIFTLEFT_ASSIGN]    = PREC_ASSIGNMENT,
+               [EXPR_BINARY_SHIFTRIGHT_ASSIGN]   = PREC_ASSIGNMENT,
+               [EXPR_BINARY_BITWISE_AND_ASSIGN]  = PREC_ASSIGNMENT,
+               [EXPR_BINARY_BITWISE_XOR_ASSIGN]  = PREC_ASSIGNMENT,
+               [EXPR_BINARY_BITWISE_OR_ASSIGN]   = PREC_ASSIGNMENT,
+               [EXPR_BINARY_COMMA]               = PREC_EXPRESSION,
+
+               [EXPR_BINARY_ISGREATER]           = PREC_PRIMARY,
+               [EXPR_BINARY_ISGREATEREQUAL]      = PREC_PRIMARY,
+               [EXPR_BINARY_ISLESS]              = PREC_PRIMARY,
+               [EXPR_BINARY_ISLESSEQUAL]         = PREC_PRIMARY,
+               [EXPR_BINARY_ISLESSGREATER]       = PREC_PRIMARY,
+               [EXPR_BINARY_ISUNORDERED]         = PREC_PRIMARY
        };
        assert((size_t)kind < lengthof(prec));
        unsigned res = prec[kind];
@@ -198,13 +195,11 @@ static unsigned get_expression_precedence(expression_kind_t kind)
  *
  * @param string  the string constant
  * @param border  the border char
- * @param skip    number of chars to skip at the end
  */
-static void print_quoted_string(const string_t *const string, char border,
-                                int skip)
+static void print_quoted_string(const string_t *const string, char border)
 {
        print_char(border);
-       const char *end = string->begin + string->size - skip;
+       const char *end = string->begin + string->size;
        for (const char *c = string->begin; c != end; ++c) {
                const char tc = *c;
                if (tc == border) {
@@ -239,10 +234,8 @@ static void print_quoted_string(const string_t *const string, char border,
 
 static void print_string_literal(const string_literal_expression_t *literal)
 {
-       if (literal->base.kind == EXPR_WIDE_STRING_LITERAL) {
-               print_char('L');
-       }
-       print_quoted_string(&literal->value, '"', 1);
+       print_string(get_string_encoding_prefix(literal->encoding));
+       print_quoted_string(&literal->value, '"');
 }
 
 static void print_literal(const literal_expression_t *literal)
@@ -251,23 +244,19 @@ static void print_literal(const literal_expression_t *literal)
        case EXPR_LITERAL_MS_NOOP:
                print_string("__noop");
                return;
-       case EXPR_LITERAL_INTEGER_HEXADECIMAL:
-       case EXPR_LITERAL_FLOATINGPOINT_HEXADECIMAL:
-               print_string("0x");
-               /* FALLTHROUGH */
+
        case EXPR_LITERAL_BOOLEAN:
-       case EXPR_LITERAL_INTEGER:
-       case EXPR_LITERAL_INTEGER_OCTAL:
        case EXPR_LITERAL_FLOATINGPOINT:
+       case EXPR_LITERAL_INTEGER:
                print_stringrep(&literal->value);
-               if (literal->suffix.size > 0)
-                       print_stringrep(&literal->suffix);
+               print_stringrep(&literal->suffix);
                return;
+
        case EXPR_LITERAL_WIDE_CHARACTER:
                print_char('L');
                /* FALLTHROUGH */
        case EXPR_LITERAL_CHARACTER:
-               print_quoted_string(&literal->value, '\'', 0);
+               print_quoted_string(&literal->value, '\'');
                return;
        default:
                break;
@@ -313,17 +302,11 @@ static void print_call_expression(const call_expression_t *call)
 {
        print_expression_prec(call->function, PREC_POSTFIX);
        print_char('(');
-       call_argument_t *argument = call->arguments;
-       int              first    = 1;
-       while (argument != NULL) {
-               if (!first) {
-                       print_string(", ");
-               } else {
-                       first = 0;
-               }
-               print_assignment_expression(argument->expression);
-
-               argument = argument->next;
+       char const *sep = "";
+       for (call_argument_t const *arg = call->arguments; arg; arg = arg->next) {
+               print_string(sep);
+               sep = ", ";
+               print_assignment_expression(arg->expression);
        }
        print_char(')');
 }
@@ -550,7 +533,7 @@ static void print_va_start(const va_start_expression_t *const expression)
        print_string("__builtin_va_start(");
        print_assignment_expression(expression->ap);
        print_string(", ");
-       print_string(expression->parameter->base.base.symbol->string);
+       print_assignment_expression(expression->parameter);
        print_char(')');
 }
 
@@ -662,96 +645,73 @@ static void print_statement_expression(const statement_expression_t *expression)
        print_char(')');
 }
 
+static bool needs_parentheses(expression_t const *const expr, unsigned const top_prec)
+{
+       if (expr->base.parenthesized)
+               return true;
+
+       if (top_prec > get_expression_precedence(expr->base.kind))
+               return true;
+
+       if (print_parenthesis && top_prec != PREC_BOTTOM) {
+               switch (expr->kind) {
+               case EXPR_ENUM_CONSTANT:
+               case EXPR_FUNCNAME:
+               case EXPR_LITERAL_CASES:
+               case EXPR_REFERENCE:
+               case EXPR_STRING_LITERAL:
+                       /* Do not print () around subexpressions consisting of a single token. */
+                       return false;
+
+               default:
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 /**
  * Prints an expression with parenthesis if needed.
  *
  * @param expression  the expression to print
  * @param top_prec    the precedence of the user of this expression.
  */
-static void print_expression_prec(const expression_t *expression, unsigned top_prec)
+static void print_expression_prec(expression_t const *expr, unsigned const top_prec)
 {
-       if (expression->kind == EXPR_UNARY_CAST
-           && expression->base.implicit && !print_implicit_casts) {
-               expression = expression->unary.value;
+       if (expr->kind == EXPR_UNARY_CAST && expr->base.implicit && !print_implicit_casts) {
+               expr = expr->unary.value;
        }
 
-       bool parenthesized =
-               expression->base.parenthesized                 ||
-               (print_parenthesis && top_prec != PREC_BOTTOM) ||
-               top_prec > get_expression_precedence(expression->base.kind);
+       bool const parenthesized = needs_parentheses(expr, top_prec);
 
        if (parenthesized)
                print_char('(');
-       switch (expression->kind) {
-       case EXPR_ERROR:
-               print_string("$error$");
-               break;
-       case EXPR_WIDE_STRING_LITERAL:
-       case EXPR_STRING_LITERAL:
-               print_string_literal(&expression->string_literal);
-               break;
-       EXPR_LITERAL_CASES
-               print_literal(&expression->literal);
-               break;
-       case EXPR_FUNCNAME:
-               print_funcname(&expression->funcname);
-               break;
-       case EXPR_COMPOUND_LITERAL:
-               print_compound_literal(&expression->compound_literal);
-               break;
-       case EXPR_CALL:
-               print_call_expression(&expression->call);
-               break;
-       EXPR_BINARY_CASES
-               print_binary_expression(&expression->binary);
-               break;
-       case EXPR_REFERENCE:
-       case EXPR_REFERENCE_ENUM_VALUE:
-               print_reference_expression(&expression->reference);
-               break;
-       case EXPR_ARRAY_ACCESS:
-               print_array_expression(&expression->array_access);
-               break;
-       case EXPR_LABEL_ADDRESS:
-               print_label_address_expression(&expression->label_address);
-               break;
-       EXPR_UNARY_CASES
-               print_unary_expression(&expression->unary);
-               break;
-       case EXPR_SIZEOF:
+       switch (expr->kind) {
        case EXPR_ALIGNOF:
-               print_typeprop_expression(&expression->typeprop);
-               break;
-       case EXPR_BUILTIN_CONSTANT_P:
-               print_builtin_constant(&expression->builtin_constant);
-               break;
-       case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
-               print_builtin_types_compatible(&expression->builtin_types_compatible);
-               break;
-       case EXPR_CONDITIONAL:
-               print_conditional(&expression->conditional);
-               break;
-       case EXPR_VA_START:
-               print_va_start(&expression->va_starte);
-               break;
-       case EXPR_VA_ARG:
-               print_va_arg(&expression->va_arge);
-               break;
-       case EXPR_VA_COPY:
-               print_va_copy(&expression->va_copye);
-               break;
-       case EXPR_SELECT:
-               print_select(&expression->select);
-               break;
-       case EXPR_CLASSIFY_TYPE:
-               print_classify_type_expression(&expression->classify_type);
-               break;
-       case EXPR_OFFSETOF:
-               print_offsetof_expression(&expression->offsetofe);
-               break;
-       case EXPR_STATEMENT:
-               print_statement_expression(&expression->statement);
-               break;
+       case EXPR_SIZEOF:                     print_typeprop_expression(     &expr->typeprop);                 break;
+       case EXPR_ARRAY_ACCESS:               print_array_expression(        &expr->array_access);             break;
+       case EXPR_BINARY_CASES:               print_binary_expression(       &expr->binary);                   break;
+       case EXPR_BUILTIN_CONSTANT_P:         print_builtin_constant(        &expr->builtin_constant);         break;
+       case EXPR_BUILTIN_TYPES_COMPATIBLE_P: print_builtin_types_compatible(&expr->builtin_types_compatible); break;
+       case EXPR_CALL:                       print_call_expression(         &expr->call);                     break;
+       case EXPR_CLASSIFY_TYPE:              print_classify_type_expression(&expr->classify_type);            break;
+       case EXPR_COMPOUND_LITERAL:           print_compound_literal(        &expr->compound_literal);         break;
+       case EXPR_CONDITIONAL:                print_conditional(             &expr->conditional);              break;
+       case EXPR_ERROR:                      print_string("$error$");                                         break;
+       case EXPR_FUNCNAME:                   print_funcname(                &expr->funcname);                 break;
+       case EXPR_LABEL_ADDRESS:              print_label_address_expression(&expr->label_address);            break;
+       case EXPR_LITERAL_CASES:              print_literal(                 &expr->literal);                  break;
+       case EXPR_OFFSETOF:                   print_offsetof_expression(     &expr->offsetofe);                break;
+       case EXPR_REFERENCE:
+       case EXPR_ENUM_CONSTANT:              print_reference_expression(    &expr->reference);                break;
+       case EXPR_SELECT:                     print_select(                  &expr->select);                   break;
+       case EXPR_STATEMENT:                  print_statement_expression(    &expr->statement);                break;
+       case EXPR_STRING_LITERAL:             print_string_literal(          &expr->string_literal);           break;
+       case EXPR_UNARY_CASES:                print_unary_expression(        &expr->unary);                    break;
+       case EXPR_VA_ARG:                     print_va_arg(                  &expr->va_arge);                  break;
+       case EXPR_VA_COPY:                    print_va_copy(                 &expr->va_copye);                 break;
+       case EXPR_VA_START:                   print_va_start(                &expr->va_starte);                break;
        }
        if (parenthesized)
                print_char(')');
@@ -785,13 +745,11 @@ static void print_compound_statement(const compound_statement_t *block)
        print_string("{\n");
        ++indent;
 
-       statement_t *statement = block->statements;
-       while (statement != NULL) {
-               print_indented_statement(statement);
+       for (statement_t const *stmt = block->statements; stmt; stmt = stmt->base.next) {
+               print_indented_statement(stmt);
                print_char('\n');
-
-               statement = statement->base.next;
        }
+
        --indent;
        print_indent();
        print_char('}');
@@ -825,6 +783,18 @@ static void print_expression_statement(const expression_statement_t *statement)
        print_char(';');
 }
 
+/**
+ * Print a computed goto statement.
+ *
+ * @param statement  the computed goto statement
+ */
+static void print_computed_goto_statement(computed_goto_statement_t const *const stmt)
+{
+       print_string("goto *");
+       print_expression(stmt->expression);
+       print_char(';');
+}
+
 /**
  * Print a goto statement.
  *
@@ -833,12 +803,7 @@ static void print_expression_statement(const expression_statement_t *statement)
 static void print_goto_statement(const goto_statement_t *statement)
 {
        print_string("goto ");
-       if (statement->expression != NULL) {
-               print_char('*');
-               print_expression(statement->expression);
-       } else {
-               print_string(statement->label->base.symbol->string);
-       }
+       print_string(statement->label->base.symbol->string);
        print_char(';');
 }
 
@@ -1071,7 +1036,7 @@ static void print_asm_arguments(asm_argument_t *arguments)
                if (argument->symbol) {
                        print_format("[%s] ", argument->symbol->string);
                }
-               print_quoted_string(&argument->constraints, '"', 1);
+               print_quoted_string(&argument->constraints, '"');
                print_string(" (");
                print_expression(argument->expression);
                print_char(')');
@@ -1090,7 +1055,7 @@ static void print_asm_clobbers(asm_clobber_t *clobbers)
                if (clobber != clobbers)
                        print_string(", ");
 
-               print_quoted_string(&clobber->clobber, '"', 1);
+               print_quoted_string(&clobber->clobber, '"');
        }
 }
 
@@ -1106,7 +1071,7 @@ static void print_asm_statement(const asm_statement_t *statement)
                print_string("volatile ");
        }
        print_char('(');
-       print_quoted_string(&statement->asm_text, '"', 1);
+       print_quoted_string(&statement->asm_text, '"');
        if (statement->outputs  == NULL &&
            statement->inputs   == NULL &&
            statement->clobbers == NULL)
@@ -1165,66 +1130,29 @@ static void print_leave_statement(const leave_statement_t *statement)
  *
  * @param statement   the statement
  */
-void print_statement(const statement_t *statement)
+void print_statement(statement_t const *const stmt)
 {
-       switch (statement->kind) {
-       case STATEMENT_EMPTY:
-               print_char(';');
-               break;
-       case STATEMENT_COMPOUND:
-               print_compound_statement(&statement->compound);
-               break;
-       case STATEMENT_RETURN:
-               print_return_statement(&statement->returns);
-               break;
-       case STATEMENT_EXPRESSION:
-               print_expression_statement(&statement->expression);
-               break;
-       case STATEMENT_LABEL:
-               print_label_statement(&statement->label);
-               break;
-       case STATEMENT_GOTO:
-               print_goto_statement(&statement->gotos);
-               break;
-       case STATEMENT_CONTINUE:
-               print_string("continue;");
-               break;
-       case STATEMENT_BREAK:
-               print_string("break;");
-               break;
-       case STATEMENT_IF:
-               print_if_statement(&statement->ifs);
-               break;
-       case STATEMENT_SWITCH:
-               print_switch_statement(&statement->switchs);
-               break;
-       case STATEMENT_CASE_LABEL:
-               print_case_label(&statement->case_label);
-               break;
-       case STATEMENT_DECLARATION:
-               print_declaration_statement(&statement->declaration);
-               break;
-       case STATEMENT_WHILE:
-               print_while_statement(&statement->whiles);
-               break;
-       case STATEMENT_DO_WHILE:
-               print_do_while_statement(&statement->do_while);
-               break;
-       case STATEMENT_FOR:
-               print_for_statement(&statement->fors);
-               break;
-       case STATEMENT_ASM:
-               print_asm_statement(&statement->asms);
-               break;
-       case STATEMENT_MS_TRY:
-               print_ms_try_statement(&statement->ms_try);
-               break;
-       case STATEMENT_LEAVE:
-               print_leave_statement(&statement->leave);
-               break;
-       case STATEMENT_ERROR:
-               print_string("$error statement$");
-               break;
+       switch (stmt->kind) {
+       case STATEMENT_ASM:           print_asm_statement(          &stmt->asms);          break;
+       case STATEMENT_BREAK:         print_string("break;");                              break;
+       case STATEMENT_CASE_LABEL:    print_case_label(             &stmt->case_label);    break;
+       case STATEMENT_COMPOUND:      print_compound_statement(     &stmt->compound);      break;
+       case STATEMENT_COMPUTED_GOTO: print_computed_goto_statement(&stmt->computed_goto); break;
+       case STATEMENT_CONTINUE:      print_string("continue;");                           break;
+       case STATEMENT_DECLARATION:   print_declaration_statement(  &stmt->declaration);   break;
+       case STATEMENT_DO_WHILE:      print_do_while_statement(     &stmt->do_while);      break;
+       case STATEMENT_EMPTY:         print_char(';');                                     break;
+       case STATEMENT_ERROR:         print_string("$error statement$");                   break;
+       case STATEMENT_EXPRESSION:    print_expression_statement(   &stmt->expression);    break;
+       case STATEMENT_FOR:           print_for_statement(          &stmt->fors);          break;
+       case STATEMENT_GOTO:          print_goto_statement(         &stmt->gotos);         break;
+       case STATEMENT_IF:            print_if_statement(           &stmt->ifs);           break;
+       case STATEMENT_LABEL:         print_label_statement(        &stmt->label);         break;
+       case STATEMENT_LEAVE:         print_leave_statement(        &stmt->leave);         break;
+       case STATEMENT_MS_TRY:        print_ms_try_statement(       &stmt->ms_try);        break;
+       case STATEMENT_RETURN:        print_return_statement(       &stmt->returns);       break;
+       case STATEMENT_SWITCH:        print_switch_statement(       &stmt->switchs);       break;
+       case STATEMENT_WHILE:         print_while_statement(        &stmt->whiles);        break;
        }
 }
 
@@ -1281,10 +1209,10 @@ void print_initializer(const initializer_t *initializer)
                return;
        }
        case INITIALIZER_STRING:
-               print_quoted_string(&initializer->string.string, '"', 1);
+               print_quoted_string(&initializer->string.string, '"');
                return;
        case INITIALIZER_WIDE_STRING:
-               print_quoted_string(&initializer->string.string, '"', 1);
+               print_quoted_string(&initializer->string.string, '"');
                return;
        case INITIALIZER_DESIGNATOR:
                print_designator(initializer->designator.designator);
@@ -1660,7 +1588,6 @@ expression_classification_t is_linker_constant(const expression_t *expression)
 {
        switch (expression->kind) {
        case EXPR_STRING_LITERAL:
-       case EXPR_WIDE_STRING_LITERAL:
        case EXPR_FUNCNAME:
        case EXPR_LABEL_ADDRESS:
                return EXPR_CLASS_CONSTANT;
@@ -1854,13 +1781,13 @@ static expression_classification_t is_object_with_constant_address(const express
 expression_classification_t is_constant_expression(const expression_t *expression)
 {
        switch (expression->kind) {
-       EXPR_LITERAL_CASES
+       case EXPR_LITERAL_CASES:
        case EXPR_CLASSIFY_TYPE:
        case EXPR_OFFSETOF:
        case EXPR_ALIGNOF:
        case EXPR_BUILTIN_CONSTANT_P:
        case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
-       case EXPR_REFERENCE_ENUM_VALUE:
+       case EXPR_ENUM_CONSTANT:
                return EXPR_CLASS_CONSTANT;
 
        case EXPR_SIZEOF: {
@@ -1871,7 +1798,6 @@ expression_classification_t is_constant_expression(const expression_t *expressio
        }
 
        case EXPR_STRING_LITERAL:
-       case EXPR_WIDE_STRING_LITERAL:
        case EXPR_FUNCNAME:
        case EXPR_LABEL_ADDRESS:
        case EXPR_SELECT: