convert statements and expression to new union style (but didn't remove all casts...
authorMatthias Braun <matze@braunis.de>
Tue, 27 Nov 2007 10:17:38 +0000 (10:17 +0000)
committerMatthias Braun <matze@braunis.de>
Tue, 27 Nov 2007 10:17:38 +0000 (10:17 +0000)
[r18549]

ast.c
ast.h
ast2firm.c
ast_t.h
parser.c
type.c
write_fluffy.c

diff --git a/ast.c b/ast.c
index b326e85..5995765 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -29,7 +29,7 @@ void print_indent(void)
                fprintf(out, "\t");
 }
 
-static void print_const(const const_t *cnst)
+static void print_const(const const_expression_t *cnst)
 {
        if(cnst->expression.datatype == NULL)
                return;
@@ -41,7 +41,8 @@ static void print_const(const const_t *cnst)
        }
 }
 
-static void print_string_literal(const string_literal_t *string_literal)
+static void print_string_literal(
+               const string_literal_expression_t *string_literal)
 {
        fputc('"', out);
        for(const char *c = string_literal->value; *c != '\0'; ++c) {
@@ -233,8 +234,8 @@ static void print_va_arg(const va_arg_expression_t *expression)
 static void print_select(const select_expression_t *expression)
 {
        print_expression(expression->compound);
-       if(expression->compound->datatype == NULL ||
-                       expression->compound->datatype->type == TYPE_POINTER) {
+       if(expression->compound->base.datatype == NULL ||
+                       expression->compound->base.datatype->type == TYPE_POINTER) {
                fputs("->", out);
        } else {
                fputc('.', out);
@@ -258,12 +259,12 @@ void print_expression(const expression_t *expression)
                fprintf(out, "*invalid expression*");
                break;
        case EXPR_CONST:
-               print_const((const const_t*) expression);
+               print_const(&expression->conste);
                break;
        case EXPR_FUNCTION:
        case EXPR_PRETTY_FUNCTION:
        case EXPR_STRING_LITERAL:
-               print_string_literal((const string_literal_t*) expression);
+               print_string_literal(&expression->string_literal);
                break;
        case EXPR_CALL:
                print_call_expression((const call_expression_t*) expression);
@@ -317,7 +318,7 @@ static void print_compound_statement(const compound_statement_t *block)
                print_indent();
                print_statement(statement);
 
-               statement = statement->next;
+               statement = statement->base.next;
        }
        indent--;
        print_indent();
diff --git a/ast.h b/ast.h
index 410c774..2d95cc7 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -5,9 +5,9 @@
 
 typedef struct context_t                    context_t;
 
-typedef struct expression_t                 expression_t;
-typedef struct const_t                      const_t;
-typedef struct string_literal_t             string_literal_t;
+typedef struct expression_base_t            expression_base_t;
+typedef struct const_expression_t           const_expression_t;
+typedef struct string_literal_expression_t  string_literal_expression_t;
 typedef struct reference_expression_t       reference_expression_t;
 typedef struct cast_expression_t            cast_expression_t;
 typedef struct call_argument_t              call_argument_t;
@@ -27,6 +27,7 @@ typedef struct offsetof_expression_t        offsetof_expression_t;
 typedef struct va_arg_expression_t          va_arg_expression_t;
 typedef struct builtin_symbol_expression_t  builtin_symbol_expression_t;
 typedef struct classify_type_expression_t   classify_type_expression_t;
+typedef union  expression_t                 expression_t;
 
 typedef struct initializer_base_t           initializer_base_t;
 typedef struct initializer_list_t           initializer_list_t;
@@ -36,7 +37,7 @@ typedef union  initializer_t                initializer_t;
 
 typedef struct declaration_t                declaration_t;
 
-typedef struct statement_t                  statement_t;
+typedef struct statement_base_t             statement_base_t;
 typedef struct compound_statement_t         compound_statement_t;
 typedef struct return_statement_t           return_statement_t;
 typedef struct if_statement_t               if_statement_t;
@@ -49,6 +50,7 @@ typedef struct case_label_statement_t       case_label_statement_t;
 typedef struct while_statement_t            while_statement_t;
 typedef struct do_while_statement_t         do_while_statement_t;
 typedef struct for_statement_t              for_statement_t;
+typedef union  statement_t                  statement_t;
 
 typedef struct translation_unit_t           translation_unit_t;
 
index bfce6c5..b6e2204 100644 (file)
@@ -587,7 +587,7 @@ static dbg_info *get_dbg_info(const source_position_t *pos)
        return (dbg_info*) pos;
 }
 
-static ir_node *const_to_firm(const const_t *cnst)
+static ir_node *const_to_firm(const const_expression_t *cnst)
 {
        dbg_info *dbgi = get_dbg_info(&cnst->expression.source_position);
        ir_mode  *mode = get_ir_mode(cnst->expression.datatype);
@@ -653,7 +653,8 @@ static ir_node *string_to_firm(const source_position_t *const src_pos,
        return create_symconst(dbgi, entity);
 }
 
-static ir_node *string_literal_to_firm(const string_literal_t* literal)
+static ir_node *string_literal_to_firm(
+               const string_literal_expression_t* literal)
 {
        return string_to_firm(&literal->expression.source_position, "Lstr",
                              literal->value);
@@ -799,11 +800,11 @@ static ir_node *call_expression_to_firm(const call_expression_t *call)
        }
        ir_node       *callee   = expression_to_firm(function);
 
-       function_type_t *function_type;
-       assert(function->datatype->type == TYPE_POINTER);
-       pointer_type_t *const ptr_type = &function->datatype->pointer;
+       type_t *type = function->base.datatype;
+       assert(type->type == TYPE_POINTER);
+       pointer_type_t *const ptr_type = &type->pointer;
        assert(ptr_type->points_to->type == TYPE_FUNCTION);
-       function_type = &ptr_type->points_to->function;
+       function_type_t *function_type = &ptr_type->points_to->function;
 
        int              n_parameters = 0;
        call_argument_t *argument     = call->arguments;
@@ -839,7 +840,7 @@ static ir_node *call_expression_to_firm(const call_expression_t *call)
 
                in[n] = arg_node;
                if(new_method_type != NULL) {
-                       ir_type *irtype = get_ir_type(expression->datatype);
+                       ir_type *irtype = get_ir_type(expression->base.datatype);
                        set_method_param_type(new_method_type, n, irtype);
                }
 
@@ -890,9 +891,9 @@ static void set_value_for_expression(const expression_t *expression,
                }
        }
 
-       dbg_info *dbgi      = get_dbg_info(&expression->source_position);
+       dbg_info *dbgi      = get_dbg_info(&expression->base.source_position);
        ir_node  *addr      = expression_to_addr(expression);
-       assert(get_irn_mode(value) == get_ir_mode(expression->datatype));
+       assert(get_irn_mode(value) == get_ir_mode(expression->base.datatype));
        ir_node  *memory    = get_store();
        ir_node  *store     = new_d_Store(dbgi, memory, addr, value);
        ir_node  *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M);
@@ -1067,7 +1068,7 @@ static ir_node *create_arithmetic_binop(const binary_expression_t *expression,
        dbg_info *dbgi  = get_dbg_info(&expression->expression.source_position);
        ir_node  *left  = expression_to_firm(expression->left);
        ir_node  *right = expression_to_firm(expression->right);
-       type_t   *type  = expression->right->datatype;
+       type_t   *type  = expression->right->base.datatype;
        /* be careful with the modes, because in arithmetic assign nodes only
         * the right operand has the mode of the arithmetic already */
        ir_mode  *mode  = get_ir_mode(type);
@@ -1130,8 +1131,8 @@ static ir_node *create_add(const binary_expression_t *expression)
 
        expression_t *expr_left  = expression->left;
        expression_t *expr_right = expression->right;
-       type_t       *type_left  = skip_typeref(expr_left->datatype);
-       type_t       *type_right = skip_typeref(expr_right->datatype);
+       type_t       *type_left  = skip_typeref(expr_left->base.datatype);
+       type_t       *type_right = skip_typeref(expr_right->base.datatype);
 
        if(is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) {
                ir_mode *const mode = get_ir_mode(type);
@@ -1154,8 +1155,8 @@ static ir_node *create_sub(const binary_expression_t *expression)
        ir_node      *const left       = expression_to_firm(expr_left);
        ir_node      *const right      = expression_to_firm(expr_right);
        type_t       *const type       = expression->expression.datatype;
-       type_t       *const type_left  = skip_typeref(expr_left->datatype);
-       type_t       *const type_right = skip_typeref(expr_right->datatype);
+       type_t       *const type_left  = skip_typeref(expr_left->base.datatype);
+       type_t       *const type_right = skip_typeref(expr_right->base.datatype);
 
        if (is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) {
                ir_mode *const mode = get_ir_mode(type);
@@ -1198,7 +1199,7 @@ static ir_node *create_shift(const binary_expression_t *expression)
        case BINEXPR_SHIFTRIGHT_ASSIGN:
        case BINEXPR_SHIFTRIGHT: {
                 expression_t *expr_left = expression->left;
-                type_t       *type_left = skip_typeref(expr_left->datatype);
+                type_t       *type_left = skip_typeref(expr_left->base.datatype);
 
                 if(is_type_signed(type_left)) {
                        res = new_d_Shrs(dbgi, left, right, mode);
@@ -1223,7 +1224,7 @@ static ir_node *create_divmod(const binary_expression_t *expression)
        ir_node  *pin   = new_Pin(new_NoMem());
        /* be careful with the modes, because in arithmetic assign nodes only
         * the right operand has the mode of the arithmetic already */
-       type_t   *type  = expression->right->datatype;
+       type_t   *type  = expression->right->base.datatype;
        ir_mode  *mode  = get_ir_mode(type);
        left            = create_conv(dbgi, left, mode);
        ir_node  *op;
@@ -1360,7 +1361,7 @@ static ir_node *array_access_addr(const array_access_expression_t *expression)
        ir_node  *offset    = expression_to_firm(expression->index);
        offset              = create_conv(dbgi, offset, mode_Iu);
 
-       type_t *ref_type = skip_typeref(expression->array_ref->datatype);
+       type_t *ref_type = skip_typeref(expression->array_ref->base.datatype);
        assert(is_type_pointer(ref_type));
        pointer_type_t *pointer_type = (pointer_type_t*) ref_type;
 
@@ -1390,7 +1391,7 @@ static ir_node *sizeof_to_firm(const sizeof_expression_t *expression)
 {
        type_t *type = expression->type;
        if(type == NULL) {
-               type = expression->size_expression->datatype;
+               type = expression->size_expression->base.datatype;
                assert(type != NULL);
        }
 
@@ -1498,7 +1499,7 @@ typedef enum gcc_type_class
 
 static ir_node *classify_type_to_firm(const classify_type_expression_t *const expr)
 {
-       const type_t *const type = expr->type_expression->datatype;
+       const type_t *const type = expr->type_expression->base.datatype;
 
        gcc_type_class tc;
        switch (type->type)
@@ -1575,7 +1576,8 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
        return new_d_Const(dbgi, mode, tv);
 }
 
-static ir_node *function_name_to_firm(const string_literal_t *const expr)
+static ir_node *function_name_to_firm(
+               const string_literal_expression_t *const expr)
 {
        if (current_function_name == NULL) {
                const source_position_t *const src_pos =
@@ -1628,36 +1630,32 @@ static ir_node *_expression_to_firm(const expression_t *expression)
 {
        switch(expression->type) {
        case EXPR_CONST:
-               return const_to_firm((const const_t*) expression);
+               return const_to_firm(&expression->conste);
        case EXPR_STRING_LITERAL:
-               return string_literal_to_firm((const string_literal_t*) expression);
+               return string_literal_to_firm(&expression->string_literal);
        case EXPR_REFERENCE:
-               return reference_expression_to_firm(
-                               (const reference_expression_t*) expression);
+               return reference_expression_to_firm(&expression->reference);
        case EXPR_CALL:
-               return call_expression_to_firm((const call_expression_t*) expression);
+               return call_expression_to_firm(&expression->call);
        case EXPR_UNARY:
-               return unary_expression_to_firm((const unary_expression_t*) expression);
+               return unary_expression_to_firm(&expression->unary);
        case EXPR_BINARY:
-               return binary_expression_to_firm(
-                               (const binary_expression_t*) expression);
+               return binary_expression_to_firm(&expression->binary);
        case EXPR_ARRAY_ACCESS:
-               return array_access_to_firm(
-                               (const array_access_expression_t*) expression);
+               return array_access_to_firm(&expression->array_access);
        case EXPR_SIZEOF:
-               return sizeof_to_firm((const sizeof_expression_t*) expression);
+               return sizeof_to_firm(&expression->sizeofe);
        case EXPR_CONDITIONAL:
-               return conditional_to_firm((const conditional_expression_t*)expression);
+               return conditional_to_firm(&expression->conditional);
        case EXPR_SELECT:
-               return select_to_firm((const select_expression_t*) expression);
+               return select_to_firm(&expression->select);
        case EXPR_CLASSIFY_TYPE:
-               return classify_type_to_firm((const classify_type_expression_t*)expression);
+               return classify_type_to_firm(&expression->classify_type);
        case EXPR_FUNCTION:
        case EXPR_PRETTY_FUNCTION:
-               return function_name_to_firm((const string_literal_t*)expression);
+               return function_name_to_firm(&expression->string_literal);
        case EXPR_STATEMENT:
-               return statement_expression_to_firm(
-                               (const statement_expression_t*) expression);
+               return statement_expression_to_firm(&expression->statement);
        case EXPR_OFFSETOF:
        case EXPR_VA_ARG:
        case EXPR_BUILTIN_SYMBOL:
@@ -1675,7 +1673,7 @@ static ir_node *expression_to_firm(const expression_t *expression)
        ir_node *res = _expression_to_firm(expression);
 
        if(res != NULL && get_irn_mode(res) == mode_b) {
-               ir_mode *mode = get_ir_mode(expression->datatype);
+               ir_mode *mode = get_ir_mode(expression->base.datatype);
                res           = create_conv(NULL, res, mode);
        }
 
@@ -1741,7 +1739,7 @@ static void create_condition_evaluation(const expression_t *expression,
                break;
        }
 
-       dbg_info *dbgi       = get_dbg_info(&expression->source_position);
+       dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
        ir_node  *condition  = expression_to_modeb(expression);
        ir_node  *cond       = new_d_Cond(dbgi, condition);
        ir_node  *true_proj  = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
@@ -1804,10 +1802,11 @@ static ir_node *compound_statement_to_firm(compound_statement_t *compound)
 {
        ir_node     *result    = NULL;
        statement_t *statement = compound->statements;
-       for( ; statement != NULL; statement = statement->next) {
+       for( ; statement != NULL; statement = statement->base.next) {
                //context2firm(&statement->context);
 
-               if(statement->next == NULL && statement->type == STATEMENT_EXPRESSION) {
+               if(statement->base.next == NULL
+                               && statement->type == STATEMENT_EXPRESSION) {
                        result = expression_statement_to_firm(
                                        (expression_statement_t*) statement);
                        break;
@@ -2424,7 +2423,7 @@ static void create_jump_statement(const statement_t *statement,
        if(get_cur_block() == NULL)
                return;
 
-       dbg_info *dbgi = get_dbg_info(&statement->source_position);
+       dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
        ir_node  *jump = new_d_Jmp(dbgi);
        add_immBlock_pred(target_block, jump);
 
@@ -2646,7 +2645,7 @@ static int count_local_declarations(const declaration_t *      decl,
 static int count_decls_in_stmts(const statement_t *stmt)
 {
        int count = 0;
-       for (; stmt != NULL; stmt = stmt->next) {
+       for (; stmt != NULL; stmt = stmt->base.next) {
                switch (stmt->type) {
                        case STATEMENT_DECLARATION: {
                                const declaration_statement_t *const decl_stmt =
diff --git a/ast_t.h b/ast_t.h
index f7598b8..5e2819b 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -39,34 +39,34 @@ struct context_t {
        declaration_t   *declarations;
 };
 
-struct expression_t {
+struct expression_base_t {
        expresion_type_t   type;
        type_t            *datatype;
        source_position_t  source_position;
 };
 
-struct const_t {
-       expression_t  expression;
+struct const_expression_t {
+       expression_base_t  expression;
        union {
                long long   int_value;
                long double float_value;
        } v;
 };
 
-struct string_literal_t {
-       expression_t  expression;
-       const char   *value;
+struct string_literal_expression_t {
+       expression_base_t  expression;
+       const char        *value;
 };
 
 struct builtin_symbol_expression_t {
-       expression_t  expression;
-       symbol_t     *symbol;
+       expression_base_t  expression;
+       symbol_t          *symbol;
 };
 
 struct reference_expression_t {
-       expression_  expression;
-       symbol_t      *symbol;
-       declaration_t *declaration;
+       expression_base_t  expression;
+       symbol_t          *symbol;
+       declaration_t     *declaration;
 };
 
 struct call_argument_t {
@@ -75,9 +75,9 @@ struct call_argument_t {
 };
 
 struct call_expression_t {
-       expression_t     expression;
-       expression_t    *function;
-       call_argument_t *arguments;
+       expression_base_t  expression;
+       expression_t      *function;
+       call_argument_t   *arguments;
 };
 
 typedef enum {
@@ -96,7 +96,7 @@ typedef enum {
 } unary_expression_type_t;
 
 struct unary_expression_t {
-       expression_t             expression;
+       expression_base_t        expression;
        unary_expression_type_t  type;
        expression_t            *value;
 };
@@ -136,31 +136,31 @@ typedef enum {
 } binary_expression_type_t;
 
 struct binary_expression_t {
-       expression_t              expression;
+       expression_base_t         expression;
        binary_expression_type_t  type;
        expression_t             *left;
        expression_t             *right;
 };
 
 struct select_expression_t {
-       expression_  expression;
-       expression_t  *compound;
-       symbol_t      *symbol;
+       expression_base_t  expression;
+       expression_t      *compound;
+       symbol_t          *symbol;
 
-       declaration_t *compound_entry;
+       declaration_t     *compound_entry;
 };
 
 struct array_access_expression_t {
-       expression_t  expression;
-       expression_t *array_ref;
-       expression_t *index;
-       bool          flipped; /* index/ref was written in a 5[a] way */
+       expression_base_t  expression;
+       expression_t      *array_ref;
+       expression_t      *index;
+       bool               flipped; /* index/ref was written in a 5[a] way */
 };
 
 struct sizeof_expression_t {
-       expression_t  expression;
-       type_t       *type;
-       expression_t *size_expression;
+       expression_base_t  expression;
+       type_t            *type;
+       expression_t      *size_expression;
 };
 
 struct designator_t {
@@ -170,32 +170,52 @@ struct designator_t {
 };
 
 struct offsetof_expression_t {
-       expression_t  expression;
-       type_t       *type;
-       designator_t *designator;
+       expression_base_t  expression;
+       type_t            *type;
+       designator_t      *designator;
 };
 
 struct va_arg_expression_t {
-       expression_t  expression;
-       expression_t *arg;
-       type_t       *type;
+       expression_base_t  expression;
+       expression_t      *arg;
+       type_t            *type;
 };
 
 struct conditional_expression_t {
-       expression_t  expression;
-       expression_t *condition;
-       expression_t *true_expression;
-       expression_t *false_expression;
+       expression_base_t  expression;
+       expression_t      *condition;
+       expression_t      *true_expression;
+       expression_t      *false_expression;
 };
 
 struct statement_expression_t {
-       expression_t  expression;
-       statement_t  *statement;
+       expression_base_t  expression;
+       statement_t       *statement;
 };
 
 struct classify_type_expression_t {
-       expression_t  expression;
-       expression_t *type_expression;
+       expression_base_t  expression;
+       expression_t      *type_expression;
+};
+
+union expression_t {
+       expresion_type_t             type;
+       expression_base_t            base;
+       const_expression_t           conste;
+       string_literal_expression_t  string_literal;
+       builtin_symbol_expression_t  builtin_symbol;
+       reference_expression_t       reference;
+       call_expression_t            call;
+       unary_expression_t           unary;
+       binary_expression_t          binary;
+       select_expression_t          select;
+       array_access_expression_t    array_access;
+       sizeof_expression_t          sizeofe;
+       offsetof_expression_t        offsetofe;
+       va_arg_expression_t          va_arg;
+       conditional_expression_t     conditional;
+       statement_expression_t       statement;
+       classify_type_expression_t   classify_type;
 };
 
 typedef enum {
@@ -300,83 +320,100 @@ typedef enum {
        STATEMENT_FOR
 } statement_type_t;
 
-struct statement_t {
+struct statement_base_t {
        statement_type_t   type;
        statement_t       *next;
        source_position_t  source_position;
 };
 
 struct return_statement_t {
-       statement_  statement;
-       expression_t *return_value;
+       statement_base_t  statement;
+       expression_t     *return_value;
 };
 
 struct compound_statement_t {
-       statement_t  statement;
-       statement_t *statements;
-       context_t    context;
+       statement_base_t  statement;
+       statement_t      *statements;
+       context_t         context;
 };
 
 struct declaration_statement_t {
-       statement_t    statement;
-       declaration_t *declarations_begin;
-       declaration_t *declarations_end;
+       statement_base_t  statement;
+       declaration_t    *declarations_begin;
+       declaration_t    *declarations_end;
 };
 
 struct if_statement_t {
-       statement_  statement;
-       expression_t *condition;
-       statement_t  *true_statement;
-       statement_t  *false_statement;
+       statement_base_t  statement;
+       expression_t     *condition;
+       statement_t      *true_statement;
+       statement_t      *false_statement;
 };
 
 struct switch_statement_t {
-       statement_  statement;
-       expression_t *expression;
-       statement_t  *body;
+       statement_base_t  statement;
+       expression_t     *expression;
+       statement_t      *body;
 };
 
 struct goto_statement_t {
-       statement_t    statement;
-       declaration_t *label;
+       statement_base_t  statement;
+       declaration_t    *label;
 };
 
 struct case_label_statement_t {
-       statement_  statement;
-       expression_t *expression;
-       statement_t  *label_statement;
+       statement_base_t  statement;
+       expression_t     *expression;
+       statement_t      *label_statement;
 };
 
 struct label_statement_t {
-       statement_t    statement;
-       declaration_t *label;
-       statement_t   *label_statement;
+       statement_base_t  statement;
+       declaration_t    *label;
+       statement_t      *label_statement;
 };
 
 struct expression_statement_t {
-       statement_  statement;
-       expression_t *expression;
+       statement_base_t  statement;
+       expression_t     *expression;
 };
 
 struct while_statement_t {
-       statement_  statement;
-       expression_t *condition;
-       statement_t  *body;
+       statement_base_t  statement;
+       expression_t     *condition;
+       statement_t      *body;
 };
 
 struct do_while_statement_t {
-       statement_  statement;
-       expression_t *condition;
-       statement_t  *body;
+       statement_base_t  statement;
+       expression_t     *condition;
+       statement_t      *body;
 };
 
 struct for_statement_t {
-       statement_t   statement;
-       expression_t  *initialisation;
-       expression_t  *condition;
-       expression_t  *step;
-       statement_t   *body;
-       context_t      context;
+       statement_base_t  statement;
+       expression_t     *initialisation;
+       expression_t     *condition;
+       expression_t     *step;
+       statement_t      *body;
+       context_t         context;
+};
+
+union statement_t {
+       statement_type_t         type;
+       statement_base_t         base;
+       return_statement_t       returns;
+       compound_statement_t     compound;
+       declaration_statement_t  declaration;
+       if_statement_t           ifs;
+       switch_statement_t       switchs;
+       goto_statement_t         gotos;
+       case_label_statement_t   case_label;
+       label_statement_t        label;
+       expression_statement_t   expression;
+       while_statement_t        whiles;
+       do_while_statement_t     do_while;
+       for_statement_t          fors;
 };
 
 struct translation_unit_t {
index 75d476c..bd205b3 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -671,21 +671,22 @@ static expression_t *create_cast_expression(expression_t *expression,
        return (expression_t*) cast;
 }
 
-static bool is_null_expression(const expression_t *const expr)
+static bool is_null_expression(const expression_t *const expression)
 {
-       if (expr->type != EXPR_CONST) return false;
+       if (expression->type != EXPR_CONST)
+               return false;
 
-       type_t *const type = skip_typeref(expr->datatype);
-       if (!is_type_integer(type)) return false;
+       type_t *const type = skip_typeref(expression->base.datatype);
+       if (!is_type_integer(type))
+               return false;
 
-       const const_t *const const_expr = (const const_t*)expr;
-       return const_expr->v.int_value == 0;
+       return expression->conste.v.int_value == 0;
 }
 
 static expression_t *create_implicit_cast(expression_t *expression,
                                           type_t *dest_type)
 {
-       type_t *source_type = expression->datatype;
+       type_t *source_type = expression->base.datatype;
 
        if(source_type == NULL)
                return expression;
@@ -707,7 +708,8 @@ static expression_t *create_implicit_cast(expression_t *expression,
 
                        if(is_type_floating(dest_type) && !is_type_scalar(source_type)) {
                                type_error_incompatible("can't cast types",
-                                               expression->source_position, source_type, dest_type);
+                                               expression->base.source_position, source_type,
+                                               dest_type);
                                return expression;
                        }
 
@@ -742,7 +744,7 @@ static expression_t *create_implicit_cast(expression_t *expression,
                        }
 
                        type_error_incompatible("can't implicitly cast types",
-                                       expression->source_position, source_type, dest_type);
+                                       expression->base.source_position, source_type, dest_type);
                        return expression;
 
                default:
@@ -754,7 +756,7 @@ static expression_t *create_implicit_cast(expression_t *expression,
 static void semantic_assign(type_t *orig_type_left, expression_t **right,
                             const char *context)
 {
-       type_t *orig_type_right = (*right)->datatype;
+       type_t *orig_type_right = (*right)->base.datatype;
 
        if(orig_type_right == NULL)
                return;
@@ -771,8 +773,8 @@ static void semantic_assign(type_t *orig_type_left, expression_t **right,
        }
 
        if (is_type_pointer(type_left) && is_type_pointer(type_right)) {
-               pointer_type_t *pointer_type_left  = (pointer_type_t*) type_left;
-               pointer_type_t *pointer_type_right = (pointer_type_t*) type_right;
+               pointer_type_t *pointer_type_left  = &type_left->pointer;
+               pointer_type_t *pointer_type_right = &type_right->pointer;
                type_t         *points_to_left     = pointer_type_left->points_to;
                type_t         *points_to_right    = pointer_type_right->points_to;
 
@@ -986,7 +988,8 @@ static initializer_t *initializer_from_expression(type_t *type,
                                        || atype == ATOMIC_TYPE_SCHAR
                                        || atype == ATOMIC_TYPE_UCHAR) {
 
-                               string_literal_t *literal = (string_literal_t*) expression;
+                               string_literal_expression_t *literal
+                                       = &expression->string_literal;
                                return initializer_from_string(array_type, literal->value);
                        }
                }
@@ -1011,7 +1014,7 @@ static initializer_t *parse_sub_initializer_elem(type_t *type)
        }
 
        expression_t *expression      = parse_assignment_expression();
-       type_t       *expression_type = skip_typeref(expression->datatype);
+       type_t       *expression_type = skip_typeref(expression->base.datatype);
 
        return parse_sub_initializer(type, expression, expression_type);
 }
@@ -1068,7 +1071,7 @@ static initializer_t *parse_sub_initializer(type_t *type,
        initializer_t  *result = NULL;
        initializer_t **elems;
        if(type->type == TYPE_ARRAY) {
-               array_type_t *array_type   = (array_type_t*) type;
+               array_type_t *array_type   = &type->array;
                type_t       *element_type = array_type->element_type;
                element_type               = skip_typeref(element_type);
 
@@ -1110,7 +1113,7 @@ static initializer_t *parse_sub_initializer(type_t *type,
        } else {
                assert(type->type == TYPE_COMPOUND_STRUCT
                                || type->type == TYPE_COMPOUND_UNION);
-               compound_type_t *compound_type = (compound_type_t*) type;
+               compound_type_t *compound_type = &type->compound;
                context_t       *context       = & compound_type->declaration->context;
 
                declaration_t *first = context->declarations;
@@ -1416,7 +1419,7 @@ restart:
                        type = parse_typename();
                } else {
                        expression = parse_expression();
-                       type       = expression->datatype;
+                       type       = expression->base.datatype;
                }
                break;
 
@@ -1426,7 +1429,7 @@ restart:
 
        default:
                expression = parse_expression();
-               type       = expression->datatype;
+               type       = expression->base.datatype;
                break;
        }
 
@@ -1792,8 +1795,7 @@ static declaration_t *parse_parameter(void)
        /* Array as last part of a paramter type is just syntactic sugar.  Turn it
         * into a pointer */
        if (declaration->type->type == TYPE_ARRAY) {
-               const array_type_t *const arr_type =
-                       (const array_type_t*)declaration->type;
+               const array_type_t *const arr_type = &declaration->type->array;
                type_t *element_type = arr_type->element_type;
                declaration->type = make_pointer_type(element_type, TYPE_QUALIFIER_NONE);
        }
@@ -2220,10 +2222,11 @@ static void parse_init_declarators(const declaration_specifiers_t *specifiers)
                        initializer_t *initializer = parse_initializer(type);
 
                        if(type->type == TYPE_ARRAY && initializer != NULL) {
-                               array_type_t       *array_type = (array_type_t*) type;
+                               array_type_t *array_type = &type->array;
 
                                if(array_type->size == NULL) {
-                                       const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+                                       const_expression_t
+                                               *cnst = allocate_ast_zero(sizeof(cnst[0]));
 
                                        cnst->expression.type     = EXPR_CONST;
                                        cnst->expression.datatype = type_size_t;
@@ -2358,8 +2361,8 @@ static void parse_declaration(void)
                switch (specifiers.type->type) {
                        case TYPE_COMPOUND_STRUCT:
                        case TYPE_COMPOUND_UNION: {
-                               const compound_type_t *const comp_type =
-                                       (const compound_type_t*)specifiers.type;
+                               const compound_type_t *const comp_type
+                                       = &specifiers.type->compound;
                                if (comp_type->declaration->symbol == NULL) {
                                        parse_warning_pos(source_position,
                                                                                                                "unnamed struct/union that defines no instances");
@@ -2423,9 +2426,9 @@ expression_parser_function_t expression_parsers[T_LAST_TOKEN];
 
 static expression_t *make_invalid_expression(void)
 {
-       expression_t *expression    = allocate_ast_zero(sizeof(expression[0]));
-       expression->type            = EXPR_INVALID;
-       expression->source_position = token.source_position;
+       expression_t *expression         = allocate_ast_zero(sizeof(expression[0]));
+       expression->type                 = EXPR_INVALID;
+       expression->base.source_position = token.source_position;
        return expression;
 }
 
@@ -2443,7 +2446,7 @@ static expression_t *expected_expression_error(void)
 
 static expression_t *parse_string_const(void)
 {
-       string_literal_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+       string_literal_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
 
        cnst->expression.type     = EXPR_STRING_LITERAL;
        cnst->expression.datatype = type_string;
@@ -2454,7 +2457,7 @@ static expression_t *parse_string_const(void)
 
 static expression_t *parse_int_const(void)
 {
-       const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+       const_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
 
        cnst->expression.type     = EXPR_CONST;
        cnst->expression.datatype = token.datatype;
@@ -2467,7 +2470,7 @@ static expression_t *parse_int_const(void)
 
 static expression_t *parse_float_const(void)
 {
-       const_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
+       const_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
 
        cnst->expression.type     = EXPR_CONST;
        cnst->expression.datatype = token.datatype;
@@ -2552,7 +2555,7 @@ static type_t *automatic_type_conversion(type_t *type)
                return NULL;
 
        if(type->type == TYPE_ARRAY) {
-               array_type_t *array_type   = (array_type_t*) type;
+               array_type_t *array_type   = &type->array;
                type_t       *element_type = array_type->element_type;
                unsigned      qualifiers   = array_type->type.qualifiers;
 
@@ -2572,7 +2575,7 @@ static type_t *automatic_type_conversion(type_t *type)
  */
 type_t *revert_automatic_type_conversion(const expression_t *expression)
 {
-       if(expression->datatype == NULL)
+       if(expression->base.datatype == NULL)
                return NULL;
 
        switch(expression->type) {
@@ -2591,8 +2594,8 @@ type_t *revert_automatic_type_conversion(const expression_t *expression)
                        = (const unary_expression_t*) expression;
                if(unary->type == UNEXPR_DEREFERENCE) {
                        expression_t   *value        = unary->value;
-                       type_t         *type         = skip_typeref(value->datatype);
-                       pointer_type_t *pointer_type = (pointer_type_t*) type;
+                       type_t         *type         = skip_typeref(value->base.datatype);
+                       pointer_type_t *pointer_type = &type->pointer;
 
                        return pointer_type->points_to;
                }
@@ -2605,10 +2608,11 @@ type_t *revert_automatic_type_conversion(const expression_t *expression)
        }
        case EXPR_ARRAY_ACCESS: {
                const array_access_expression_t *array_access
-                       = (const array_access_expression_t*) expression;
-               type_t *type_left  = skip_typeref(array_access->array_ref->datatype);
+                       = &expression->array_access;
+               const expression_t *array_ref = array_access->array_ref;
+               type_t *type_left  = skip_typeref(array_ref->base.datatype);
                assert(is_type_pointer(type_left));
-               pointer_type_t *pointer_type = (pointer_type_t*) type_left;
+               pointer_type_t *pointer_type = &type_left->pointer;
                return pointer_type->points_to;
        }
 
@@ -2616,7 +2620,7 @@ type_t *revert_automatic_type_conversion(const expression_t *expression)
                break;
        }
 
-       return expression->datatype;
+       return expression->base.datatype;
 }
 
 static expression_t *parse_reference(void)
@@ -2709,7 +2713,7 @@ static expression_t *parse_statement_expression(void)
        /* find last statement and use it's type */
        const statement_t *last_statement = NULL;
        const statement_t *iter           = compound_statement->statements;
-       for( ; iter != NULL; iter = iter->next) {
+       for( ; iter != NULL; iter = iter->base.next) {
                last_statement = iter;
        }
 
@@ -2717,7 +2721,7 @@ static expression_t *parse_statement_expression(void)
                const expression_statement_t *expression_statement =
                        (const expression_statement_t*) last_statement;
                expression->expression.datatype
-                       = expression_statement->expression->datatype;
+                       = expression_statement->expression->base.datatype;
        } else {
                expression->expression.datatype = type_void;
        }
@@ -2760,7 +2764,9 @@ static expression_t *parse_function_keyword(void)
                parse_error("'__func__' used outside of a function");
        }
 
-       string_literal_t *expression = allocate_ast_zero(sizeof(expression[0]));
+       string_literal_expression_t *expression
+               = allocate_ast_zero(sizeof(expression[0]));
+
        expression->expression.type     = EXPR_FUNCTION;
        expression->expression.datatype = type_string;
        expression->value               = "TODO: FUNCTION";
@@ -2773,7 +2779,9 @@ static expression_t *parse_pretty_function_keyword(void)
        eat(T___PRETTY_FUNCTION__);
        /* TODO */
 
-       string_literal_t *expression = allocate_ast_zero(sizeof(expression[0]));
+       string_literal_expression_t *expression
+               = allocate_ast_zero(sizeof(expression[0]));
+
        expression->expression.type     = EXPR_PRETTY_FUNCTION;
        expression->expression.datatype = type_string;
        expression->value               = "TODO: PRETTY FUNCTION";
@@ -2935,18 +2943,21 @@ static expression_t *parse_array_expression(unsigned precedence,
 
        array_access->expression.type = EXPR_ARRAY_ACCESS;
 
-       type_t *type_left   = skip_typeref(left->datatype);
-       type_t *type_inside = skip_typeref(inside->datatype);
-       type_t *result_type;
+       type_t *type_left   = left->base.datatype;
+       type_t *type_inside = inside->base.datatype;
+       type_t *result_type = NULL;
 
        if(type_left != NULL && type_inside != NULL) {
+               type_left   = skip_typeref(type_left);
+               type_inside = skip_typeref(type_inside);
+
                if(is_type_pointer(type_left)) {
-                       pointer_type_t *pointer = (pointer_type_t*) type_left;
+                       pointer_type_t *pointer = &type_left->pointer;
                        result_type             = pointer->points_to;
                        array_access->array_ref = left;
                        array_access->index     = inside;
                } else if(is_type_pointer(type_inside)) {
-                       pointer_type_t *pointer = (pointer_type_t*) type_inside;
+                       pointer_type_t *pointer = &type_inside->pointer;
                        result_type             = pointer->points_to;
                        array_access->array_ref = inside;
                        array_access->index     = left;
@@ -3009,10 +3020,10 @@ static expression_t *parse_sizeof(unsigned precedence)
                sizeof_expression->type = parse_typename();
                expect(')');
        } else {
-               expression_t *expression = parse_sub_expression(precedence);
-               expression->datatype     = revert_automatic_type_conversion(expression);
+               expression_t *expression  = parse_sub_expression(precedence);
+               expression->base.datatype = revert_automatic_type_conversion(expression);
 
-               sizeof_expression->type            = expression->datatype;
+               sizeof_expression->type            = expression->base.datatype;
                sizeof_expression->size_expression = expression;
        }
 
@@ -3041,7 +3052,7 @@ static expression_t *parse_select_expression(unsigned precedence,
        select->symbol   = symbol;
        next_token();
 
-       type_t *orig_type = compound->datatype;
+       type_t *orig_type = compound->base.datatype;
        if(orig_type == NULL)
                return make_invalid_expression();
 
@@ -3056,7 +3067,7 @@ static expression_t *parse_select_expression(unsigned precedence,
                        fputc('\n', stderr);
                        return make_invalid_expression();
                }
-               pointer_type_t *pointer_type = (pointer_type_t*) type;
+               pointer_type_t *pointer_type = &type->pointer;
                type_left                    = pointer_type->points_to;
        }
        type_left = skip_typeref(type_left);
@@ -3071,7 +3082,7 @@ static expression_t *parse_select_expression(unsigned precedence,
                return make_invalid_expression();
        }
 
-       compound_type_t *compound_type = (compound_type_t*) type_left;
+       compound_type_t *compound_type = &type_left->compound;
        declaration_t   *declaration   = compound_type->declaration;
 
        if(!declaration->init.is_defined) {
@@ -3113,19 +3124,18 @@ static expression_t *parse_call_expression(unsigned precedence,
        call->expression.type   = EXPR_CALL;
        call->function          = expression;
 
-       function_type_t *function_type;
-       type_t          *orig_type     = expression->datatype;
+       function_type_t *function_type = NULL;
+       type_t          *orig_type     = expression->base.datatype;
        if(orig_type != NULL) {
-               function_type = NULL;
                type_t *type  = skip_typeref(orig_type);
 
                if(is_type_pointer(type)) {
-                       pointer_type_t *pointer_type = (pointer_type_t*) type;
+                       pointer_type_t *pointer_type = &type->pointer;
 
                        type = skip_typeref(pointer_type->points_to);
 
                        if (type->type == TYPE_FUNCTION) {
-                               function_type             = (function_type_t*) type;
+                               function_type             = &type->function;
                                call->expression.datatype = function_type->result_type;
                        }
                }
@@ -3193,7 +3203,7 @@ static expression_t *parse_call_expression(unsigned precedence,
                        } else {
                                /* do default promotion */
                                for( ; argument != NULL; argument = argument->next) {
-                                       type_t *type = argument->expression->datatype;
+                                       type_t *type = argument->expression->base.datatype;
                                        type = skip_typeref(type);
 
                                        if(type == NULL)
@@ -3228,12 +3238,12 @@ static expression_t *parse_conditional_expression(unsigned precedence,
        conditional->condition       = expression;
 
        /* 6.5.15.2 */
-       type_t *condition_type_orig = conditional->condition->datatype;
+       type_t *condition_type_orig = conditional->condition->base.datatype;
        if(condition_type_orig != NULL) {
                type_t *condition_type      = skip_typeref(condition_type_orig);
                if(condition_type != NULL && !is_type_scalar(condition_type)) {
-                       type_error("expected a scalar type", expression->source_position,
-                                          condition_type_orig);
+                       type_error("expected a scalar type",
+                                  expression->base.source_position, condition_type_orig);
                }
        }
 
@@ -3243,10 +3253,10 @@ static expression_t *parse_conditional_expression(unsigned precedence,
        expression_t *const f_expr = parse_sub_expression(precedence);
        conditional->false_expression = f_expr;
 
-       type_t *const true_type  = t_expr->datatype;
+       type_t *const true_type  = t_expr->base.datatype;
        if(true_type == NULL)
                return (expression_t*) conditional;
-       type_t *const false_type = f_expr->datatype;
+       type_t *const false_type = f_expr->base.datatype;
        if(false_type == NULL)
                return (expression_t*) conditional;
 
@@ -3276,7 +3286,7 @@ static expression_t *parse_conditional_expression(unsigned precedence,
                /* TODO */
        } else {
                type_error_incompatible("while parsing conditional",
-                                       expression->source_position, true_type,
+                                       expression->base.source_position, true_type,
                                        skipped_false_type);
        }
 
@@ -3311,7 +3321,7 @@ static expression_t *parse_builtin_classify_type(const unsigned precedence)
 
 static void semantic_incdec(unary_expression_t *expression)
 {
-       type_t *orig_type = expression->value->datatype;
+       type_t *orig_type = expression->value->base.datatype;
        if(orig_type == NULL)
                return;
 
@@ -3328,7 +3338,7 @@ static void semantic_incdec(unary_expression_t *expression)
 
 static void semantic_unexpr_arithmetic(unary_expression_t *expression)
 {
-       type_t *orig_type = expression->value->datatype;
+       type_t *orig_type = expression->value->base.datatype;
        if(orig_type == NULL)
                return;
 
@@ -3345,7 +3355,7 @@ static void semantic_unexpr_arithmetic(unary_expression_t *expression)
 
 static void semantic_unexpr_scalar(unary_expression_t *expression)
 {
-       type_t *orig_type = expression->value->datatype;
+       type_t *orig_type = expression->value->base.datatype;
        if(orig_type == NULL)
                return;
 
@@ -3360,7 +3370,7 @@ static void semantic_unexpr_scalar(unary_expression_t *expression)
 
 static void semantic_unexpr_integer(unary_expression_t *expression)
 {
-       type_t *orig_type = expression->value->datatype;
+       type_t *orig_type = expression->value->base.datatype;
        if(orig_type == NULL)
                return;
 
@@ -3375,20 +3385,20 @@ static void semantic_unexpr_integer(unary_expression_t *expression)
 
 static void semantic_dereference(unary_expression_t *expression)
 {
-       type_t *orig_type = expression->value->datatype;
+       type_t *orig_type = expression->value->base.datatype;
        if(orig_type == NULL)
                return;
 
        type_t *type = skip_typeref(orig_type);
        if(!is_type_pointer(type)) {
                parser_print_error_prefix();
-               fputs("'Unary *' needs pointer or arrray type, but type ", stderr);
+               fputs("Unary '*' needs pointer or arrray type, but type ", stderr);
                print_type_quoted(orig_type);
                fputs(" given.\n", stderr);
                return;
        }
 
-       pointer_type_t *pointer_type = (pointer_type_t*)type;
+       pointer_type_t *pointer_type = &type->pointer;
        type_t         *result_type  = pointer_type->points_to;
 
        result_type = automatic_type_conversion(result_type);
@@ -3397,10 +3407,10 @@ static void semantic_dereference(unary_expression_t *expression)
 
 static void semantic_take_addr(unary_expression_t *expression)
 {
-       expression_t *value = expression->value;
-       value->datatype     = revert_automatic_type_conversion(value);
+       expression_t *value  = expression->value;
+       value->base.datatype = revert_automatic_type_conversion(value);
 
-       type_t *orig_type = value->datatype;
+       type_t *orig_type = value->base.datatype;
        if(orig_type == NULL)
                return;
 
@@ -3507,8 +3517,8 @@ static void semantic_binexpr_arithmetic(binary_expression_t *expression)
 {
        expression_t *left       = expression->left;
        expression_t *right      = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3533,8 +3543,8 @@ static void semantic_shift_op(binary_expression_t *expression)
 {
        expression_t *left       = expression->left;
        expression_t *right      = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3561,8 +3571,8 @@ static void semantic_add(binary_expression_t *expression)
 {
        expression_t *left            = expression->left;
        expression_t *right           = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3595,8 +3605,8 @@ static void semantic_sub(binary_expression_t *expression)
 {
        expression_t *left            = expression->left;
        expression_t *right           = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3639,8 +3649,8 @@ static void semantic_comparison(binary_expression_t *expression)
 {
        expression_t *left            = expression->left;
        expression_t *right           = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3672,8 +3682,8 @@ static void semantic_arithmetic_assign(binary_expression_t *expression)
 {
        expression_t *left            = expression->left;
        expression_t *right           = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3701,8 +3711,8 @@ static void semantic_arithmetic_addsubb_assign(binary_expression_t *expression)
 {
        expression_t *left            = expression->left;
        expression_t *right           = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3735,8 +3745,8 @@ static void semantic_logical_op(binary_expression_t *expression)
 {
        expression_t *left            = expression->left;
        expression_t *right           = expression->right;
-       type_t       *orig_type_left  = left->datatype;
-       type_t       *orig_type_right = right->datatype;
+       type_t       *orig_type_left  = left->base.datatype;
+       type_t       *orig_type_right = right->base.datatype;
 
        if(orig_type_left == NULL || orig_type_right == NULL)
                return;
@@ -3764,7 +3774,7 @@ static bool has_const_fields(type_t *type)
 static void semantic_binexpr_assign(binary_expression_t *expression)
 {
        expression_t *left           = expression->left;
-       type_t       *orig_type_left = left->datatype;
+       type_t       *orig_type_left = left->base.datatype;
 
        if(orig_type_left == NULL)
                return;
@@ -3815,7 +3825,7 @@ static void semantic_binexpr_assign(binary_expression_t *expression)
 
 static void semantic_comma(binary_expression_t *expression)
 {
-       expression->expression.datatype = expression->right->datatype;
+       expression->expression.datatype = expression->right->base.datatype;
 }
 
 #define CREATE_BINEXPR_PARSER(token_type, binexpression_type, sfunc, lr) \
@@ -3899,7 +3909,7 @@ static expression_t *parse_sub_expression(unsigned precedence)
                left = parse_primary_expression();
        }
        assert(left != NULL);
-       left->source_position = source_position;
+       left->base.source_position = source_position;
 
        while(true) {
                if(token.type < 0) {
@@ -3916,7 +3926,7 @@ static expression_t *parse_sub_expression(unsigned precedence)
 
                assert(left != NULL);
                assert(left->type != EXPR_UNKNOWN);
-               left->source_position = source_position;
+               left->base.source_position = source_position;
        }
 
        return left;
@@ -4265,9 +4275,9 @@ static statement_t *parse_continue(void)
        eat(T_continue);
        expect(';');
 
-       statement_t *statement     = allocate_ast_zero(sizeof(statement[0]));
-       statement->type            = STATEMENT_CONTINUE;
-       statement->source_position = token.source_position;
+       statement_t *statement          = allocate_ast_zero(sizeof(statement[0]));
+       statement->type                 = STATEMENT_CONTINUE;
+       statement->base.source_position = token.source_position;
 
        return statement;
 }
@@ -4277,9 +4287,9 @@ static statement_t *parse_break(void)
        eat(T_break);
        expect(';');
 
-       statement_t *statement     = allocate_ast_zero(sizeof(statement[0]));
-       statement->type            = STATEMENT_BREAK;
-       statement->source_position = token.source_position;
+       statement_t *statement          = allocate_ast_zero(sizeof(statement[0]));
+       statement->type                 = STATEMENT_BREAK;
+       statement->base.source_position = token.source_position;
 
        return statement;
 }
@@ -4294,14 +4304,25 @@ static statement_t *parse_return(void)
        statement->statement.source_position = token.source_position;
 
        assert(current_function->type->type == TYPE_FUNCTION);
-       function_type_t *function_type = (function_type_t*) current_function->type;
+       function_type_t *function_type = &current_function->type->function;
        type_t          *return_type   = function_type->result_type;
 
-       expression_t *return_value;
+       expression_t *return_value = NULL;
        if(token.type != ';') {
                return_value = parse_expression();
+       }
+       expect(';');
+
+       if(return_type == NULL)
+               return (statement_t*) statement;
+
+       return_type = skip_typeref(return_type);
 
-               if(return_type == type_void && return_value->datatype != type_void) {
+       if(return_value != NULL) {
+               type_t *return_value_type = skip_typeref(return_value->base.datatype);
+
+               if(is_type_atomic(return_type, ATOMIC_TYPE_VOID)
+                               && !is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) {
                        parse_warning("'return' with a value, in function returning void");
                        return_value = NULL;
                } else {
@@ -4310,16 +4331,13 @@ static statement_t *parse_return(void)
                        }
                }
        } else {
-               return_value = NULL;
-               if(return_type != type_void) {
+               if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
                        parse_warning("'return' without value, in function returning "
                                      "non-void");
                }
        }
        statement->return_value = return_value;
 
-       expect(';');
-
        return (statement_t*) statement;
 }
 
@@ -4456,7 +4474,8 @@ static statement_t *parse_statement(void)
                break;
        }
 
-       assert(statement == NULL || statement->source_position.input_name != NULL);
+       assert(statement == NULL
+                       || statement->base.source_position.input_name != NULL);
 
        return statement;
 }
@@ -4482,13 +4501,13 @@ static statement_t *parse_compound_statement(void)
                        continue;
 
                if(last_statement != NULL) {
-                       last_statement->next = statement;
+                       last_statement->base.next = statement;
                } else {
                        compound_statement->statements = statement;
                }
 
-               while(statement->next != NULL)
-                       statement = statement->next;
+               while(statement->base.next != NULL)
+                       statement = statement->base.next;
 
                last_statement = statement;
        }
diff --git a/type.c b/type.c
index 6c8e25e..5c71465 100644 (file)
--- a/type.c
+++ b/type.c
@@ -588,7 +588,7 @@ type_t *skip_typeref(type_t *type)
                        if(typeof_type->typeof_type != NULL) {
                                type = typeof_type->typeof_type;
                        } else {
-                               type = typeof_type->expression->datatype;
+                               type = typeof_type->expression->base.datatype;
                        }
                        continue;
                }
index 4ad6fc0..4895a36 100644 (file)
@@ -215,12 +215,12 @@ static void write_unary_expression(const unary_expression_t *expression)
 
 static void write_expression(const expression_t *expression)
 {
-       const const_t *constant;
+       const const_expression_t *constant;
        /* TODO */
        switch(expression->type) {
        case EXPR_CONST:
-               constant = (const const_t*) expression;
-               if(is_type_integer(expression->datatype)) {
+               constant = &expression->conste;
+               if(is_type_integer(expression->base.datatype)) {
                        fprintf(out, "%lld", constant->v.int_value);
                } else {
                        fprintf(out, "%Lf", constant->v.float_value);