Esempio n. 1
0
File: msc.c Progetto: shoo/dmd
elem *exp2_copytotemp(elem *e)
{
    //printf("exp2_copytotemp()\n");
    elem_debug(e);
    Symbol *stmp = symbol_genauto(e);
    elem *eeq = el_bin(OPeq,e->Ety,el_var(stmp),e);
    elem *er = el_bin(OPcomma,e->Ety,eeq,el_var(stmp));
    if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray)
    {
        eeq->Eoper = OPstreq;
        eeq->ET = e->ET;
        eeq->E1->ET = e->ET;
        er->ET = e->ET;
        er->E2->ET = e->ET;
    }
    return er;
}
Esempio n. 2
0
File: type.c Progetto: michelf/dmd
elem *type_vla_fix(type **pt)
{
    type *t;
    elem *e = NULL;

    for (t = *pt; t; t = t->Tnext)
    {
        type_debug(t);
        if (tybasic(t->Tty) == TYarray && t->Tflags & TFvla && t->Tel)
        {   symbol *s;
            elem *ec;

            s = symbol_genauto(tsuns);
            ec = el_var(s);
            ec = el_bint(OPeq, tsuns, ec, t->Tel);
            e = el_combine(e, ec);
            t->Tel = el_var(s);
        }
    }
    return e;
}
Esempio n. 3
0
File: ee.c Progetto: DinrusGroup/DRC
void eecontext_parse()
{
    if (eecontext.EEimminent)
    {   type *t;
        unsigned marksi;
        symbol *s;

        //printf("imminent\n");
        marksi = globsym.top;
        eecontext.EEin++;
        s = symbol_genauto(tspvoid);
        eecontext.EEelem = func_expr_dtor(TRUE);
        t = eecontext.EEelem->ET;
        if (tybasic(t->Tty) != TYvoid)
        {   unsigned op;
            elem *e;

            e = el_unat(OPind,t,el_var(s));
            op = tyaggregate(t->Tty) ? OPstreq : OPeq;
            eecontext.EEelem = el_bint(op,t,e,eecontext.EEelem);
        }
        eecontext.EEin--;
        eecontext.EEimminent = 0;
        eecontext.EEfunc = funcsym_p;

        eecontext_convs(marksi);

        // Generate the typedef
        if (eecontext.EEtypedef && config.fulltypes)
        {   symbol *s;

            s = symbol_name(eecontext.EEtypedef,SCtypedef,t);
            cv_outsym(s);
            symbol_free(s);
        }
    }
}
Esempio n. 4
0
File: s2ir.c Progetto: Faianca/dmd
    void visit(TryCatchStatement *s)
    {
        Blockx *blx = irs->blx;

#if SEH
        if (!global.params.is64bit)
            nteh_declarvars(blx);
#endif

        IRState mystate(irs, s);

        block *tryblock = block_goto(blx,BCgoto,NULL);

        int previndex = blx->scope_index;
        tryblock->Blast_index = previndex;
        blx->scope_index = tryblock->Bscope_index = blx->next_index++;

        // Set the current scope index
        setScopeIndex(blx,tryblock,tryblock->Bscope_index);

        // This is the catch variable
        tryblock->jcatchvar = symbol_genauto(type_fake(mTYvolatile | TYnptr));

        blx->tryblock = tryblock;
        block *breakblock = block_calloc(blx);
        block_goto(blx,BC_try,NULL);
        if (s->_body)
        {
            Statement_toIR(s->_body, &mystate);
        }
        blx->tryblock = tryblock->Btry;

        // break block goes here
        block_goto(blx, BCgoto, breakblock);

        setScopeIndex(blx,blx->curblock, previndex);
        blx->scope_index = previndex;

        // create new break block that follows all the catches
        breakblock = block_calloc(blx);

        blx->curblock->appendSucc(breakblock);
        block_next(blx,BCgoto,NULL);

        assert(s->catches);
        for (size_t i = 0 ; i < s->catches->dim; i++)
        {
            Catch *cs = (*s->catches)[i];
            if (cs->var)
                cs->var->csym = tryblock->jcatchvar;
            block *bcatch = blx->curblock;
            if (cs->type)
                bcatch->Bcatchtype = toSymbol(cs->type->toBasetype());
            tryblock->appendSucc(bcatch);
            block_goto(blx, BCjcatch, NULL);
            if (cs->handler != NULL)
            {
                IRState catchState(irs, s);

                /* Append to block:
                 *   *(sclosure + cs.offset) = cs;
                 */
                if (cs->var && cs->var->offset)
                {
                    tym_t tym = totym(cs->var->type);
                    elem *ex = el_var(irs->sclosure);
                    ex = el_bin(OPadd, TYnptr, ex, el_long(TYsize_t, cs->var->offset));
                    ex = el_una(OPind, tym, ex);
                    ex = el_bin(OPeq, tym, ex, el_var(toSymbol(cs->var)));
                    block_appendexp(catchState.blx->curblock, ex);
                }
                Statement_toIR(cs->handler, &catchState);
            }
            blx->curblock->appendSucc(breakblock);
            block_next(blx, BCgoto, NULL);
        }

        block_next(blx,(enum BC)blx->curblock->BC, breakblock);
    }
Esempio n. 5
0
File: s2ir.c Progetto: Rayerd/dmd
void ForeachRangeStatement::toIR(IRState *irs)
{
    assert(0);
#if 0
    Type *tab;
    elem *eaggr;
    elem *elwr;
    elem *eupr;
    elem *e;
    elem *elength;
    tym_t keytym;

    //printf("ForeachStatement::toIR()\n");
    block *bpre;
    block *bcond;
    block *bbody;
    block *bbodyx;
    Blockx *blx = irs->blx;

    IRState mystate(irs,this);
    mystate.breakBlock = block_calloc(blx);
    mystate.contBlock = block_calloc(blx);

    incUsage(irs, lwr->loc);
    elwr = lwr->toElem(irs);

    incUsage(irs, upr->loc);
    eupr = upr->toElem(irs);

    /* Create skey, the index to the array.
     * Initialize skey to elwr (foreach) or eupr (foreach_reverse).
     */
    Symbol *skey = key->toSymbol();
    symbol_add(skey);
    keytym = key->type->totym();

    elem *ekey;
    if (key->offset)            // if key is member of a closure
    {
        assert(irs->sclosure);
        ekey = el_var(irs->sclosure);
        ekey = el_bin(OPadd, TYnptr, ekey, el_long(TYint, key->offset));
        ekey = el_una(OPind, keytym, ekey);
    }
    else
        ekey = el_var(skey);

    elem *einit = (op == TOKforeach_reverse) ? eupr : elwr;
    e = el_bin(OPeq, keytym, ekey, einit);   // skey = einit;
    block_appendexp(blx->curblock, e);

    /* Make a copy of the end condition, so it only
     * gets evaluated once.
     */
    elem *eend = (op == TOKforeach_reverse) ? elwr : eupr;
    Symbol *send = symbol_genauto(eend);
    e = el_bin(OPeq, eend->Ety, el_var(send), eend);
    assert(tybasic(e->Ety) != TYstruct);
    block_appendexp(blx->curblock, e);

    bpre = blx->curblock;
    block_next(blx,BCgoto,NULL);
    bcond = blx->curblock;

    if (op == TOKforeach_reverse)
    {
        // Construct (key > elwr)
        e = el_bin(OPgt, TYint, el_copytree(ekey), el_var(send));
    }
    else
    {
        // Construct (key < eupr)
        e = el_bin(OPlt, TYint, el_copytree(ekey), el_var(send));
    }

    // The size of the increment
    size_t sz = 1;
    Type *tkeyb = key->type->toBasetype();
    if (tkeyb->ty == Tpointer)
        sz = tkeyb->nextOf()->size();

    bcond->Belem = e;
    block_next(blx, BCiftrue, NULL);

    if (op == TOKforeach_reverse)
    {
        // Construct (skey -= 1)
        e = el_bin(OPminass, keytym, el_copytree(ekey), el_long(keytym, sz));
        block_appendexp(blx->curblock, e);
    }

    bbody = blx->curblock;
    if (body)
        body->toIR(&mystate);
    bbodyx = blx->curblock;
    block_next(blx,BCgoto,mystate.contBlock);

    if (op == TOKforeach)
    {
        // Construct (skey += 1)
        e = el_bin(OPaddass, keytym, el_copytree(ekey), el_long(keytym, sz));
        mystate.contBlock->Belem = e;
    }
    block_next(blx,BCgoto,mystate.breakBlock);

    list_append(&bpre->Bsucc,bcond);
    list_append(&bcond->Bsucc,bbody);
    list_append(&bcond->Bsucc,mystate.breakBlock);
    list_append(&bbodyx->Bsucc,mystate.contBlock);
    list_append(&mystate.contBlock->Bsucc,bcond);
#endif
}
Esempio n. 6
0
File: s2ir.c Progetto: Rayerd/dmd
void ForeachStatement::toIR(IRState *irs)
{
    printf("ForeachStatement::toIR() %s\n", toChars());
    assert(0);  // done by "lowering" in the front end
#if 0
    Type *tab;
    elem *eaggr;
    elem *e;
    elem *elength;
    tym_t keytym;

    //printf("ForeachStatement::toIR()\n");
    block *bpre;
    block *bcond;
    block *bbody;
    block *bbodyx;
    Blockx *blx = irs->blx;

    IRState mystate(irs,this);
    mystate.breakBlock = block_calloc(blx);
    mystate.contBlock = block_calloc(blx);

    tab = aggr->type->toBasetype();
    assert(tab->ty == Tarray || tab->ty == Tsarray);

    incUsage(irs, aggr->loc);
    eaggr = aggr->toElem(irs);

    /* Create sp: pointer to start of array data
     */

    Symbol *sp = symbol_genauto(TYnptr);

    if (tab->ty == Tarray)
    {
        // stmp is copy of eaggr (the array), so eaggr is evaluated only once
        Symbol *stmp;

        // Initialize stmp
        stmp = symbol_genauto(eaggr);
        e = el_bin(OPeq, eaggr->Ety, el_var(stmp), eaggr);
        block_appendexp(blx->curblock, e);

        // Initialize sp
        e = el_una(OPmsw, TYnptr, el_var(stmp));
        e = el_bin(OPeq, TYnptr, el_var(sp), e);
        block_appendexp(blx->curblock, e);

        // Get array.length
        elength = el_var(stmp);
        elength->Ety = TYsize_t;
    }
    else // Tsarray
    {
        // Initialize sp
        e = el_una(OPaddr, TYnptr, eaggr);
        e = el_bin(OPeq, TYnptr, el_var(sp), e);
        block_appendexp(blx->curblock, e);

        // Get array.length
        elength = el_long(TYsize_t, ((TypeSArray *)tab)->dim->toInteger());
    }

    Symbol *spmax;
    Symbol *skey;

    if (key)
    {
        /* Create skey, the index to the array.
         * Initialize skey to 0 (foreach) or .length (foreach_reverse).
         */
        skey = key->toSymbol();
        symbol_add(skey);
        keytym = key->type->totym();
        elem *einit = (op == TOKforeach_reverse) ? elength : el_long(keytym, 0);
        e = el_bin(OPeq, keytym, el_var(skey), einit);
    }
    else
    {
        /* Create spmax, pointer past end of data.
         * Initialize spmax = sp + array.length * size
         */
        spmax = symbol_genauto(TYnptr);
        e = el_bin(OPmul, TYsize_t, elength, el_long(TYsize_t, tab->nextOf()->size()));
        e = el_bin(OPadd, TYnptr, el_var(sp), e);
        e = el_bin(OPeq, TYnptr, el_var(spmax), e);

        /* For foreach_reverse, swap sp and spmax
         */
        if (op == TOKforeach_reverse)
        {   Symbol *s = sp;
            sp = spmax;
            spmax = s;
        }
    }
    block_appendexp(blx->curblock, e);

    bpre = blx->curblock;
    block_next(blx,BCgoto,NULL);
    bcond = blx->curblock;

    if (key)
    {
        if (op == TOKforeach_reverse)
        {
            // Construct (key != 0)
            e = el_bin(OPne, TYint, el_var(skey), el_long(keytym, 0));
        }
        else
        {
            // Construct (key < elength)
            e = el_bin(OPlt, TYint, el_var(skey), elength);
        }
    }
    else
    {
        if (op == TOKforeach_reverse)
        {
            // Construct (sp > spmax)
            e = el_bin(OPgt, TYint, el_var(sp), el_var(spmax));
        }
        else
        {
            // Construct (sp < spmax)
            e = el_bin(OPlt, TYint, el_var(sp), el_var(spmax));
        }
    }
    bcond->Belem = e;
    block_next(blx, BCiftrue, NULL);

    if (op == TOKforeach_reverse)
    {
        if (key)
        {   // Construct (skey -= 1)
            e = el_bin(OPminass, keytym, el_var(skey), el_long(keytym, 1));
        }
        else
        {   // Construct (sp--)
            e = el_bin(OPminass, TYnptr, el_var(sp), el_long(TYsize_t, tab->nextOf()->size()));
        }
        block_appendexp(blx->curblock, e);
    }

    Symbol *s;
    FuncDeclaration *fd = NULL;
    if (value->toParent2())
        fd = value->toParent2()->isFuncDeclaration();
    int nrvo = 0;
    if (fd && fd->nrvo_can && fd->nrvo_var == value)
    {
        s = fd->shidden;
        nrvo = 1;
    }
    else
    {   s = value->toSymbol();
        symbol_add(s);
    }

    // Construct (value = *sp) or (value = sp[skey * elemsize])
    tym_t tym = value->type->totym();
    if (key)
    {   // sp + skey * elemsize
        e = el_bin(OPmul, keytym, el_var(skey), el_long(keytym, tab->nextOf()->size()));
        e = el_bin(OPadd, TYnptr, el_var(sp), e);
    }
    else
        e = el_var(sp);

    elem *evalue;
#if DMDV2
    if (value->offset)  // if value is a member of a closure
    {
        assert(irs->sclosure);
        evalue = el_var(irs->sclosure);
        evalue = el_bin(OPadd, TYnptr, evalue, el_long(TYint, value->offset));
        evalue = el_una(OPind, value->type->totym(), evalue);
    }
    else
#endif
        evalue = el_var(s);

    if (value->isOut() || value->isRef())
    {
        assert(value->storage_class & (STCout | STCref));
        e = el_bin(OPeq, TYnptr, evalue, e);
    }
    else
    {
        if (nrvo)
            evalue = el_una(OPind, tym, evalue);
        StructDeclaration *sd = needsPostblit(value->type);
        if (tybasic(tym) == TYstruct)
        {
            e = el_bin(OPeq, tym, evalue, el_una(OPind, tym, e));
            e->Eoper = OPstreq;
            e->ET = value->type->toCtype();
#if DMDV2
            // Call postblit on e
            if (sd)
            {   FuncDeclaration *fd = sd->postblit;
                elem *ec = el_copytree(evalue);
                ec = el_una(OPaddr, TYnptr, ec);
                ec = callfunc(loc, irs, 1, Type::tvoid, ec, sd->type->pointerTo(), fd, fd->type, NULL, NULL);
                e = el_combine(e, ec);
            }
#endif
        }
        else if (tybasic(tym) == TYarray)
        {
            if (sd)
            {
                /* Generate:
                 *      _d_arrayctor(ti, efrom, eto)
                 */
                Expression *ti = value->type->toBasetype()->nextOf()->toBasetype()->getTypeInfo(NULL);
                elem *esize = el_long(TYsize_t, ((TypeSArray *)value->type->toBasetype())->dim->toInteger());
                elem *eto = el_pair(TYdarray, esize, el_una(OPaddr, TYnptr, evalue));
                elem *efrom = el_pair(TYdarray, el_copytree(esize), e);
                elem *ep = el_params(eto, efrom, ti->toElem(irs), NULL);
                int rtl = RTLSYM_ARRAYCTOR;
                e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), ep);
            }
            else
            {
                e = el_bin(OPeq, tym, evalue, el_una(OPind, tym, e));
                e->Eoper = OPstreq;
                e->Ejty = e->Ety = TYstruct;
                e->ET = value->type->toCtype();
            }
        }
        else
            e = el_bin(OPeq, tym, evalue, el_una(OPind, tym, e));
    }
    incUsage(irs, loc);
    block_appendexp(blx->curblock, e);

    bbody = blx->curblock;
    if (body)
        body->toIR(&mystate);
    bbodyx = blx->curblock;
    block_next(blx,BCgoto,mystate.contBlock);

    if (op == TOKforeach)
    {
        if (key)
        {   // Construct (skey += 1)
            e = el_bin(OPaddass, keytym, el_var(skey), el_long(keytym, 1));
        }
        else
        {   // Construct (sp++)
            e = el_bin(OPaddass, TYnptr, el_var(sp), el_long(TYsize_t, tab->nextOf()->size()));
        }
        mystate.contBlock->Belem = e;
    }
    block_next(blx,BCgoto,mystate.breakBlock);

    list_append(&bpre->Bsucc,bcond);
    list_append(&bcond->Bsucc,bbody);
    list_append(&bcond->Bsucc,mystate.breakBlock);
    list_append(&bbodyx->Bsucc,mystate.contBlock);
    list_append(&mystate.contBlock->Bsucc,bcond);
