Renamed enum entry.
[cparser] / ast.c
diff --git a/ast.c b/ast.c
index 1e0ff3f..cb40c3f 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -67,13 +67,6 @@ void print_indent(void)
                print_char('\t');
 }
 
-static void print_stringrep(const string_t *string)
-{
-       for (size_t i = 0; i < string->size; ++i) {
-               print_char(string->begin[i]);
-       }
-}
-
 /**
  * Returns 1 if a given precedence level has right-to-left
  * associativity, else 0.
@@ -101,91 +94,86 @@ static int right_to_left(unsigned precedence)
 static unsigned get_expression_precedence(expression_kind_t kind)
 {
        static const unsigned prec[] = {
-               [EXPR_ERROR]                             = PREC_PRIMARY,
-               [EXPR_REFERENCE]                         = PREC_PRIMARY,
-               [EXPR_ENUM_CONSTANT]                     = 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_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];
@@ -199,13 +187,13 @@ 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_string(get_string_encoding_prefix(string->encoding));
+
        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) {
@@ -238,12 +226,9 @@ static void print_quoted_string(const string_t *const string, char border,
        print_char(border);
 }
 
-static void print_string_literal(const string_literal_expression_t *literal)
+static void print_string_literal(string_literal_expression_t const *const literal, char const delimiter)
 {
-       if (literal->base.kind == EXPR_WIDE_STRING_LITERAL) {
-               print_char('L');
-       }
-       print_quoted_string(&literal->value, '"', 1);
+       print_quoted_string(&literal->value, delimiter);
 }
 
 static void print_literal(const literal_expression_t *literal)
@@ -252,24 +237,13 @@ 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:
-               print_stringrep(&literal->value);
-               print_stringrep(&literal->suffix);
+       case EXPR_LITERAL_INTEGER:
+               print_string(literal->value.begin);
                return;
 
-       case EXPR_LITERAL_WIDE_CHARACTER:
-               print_char('L');
-               /* FALLTHROUGH */
-       case EXPR_LITERAL_CHARACTER:
-               print_quoted_string(&literal->value, '\'', 0);
-               return;
        default:
                break;
        }
@@ -473,11 +447,10 @@ static void print_array_expression(const array_access_expression_t *expression)
  */
 static void print_typeprop_expression(const typeprop_expression_t *expression)
 {
-       if (expression->base.kind == EXPR_SIZEOF) {
-               print_string("sizeof");
-       } else {
-               assert(expression->base.kind == EXPR_ALIGNOF);
-               print_string("__alignof__");
+       switch (expression->base.kind) {
+       case EXPR_SIZEOF:  print_string("sizeof");      break;
+       case EXPR_ALIGNOF: print_string("__alignof__"); break;
+       default:           panic("invalid typeprop kind");
        }
        if (expression->tp_expression != NULL) {
                /* PREC_TOP: always print the '()' here, sizeof x is right but unusual */
@@ -545,7 +518,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(')');
 }
 
@@ -657,6 +630,33 @@ 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_LITERAL_CHARACTER:
+               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.
  *
@@ -669,10 +669,7 @@ static void print_expression_prec(expression_t const *expr, unsigned const top_p
                expr = expr->unary.value;
        }
 
-       bool parenthesized =
-               expr->base.parenthesized                       ||
-               (print_parenthesis && top_prec != PREC_BOTTOM) ||
-               top_prec > get_expression_precedence(expr->base.kind);
+       bool const parenthesized = needs_parentheses(expr, top_prec);
 
        if (parenthesized)
                print_char('(');
@@ -691,13 +688,13 @@ static void print_expression_prec(expression_t const *expr, unsigned const top_p
        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_LITERAL_CHARACTER:          print_string_literal(          &expr->string_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:
-       case EXPR_WIDE_STRING_LITERAL:        print_string_literal(          &expr->string_literal);           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;
@@ -1026,7 +1023,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(')');
@@ -1045,7 +1042,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, '"');
        }
 }
 
@@ -1061,7 +1058,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)
@@ -1177,13 +1174,12 @@ void print_initializer(const initializer_t *initializer)
        }
 
        switch (initializer->kind) {
-       case INITIALIZER_VALUE: {
-               const initializer_value_t *value = &initializer->value;
-               print_assignment_expression(value->value);
+       case INITIALIZER_STRING:
+       case INITIALIZER_VALUE:
+               print_assignment_expression(initializer->value.value);
                return;
-       }
+
        case INITIALIZER_LIST: {
-               assert(initializer->kind == INITIALIZER_LIST);
                print_string("{ ");
                const initializer_list_t *list = &initializer->list;
 
@@ -1198,12 +1194,7 @@ void print_initializer(const initializer_t *initializer)
                print_string(" }");
                return;
        }
-       case INITIALIZER_STRING:
-               print_quoted_string(&initializer->string.string, '"', 1);
-               return;
-       case INITIALIZER_WIDE_STRING:
-               print_quoted_string(&initializer->string.string, '"', 1);
-               return;
+
        case INITIALIZER_DESIGNATOR:
                print_designator(initializer->designator.designator);
                print_string(" = ");
@@ -1492,7 +1483,6 @@ expression_classification_t is_constant_initializer(const initializer_t *initial
 {
        switch (initializer->kind) {
        case INITIALIZER_STRING:
-       case INITIALIZER_WIDE_STRING:
        case INITIALIZER_DESIGNATOR:
                return EXPR_CLASS_CONSTANT;
 
@@ -1578,7 +1568,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;
@@ -1773,6 +1762,7 @@ expression_classification_t is_constant_expression(const expression_t *expressio
 {
        switch (expression->kind) {
        case EXPR_LITERAL_CASES:
+       case EXPR_LITERAL_CHARACTER:
        case EXPR_CLASSIFY_TYPE:
        case EXPR_OFFSETOF:
        case EXPR_ALIGNOF:
@@ -1789,7 +1779,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: