Adapted cparser to CopyB lowering changes.
[cparser] / ast2firm.c
index 7a33f35..d9cf3f5 100644 (file)
@@ -44,7 +44,7 @@
 #include "types.h"
 #include "type_hash.h"
 #include "mangle.h"
-#include "walk_statements.h"
+#include "walk.h"
 #include "warning.h"
 #include "printer.h"
 #include "entitymap_t.h"
@@ -81,7 +81,6 @@ static label_t  **all_labels;
 static entity_t **inner_functions;
 static ir_node   *ijmp_list;
 static bool       constant_folding;
-static bool       initializer_use_bitfield_basetype;
 
 static const entity_t     *current_function_entity;
 static ir_node            *current_function_name;
@@ -91,8 +90,8 @@ static ir_graph           *current_function;
 static translation_unit_t *current_translation_unit;
 static trampoline_region  *current_trampolines;
 static ir_type            *current_outer_frame;
-static ir_type            *current_outer_value_type;
 static ir_node            *current_static_link;
+static ir_entity          *current_vararg_entity;
 
 static entitymap_t  entitymap;
 
@@ -126,11 +125,9 @@ static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
 {
        const entity_t *entity = get_irg_loc_description(irg, pos);
 
-       if (entity != NULL && warning.uninitialized) {
-               warningf(&entity->base.source_position,
-                        "%s '%#T' might be used uninitialized",
-                        get_entity_kind_name(entity->kind),
-                        entity->declaration.type, entity->base.symbol);
+       if (entity != NULL) {
+               source_position_t const *const pos = &entity->base.source_position;
+               warningf(WARN_UNINITIALIZED, pos, "'%N' might be used uninitialized", entity);
        }
        return new_r_Unknown(irg, mode);
 }
@@ -185,6 +182,15 @@ static ir_node *_expression_to_firm(const expression_t *expression);
 static ir_node *expression_to_firm(const expression_t *expression);
 static void create_local_declaration(entity_t *entity);
 
+static unsigned decide_modulo_shift(unsigned type_size)
+{
+       if (architecture_modulo_shift == 0)
+               return 0;
+       if (type_size < architecture_modulo_shift)
+               return architecture_modulo_shift;
+       return type_size;
+}
+
 static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
 {
        unsigned flags = get_atomic_type_flags(kind);
@@ -195,7 +201,7 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
                ir_mode_sort    sort;
                unsigned        bit_size     = size * 8;
                bool            is_signed    = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0;
-               unsigned        modulo_shift;
+               unsigned        modulo_shift = 0;
                ir_mode_arithmetic arithmetic;
 
                if (flags & ATOMIC_TYPE_FLAG_INTEGER) {
@@ -204,13 +210,12 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
                                 bit_size);
                        sort         = irms_int_number;
                        arithmetic   = irma_twos_complement;
-                       modulo_shift = bit_size < machine_size ? machine_size : bit_size;
+                       modulo_shift = decide_modulo_shift(bit_size);
                } else {
                        assert(flags & ATOMIC_TYPE_FLAG_FLOAT);
                        snprintf(name, sizeof(name), "F%u", bit_size);
                        sort         = irms_float_number;
                        arithmetic   = irma_ieee754;
-                       modulo_shift = 0;
                }
                return new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
                                   modulo_shift);
@@ -232,26 +237,6 @@ static void init_atomic_modes(void)
 
        /* there's no real void type in firm */
        atomic_modes[ATOMIC_TYPE_VOID] = atomic_modes[ATOMIC_TYPE_CHAR];
-
-       /* initialize pointer modes */
-       char            name[64];
-       ir_mode_sort    sort         = irms_reference;
-       unsigned        bit_size     = machine_size;
-       bool            is_signed    = 0;
-       ir_mode_arithmetic arithmetic   = irma_twos_complement;
-       unsigned        modulo_shift
-               = bit_size < machine_size ? machine_size : bit_size;
-
-       snprintf(name, sizeof(name), "p%u", machine_size);
-       ir_mode *ptr_mode = new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
-                                       modulo_shift);
-
-       set_reference_mode_signed_eq(ptr_mode, atomic_modes[get_intptr_kind()]);
-       set_reference_mode_unsigned_eq(ptr_mode, atomic_modes[get_uintptr_kind()]);
-
-       /* Hmm, pointers should be machine size */
-       set_modeP_data(ptr_mode);
-       set_modeP_code(ptr_mode);
 }
 
 ir_mode *get_atomic_mode(atomic_type_kind_t kind)
@@ -321,7 +306,7 @@ static ir_type *create_atomic_type(atomic_type_kind_t akind, const type_t *type)
 /**
  * Creates a Firm type for a complex type
  */
