Adapt cpu_arch after processing a target tripel.
[cparser] / ast.c
diff --git a/ast.c b/ast.c
index 0686d04..6224cad 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -66,11 +66,6 @@ void print_indent(void)
                print_string("\t");
 }
 
-static void print_symbol(const symbol_t *symbol)
-{
-       print_string(symbol->string);
-}
-
 static void print_stringrep(const string_t *string)
 {
        for (size_t i = 0; i < string->size; ++i) {
@@ -105,8 +100,6 @@ static int right_to_left(unsigned precedence)
 static unsigned get_expression_precedence(expression_kind_t kind)
 {
        static const unsigned prec[] = {
-               [EXPR_UNKNOWN]                           = PREC_PRIMARY,
-               [EXPR_INVALID]                           = PREC_PRIMARY,
                [EXPR_REFERENCE]                         = PREC_PRIMARY,
                [EXPR_REFERENCE_ENUM_VALUE]              = PREC_PRIMARY,
                [EXPR_LITERAL_INTEGER]                   = PREC_PRIMARY,
@@ -149,7 +142,6 @@ static unsigned get_expression_precedence(expression_kind_t kind)
                [EXPR_UNARY_PREFIX_INCREMENT]            = PREC_UNARY,
                [EXPR_UNARY_PREFIX_DECREMENT]            = PREC_UNARY,
                [EXPR_UNARY_CAST]                        = PREC_UNARY,
-               [EXPR_UNARY_CAST_IMPLICIT]               = PREC_UNARY,
                [EXPR_UNARY_ASSUME]                      = PREC_PRIMARY,
                [EXPR_UNARY_DELETE]                      = PREC_UNARY,
                [EXPR_UNARY_DELETE_ARRAY]                = PREC_UNARY,
@@ -267,8 +259,8 @@ static void print_literal(const literal_expression_t *literal)
        case EXPR_LITERAL_INTEGER_OCTAL:
        case EXPR_LITERAL_FLOATINGPOINT:
                print_stringrep(&literal->value);
-               if (literal->suffix != NULL)
-                       print_symbol(literal->suffix);
+               if (literal->suffix.size > 0)
+                       print_stringrep(&literal->suffix);
                return;
        case EXPR_LITERAL_WIDE_CHARACTER:
                print_char('L');
@@ -413,7 +405,6 @@ static void print_unary_expression(const unary_expression_t *unexpr)
                print_expression_prec(unexpr->value, prec);
                print_string("--");
                return;
-       case EXPR_UNARY_CAST_IMPLICIT:
        case EXPR_UNARY_CAST:
                print_string("(");
                print_type(unexpr->base.type);
@@ -598,6 +589,12 @@ static void print_va_copy(const va_copy_expression_t *expression)
 static void print_select(const select_expression_t *expression)
 {
        print_expression_prec(expression->compound, PREC_POSTFIX);
+       /* do not print anything for anonymous struct/union selects
+        * FIXME: if the anonymous select was a '->' this will print '.'
+        */
+       if (expression->compound_entry->base.symbol == NULL)
+               return;
+
        if (is_type_pointer(skip_typeref(expression->compound->base.type))) {
                print_string("->");
        } else {
@@ -672,7 +669,8 @@ static void print_statement_expression(const statement_expression_t *expression)
  */
 static void print_expression_prec(const expression_t *expression, unsigned top_prec)
 {
-       if (expression->kind == EXPR_UNARY_CAST_IMPLICIT && !print_implicit_casts) {
+       if (expression->kind == EXPR_UNARY_CAST
+           && expression->base.implicit && !print_implicit_casts) {
                expression = expression->unary.value;
        }
 
@@ -684,9 +682,8 @@ static void print_expression_prec(const expression_t *expression, unsigned top_p
        if (parenthesized)
                print_string("(");
        switch (expression->kind) {
-       case EXPR_UNKNOWN:
-       case EXPR_INVALID:
-               print_string("$invalid expression$");
+       case EXPR_ERROR:
+               print_string("$error$");
                break;
        case EXPR_WIDE_STRING_LITERAL:
        case EXPR_STRING_LITERAL:
@@ -754,13 +751,6 @@ static void print_expression_prec(const expression_t *expression, unsigned top_p
        case EXPR_STATEMENT:
                print_statement_expression(&expression->statement);
                break;
-
-#if 0
-       default:
-               /* TODO */
-               print_format("some expression of type %d", (int)expression->kind);
-               break;
-#endif
        }
        if (parenthesized)
                print_string(")");
@@ -1190,8 +1180,8 @@ void print_statement(const statement_t *statement)
        case STATEMENT_LEAVE:
                print_leave_statement(&statement->leave);
                break;
-       case STATEMENT_INVALID:
-               print_string("$invalid statement$\n");
+       case STATEMENT_ERROR:
+               print_string("$error statement$\n");
                break;
        }
 }
@@ -1430,6 +1420,13 @@ void print_declaration(const entity_t *entity)
                        }
                        break;
 
+               case ENTITY_COMPOUND_MEMBER:
+                       print_type_ext(declaration->type, declaration->base.symbol, NULL);
+                       if (entity->compound_member.bitfield) {
+                               print_format(" : %u", entity->compound_member.bit_size);
+                       }
+                       break;
+
                default:
                        print_type_ext(declaration->type, declaration->base.symbol, NULL);
                        break;
@@ -1504,8 +1501,6 @@ print_compound:
        case ENTITY_LABEL:
        case ENTITY_ENUM_VALUE:
                panic("print_entity used on unexpected entity type");
-       case ENTITY_INVALID:
-               break;
        }
        panic("Invalid entity type encountered");
 }
@@ -1559,24 +1554,32 @@ expression_classification_t is_constant_initializer(const initializer_t *initial
        panic("invalid initializer kind found");
 }
 
-static expression_classification_t is_object_with_linker_constant_address(const expression_t *expression)
+/**
+ * Checks if an expression references an object with a constant/known location
+ * to the linker. Example:
+ *  - "x", "*&x" with x being a global variable. The value of x need not be
+ *         constant but the address of x is.
+ *  - "a.b.c" when a has a constant/known location to the linker
+ */
+static expression_classification_t is_object_with_linker_constant_address(
+       const expression_t *expression)
 {
        switch (expression->kind) {
        case EXPR_UNARY_DEREFERENCE:
-               return is_address_constant(expression->unary.value);
+               return is_linker_constant(expression->unary.value);
 
        case EXPR_SELECT: {
                type_t *base_type = skip_typeref(expression->select.compound->base.type);
                if (is_type_pointer(base_type)) {
                        /* it's a -> */
-                       return is_address_constant(expression->select.compound);
+                       return is_linker_constant(expression->select.compound);
                } else {
                        return is_object_with_linker_constant_address(expression->select.compound);
                }
        }
 
        case EXPR_ARRAY_ACCESS: {
-               expression_classification_t const ref = is_address_constant(expression->array_access.array_ref);
+               expression_classification_t const ref = is_linker_constant(expression->array_access.array_ref);
                expression_classification_t const idx = is_constant_expression(expression->array_access.index);
                return ref < idx ? ref : idx;
        }
@@ -1603,7 +1606,7 @@ static expression_classification_t is_object_with_linker_constant_address(const
                return EXPR_CLASS_VARIABLE;
        }
 
-       case EXPR_INVALID:
+       case EXPR_ERROR:
                return EXPR_CLASS_ERROR;
 
        default:
@@ -1611,7 +1614,7 @@ static expression_classification_t is_object_with_linker_constant_address(const
        }
 }
 
-expression_classification_t is_address_constant(const expression_t *expression)
+expression_classification_t is_linker_constant(const expression_t *expression)
 {
        switch (expression->kind) {
        case EXPR_STRING_LITERAL:
@@ -1628,7 +1631,7 @@ expression_classification_t is_address_constant(const expression_t *expression)
                        = revert_automatic_type_conversion(expression->unary.value);
                /* dereferencing a function is a NOP */
                if (is_type_function(real_type)) {
-                       return is_address_constant(expression->unary.value);
+                       return is_linker_constant(expression->unary.value);
                }
                /* FALLTHROUGH */
        }
@@ -1638,12 +1641,12 @@ expression_classification_t is_address_constant(const expression_t *expression)
                if (!is_type_pointer(dest) && (
                                dest->kind != TYPE_ATOMIC                                               ||
                                !(get_atomic_type_flags(dest->atomic.akind) & ATOMIC_TYPE_FLAG_INTEGER) ||
-                               get_atomic_type_size(dest->atomic.akind) < get_atomic_type_size(get_intptr_kind())
+                               get_atomic_type_size(dest->atomic.akind) < get_type_size(type_void_ptr)
                    ))
                        return EXPR_CLASS_VARIABLE;
 
                expression_classification_t const expr = is_constant_expression(expression->unary.value);
-               expression_classification_t const addr = is_address_constant(expression->unary.value);
+               expression_classification_t const addr = is_linker_constant(expression->unary.value);
                return expr > addr ? expr : addr;
        }
 
@@ -1655,12 +1658,12 @@ expression_classification_t is_address_constant(const expression_t *expression)
                type_t       *const rtype = skip_typeref(right->base.type);
 
                if (is_type_pointer(ltype)) {
-                       expression_classification_t const l = is_address_constant(left);
+                       expression_classification_t const l = is_linker_constant(left);
                        expression_classification_t const r = is_constant_expression(right);
                        return l < r ? l : r;
                } else if (is_type_pointer(rtype)) {
                        expression_classification_t const l = is_constant_expression(left);
-                       expression_classification_t const r = is_address_constant(right);
+                       expression_classification_t const r = is_linker_constant(right);
                        return l < r ? l : r;
                } else if (!is_type_valid(ltype) || !is_type_valid(rtype)) {
                        return EXPR_CLASS_ERROR;
@@ -1691,7 +1694,7 @@ expression_classification_t is_address_constant(const expression_t *expression)
                        skip_typeref(revert_automatic_type_conversion(expression));
                if (!is_type_array(type))
                        return EXPR_CLASS_VARIABLE;
-               expression_classification_t const ref = is_address_constant(expression->array_access.array_ref);
+               expression_classification_t const ref = is_linker_constant(expression->array_access.array_ref);
                expression_classification_t const idx = is_constant_expression(expression->array_access.index);
                return ref < idx ? ref : idx;
        }
@@ -1704,9 +1707,9 @@ expression_classification_t is_address_constant(const expression_t *expression)
 
                if (fold_constant_to_bool(c)) {
                        expression_t const *const t = expression->conditional.true_expression;
-                       return is_address_constant(t != NULL ? t : c);
+                       return is_linker_constant(t != NULL ? t : c);
                } else {
-                       return is_address_constant(expression->conditional.false_expression);
+                       return is_linker_constant(expression->conditional.false_expression);
                }
        }
 
@@ -1714,16 +1717,22 @@ expression_classification_t is_address_constant(const expression_t *expression)
                entity_t *entity = expression->select.compound_entry;
                if (!is_declaration(entity))
                        return EXPR_CLASS_VARIABLE;
-               expression_t *compound = expression->select.compound;
-               type_t       *type     = skip_typeref(entity->declaration.type);
+               type_t *type = skip_typeref(entity->declaration.type);
                if (is_type_array(type)) {
-                       return is_object_with_linker_constant_address(compound);
-               } else {
-                       return is_address_constant(compound);
+                       /* arrays automatically convert to their address */
+                       expression_t *compound  = expression->select.compound;
+                       type_t       *base_type = skip_typeref(compound->base.type);
+                       if (is_type_pointer(base_type)) {
+                               /* it's a -> */
+                               return is_linker_constant(compound);
+                       } else {
+                               return is_object_with_linker_constant_address(compound);
+                       }
                }
+               return EXPR_CLASS_VARIABLE;
        }
 
-       case EXPR_INVALID:
+       case EXPR_ERROR:
                return EXPR_CLASS_ERROR;
 
        default:
@@ -1803,7 +1812,7 @@ static expression_classification_t is_object_with_constant_address(const express
        case EXPR_UNARY_DEREFERENCE:
                return is_constant_pointer(expression->unary.value);
 
-       case EXPR_INVALID:
+       case EXPR_ERROR:
                return EXPR_CLASS_ERROR;
 
        default:
@@ -1880,8 +1889,7 @@ expression_classification_t is_constant_expression(const expression_t *expressio
        case EXPR_UNARY_NOT:
                return is_constant_expression(expression->unary.value);
 
-       case EXPR_UNARY_CAST:
-       case EXPR_UNARY_CAST_IMPLICIT: {
+       case EXPR_UNARY_CAST: {
                type_t *const type = skip_typeref(expression->base.type);
                if (is_type_scalar(type))
                        return is_constant_expression(expression->unary.value);
@@ -1954,11 +1962,8 @@ expression_classification_t is_constant_expression(const expression_t *expressio
                }
        }
 
-       case EXPR_INVALID:
+       case EXPR_ERROR:
                return EXPR_CLASS_ERROR;
-
-       case EXPR_UNKNOWN:
-               break;
        }
        panic("invalid expression found (is constant expression)");
 }