#endif
}
Esempio n. 7
0
File: s2ir.c Progetto: Rayerd/dmd
void TryCatchStatement::toIR(IRState *irs)
{
    Blockx *blx = irs->blx;

#if SEH
    nteh_declarvars(blx);
#endif

    IRState mystate(irs, this);

    block *tryblock = block_goto(blx,BCgoto,NULL);

    int previndex = blx->scope_index;
    tryblock->Blast_index = previndex;
    blx->scope_index = tryblock->Bscope_index = blx->next_index++;

    // Set the current scope index
    setScopeIndex(blx,tryblock,tryblock->Bscope_index);

    // This is the catch variable
    tryblock->jcatchvar = symbol_genauto(type_fake(mTYvolatile | TYnptr));

    blx->tryblock = tryblock;
    block *breakblock = block_calloc(blx);
    block_goto(blx,BC_try,NULL);
    if (body)
    {
        body->toIR(&mystate);
    }
    blx->tryblock = tryblock->Btry;

    // break block goes here
    block_goto(blx, BCgoto, breakblock);

    setScopeIndex(blx,blx->curblock, previndex);
    blx->scope_index = previndex;

    // create new break block that follows all the catches
    breakblock = block_calloc(blx);

    list_append(&blx->curblock->Bsucc, breakblock);
    block_next(blx,BCgoto,NULL);

    assert(catches);
    for (size_t i = 0 ; i < catches->dim; i++)
    {
        Catch *cs = catches->tdata()[i];
        if (cs->var)
            cs->var->csym = tryblock->jcatchvar;
        block *bcatch = blx->curblock;
        if (cs->type)
            bcatch->Bcatchtype = cs->type->toBasetype()->toSymbol();
        list_append(&tryblock->Bsucc,bcatch);
        block_goto(blx,BCjcatch,NULL);
        if (cs->handler != NULL)
        {
            IRState catchState(irs, this);
            cs->handler->toIR(&catchState);
        }
        list_append(&blx->curblock->Bsucc, breakblock);
        block_next(blx, BCgoto, NULL);
    }

    block_next(blx,(enum BC)blx->curblock->BC, breakblock);
}