Alien-TinyCCx

 view release on metacpan or  search on metacpan

src/tccgen.c  view on Meta::CPAN

        size = type_size(&type, &align);
        if (t == TOK_SIZEOF) {
            if (!(type.t & VT_VLA)) {
                if (size < 0)
                    tcc_error("sizeof applied to an incomplete type");
                vpushs(size);
            } else {
                vla_runtime_type_size(&type, &align);
            }
        } else {
            vpushs(align);
        }
        vtop->type.t |= VT_UNSIGNED;
        break;

    case TOK_builtin_expect:
        {
            /* __builtin_expect is a no-op for now */
            int saved_nocode_wanted;
            next();
            skip('(');
            expr_eq();
            skip(',');
            saved_nocode_wanted = nocode_wanted;
            nocode_wanted = 1;
            expr_lor_const();
            vpop();
            nocode_wanted = saved_nocode_wanted;
            skip(')');
        }
        break;
    case TOK_builtin_types_compatible_p:
        {
            CType type1, type2;
            next();
            skip('(');
            parse_type(&type1);
            skip(',');
            parse_type(&type2);
            skip(')');
            type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
            type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
            vpushi(is_compatible_types(&type1, &type2));
        }
        break;
    case TOK_builtin_constant_p:
        {
            int saved_nocode_wanted, res;
            next();
            skip('(');
            saved_nocode_wanted = nocode_wanted;
            nocode_wanted = 1;
            gexpr();
            res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
            vpop();
            nocode_wanted = saved_nocode_wanted;
            skip(')');
            vpushi(res);
        }
        break;
    case TOK_builtin_frame_address:
    case TOK_builtin_return_address:
        {
            int tok1 = tok;
            int level;
            CType type;
            next();
            skip('(');
            if (tok != TOK_CINT) {
                tcc_error("%s only takes positive integers",
                          tok1 == TOK_builtin_return_address ?
                          "__builtin_return_address" :
                          "__builtin_frame_address");
            }
            level = (uint32_t)tokc.i;
            next();
            skip(')');
            type.t = VT_VOID;
            mk_pointer(&type);
            vset(&type, VT_LOCAL, 0);       /* local frame */
            while (level--) {
                mk_pointer(&vtop->type);
                indir();                    /* -> parent frame */
            }
            if (tok1 == TOK_builtin_return_address) {
                // assume return address is just above frame pointer on stack
                vpushi(PTR_SIZE);
                gen_op('+');
                mk_pointer(&vtop->type);
                indir();
            }
        }
        break;
#ifdef TCC_TARGET_X86_64
#ifdef TCC_TARGET_PE
    case TOK_builtin_va_start:
        {
            next();
            skip('(');
            expr_eq();
            skip(',');
            expr_eq();
            skip(')');
            if ((vtop->r & VT_VALMASK) != VT_LOCAL)
                tcc_error("__builtin_va_start expects a local variable");
            vtop->r &= ~(VT_LVAL | VT_REF);
            vtop->type = char_pointer_type;
            vtop->c.i += 8;
            vstore();
        }
        break;
#else
    case TOK_builtin_va_arg_types:
        {
            CType type;
            next();
            skip('(');
            parse_type(&type);
            skip(')');
            vpushi(classify_x86_64_va_arg(&type));
        }
        break;
#endif
#endif

#ifdef TCC_TARGET_ARM64
    case TOK___va_start: {
        if (nocode_wanted)
            tcc_error("statement in global scope");
        next();
        skip('(');
        expr_eq();
        skip(',');
        expr_eq();
        skip(')');
        //xx check types
        gen_va_start();
        vpushi(0);
        vtop->type.t = VT_VOID;
        break;
    }
    case TOK___va_arg: {
        CType type;
        if (nocode_wanted)
            tcc_error("statement in global scope");
        next();

src/tccgen.c  view on Meta::CPAN

        gsym(a);
        gsym_addr(b, d);
    } else if (tok == '{') {
        Sym *llabel;
        int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;

        next();
        /* record local declaration stack position */
        s = local_stack;
        llabel = local_label_stack;
        ++local_scope;
        
        /* handle local labels declarations */
        if (tok == TOK_LABEL) {
            next();
            for(;;) {
                if (tok < TOK_UIDENT)
                    expect("label identifier");
                label_push(&local_label_stack, tok, LABEL_DECLARED);
                next();
                if (tok == ',') {
                    next();
                } else {
                    skip(';');
                    break;
                }
            }
        }
        while (tok != '}') {
            label_or_decl(VT_LOCAL);
            if (tok != '}') {
                if (is_expr)
                    vpop();
                block(bsym, csym, is_expr);
            }
        }
        /* pop locally defined labels */
        label_pop(&local_label_stack, llabel);
        if(is_expr) {
            /* XXX: this solution makes only valgrind happy...
               triggered by gcc.c-torture/execute/20000917-1.c */
            Sym *p;
            switch(vtop->type.t & VT_BTYPE) {
            /* case VT_PTR: */
        	/* this breaks a compilation of the linux kernel v2.4.26 */
        	/* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
        	/* Look a commit a80acab: Display error on statement expressions with complex return type */
        	/* A pointer is not a complex return type */
            case VT_STRUCT:
            case VT_ENUM:
            case VT_FUNC:
                for(p=vtop->type.ref;p;p=p->prev)
                    if(p->prev==s)
                        tcc_error("unsupported expression type");
            }
        }
        /* pop locally defined symbols */
        --local_scope;
        sym_pop(&local_stack, s);
        
        /* Pop VLA frames and restore stack pointer if required */
        if (vlas_in_scope > saved_vlas_in_scope) {
            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
            vla_sp_restore();
        }
        vlas_in_scope = saved_vlas_in_scope;
        
        next();
    } else if (tok == TOK_RETURN) {
        next();
        if (tok != ';') {
            gexpr();
            gen_assign_cast(&func_vt);
#ifdef TCC_TARGET_ARM64
            // Perhaps it would be better to use this for all backends:
            greturn();
#else
            if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
                CType type, ret_type;
                int ret_align, ret_nregs, regsize;
                ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
                                       &ret_align, &regsize);
                if (0 == ret_nregs) {
                    /* if returning structure, must copy it to implicit
                       first pointer arg location */
                    type = func_vt;
                    mk_pointer(&type);
                    vset(&type, VT_LOCAL | VT_LVAL, func_vc);
                    indir();
                    vswap();
                    /* copy structure value to pointer */
                    vstore();
                } else {
                    /* returning structure packed into registers */
                    int r, size, addr, align;
                    size = type_size(&func_vt,&align);
                    if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
                         (vtop->c.i & (ret_align-1)))
                        && (align & (ret_align-1))) {
                        loc = (loc - size) & -ret_align;
                        addr = loc;
                        type = func_vt;
                        vset(&type, VT_LOCAL | VT_LVAL, addr);
                        vswap();
                        vstore();
                        vpop();
                        vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
                    }
                    vtop->type = ret_type;
                    if (is_float(ret_type.t))
                        r = rc_fret(ret_type.t);
                    else
                        r = RC_IRET;

                    if (ret_nregs == 1)
                        gv(r);
                    else {
                        for (;;) {
                            vdup();
                            gv(r);
                            vpop();



( run in 0.585 second using v1.01-cache-2.11-cpan-df04353d9ac )