-static ir_type *create_complex_type(const complex_type_t *type)
+static ir_type *create_complex_type(const atomic_type_t *type)
 {
        atomic_type_kind_t  kind = type->akind;
        ir_mode            *mode = atomic_modes[kind];
@@ -336,9 +321,9 @@ static ir_type *create_complex_type(const complex_type_t *type)
 /**
  * Creates a Firm type for an imaginary type
  */
-static ir_type *create_imaginary_type(imaginary_type_t *type)
+static ir_type *create_imaginary_type(const atomic_type_t *type)
 {
-       return create_atomic_type(type->akind, (const type_t*) type);
+       return create_atomic_type(type->akind, (const type_t*)type);
 }
 
 /**
@@ -539,21 +524,20 @@ static ir_type *get_unsigned_int_type_for_bit_size(ir_type *base_tp,
        return res;
 }
 
-static ir_type *create_bitfield_type(bitfield_type_t *const type)
+static ir_type *create_bitfield_type(const entity_t *entity)
 {
-       type_t *base = skip_typeref(type->base_type);
+       assert(entity->kind == ENTITY_COMPOUND_MEMBER);
+       type_t *base = skip_typeref(entity->declaration.type);
        assert(base->kind == TYPE_ATOMIC || base->kind == TYPE_ENUM);
        ir_type *irbase = get_ir_type(base);
 
-       unsigned size = type->bit_size;
+       unsigned bit_size = entity->compound_member.bit_size;
 
        assert(!is_type_float(base));
        if (is_type_signed(base)) {
-               return get_signed_int_type_for_bit_size(irbase, size,
-                                                       (const type_t*) type);
+               return get_signed_int_type_for_bit_size(irbase, bit_size, base);
        } else {
-               return get_unsigned_int_type_for_bit_size(irbase, size,
-                                                         (const type_t*) type);
+               return get_unsigned_int_type_for_bit_size(irbase, bit_size, base);
        }
 }
 
@@ -619,7 +603,7 @@ static ir_type *create_compound_type(compound_type_t *type,
                ident    *ident;
                if (symbol == NULL) {
                        /* anonymous bitfield member, skip */
-                       if (entry_type->kind == TYPE_BITFIELD)
+                       if (entry->compound_member.bitfield)
                                continue;
                        assert(entry_type->kind == TYPE_COMPOUND_STRUCT
                                        || entry_type->kind == TYPE_COMPOUND_UNION);
@@ -630,7 +614,12 @@ static ir_type *create_compound_type(compound_type_t *type,
 
                dbg_info *dbgi       = get_dbg_info(&entry->base.source_position);
 
-               ir_type   *entry_irtype = get_ir_type(entry_type);
+               ir_type *entry_irtype;
+               if (entry->compound_member.bitfield) {
+                       entry_irtype = create_bitfield_type(entry);
+               } else {
+                       entry_irtype = get_ir_type(entry_type);
+               }
                ir_entity *entity = new_d_entity(irtype, ident, entry_irtype, dbgi);
 
                set_entity_offset(entity, entry->compound_member.offset);
@@ -651,7 +640,7 @@ static ir_type *create_compound_type(compound_type_t *type,
 
 static ir_type *create_enum_type(enum_type_t *const type)
 {
-       type->base.firm_type = ir_type_int;
+       type->base.base.firm_type = ir_type_int;
 
        ir_mode   *const mode    = mode_int;
        ir_tarval *const one     = get_mode_one(mode);
@@ -680,7 +669,7 @@ static ir_type *create_enum_type(enum_type_t *const type)
 
        constant_folding = constant_folding_old;
 
-       return create_atomic_type(type->akind, (const type_t*) type);
+       return create_atomic_type(type->base.akind, (const type_t*) type);
 }
 
 static ir_type *get_ir_type_incomplete(type_t *type)
@@ -724,10 +713,10 @@ ir_type *get_ir_type(type_t *type)
                firm_type = create_atomic_type(type->atomic.akind, type);
                break;
        case TYPE_COMPLEX:
-               firm_type = create_complex_type(&type->complex);
+               firm_type = create_complex_type(&type->atomic);
                break;
        case TYPE_IMAGINARY:
-               firm_type = create_imaginary_type(&type->imaginary);
+               firm_type = create_imaginary_type(&type->atomic);
                break;
        case TYPE_FUNCTION:
                firm_type = create_method_type(&type->function, false);
@@ -750,13 +739,9 @@ ir_type *get_ir_type(type_t *type)
        case TYPE_ENUM:
                firm_type = create_enum_type(&type->enumt);
                break;
-       case TYPE_BITFIELD:
-               firm_type = create_bitfield_type(&type->bitfield);
-               break;
 
        case TYPE_TYPEOF:
        case TYPE_TYPEDEF:
-       case TYPE_INVALID:
                break;
        }
        if (firm_type == NULL)
@@ -944,15 +929,16 @@ static bool is_main(entity_t *entity)
 static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
 {
        assert(entity->kind == ENTITY_FUNCTION);
-       if (entity->function.irentity != NULL) {
+       if (entity->function.irentity != NULL)
                return entity->function.irentity;
-       }
 
-       entity_t *original_entity = entity;
-       if (entity->function.btk != bk_none) {
-               entity = get_builtin_replacement(entity);
-               if (entity == NULL)
-                       return NULL;
+       switch (entity->function.btk) {
+       case BUILTIN_NONE:
+       case BUILTIN_LIBC:
+       case BUILTIN_LIBC_CHECK:
+               break;
+       default:
+               return NULL;
        }
 
        if (is_main(entity)) {
@@ -994,7 +980,7 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
                nested_function = true;
 
        dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
-       irentity             = new_d_entity(owner_type, id, ir_type_method, dbgi);
+       irentity = new_d_entity(owner_type, id, ir_type_method, dbgi);
 
        ident *ld_id;
        if (nested_function)
@@ -1064,8 +1050,8 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
        entitymap_insert(&entitymap, symbol, irentity);
 
 entity_created:
-       original_entity->declaration.kind  = DECLARATION_KIND_FUNCTION;
-       original_entity->function.irentity = irentity;
+       entity->declaration.kind  = DECLARATION_KIND_FUNCTION;
+       entity->function.irentity = irentity;
 
        return irentity;
 }
@@ -1210,12 +1196,12 @@ static bool try_create_integer(literal_expression_t *literal,
 
 static void create_integer_tarval(literal_expression_t *literal)
 {
-       unsigned  us     = 0;
-       unsigned  ls     = 0;
-       symbol_t *suffix = literal->suffix;
+       unsigned        us     = 0;
+       unsigned        ls     = 0;
+       const string_t *suffix = &literal->suffix;
        /* parse suffix */
-       if (suffix != NULL) {
-               for (const char *c = suffix->string; *c != '\0'; ++c) {
+       if (suffix->size > 0) {
+               for (const char *c = suffix->begin; *c != '\0'; ++c) {
                        if (*c == 'u' || *c == 'U') { ++us; }
                        if (*c == 'l' || *c == 'L') { ++ls; }
                }
@@ -1299,6 +1285,8 @@ static ir_node *literal_to_firm(const literal_expression_t *literal)
        }
        case EXPR_LITERAL_CHARACTER: {
                long long int v;
+               bool char_is_signed
+                       = get_atomic_type_flags(ATOMIC_TYPE_CHAR) & ATOMIC_TYPE_FLAG_SIGNED;
                if (size == 1 && char_is_signed) {
                        v = (signed char)string[0];
                } else {
@@ -1499,7 +1487,7 @@ static ir_node *get_local_frame(ir_entity *const ent)
 {
        ir_graph      *const irg   = current_ir_graph;
        const ir_type *const owner = get_entity_owner(ent);
-       if (owner == current_outer_frame || owner == current_outer_value_type) {
+       if (owner == current_outer_frame) {
                assert(current_static_link != NULL);
                return current_static_link;
        } else {
@@ -1541,16 +1529,15 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        /* make sure the type is constructed */
        (void) get_ir_type(type);
 
-       if (entity->kind == ENTITY_FUNCTION && entity->function.btk != bk_none) {
+       if (entity->kind == ENTITY_FUNCTION
+           && entity->function.btk != BUILTIN_NONE) {
                ir_entity *irentity = get_function_entity(entity, NULL);
                /* for gcc compatibility we have to produce (dummy) addresses for some
                 * builtins which don't have entities */
                if (irentity == NULL) {
-                       if (warning.other) {
-                               warningf(&ref->base.source_position,
-                                               "taking address of builtin '%Y'",
-                                               ref->entity->base.symbol);
-                       }
+                       source_position_t const *const pos = &ref->base.source_position;
+                       symbol_t          const *const sym = ref->entity->base.symbol;
+                       warningf(WARN_OTHER, pos, "taking address of builtin '%Y'", sym);
 
                        /* simply create a NULL pointer */
                        ir_mode  *mode = get_ir_mode_arithmetic(type_void_ptr);
@@ -1675,72 +1662,6 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        panic("reference to declaration with unknown type found");
 }
 
-/**
- * Generate an unary builtin.
- *
- * @param kind           the builtin kind to generate
- * @param op             the operand
- * @param function_type  the function type for the GNU builtin routine
- * @param db             debug info
- */
-static ir_node *gen_unary_builtin(ir_builtin_kind kind, expression_t *op, type_t *function_type, dbg_info *db)
-{
-       ir_node *in[1];
-       in[0] = expression_to_firm(op);
-
-       ir_type *tp  = get_ir_type(function_type);
-       ir_type *res = get_method_res_type(tp, 0);
-       ir_node *irn = new_d_Builtin(db, get_irg_no_mem(current_ir_graph), 1, in, kind, tp);
-       set_irn_pinned(irn, op_pin_state_floats);
-       return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
-}
-
-/**
- * Generate a pinned unary builtin.
- *
- * @param kind           the builtin kind to generate
- * @param op             the operand
- * @param function_type  the function type for the GNU builtin routine
- * @param db             debug info
- */
-static ir_node *gen_unary_builtin_pinned(ir_builtin_kind kind, expression_t *op,
-                                         type_t *function_type, dbg_info *db)
-{
-       ir_node *in[1];
-       in[0] = expression_to_firm(op);
-
-       ir_type *tp  = get_ir_type(function_type);
-       ir_type *res = get_method_res_type(tp, 0);
-       ir_node *mem = get_store();
-       ir_node *irn = new_d_Builtin(db, mem, 1, in, kind, tp);
-       set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-       return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
-}
-
-/**
- * Generate an binary-void-return builtin.
- *
- * @param kind           the builtin kind to generate
- * @param op1            the first operand
- * @param op2            the second operand
- * @param function_type  the function type for the GNU builtin routine
- * @param db             debug info
- */
-static ir_node *gen_binary_builtin_mem(ir_builtin_kind kind, expression_t *op1,
-                                       expression_t *op2, type_t *function_type,
-                                                                          dbg_info *db)
-{
-       ir_node *in[2];
-       in[0] = expression_to_firm(op1);
-       in[1] = expression_to_firm(op2);
-
-       ir_type *tp  = get_ir_type(function_type);
-       ir_node *mem = get_store();
-       ir_node *irn = new_d_Builtin(db, mem, 2, in, kind, tp);
-       set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-       return NULL;
-}
-
 /**
  * Transform calls to builtin functions.
  */
@@ -1757,10 +1678,9 @@ static ir_node *process_builtin_call(const call_expression_t *call)
        type_t *function_type = skip_typeref(expr_type->pointer.points_to);
 
        switch (builtin->entity->function.btk) {
-       case bk_gnu_builtin_alloca: {
-               if (call->arguments == NULL || call->arguments->next != NULL) {
-                       panic("invalid number of parameters on __builtin_alloca");
-               }
+       case BUILTIN_NONE:
+               break;
+       case BUILTIN_ALLOCA: {
                expression_t *argument = call->arguments->expression;
                ir_node      *size     = expression_to_firm(argument);
 
@@ -1773,22 +1693,14 @@ static ir_node *process_builtin_call(const call_expression_t *call)
 
                return res;
        }
-
-       case bk_gnu_builtin_huge_val:
-       case bk_gnu_builtin_huge_valf:
-       case bk_gnu_builtin_huge_vall:
-       case bk_gnu_builtin_inf:
-       case bk_gnu_builtin_inff:
-       case bk_gnu_builtin_infl: {
+       case BUILTIN_INF: {
                type_t    *type = function_type->function.return_type;
                ir_mode   *mode = get_ir_mode_arithmetic(type);
                ir_tarval *tv   = get_mode_infinite(mode);
                ir_node   *res  = new_d_Const(dbgi, tv);
                return res;
        }
-       case bk_gnu_builtin_nan:
-       case bk_gnu_builtin_nanf:
-       case bk_gnu_builtin_nanl: {
+       case BUILTIN_NAN: {
                /* Ignore string for now... */
                assert(is_type_function(function_type));
                type_t    *type = function_type->function.return_type;
@@ -1797,80 +1709,15 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                ir_node   *res  = new_d_Const(dbgi, tv);
                return res;
        }
-       case bk_gnu_builtin_expect: {
+       case BUILTIN_EXPECT: {
                expression_t *argument = call->arguments->expression;
                return _expression_to_firm(argument);
        }
-       case bk_gnu_builtin_va_end:
+       case BUILTIN_VA_END:
                /* evaluate the argument of va_end for its side effects */
                _expression_to_firm(call->arguments->expression);
                return NULL;
-       case bk_gnu_builtin_frame_address: {
-               expression_t *const expression = call->arguments->expression;
-               bool val = fold_constant_to_bool(expression);
-               if (!val) {
-                       /* the nice case */
-                       return get_irg_frame(current_ir_graph);
-               } else {
-                       /* get the argument */
-                       ir_node *in[2];
-
-                       in[0] = expression_to_firm(expression);
-                       in[1] = get_irg_frame(current_ir_graph);
-                       ir_type *tp  = get_ir_type(function_type);
-                       ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_frame_address, tp);
-                       return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
-               }
-       }
-       case bk_gnu_builtin_return_address: {
-               expression_t *const expression = call->arguments->expression;
-               ir_node *in[2];
-
-               in[0] = expression_to_firm(expression);
-               in[1] = get_irg_frame(current_ir_graph);
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp);
-               return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
-       }
-       case bk_gnu_builtin_ffs:
-                return gen_unary_builtin(ir_bk_ffs,      call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_clz:
-                return gen_unary_builtin(ir_bk_clz,      call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_ctz:
-                return gen_unary_builtin(ir_bk_ctz,      call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_popcount:
-       case bk_ms__popcount:
-                return gen_unary_builtin(ir_bk_popcount, call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_parity:
-                return gen_unary_builtin(ir_bk_parity,   call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_prefetch: {
-               call_argument_t *const args = call->arguments;
-               expression_t *const addr    = args->expression;
-               ir_node *in[3];
-
-               in[0] = _expression_to_firm(addr);
-               if (args->next != NULL) {
-                       expression_t *const rw = args->next->expression;
-
-                       in[1] = _expression_to_firm(rw);
-
-                       if (args->next->next != NULL) {
-                               expression_t *const locality = args->next->next->expression;
-
-                               in[2] = expression_to_firm(locality);
-                       } else {
-                               in[2] = new_Const_long(mode_int, 3);
-                       }
-               } else {
-                       in[1] = new_Const_long(mode_int, 0);
-                       in[2] = new_Const_long(mode_int, 3);
-               }
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), 3, in, ir_bk_prefetch, tp);
-               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-               return NULL;
-       }
-       case bk_gnu_builtin_object_size: {
+       case BUILTIN_OBJECT_SIZE: {
                /* determine value of "type" */
                expression_t *type_expression = call->arguments->next->expression;
                long          type_val        = fold_constant_to_int(type_expression);
@@ -1882,38 +1729,13 @@ static ir_node *process_builtin_call(const call_expression_t *call)
 
                return new_d_Const(dbgi, result);
        }
-       case bk_gnu_builtin_trap:
-       case bk_ms__ud2:
-       {
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), 0, NULL, ir_bk_trap, tp);
-               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-               return NULL;
-       }
-       case bk_ms__debugbreak: {
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), 0, NULL, ir_bk_debugbreak, tp);
-               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-               return NULL;
-       }
-       case bk_ms_ReturnAddress: {
-               ir_node *in[2];
-
-               in[0] = new_Const(get_mode_null(mode_int));
-               in[1] = get_irg_frame(current_ir_graph);
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp);
-               return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
-       }
-       case bk_ms_rotl:
-       case bk_ms_rotl64: {
+       case BUILTIN_ROTL: {
                ir_node *val  = expression_to_firm(call->arguments->expression);
                ir_node *shf  = expression_to_firm(call->arguments->next->expression);
                ir_mode *mode = get_irn_mode(val);
                return new_d_Rotl(dbgi, val, create_conv(dbgi, shf, mode_uint), mode);
        }
-       case bk_ms_rotr:
-       case bk_ms_rotr64: {
+       case BUILTIN_ROTR: {
                ir_node *val  = expression_to_firm(call->arguments->expression);
                ir_node *shf  = expression_to_firm(call->arguments->next->expression);
                ir_mode *mode = get_irn_mode(val);
@@ -1921,22 +1743,13 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                ir_node *sub  = new_d_Sub(dbgi, c, create_conv(dbgi, shf, mode_uint), mode_uint);
                return new_d_Rotl(dbgi, val, sub, mode);
        }
-       case bk_ms_byteswap_ushort:
-       case bk_ms_byteswap_ulong:
-       case bk_ms_byteswap_uint64:
-               return gen_unary_builtin(ir_bk_bswap, call->arguments->expression, function_type, dbgi);
-       case bk_ms__inbyte:
-       case bk_ms__inword:
-       case bk_ms__indword:
-               return gen_unary_builtin_pinned(ir_bk_inport, call->arguments->expression, function_type, dbgi);
-       case bk_ms__outbyte:
-       case bk_ms__outword:
-       case bk_ms__outdword:
-               return gen_binary_builtin_mem(ir_bk_outport, call->arguments->expression,
-                       call->arguments->next->expression, function_type, dbgi);
-       default:
-               panic("unsupported builtin found");
+       case BUILTIN_FIRM:
+               break;
+       case BUILTIN_LIBC:
+       case BUILTIN_LIBC_CHECK:
+               panic("builtin did not produce an entity");
        }
+       panic("invalid builtin found");
 }
 
 /**
@@ -1951,42 +1764,27 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
        dbg_info *const dbgi = get_dbg_info(&call->base.source_position);
        assert(currently_reachable());
 
-       expression_t *function = call->function;
+       expression_t   *function = call->function;
+       ir_node        *callee   = NULL;
+       bool            firm_builtin = false;
+       ir_builtin_kind firm_builtin_kind = ir_bk_trap;
        if (function->kind == EXPR_REFERENCE) {
                const reference_expression_t *ref    = &function->reference;
                entity_t                     *entity = ref->entity;
 
                if (entity->kind == ENTITY_FUNCTION) {
-                       ir_entity *irentity = entity->function.irentity;
-                       if (irentity == NULL)
-                               irentity = get_function_entity(entity, NULL);
-
-                       if (irentity == NULL && entity->function.btk != bk_none) {
+                       builtin_kind_t builtin = entity->function.btk;
+                       if (builtin == BUILTIN_FIRM) {
+                               firm_builtin = true;
+                               firm_builtin_kind = entity->function.b.firm_builtin_kind;
+                       } else if (builtin != BUILTIN_NONE && builtin != BUILTIN_LIBC
+                                  && builtin != BUILTIN_LIBC_CHECK) {
                                return process_builtin_call(call);
                        }
-
-#if 0
-                       if (irentity == rts_entities[rts_alloca]) {
-                               /* handle alloca() call */
-                               expression_t *argument = call->arguments->expression;
-                               ir_node      *size     = expression_to_firm(argument);
-                               ir_mode      *mode     = get_ir_mode_arithmetic(type_size_t);
-
-                               size = create_conv(dbgi, size, mode);
-
-                               ir_node  *store  = get_store();
-                               ir_node  *alloca = new_d_Alloc(dbgi, store, size,
-                                                              firm_unknown_type, stack_alloc);
-                               ir_node  *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M);
-                               set_store(proj_m);
-                               ir_node  *res    = new_Proj(alloca, mode_P_data, pn_Alloc_res);
-
-                               return res;
-                       }
-#endif
                }
        }
-       ir_node *callee = expression_to_firm(function);
+       if (!firm_builtin)
+               callee = expression_to_firm(function);
 
        type_t *type = skip_typeref(function->base.type);
        assert(is_type_pointer(type));
@@ -1995,7 +1793,7 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
        assert(is_type_function(points_to));
        function_type_t *function_type = &points_to->function;
 
-       int      n_parameters = 0;
+       int      n_parameters    = 0;
        ir_type *ir_method_type  = get_ir_type((type_t*) function_type);
        ir_type *new_method_type = NULL;
        if (function_type->variadic || function_type->unspecified_parameters) {
@@ -2050,26 +1848,50 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                argument = argument->next;
        }
 
-       ir_node  *store = get_store();
-       ir_node  *node  = new_d_Call(dbgi, store, callee, n_parameters, in,
-                                    ir_method_type);
-       ir_node  *mem   = new_d_Proj(dbgi, node, mode_M, pn_Call_M);
-       set_store(mem);
+       ir_node *store;
+       if (function_type->modifiers & DM_CONST) {
+               store = get_irg_no_mem(current_ir_graph);
+       } else {
+               store = get_store();
+       }
 
+       ir_node *node;
        type_t  *return_type = skip_typeref(function_type->return_type);
        ir_node *result      = NULL;
+       if (firm_builtin) {
+               node = new_d_Builtin(dbgi, store, n_parameters, in, firm_builtin_kind,
+                                    ir_method_type);
+               if (! (function_type->modifiers & DM_CONST)) {
+                       ir_node *mem = new_Proj(node, mode_M, pn_Builtin_M);
+                       set_store(mem);
+               }
 
-       if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
-               ir_node *resproj = new_d_Proj(dbgi, node, mode_T, pn_Call_T_result);
-
-               if (is_type_scalar(return_type)) {
-                       ir_mode *mode       = get_ir_mode_storage(return_type);
-                       result              = new_d_Proj(dbgi, resproj, mode, 0);
+               if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+                       assert(is_type_scalar(return_type));
+                       ir_mode *mode = get_ir_mode_storage(return_type);
+                       result = new_Proj(node, mode, pn_Builtin_1_result);
                        ir_mode *mode_arith = get_ir_mode_arithmetic(return_type);
                        result              = create_conv(NULL, result, mode_arith);
-               } else {
-                       ir_mode *mode = mode_P_data;
-                       result        = new_d_Proj(dbgi, resproj, mode, 0);
+               }
+       } else {
+               node = new_d_Call(dbgi, store, callee, n_parameters, in, ir_method_type);
+               if (! (function_type->modifiers & DM_CONST)) {
+                       ir_node *mem = new_Proj(node, mode_M, pn_Call_M);
+                       set_store(mem);
+               }
+
+               if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+                       ir_node *resproj = new_Proj(node, mode_T, pn_Call_T_result);
+
+                       if (is_type_scalar(return_type)) {
+                               ir_mode *mode       = get_ir_mode_storage(return_type);
+                               result              = new_Proj(resproj, mode, 0);
+                               ir_mode *mode_arith = get_ir_mode_arithmetic(return_type);
+                               result              = create_conv(NULL, result, mode_arith);
+                       } else {
+                               ir_mode *mode = mode_P_data;
+                               result        = new_Proj(resproj, mode, 0);
+                       }
                }
        }
 
@@ -2152,9 +1974,8 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
        value = create_conv(dbgi, value, mode);
 
        /* kill upper bits of value and shift to right position */
-       int      bitoffset    = get_entity_offset_bits_remainder(entity);
-       int      bitsize      = get_mode_size_bits(get_type_mode(entity_type));
-
+       int        bitoffset       = get_entity_offset_bits_remainder(entity);
+       int        bitsize         = get_mode_size_bits(get_type_mode(entity_type));
        ir_tarval *mask            = create_bitfield_mask(mode, 0, bitsize);
        ir_node   *mask_node       = new_d_Const(dbgi, mask);
        ir_node   *value_masked    = new_d_And(dbgi, value, mask_node, mode);
@@ -2184,44 +2005,51 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
 }
 
 static ir_node *bitfield_extract_to_firm(const select_expression_t *expression,
-               ir_node *addr)
-{
-       dbg_info *dbgi     = get_dbg_info(&expression->base.source_position);
-       type_t   *type     = expression->base.type;
-       ir_mode  *mode     = get_ir_mode_storage(type);
-       ir_node  *mem      = get_store();
-       ir_node  *load     = new_d_Load(dbgi, mem, addr, mode, cons_none);
-       ir_node  *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
-       ir_node  *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res);
-
-       load_res           = create_conv(dbgi, load_res, mode_int);
+                                         ir_node *addr)
+{
+       dbg_info *dbgi      = get_dbg_info(&expression->base.source_position);
+       entity_t *entity    = expression->compound_entry;
+       type_t   *base_type = entity->declaration.type;
+       ir_mode  *mode      = get_ir_mode_storage(base_type);
+       ir_node  *mem       = get_store();
+       ir_node  *load      = new_d_Load(dbgi, mem, addr, mode, cons_none);
+       ir_node  *load_mem  = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
+       ir_node  *load_res  = new_d_Proj(dbgi, load, mode, pn_Load_res);
+
+       ir_mode  *amode     = mode;
+       /* optimisation, since shifting in modes < machine_size is usually
+        * less efficient */
+       if (get_mode_size_bits(amode) < get_mode_size_bits(mode_uint)) {
+               amode = mode_uint;
+       }
+       unsigned amode_size = get_mode_size_bits(amode);
+       load_res = create_conv(dbgi, load_res, amode);
 
        set_store(load_mem);
 
        /* kill upper bits */
        assert(expression->compound_entry->kind == ENTITY_COMPOUND_MEMBER);
-       ir_entity *entity       = expression->compound_entry->compound_member.entity;
-       int        bitoffset    = get_entity_offset_bits_remainder(entity);
-       ir_type   *entity_type  = get_entity_type(entity);
-       int        bitsize      = get_mode_size_bits(get_type_mode(entity_type));
-       long       shift_bitsl  = machine_size - bitoffset - bitsize;
-       assert(shift_bitsl >= 0);
-       ir_tarval *tvl          = new_tarval_from_long(shift_bitsl, mode_uint);
-       ir_node   *countl       = new_d_Const(dbgi, tvl);
-       ir_node   *shiftl       = new_d_Shl(dbgi, load_res, countl, mode_int);
-
-       long       shift_bitsr  = bitoffset + shift_bitsl;
-       assert(shift_bitsr <= (long) machine_size);
-       ir_tarval *tvr          = new_tarval_from_long(shift_bitsr, mode_uint);
-       ir_node   *countr       = new_d_Const(dbgi, tvr);
+       int        bitoffset   = entity->compound_member.bit_offset;
+       int        bitsize     = entity->compound_member.bit_size;
+       unsigned   shift_bitsl = amode_size - bitoffset - bitsize;
+       ir_tarval *tvl         = new_tarval_from_long((long)shift_bitsl, mode_uint);
+       ir_node   *countl      = new_d_Const(dbgi, tvl);
+       ir_node   *shiftl      = new_d_Shl(dbgi, load_res, countl, amode);
+
+       unsigned   shift_bitsr = bitoffset + shift_bitsl;
+       assert(shift_bitsr <= amode_size);
+       ir_tarval *tvr         = new_tarval_from_long((long)shift_bitsr, mode_uint);
+       ir_node   *countr      = new_d_Const(dbgi, tvr);
        ir_node   *shiftr;
        if (mode_is_signed(mode)) {
-               shiftr = new_d_Shrs(dbgi, shiftl, countr, mode_int);
+               shiftr = new_d_Shrs(dbgi, shiftl, countr, amode);
        } else {
-               shiftr = new_d_Shr(dbgi, shiftl, countr, mode_int);
+               shiftr = new_d_Shr(dbgi, shiftl, countr, amode);
        }
 
-       return create_conv(dbgi, shiftr, mode);
+       type_t  *type    = expression->base.type;
+       ir_mode *resmode = get_ir_mode_arithmetic(type);
+       return create_conv(dbgi, shiftr, resmode);
 }
 
 /* make sure the selected compound type is constructed */
@@ -2272,7 +2100,7 @@ static ir_node *set_value_for_expression_addr(const expression_t *expression,
 
                entity_t *entity = select->compound_entry;
                assert(entity->kind == ENTITY_COMPOUND_MEMBER);
-               if (entity->declaration.type->kind == TYPE_BITFIELD) {
+               if (entity->compound_member.bitfield) {
                        ir_entity *irentity = entity->compound_member.entity;
                        bool       set_volatile
                                = select->base.type->base.qualifiers & TYPE_QUALIFIER_VOLATILE;
@@ -2325,7 +2153,7 @@ static ir_node *get_value_from_lvalue(const expression_t *expression,
 
        ir_node *value;
        if (expression->kind == EXPR_SELECT &&
-           expression->select.compound_entry->declaration.type->kind == TYPE_BITFIELD){
+           expression->select.compound_entry->compound_member.bitfield) {
            construct_select_compound(&expression->select);
                value = bitfield_extract_to_firm(&expression->select, addr);
        } else {
@@ -2597,7 +2425,6 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
        case EXPR_UNARY_PREFIX_INCREMENT:
        case EXPR_UNARY_PREFIX_DECREMENT:
                return create_incdec(expression);
-       case EXPR_UNARY_CAST_IMPLICIT:
        case EXPR_UNARY_CAST: {
                ir_node *value_node = expression_to_firm(value);
                type_t  *from_type  = value->base.type;
@@ -3109,9 +2936,17 @@ static ir_tarval *fold_constant_to_tarval(const expression_t *expression)
        return get_Const_tarval(cnst);
 }
 
+/* this function is only used in parser.c, but it relies on libfirm functionality */
+bool constant_is_negative(const expression_t *expression)
+{
+       assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT);
+       ir_tarval *tv = fold_constant_to_tarval(expression);
+       return tarval_is_negative(tv);
+}
+
 long fold_constant_to_int(const expression_t *expression)
 {
-       if (expression->kind == EXPR_INVALID)
+       if (expression->kind == EXPR_ERROR)
                return 0;
 
        ir_tarval *tv = fold_constant_to_tarval(expression);
@@ -3124,7 +2959,7 @@ long fold_constant_to_int(const expression_t *expression)
 
 bool fold_constant_to_bool(const expression_t *expression)
 {
-       if (expression->kind == EXPR_INVALID)
+       if (expression->kind == EXPR_ERROR)
                return false;
        ir_tarval *tv = fold_constant_to_tarval(expression);
        return !tarval_is_null(tv);
@@ -3227,11 +3062,10 @@ static ir_node *select_to_firm(const select_expression_t *expression)
                        (const expression_t*) expression);
        type           = skip_typeref(type);
 
-       entity_t *entry      = expression->compound_entry;
+       entity_t *entry = expression->compound_entry;
        assert(entry->kind == ENTITY_COMPOUND_MEMBER);
-       type_t   *entry_type = skip_typeref(entry->declaration.type);
 
-       if (entry_type->kind == TYPE_BITFIELD) {
+       if (entry->compound_member.bitfield) {
                return bitfield_extract_to_firm(expression, addr);
        }
 
@@ -3313,7 +3147,6 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
 
                        case TYPE_COMPLEX:         tc = complex_type_class; goto make_const;
                        case TYPE_IMAGINARY:       tc = complex_type_class; goto make_const;
-                       case TYPE_BITFIELD:        tc = integer_type_class; goto make_const;
                        case TYPE_ARRAY:           /* gcc handles this as pointer */
                        case TYPE_FUNCTION:        /* gcc handles this as pointer */
                        case TYPE_POINTER:         tc = pointer_type_class; goto make_const;
@@ -3329,7 +3162,6 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
                        /* typedef/typeof should be skipped already */
                        case TYPE_TYPEDEF:
                        case TYPE_TYPEOF:
-                       case TYPE_INVALID:
                        case TYPE_ERROR:
                                break;
                }
@@ -3380,25 +3212,21 @@ static ir_node *statement_expression_to_firm(const statement_expression_t *expr)
 static ir_node *va_start_expression_to_firm(
        const va_start_expression_t *const expr)
 {
-       type_t    *const type        = current_function_entity->declaration.type;
-       ir_type   *const method_type = get_ir_type(type);
-       int        const n           = get_method_n_params(method_type) - 1;
-       ir_entity *const parm_ent    = get_method_value_param_ent(method_type, n);
-       ir_node   *const frame       = get_irg_frame(current_ir_graph);
-       dbg_info  *const dbgi        = get_dbg_info(&expr->base.source_position);
-       ir_node   *const no_mem      = new_NoMem();
-       ir_node   *const arg_sel     =
-               new_d_simpleSel(dbgi, no_mem, frame, parm_ent);
-
-       type_t    *const param_type  = expr->parameter->base.type;
-       ir_node   *const cnst        = get_type_size_node(param_type);
-       ir_mode   *const mode        = get_irn_mode(cnst);
-       ir_node   *const c1          = new_Const_long(mode, stack_param_align - 1);
-       ir_node   *const c2          = new_d_Add(dbgi, cnst, c1, mode);
-       ir_node   *const c3          = new_Const_long(mode, -(long)stack_param_align);
-       ir_node   *const c4          = new_d_And(dbgi, c2, c3, mode);
-       ir_node   *const add         = new_d_Add(dbgi, arg_sel, c4, mode_P_data);
-       set_value_for_expression(expr->ap, add);
+       ir_entity *param_ent = current_vararg_entity;
+       if (param_ent == NULL) {
+               size_t   const n           = IR_VA_START_PARAMETER_NUMBER;
+               ir_type *const frame_type  = get_irg_frame_type(current_ir_graph);
+               ir_type *const param_type  = get_unknown_type();
+               param_ent = new_parameter_entity(frame_type, n, param_type);
+               current_vararg_entity = param_ent;
+       }
+
+       ir_node  *const frame   = get_irg_frame(current_ir_graph);
+       dbg_info *const dbgi    = get_dbg_info(&expr->base.source_position);
+       ir_node  *const no_mem  = new_NoMem();
+       ir_node  *const arg_sel = new_d_simpleSel(dbgi, no_mem, frame, param_ent);
+
+       set_value_for_expression(expr->ap, arg_sel);
 
        return NULL;
 }
@@ -3518,6 +3346,12 @@ static ir_node *label_address_to_firm(const label_address_expression_t *label)
        return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
 }
 
+static ir_node *error_to_firm(const expression_t *expression)
+{
+       ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
+       return new_Bad(mode);
+}
+
 /**
  * creates firm nodes for an expression. The difference between this function
  * and expression_to_firm is, that this version might produce mode_b nodes
@@ -3583,9 +3417,8 @@ static ir_node *_expression_to_firm(const expression_t *expression)
        case EXPR_LABEL_ADDRESS:
                return label_address_to_firm(&expression->label_address);
 
-       case EXPR_UNKNOWN:
-       case EXPR_INVALID:
-               break;
+       case EXPR_ERROR:
+               return error_to_firm(expression);
        }
        panic("invalid expression found");
 }
@@ -3603,7 +3436,7 @@ static bool is_builtin_expect(const expression_t *expression)
                return false;
        reference_expression_t *ref = &function->reference;
        if (ref->entity->kind         != ENTITY_FUNCTION ||
-           ref->entity->function.btk != bk_gnu_builtin_expect)
+           ref->entity->function.btk != BUILTIN_EXPECT)
                return false;
 
        return true;
@@ -4034,15 +3867,6 @@ static ir_initializer_t *create_ir_initializer_value(
        }
        type_t       *type = initializer->value->base.type;
        expression_t *expr = initializer->value;
-       if (initializer_use_bitfield_basetype) {
-               type_t *skipped = skip_typeref(type);
-               if (skipped->kind == TYPE_BITFIELD) {
-                       /* remove the bitfield cast... */
-                       assert(expr->kind == EXPR_UNARY_CAST_IMPLICIT);
-                       expr = expr->unary.value;
-                       type = skipped->bitfield.base_type;
-               }
-       }
        ir_node *value = expression_to_firm(expr);
        ir_mode *mode  = get_ir_mode_storage(type);
        value          = create_conv(NULL, value, mode);
@@ -4377,13 +4201,8 @@ static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi,
        }
 
        if (is_constant_initializer(initializer) == EXPR_CLASS_VARIABLE) {
-               bool old_initializer_use_bitfield_basetype
-                       = initializer_use_bitfield_basetype;
-               initializer_use_bitfield_basetype = true;
                ir_initializer_t *irinitializer
                        = create_ir_initializer(initializer, type);
-               initializer_use_bitfield_basetype
-                       = old_initializer_use_bitfield_basetype;
 
                create_dynamic_initializer(irinitializer, dbgi, entity);
                return;
@@ -5294,20 +5113,19 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
                asm_constraint_flags_t asm_flags
                        = be_parse_asm_constraints(constraints);
 
-               if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
-                       warningf(&statement->base.source_position,
-                              "some constraints in '%s' are not supported", constraints);
-               }
-               if (asm_flags & ASM_CONSTRAINT_FLAG_INVALID) {
-                       errorf(&statement->base.source_position,
-                              "some constraints in '%s' are invalid", constraints);
-                       continue;
-               }
-               if (! (asm_flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE)) {
-                       errorf(&statement->base.source_position,
-                              "no write flag specified for output constraints '%s'",
-                              constraints);
-                       continue;
+               {
+                       source_position_t const *const pos = &statement->base.source_position;
+                       if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
+                               warningf(WARN_OTHER, pos, "some constraints in '%s' are not supported", constraints);
+                       }
+                       if (asm_flags & ASM_CONSTRAINT_FLAG_INVALID) {
+                               errorf(pos, "some constraints in '%s' are invalid", constraints);
+                               continue;
+                       }
+                       if (! (asm_flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE)) {
+                               errorf(pos, "no write flag specified for output constraints '%s'", constraints);
+                               continue;
+                       }
                }
 
                unsigned pos = next_pos++;
@@ -5480,7 +5298,8 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
 static void ms_try_statement_to_firm(ms_try_statement_t *statement)
 {
        statement_to_firm(statement->try_statement);
-       warningf(&statement->base.source_position, "structured exception handling ignored");
+       source_position_t const *const pos = &statement->base.source_position;
+       warningf(WARN_OTHER, pos, "structured exception handling ignored");
 }
 
 static void leave_statement_to_firm(leave_statement_t *statement)
@@ -5499,8 +5318,8 @@ static void statement_to_firm(statement_t *statement)
 #endif
 
        switch (statement->kind) {
-       case STATEMENT_INVALID:
-               panic("invalid statement found");
+       case STATEMENT_ERROR:
+               panic("error statement found");
        case STATEMENT_EMPTY:
                /* nothing */
                return;
@@ -5629,16 +5448,23 @@ static void initialize_function_parameters(entity_t *entity)
        assert(entity->kind == ENTITY_FUNCTION);
        ir_graph *irg             = current_ir_graph;
        ir_node  *args            = get_irg_args(irg);
-       ir_type  *function_irtype = get_ir_type(entity->declaration.type);
-       int      first_param_nr   = 0;
+       int       n               = 0;
+       ir_type  *function_irtype;
 
        if (entity->function.need_closure) {
                /* add an extra parameter for the static link */
                entity->function.static_link = new_r_Proj(args, mode_P_data, 0);
-               ++first_param_nr;
+               ++n;
+
+               /* Matze: IMO this is wrong, nested functions should have an own
+                * type and not rely on strange parameters... */
+               function_irtype = create_method_type(&entity->declaration.type->function, true);
+       } else {
+               function_irtype = get_ir_type(entity->declaration.type);
        }
 
-       int       n         = 0;
+
+
        entity_t *parameter = entity->function.parameters.entities;
        for ( ; parameter != NULL; parameter = parameter->base.next, ++n) {
                if (parameter->kind != ENTITY_PARAMETER)
@@ -5653,22 +5479,20 @@ static void initialize_function_parameters(entity_t *entity)
                        needs_entity = true;
                }
 
+               ir_type *param_irtype = get_method_param_type(function_irtype, n);
                if (needs_entity) {
-                       ir_entity *param = get_method_value_param_ent(function_irtype, n);
-                       ident     *id    = new_id_from_str(parameter->base.symbol->string);
-                       set_entity_ident(param, id);
-
+                       ir_type   *frame_type = get_irg_frame_type(irg);
+                       ir_entity *param
+                               = new_parameter_entity(frame_type, n, param_irtype);
                        parameter->declaration.kind
                                = DECLARATION_KIND_PARAMETER_ENTITY;
                        parameter->parameter.v.entity = param;
                        continue;
                }
 
-               ir_type *param_irtype = get_method_param_type(function_irtype, n);
-               ir_mode *param_mode   = get_type_mode(param_irtype);
-
-               long     pn    = n + first_param_nr;
-               ir_node *value = new_r_Proj(args, param_mode, pn);
+               ir_mode *param_mode = get_type_mode(param_irtype);
+               long     pn         = n;
+               ir_node *value      = new_r_Proj(args, param_mode, pn);
 
                ir_mode *mode = get_ir_mode_storage(type);
                value = create_conv(NULL, value, mode);
@@ -5802,6 +5626,9 @@ static void create_function(entity_t *entity)
        ir_graph *old_current_function = current_function;
        current_function = irg;
 
+       ir_entity *const old_current_vararg_entity = current_vararg_entity;
+       current_vararg_entity = NULL;
+
        set_irg_fp_model(irg, firm_fp_model);
        tarval_enable_fp_ops(1);
        set_irn_dbg_info(get_irg_start_block(irg),
@@ -5865,9 +5692,8 @@ static void create_function(entity_t *entity)
        if (has_computed_gotos) {
                /* if we have computed goto's in the function, we cannot inline it */
                if (get_irg_inline_property(irg) >= irg_inline_recomended) {
-                       warningf(&entity->base.source_position,
-                                "function '%Y' can never be inlined because it contains a computed goto",
-                                entity->base.symbol);
+                       source_position_t const *const pos = &entity->base.source_position;
+                       warningf(WARN_OTHER, pos, "'%N' can never be inlined because it contains a computed goto", entity);
                }
                set_irg_inline_property(irg, irg_inline_forbidden);
        }
@@ -5907,7 +5733,8 @@ static void create_function(entity_t *entity)
        set_type_alignment_bytes(frame_type, align_all);
 
        irg_verify(irg, VERIFY_ENFORCE_SSA);
-       current_function = old_current_function;
+       current_vararg_entity = old_current_vararg_entity;
+       current_function      = old_current_function;
 
        if (current_trampolines != NULL) {
                DEL_ARR_F(current_trampolines);
@@ -5919,14 +5746,11 @@ static void create_function(entity_t *entity)
        if (inner != NULL) {
                ir_type *rem_outer_frame      = current_outer_frame;
                current_outer_frame           = get_irg_frame_type(current_ir_graph);
-               ir_type *rem_outer_value_type = current_outer_value_type;
-               current_outer_value_type      = get_irg_value_param_type(current_ir_graph);
                for (int i = ARR_LEN(inner) - 1; i >= 0; --i) {
                        create_function(inner[i]);
                }
                DEL_ARR_F(inner);
 
-               current_outer_value_type = rem_outer_value_type;
                current_outer_frame      = rem_outer_frame;
        }
 }
@@ -5940,7 +5764,7 @@ static void scope_to_firm(scope_t *scope)
                        continue;
 
                if (entity->kind == ENTITY_FUNCTION) {
-                       if (entity->function.btk != bk_none) {
+                       if (entity->function.btk != BUILTIN_NONE) {
                                /* builtins have no representation */
                                continue;
                        }
@@ -5959,7 +5783,7 @@ static void scope_to_firm(scope_t *scope)
                        continue;
 
                if (entity->kind == ENTITY_FUNCTION) {
-                       if (entity->function.btk != bk_none) {
+                       if (entity->function.btk != BUILTIN_NONE) {
                                /* builtins have no representation */
                                continue;
                        }