Ejemplo n.º 1
0
static void createCaller(void)
{
    FUNCTIONCALL *params = Alloc(sizeof(FUNCTIONCALL));
    TYPE *args = realArgs(lambdas->func);
    SYMBOL *func = makeID(sc_member, args, NULL, overloadNameTab[CI_FUNC]);
    SYMBOL *lambdaCall = search(isstructured(basetype(lambdas->func->tp)->btp) ? "__lambdaCallS" : "__lambdaCall", globalNameSpace->syms);
    BLOCKDATA block1, block2;
    STATEMENT *st;
    lambdaCall = (SYMBOL *)lambdaCall->tp->syms->table[0]->p;
    func->parentClass = lambdas->cls;
    func->linkage = lk_virtual;
    func->isInline = FALSE;
    func->omitFrame = TRUE;
    memset(&block1, 0, sizeof(BLOCKDATA));
    memset(&block2, 0, sizeof(BLOCKDATA));
    insertFunc(lambdas->cls, func);
    InsertInline(func);
    st = stmtNode(NULL, &block2, isstructured(basetype(lambdas->func->tp)->btp) ? st_expr : st_return);
    st->select = varNode(en_func, NULL);
    st->select->v.func = params;
    params->arguments = Alloc(sizeof(INITLIST));
    params->arguments->exp = varNode(en_pc, lambdas->func);
    params->arguments->tp = &stdpointer;
    params->ascall = TRUE;
    params->sp = func;
    params->fcall = varNode(en_pc, lambdaCall);
    params->functp = func->tp;
    st = stmtNode(NULL, &block1, st_block);
    st->lower = block2.head;
    st->blockTail = block2.blockTail;
    func->inlineFunc.stmt = stmtNode(NULL, NULL, st_block);
    func->inlineFunc.stmt->lower = block1.head;
    func->inlineFunc.stmt->blockTail = block1.blockTail;
}
Ejemplo n.º 2
0
SYMBOL *gen_mp_virtual_thunk(SYMBOL *vsp)
{

        QUAD *oi = intermed_head, *ot = intermed_tail;
        LIST *v = mpthunklist;
        SYMBOL *sp;
        IMODE *ap1,  *ap2;
        char buf[256];
        while (v)
        {
            sp = (SYMBOL*)v->data;
            if (sp->value.i == vsp->value.classdata.vtabindex)
                if (isstructured(vsp->tp->btp) == isstructured(sp->tp->btp))
                    return sp;
            v = v->link;
        }
        intermed_head = intermed_tail = NULL;
        blockMax = 0;
        blockCount = tempCount = 0;
        exitBlock = 0;
        IncGlobalFlag();
        sp = Alloc(sizeof(SYMBOL));
        sp->storage_class = sc_static;
        sp->tp = vsp->tp;
        sp->value.i = vsp->value.classdata.vtabindex;
        //sprintf(buf, "@$mpt$%d$%d", sp->value.i, isstructured(sp->tp->btp));
        sp->name = sp->decoratedName = litlate(buf);
        sp->errname = sp->decoratedName;
        sp->staticlabel = FALSE;
        sp->gennedvirtfunc = TRUE;
        v = (LIST *)Alloc(sizeof(LIST));
        v->data = sp;
        v->link = mpthunklist;
        mpthunklist = v;
        DecGlobalFlag();

        gen_virtual(sp, FALSE);
        addblock(i_goto);
        gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL);
        gen_icode(i_add, ap2, ap2 , make_immed(ISZ_NONE, isstructured(sp->tp->btp) ? ISZ_ADDR * 2 : ISZ_ADDR));
        ap1 = indnode(ap2, ISZ_ADDR);
        gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0);
        if (sp->value.classdata.baseofs)
            gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.classdata.baseofs));
        ap1 = indnode(ap2, ISZ_ADDR);
        gen_icode(i_assn, ap2 = tempreg(ISZ_ADDR, 0), ap1, 0);
        gen_icode(i_add, ap2, ap2, make_immed(ISZ_NONE, sp->value.i));
        ap1 = indnode(ap2, ISZ_ADDR);
        gen_icode(i_directbranch, 0, ap1, 0);
        addblock(i_ret);
        optimize();
        rewrite_icode(); /* Translate to machine code & dump */
        if (chosenAssembler->gen->post_function_gen)
            chosenAssembler->gen->post_function_gen(intermed_head);
        gen_endvirtual(sp);
        intermed_head = oi;
        intermed_tail = ot;
        return sp;
}
Ejemplo n.º 3
0
static BOOLEAN isStandardLayout(TYPE *tp, SYMBOL **result)
{
    if (isstructured(tp) && !hasVTab(basetype(tp)->sp) && !basetype(tp)->sp->vbaseEntries )
    {
        int n;
        int access = -1;
        SYMBOL *found = NULL, *first;
        HASHREC *hr;
        n = FindBaseClassWithData(tp->sp, &found);
        if (n > 1)
            return FALSE;
        if (n)
        {
            SYMBOL *first = NULL;
            hr = basetype(found->tp)->syms->table[0];
            while (hr)
            {
                SYMBOL *sp = (SYMBOL *)hr->p;
                if (!first)
                    first = sp;
                if (sp->storage_class == sc_member || sp->storage_class == sc_mutable)
                {
                    if (isstructured(sp->tp) && !isStandardLayout(sp->tp, NULL))
                        return FALSE;
                    if (access != -1)
                    {
                        if (access != sp->access)
                            return FALSE;
                    }
                    access = sp->access;
                }
                hr = hr->next;
            }
            if (first && isstructured(first->tp))
            {
                BASECLASS *bc = found->baseClasses;
                while (bc)
                {
                    if (comparetypes(bc->cls->tp, first->tp, TRUE))
                        return FALSE;
                    bc = bc->next;
                }
            }
        }
        if (result)
            *result = found;
        return TRUE;
    }
    return FALSE;
    /*
 hasnonon-staticdatamembersoftypenon-standard-layoutclass(orarrayofsuchtypes)orreference, 
 — has no virtual functions (10.3) and no virtual base classes (10.1), 
 — has the same access control (Clause 11) for all non-static data members, 
 — has no non-standard-layout base classes, 
 — either has no non-static data members in the most derived class and at most one base class with non-static data members, 
    or has no base classes with non-static data members, and 
 — has no base classes of the same type as the ?rst non-static data member.     
 */
}
Ejemplo n.º 4
0
static BOOLEAN trivialCopyAssignable(TYPE *tp)
{
    if (isstructured(tp))
    {
        HASHREC *hr;
        SYMBOL *ovl;
        BASECLASS * bc;
        ovl = search(overloadNameTab[assign - kw_new + CI_NEW ], basetype(tp)->syms);
        if (ovl)
        {
            if (!trivialFunc(ovl, FALSE) || !trivialFunc(ovl, TRUE))
                return FALSE;
        }
        bc = basetype(tp)->sp->baseClasses;
        while (bc)
        {
            if (!trivialCopyAssignable(bc->cls->tp))
                return FALSE;
            bc = bc->next;
        }
        hr = basetype(tp)->syms->table[0];
        while (hr)
        {
            SYMBOL *sym = (SYMBOL *)hr->p;
            if (sym->storage_class == sc_mutable || sym->storage_class == sc_member)
                if (!trivialCopyAssignable(sym->tp))
                    return FALSE;
            hr = hr->next;
        }
    }
    return TRUE;
}
Ejemplo n.º 5
0
EXPRESSION *anonymousVar(enum e_sc storage_class, TYPE *tp)
{
    static int anonct = 1;
    char buf[256];
    SYMBOL *rv = (SYMBOL *)Alloc(sizeof(SYMBOL));
//    if ((storage_class == sc_localstatic || storage_class == sc_auto) && !theCurrentFunc)
//    {
//        storage_class = sc_static;
//        insertInitSym(rv);
//    }
    if (tp->size == 0 && isstructured(tp))
        tp = basetype(tp)->sp->tp;
    rv->storage_class = storage_class;
    rv->tp = tp;
    rv->anonymous = TRUE;
    rv->allocate = !anonymousNotAlloc;
    rv->assigned = TRUE;
    rv->used = TRUE;
    if (theCurrentFunc)
        rv->value.i = theCurrentFunc->value.i;
    sprintf(buf,"$anontemp%d", anonct++);
    rv->name = litlate(buf);
    tp->size = basetype(tp)->size;
    if (theCurrentFunc && !inDefaultParam)
        InsertSymbol(rv, storage_class, FALSE, FALSE);
    SetLinkerNames(rv, lk_none);
    return varNode(storage_class == sc_auto || storage_class == sc_parameter ? en_auto : storage_class == sc_localstatic ? en_label : en_global, rv);
}
Ejemplo n.º 6
0
static BOOLEAN nothrowConstructible(TYPE *tp)
{
    if (isstructured(tp))
    {
        SYMBOL *ovl;
        // recursion will have been taken care of elsewhere...
        ovl = search(overloadNameTab[CI_CONSTRUCTOR ], basetype(tp)->syms);
        if (ovl)
        {
            HASHREC *hr = ovl->tp->syms->table[0];
            hr = basetype(ovl->tp)->syms->table[0];
            while (hr)
            {
                SYMBOL *sp = (SYMBOL *)hr->p;
                HASHREC *hr1 = basetype(sp->tp)->syms->table[0];
                if (matchesCopy(sp, FALSE) || matchesCopy(sp, TRUE) || !hr1->next || !hr1->next->next || ((SYMBOL *)hr1->next->next->p)->tp->type == bt_void)
                {
                    if (sp->xcMode != xc_none)
                        return FALSE;
                }
                hr = hr->next;
            }
        }
    }
    return TRUE;
}
Ejemplo n.º 7
0
static BOOLEAN trivialDestructor(TYPE *tp)
{
    if (isstructured(tp))
    {
        HASHREC *hr;
        SYMBOL *ovl;
        BASECLASS *bc;
        ovl = search(overloadNameTab[CI_DESTRUCTOR ], basetype(tp)->syms);
        if (ovl)
        {
            ovl = (SYMBOL *)ovl->tp->syms->table[0]->p;
            if (!ovl->defaulted)
                return FALSE;
        }
        bc = basetype(tp)->sp->baseClasses;
        while (bc)
        {
            if (!trivialDestructor(bc->cls->tp))
                return FALSE;
            bc = bc->next;
        }
        hr = basetype(tp)->syms->table[0];
        while (hr)
        {
            SYMBOL *sym = (SYMBOL *)hr->p;
            if (sym->storage_class == sc_mutable || sym->storage_class == sc_member)
                if (!trivialDestructor(sym->tp))
                    return FALSE;
            hr = hr->next;
        }
    }
    return TRUE;
}
Ejemplo n.º 8
0
static BOOLEAN is_polymorphic(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp)
{
    INITLIST *lst;
    BOOLEAN rv = FALSE;
    FUNCTIONCALL funcparams;
    memset(&funcparams, 0, sizeof(funcparams));
    funcparams.sp = sym;
    *lex = getTypeList(*lex, funcsp, &funcparams.arguments);
    lst = funcparams.arguments;
    while (lst)
    {
        lst->tp = PerformDeferredInitialization(lst->tp, NULL);
        lst = lst->next;
        
    }
    if (funcparams.arguments && !funcparams.arguments-> next)
    {
        // yes references are literal types...
        if (isstructured(funcparams.arguments->tp))
            rv = !! hasVTab(basetype(funcparams.arguments->tp)->sp);
    }
    *exp = intNode(en_c_i, rv);
    *tp = &stdint;
    return TRUE;
}
Ejemplo n.º 9
0
static BOOLEAN trivialStructure(TYPE *tp)
{
    if (isstructured(tp))
    {
        return triviallyCopyable(tp) && trivialDefaultConstructor(tp);
    }
    return FALSE;
}
Ejemplo n.º 10
0
// these next two rely on the CONST specifier on the func not being set up yet.
static SYMBOL *createPtrCaller(SYMBOL *self)
{
    // if the closure is copied then used on another thread yes the resulting
    // code can get into a race condition...
    INITLIST *args;
    FUNCTIONCALL *params = Alloc(sizeof(FUNCTIONCALL));
    TYPE *pargs = realArgs(lambdas->func);
    SYMBOL *func = makeID(sc_static, pargs, NULL, "$ptrcaller");
    SYMBOL *lambdaCall = search(isstructured(basetype(lambdas->func->tp)->btp) ? "__lambdaPtrCallS" : "__lambdaPtrCall", globalNameSpace->syms);
    BLOCKDATA block1, block2;
    STATEMENT *st;
    EXPRESSION *exp = varNode(en_label, self);
    lambdaCall = (SYMBOL *)lambdaCall->tp->syms->table[0]->p;
    func->parentClass = lambdas->cls;
    func->linkage = lk_virtual;
    func->isInline = FALSE;
    func->omitFrame = TRUE;
    deref(&stdpointer, &exp);
    memset(&block1, 0, sizeof(BLOCKDATA));
    memset(&block2, 0, sizeof(BLOCKDATA));
    insertFunc(lambdas->cls, func);
    st = stmtNode(NULL, &block2, isstructured(basetype(lambdas->func->tp)->btp) ? st_expr : st_return);
    st->select = varNode(en_func, NULL);
    st->select->v.func = params;
    params->arguments = Alloc(sizeof(INITLIST));
    params->arguments->exp = varNode(en_pc, lambdas->func);
    params->arguments->tp = &stdpointer;
    args = Alloc(sizeof(INITLIST));
    args->next = params->arguments;
    params->arguments = args;
    params->arguments->exp = exp;
    params->arguments->tp = &stdpointer;
    params->ascall = TRUE;
    params->sp = func;
    params->fcall = varNode(en_pc, lambdaCall);
    params->functp = func->tp;
    st = stmtNode(NULL, &block1, st_block);
    st->lower = block2.head;
    st->blockTail = block2. blockTail;
    func->inlineFunc.stmt = stmtNode(NULL, NULL, st_block);
    func->inlineFunc.stmt->lower = block1.head;
    func->inlineFunc.stmt->blockTail = block1.blockTail;
    return func;
}
Ejemplo n.º 11
0
static EXPRESSION *newReturn(TYPE *tp)
{
    EXPRESSION *exp ;
    if (!isstructured(tp) && !isvoid(tp))
    {
        exp = varNode(en_auto, anonymousVar(sc_auto, tp));
        deref(tp, &exp);
    }
    else
        exp = intNode(en_c_i, 0);
    return exp;
}
Ejemplo n.º 12
0
/*-------------------------------------------------------------------------*/
static void InsertParameterThunks(SYMBOL *funcsp, BLOCK *b)
{
    HASHREC *hr = basetype(funcsp->tp)->syms->table[0];
    QUAD *old , *oldit;
    BLOCK *ocb = currentBlock;
    old = b->head->fwd;
    while (old != b->tail && old->dc.opcode != i_label) old = old->fwd;
    old = old->fwd;
    oldit = intermed_tail;
    intermed_tail = old->back;
    intermed_tail->fwd = NULL;
    currentBlock = b;
    while (hr)
    {
        SYMBOL *sp = (SYMBOL *)hr->p;
        if (sp->tp->type == bt_void || sp->tp->type == bt_ellipse || isstructured(sp->tp))
        {
            hr = hr->next;
            continue;
        }
        if (!sp->imvalue || sp->imaddress)
        {
            hr = hr->next;
            continue;
        }
        if (funcsp->oldstyle && sp->tp->type == bt_float)
        {
            IMODE *right = (IMODE *)Alloc(sizeof(IMODE));
            *right = *sp->imvalue;
            right->size = ISZ_DOUBLE;
            if (!chosenAssembler->arch->hasFloatRegs)
            {
                IMODE *dp = tempreg(ISZ_DOUBLE, 0);
                IMODE *fp = tempreg(ISZ_FLOAT, 0);
                /* oldstyle float gets promoted from double */
                gen_icode(i_assn, dp, right, 0);
                gen_icode(i_assn, fp, dp, 0);
                gen_icode(i_assn, sp->imvalue, fp, 0);
            }
        }
        hr = hr->next;
    }
    currentBlock = ocb;
    if (old->back == b->tail)
    {
        b->tail = intermed_tail;
    }
    old->back = intermed_tail;
    intermed_tail->fwd = old;
    intermed_tail = oldit;
}
Ejemplo n.º 13
0
static BOOLEAN is_base_of(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp)
{
    INITLIST *lst;
    BOOLEAN rv = FALSE;
    FUNCTIONCALL funcparams;
    memset(&funcparams, 0, sizeof(funcparams));
    funcparams.sp = sym;
    *lex = getTypeList(*lex, funcsp, &funcparams.arguments);
    lst = funcparams.arguments;
    while (lst)
    {
        lst->tp = PerformDeferredInitialization(lst->tp, NULL);
        lst = lst->next;
        
    }
    if (funcparams.arguments && funcparams.arguments-> next && !funcparams.arguments->next->next)
    {
        if (isstructured(funcparams.arguments->tp) && isstructured(funcparams.arguments->next->tp))
            rv = classRefCount(basetype(funcparams.arguments->tp)->sp, basetype(funcparams.arguments->next->tp)->sp) != 0;
    }
    *exp = intNode(en_c_i, rv);
    *tp = &stdint;
    return TRUE;
}
Ejemplo n.º 14
0
static BOOLEAN is_class(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp)
{
    INITLIST *lst;
    BOOLEAN rv = FALSE;
    FUNCTIONCALL funcparams;
    memset(&funcparams, 0, sizeof(funcparams));
    funcparams.sp = sym;
    *lex = getTypeList(*lex, funcsp, &funcparams.arguments);
    if (funcparams.arguments && !funcparams.arguments-> next)
    {
        rv = isstructured(funcparams.arguments->tp) && basetype(funcparams.arguments->tp)->type != bt_union;
    }
    *exp = intNode(en_c_i, rv);
    *tp = &stdint;
    return TRUE;
}
Ejemplo n.º 15
0
static void inlineResetReturn(STATEMENT *block, TYPE *rettp, EXPRESSION *retnode)
{
    EXPRESSION *exp;
    if (isstructured(rettp))
    {
        diag("structure in inlineResetReturn");
    }
    else
    {
        exp = block->select;
        cast(rettp, &exp);
        exp = exprNode(en_assign, retnode, exp);
    }
    block->type = st_expr;
    block->select = exp;
}
Ejemplo n.º 16
0
static BOOLEAN is_literal(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp)
{
    INITLIST *lst;
    BOOLEAN rv = FALSE;
    FUNCTIONCALL funcparams;
    memset(&funcparams, 0, sizeof(funcparams));
    funcparams.sp = sym;
    *lex = getTypeList(*lex, funcsp, &funcparams.arguments);
    if (funcparams.arguments && !funcparams.arguments-> next)
    {
        // yes references are literal types...
        rv = !isstructured(funcparams.arguments->tp);
    }
    *exp = intNode(en_c_i, rv);
    *tp = &stdint;
    return TRUE;
}
Ejemplo n.º 17
0
    /*
A trivially copyable class is a class that: 
— has no non-trivial copy constructors (12.8),
— has no non-trivial move constructors (12.8), 
— has no non-trivial copy assignment operators (13.5.3, 12.8), 
— has no non-trivial move assignment operators (13.5.3, 12.8), and 
— has a trivial destructor (12.4). 

A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.     
*/
static BOOLEAN trivialStructureWithBases(TYPE *tp)
{
    if (isstructured(tp))
    {
        BASECLASS *bc;
        if (!trivialStructure(tp))
            return FALSE;
        bc = basetype(tp)->sp->baseClasses;
        while (bc)
        {
            if (!trivialStructureWithBases(bc->cls->tp))
                return FALSE;
            bc = bc->next;
        }
    }
    return TRUE;
}
Ejemplo n.º 18
0
static BOOLEAN trivialDefaultConstructor(TYPE *tp)
{
    if (isstructured(tp))
    {
        HASHREC *hr;
        SYMBOL *ovl;
        BASECLASS *bc;
        ovl = search(overloadNameTab[CI_CONSTRUCTOR ], basetype(tp)->syms);
        if (ovl)
        {
            HASHREC *hr = ovl->tp->syms->table[0];
            while (hr)
            {
                SYMBOL *sym = (SYMBOL *)hr->p;
                HASHREC *hr1 = basetype(sym->tp)->syms->table[0];
                
                if (!hr1->next || !hr1->next->next || ((SYMBOL *)hr1->next->next->p)->tp->type == bt_void)
                    if (!sym->defaulted)
                        return FALSE;
                    else
                        break;
                hr = hr->next;
            }
        }
        bc = basetype(tp)->sp->baseClasses;
        while (bc)
        {
            if (!trivialDefaultConstructor(bc->cls->tp))
                return FALSE;
            bc = bc->next;
        }
        hr = basetype(tp)->syms->table[0];
        while (hr)
        {
            SYMBOL *sym = (SYMBOL *)hr->p;
            if (sym->storage_class == sc_mutable || sym->storage_class == sc_member)
                if (!trivialDefaultConstructor(sym->tp))
                    return FALSE;
            hr = hr->next;
        }
    }
    return TRUE;
}
Ejemplo n.º 19
0
BOOL checktypeassign(TYPE *typ1, TYPE *typ2)
{
    /* this is so we can put an ampersand in front of a func name we are using */
    if (isfuncptr(typ1) && isfuncptr(typ2))
        return TRUE;
    while (typ1 && typ2)
    {
        typ1 = basetype(typ1);
        typ2 = basetype(typ2);
        if (isarithmetic(typ1) && isarithmetic(typ2))
               return TRUE;
        if (isstructured(typ1) && comparetypes(typ1, typ2, TRUE))
            return TRUE;
        typ1 = typ1->btp;
        typ2 = typ2->btp;
    }
    if (!typ1 && !typ2)
        return (TRUE);
    return (FALSE);
}
Ejemplo n.º 20
0
static BOOLEAN isPOD(TYPE *tp)
{
    SYMBOL *found = NULL;
    if (isStandardLayout(tp, found) && trivialStructureWithBases(tp))
    {
        if (found)
        {
            HASHREC *hr = basetype(found->tp)->syms->table;
            while (hr)
            {
                SYMBOL *sym = (SYMBOL *)hr->p;
                if (isstructured(sym->tp) && !trivialStructureWithBases(sym->tp))
                    return FALSE;
                hr = hr->next;
            }
        }
        return TRUE;
    }
    return FALSE;
}
Ejemplo n.º 21
0
void genreturn(STATEMENT *stmt, SYMBOL *funcsp, int flag, int noepilogue, IMODE *allocaAP)
/*
 *      generate a return statement.
 */
{
    IMODE *ap = NULL,  *ap1, *ap3;
    EXPRESSION ep;
    int size;
    /* returns a value? */
    if (stmt != 0 && stmt->select != 0)
    {
        if (basetype(funcsp->tp)->btp && (isstructured(basetype(funcsp->tp)->btp) ||
                                          basetype(basetype(funcsp->tp)->btp)->type == bt_memberptr))
        {
            EXPRESSION *en = anonymousVar(sc_parameter, &stdpointer);
            SYMBOL *sp = en->v.sp;
            gen_expr(funcsp, stmt->select, 0, ISZ_ADDR);
            DumpIncDec(funcsp);
            sp->offset = chosenAssembler->arch->retblocksize;
            sp->allocate = FALSE;
            if ((funcsp->linkage == lk_pascal) &&
                    basetype(funcsp->tp)->syms->table[0] && 
                    ((SYMBOL *)basetype(funcsp->tp)->syms->table[0])->tp->type != bt_void)
                sp->offset = funcsp->paramsize;
            deref(&stdpointer, &en);
            ap = gen_expr(funcsp, en, 0, ISZ_ADDR);
            size = ISZ_ADDR;
        }
        else
        {
            size = natural_size(stmt->select);
            ap3 = gen_expr(funcsp, stmt->select, 0, size);
            DumpIncDec(funcsp);
            ap = LookupLoadTemp(NULL, ap3);
            if (ap != ap3)
            {
                IMODE *barrier;
                if (stmt->select->isatomic)
                {
                    barrier = doatomicFence(funcsp, stmt->select, NULL);
                }
                gen_icode(i_assn, ap, ap3, NULL);
                if (stmt->select->isatomic)
                {
                    doatomicFence(funcsp, stmt->select, barrier);
                }
            }
            if (abs(size) < ISZ_UINT)
                size = -ISZ_UINT;
        }
    }
    else
    {
        DumpIncDec(funcsp);
    }
    if (ap)
    {
        ap1 = tempreg(size, 0);
        ap1->retval = TRUE;
        gen_icode(i_assn, ap1, ap, 0);
    }
    if (stmt && stmt->destexp)
    {
        gen_expr(funcsp, stmt->destexp, F_NOVALUE, ISZ_ADDR);
    }
    /* create the return or a branch to the return
     * return is put at end of function...
     */
    if (flag)
    {
        int retsize = 0;
        if (funcsp->linkage == lk_pascal || funcsp->linkage == lk_stdcall)
        {
           retsize = funcsp->paramsize ;
        }
        gen_label(retlab);
        if (!noepilogue)
        {
            if (allocaAP)
            {
                gen_icode(i_loadstack, 0, allocaAP, 0);
            }
/*			if (funcsp->loadds && funcsp->farproc)
                gen_icode(i_unloadcontext,0,0,0);
*/
        
            if (cparams.prm_xcept && funcsp->xc && funcsp->xc->xcRundownFunc)
                gen_expr(funcsp, funcsp->xc->xcRundownFunc, F_NOVALUE, ISZ_UINT);
            gen_icode(i_epilogue,0,0,0);
            if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) {
/*				if (funcsp->loadds)
                    gen_icode(i_unloadcontext,0,0,0);
*/
                gen_icode(i_popcontext, 0,0,0);
                gen_icode(i_rett, 0, make_immed(ISZ_UINT,funcsp->linkage == lk_interrupt), 0);
            } else
            {
                gen_icode(i_ret, 0, make_immed(ISZ_UINT,retsize), 0);
            }
        }
    }
    else
    {	
        /* not using gen_igoto because it will make a new block */
        gen_icode(i_goto, NULL, NULL, NULL);
        intermed_tail->dc.v.label = retlab;
    }
}
Ejemplo n.º 22
0
void genreturn(STATEMENT *stmt, SYMBOL *funcsp, int flag, int noepilogue, IMODE *allocaAP)
/*
 *      generate a return statement.
 */
{
    IMODE *ap,  *ap1, *ap3;
    EXPRESSION ep;
    /* returns a value? */
    if (stmt != 0 && stmt->select != 0)
    {
        if (basetype(funcsp->tp)->btp && (isstructured(basetype(funcsp->tp)->btp) ||
                                          basetype(basetype(funcsp->tp)->btp)->type == bt_memberptr))
        {
            SYMBOL *sp = anonymousVar(sc_parameter, &stdpointer);
            EXPRESSION *en = varNode(en_auto, sp);
            IMODE *ap3 = gen_expr(funcsp, stmt->select, 0, ISZ_ADDR), *ap2, *ap1;
            DumpIncDec(funcsp);
            if (!ap3->retval)
            {
                ap1 = LookupLoadTemp(NULL, ap3);
                if (ap1 != ap3)
                {
                    IMODE *barrier;
                    if (stmt->select->isatomic)
                    {
                        barrier = doatomicFence(funcsp, stmt->select, NULL);
                    }
                    gen_icode(i_assn, ap1, ap3, NULL);
                    if (stmt->select->isatomic)
                    {
                        doatomicFence(funcsp, stmt->select, barrier);
                    }
                }
            }
            else
            {
                ap1 = ap3;
            }
            if ((funcsp->linkage == lk_pascal) &&
                basetype(funcsp->tp)->syms->table[0] && 
                ((SYMBOL *)basetype(funcsp->tp)->syms->table[0])->tp->type != bt_void)
            {
                sp->offset = funcsp->paramsize;
            }
            else
            {
                sp->offset = chosenAssembler->arch->retblocksize+(funcsp->farproc
                    *getSize(bt_pointer));
                if (funcsp->storage_class == sc_member || funcsp->storage_class == sc_virtual)
                    sp->offset += getSize(bt_pointer);
            }
                
            en = exprNode(en_l_p, en, NULL);
            ap3 = gen_expr(funcsp, en, 0, ISZ_ADDR);
            ap = LookupLoadTemp(NULL, ap3);
            if (ap != ap3)
            {
                IMODE *barrier;
                if (en->isatomic)
                {
                    barrier = doatomicFence(funcsp, en, NULL);
                }
                gen_icode(i_assn, ap, ap3, NULL);
                if (en->isatomic)
                {
                    doatomicFence(funcsp, en, barrier);
                }
            }
            gen_icode(i_assnblock, make_immed(ISZ_NONE, basetype(funcsp->tp)->btp->size),
                      ap, ap1);
            ap1 = tempreg(ISZ_ADDR, 0);
            ap1->retval = TRUE;
            gen_icode(i_assn, ap1, ap, NULL);
        }
        else if (basetype(funcsp->tp)->btp && basetype(funcsp->tp)->btp->type ==
            bt_memberptr)
        {
            ap3 = gen_expr(funcsp, stmt->select, F_VOL, ISZ_ADDR);
            DumpIncDec(funcsp);
            ap = LookupLoadTemp(NULL, ap3);
            if (ap != ap3)
            {
                IMODE *barrier;
                if (stmt->select->isatomic)
                {
                    barrier = doatomicFence(funcsp, stmt->select, NULL);
                }
                gen_icode(i_assn, ap, ap3, NULL);
                if (stmt->select->isatomic)
                {
                    doatomicFence(funcsp, stmt->select, barrier);
                }
            }
            ap1 = tempreg(ISZ_ADDR, 0);
            ap1->retval = TRUE;
            gen_icode(i_assn, ap1, ap, 0);
        }
        else
        {
            int size = natural_size(stmt->select);
            ap3 = gen_expr(funcsp, stmt->select, 0, size);
            DumpIncDec(funcsp);
            ap = LookupLoadTemp(NULL, ap3);
            if (ap != ap3)
            {
                IMODE *barrier;
                if (stmt->select->isatomic)
                {
                    barrier = doatomicFence(funcsp, stmt->select, NULL);
                }
                gen_icode(i_assn, ap, ap3, NULL);
                if (stmt->select->isatomic)
                {
                    doatomicFence(funcsp, stmt->select, barrier);
                }
            }
            if (abs(size) < ISZ_UINT)
                size = -ISZ_UINT;
            ap1 = tempreg(size, 0);
            ap1->retval = TRUE;
            gen_icode(i_assn, ap1, ap, 0);
        }
    }
    else
    {
        DumpIncDec(funcsp);
    }
    /* create the return or a branch to the return
     * return is put at end of function...
     */
    if (flag)
    {
        int retsize = 0;
        if (funcsp->linkage == lk_pascal || funcsp->linkage == lk_stdcall)
        {
           retsize = funcsp->paramsize ;
        }
        gen_label(retlab);
        if (!noepilogue)
        {
            if (allocaAP)
            {
                gen_icode(i_loadstack, 0, allocaAP, 0);
            }
/*			if (funcsp->loadds && funcsp->farproc)
                gen_icode(i_unloadcontext,0,0,0);
*/
        
            gen_icode(i_epilogue,0,0,0);
            if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) {
/*				if (funcsp->loadds)
                    gen_icode(i_unloadcontext,0,0,0);
*/
                gen_icode(i_popcontext, 0,0,0);
                gen_icode(i_rett, 0, make_immed(ISZ_NONE,funcsp->linkage == lk_interrupt), 0);
            } else
            {
                gen_icode(i_ret, 0, make_immed(ISZ_NONE,retsize), 0);
            }
        }
    }
    else
    {	
        /* not using gen_igoto because it will make a new block */
        gen_icode(i_goto, NULL, NULL, NULL);
        intermed_tail->dc.v.label = retlab;
    }
}
Ejemplo n.º 23
0
static EXPRESSION *createLambda(BOOLEAN noinline)
{
    EXPRESSION *rv = NULL, **cur = &rv;
    HASHREC *hr;
    EXPRESSION *clsThs, *parentThs;
    SYMBOL *cls = makeID(lambdas->enclosingFunc ? sc_auto : sc_localstatic, lambdas->cls->tp, NULL, AnonymousName());
    SetLinkerNames(cls, lk_cdecl);
    cls->allocate = TRUE;
    if (lambdas->enclosingFunc)
    {
        insert(cls, localNameSpace->syms);
        clsThs = varNode(en_auto, cls); // this ptr
    }
    else
    {
        insert(cls, globalNameSpace->syms); // well if we could put this as an auto in the init func that would be good but there is no way to do that here...
        clsThs = varNode(en_label, cls); // this ptr
        cls->label = nextLabel++;
        insertInitSym(cls);
    }
    {
        INITIALIZER *init = NULL;
        EXPRESSION *exp = clsThs;
        callDestructor(cls, NULL, &exp, NULL, TRUE, FALSE, FALSE);
        initInsert(&init, cls->tp, exp, 0, TRUE);
        if (cls->storage_class != sc_auto)
        {
            insertDynamicDestructor(cls, init);
        }
        else
        {
            cls->dest = init;
        }
    }
    parentThs = varNode(en_auto, (SYMBOL *)basetype(lambdas->func->tp)->syms->table[0]->p); // this ptr
    hr = lambdas->cls->tp->syms->table[0];
    while (hr)
    {
        SYMBOL *sp = (SYMBOL *)hr->p;
        EXPRESSION *en = NULL, *en1 = NULL;
        if (!strcmp(sp->name, "$self"))
        {
            en1 = clsThs;
            en = varNode(en_label, sp);
            deref(&stdpointer, &en);
            en = exprNode(en_assign, en, en1);
        }
        else if (!strcmp(sp->name, "$parent"))
        {
            en1 = parentThs; // get parent from function call
            deref(&stdpointer, &en1);
            en = exprNode(en_add, clsThs, intNode(en_c_i, sp->offset)) ;
            deref(&stdpointer, &en);
            en = exprNode(en_assign, en, en1);
        }
        else if (!strcmp(sp->name, "$this"))
        {
            if (!lambdas->next || !lambdas->captureThis)
            {
                en1 = parentThs; // get parent from function call
            }
            else
            {
                SYMBOL *parent = search("$parent", lambdas->cls->tp->syms);
                en1 = varNode(en_auto, cls);
                deref(&stdpointer, &en1);
                en1 = exprNode(en_add, en1, intNode(en_c_i, parent->offset));
            }
            deref(&stdpointer, &en1);
            en = exprNode(en_add, clsThs, intNode(en_c_i, sp->offset)) ;
            deref(&stdpointer, &en);
            en = exprNode(en_assign, en, en1);
        }
        else if (sp->lambdaMode)
        {
            LAMBDASP *lsp = (LAMBDASP *)search(sp->name, lambdas->captured);
            if (lsp)
            {
                en1 = exprNode(en_add, clsThs, intNode(en_c_i, sp->offset));
                if (sp->lambdaMode == cmRef)
                {
                    SYMBOL *capture = lsp->parent;
                    deref(&stdpointer, &en1);
                    if (capture->lambdaMode)
                    {
                        en = parentThs;
                        deref(&stdpointer, &en);
                        en = exprNode(en_add, en, intNode(en_c_i, capture->offset));
                    }
                    else // must be an sc_auto
                    {
                        en = varNode(en_auto, capture);
                    }
                    if (isref(capture->tp))
                    {
                        deref(&stdpointer, &en);
                    }
                    en = exprNode(en_assign, en1, en);
                }
                else // cmValue
                {
                    SYMBOL *capture = lsp->parent;
                    TYPE *ctp = capture->tp;
                    if (capture->lambdaMode)
                    {
                        en = parentThs;
                        deref(&stdpointer, &en);
                        en = exprNode(en_add, en, intNode(en_c_i, capture->offset));
                    }
                    else // must be an sc_auto
                    {
                        en = varNode(en_auto, capture);
                    }
                    if (isref(ctp))
                    {
                        ctp = basetype(ctp)->btp;
                        deref(&stdpointer, &en);
                    }
                    if (isstructured(ctp))
                    {
                        FUNCTIONCALL *params = (FUNCTIONCALL *)Alloc(sizeof(FUNCTIONCALL));
                        params->arguments = (INITLIST *)Alloc(sizeof(INITLIST));
                        params->arguments->tp = ctp;
                        params->arguments->exp = en;
                        if (!callConstructor(&ctp, &en1, params, FALSE, NULL, TRUE, FALSE, TRUE, FALSE, FALSE))
                            errorsym(ERR_NO_APPROPRIATE_CONSTRUCTOR, lsp->sym);
                        en = en1;
                    }
                    else
                    {
                        deref(ctp, &en1);
                        deref(ctp, &en);
                        en = exprNode(en_assign, en1, en);
                    }
                }
            }
            else
            {
                diag("createLambda: no capture var");
            }
        }
        if (en)
        {
            *cur = exprNode(en_void, en, NULL);
            cur = &(*cur)->right;            
        }
        hr = hr->next;
    }
    *cur = clsThs; // this expression will be used in copy constructors, or discarded if unneeded
    return rv;
}
Ejemplo n.º 24
0
BOOL comparetypes(TYPE *typ1, TYPE *typ2, int exact)
{
    if (typ1->type == bt_any || typ2->type == bt_any)
        return TRUE;
    if (typ1->type == bt_typedef)
        typ1 = basetype(typ1);
    if (typ2->type == bt_typedef)
        typ2 = basetype(typ2);
    if (isref(typ1))
        typ1 = basetype(typ1)->btp;
    if (isref(typ2))
        typ2 = basetype(typ2)->btp;
    if (ispointer(typ1) && ispointer(typ2))
        if (exact)
        {
            int arr = FALSE;
            int first = TRUE;
            while (ispointer(typ1) && ispointer(typ2))
            {
                if (!first && (exact == 1))
                    if (isconst(typ2) && !isconst(typ1) || isvolatile(typ2) && !isvolatile(typ1))
                        return FALSE;
                first = FALSE;
                typ1 = basetype(typ1);
                typ2 = basetype(typ2);
                if (typ1->type != typ2->type)
                    return FALSE;
                if (arr && typ1->array != typ2->array)	
                    return FALSE;
                if (arr && typ1->size != typ2->size)
                    return FALSE;
                arr |= typ1->array | typ2->array;
                typ1 = typ1->btp;
                typ2 = typ2->btp;				
            }
            if ((exact == 1) && (isconst(typ2) && !isconst(typ1) || isvolatile(typ2) && !isvolatile(typ1)))
                return FALSE;
            return comparetypes(typ1, typ2, TRUE);
        }
            
        else
            return TRUE;
    
    typ1 = basetype(typ1);
    typ2 = basetype(typ2);
    if (exact && (isfunction(typ1) || isfuncptr(typ1)) && (isfunction(typ2) || isfuncptr(typ2)))
    {
        HASHREC *hr1;
        HASHREC *hr2;
        typ1 = basetype(typ1);
        typ2 = basetype(typ2);
        if (ispointer(typ1))
            typ1 = basetype(typ1->btp);
        if (ispointer(typ2))
            typ2 = basetype(typ2->btp);
        if (!comparetypes(typ1->btp, typ2->btp, exact))
            return FALSE;
        hr1 = typ1->syms->table[0];
        hr2 = typ2->syms->table[0];
        while (hr1 && hr2)
        {
            SYMBOL *sp1 = (SYMBOL *)hr1->p;
            SYMBOL *sp2 = (SYMBOL *)hr2->p;
            if (!comparetypes(sp1->tp, sp2->tp, exact))
                return FALSE;
            hr1 = hr1->next;
            hr2 = hr2->next;
        }
        if (hr1 || hr2)
            return FALSE;
        return TRUE;
    }
    if (cparams.prm_cplusplus)
    {
        if (typ1->scoped != typ2->scoped)
            return FALSE;
        if (typ1->type == bt_enum)
        {
            if (typ2->type == bt_enum)
                return typ1->sp == typ2->sp;
            else
                return isint(typ2);
        }
        else if (typ2->type == bt_enum)
        {
            return isint(typ1);
        }
        if (typ1->type == typ2->type && typ1->type == bt_memberptr)
        {
            if (typ1->sp != typ2->sp)
            {
                if (classRefCount(typ2->sp, typ1->sp) != 1)
                    return FALSE;
            }
            return comparetypes(typ1->btp, typ2->btp, exact);
        }
    }
    if (typ1->type == typ2->type && (isstructured(typ1) || exact && typ1->type == bt_enum))
        return typ1->sp == typ2->sp;
    if (typ1->type == typ2->type || !exact && isarithmetic(typ2) && isarithmetic(typ1))
        return TRUE;
    if (isfunction(typ1) && isfunction(typ2) && 
        typ1->sp->linkage == typ2->sp->linkage)
        return TRUE;
    else if (!exact && (ispointer(typ1) && (isfuncptr(typ2) || isfunction(typ2) || isint(typ2))
             || ispointer(typ2) && (isfuncptr(typ1) || isfunction(typ1) || isint(typ1))))
            return (TRUE);
    else if (typ1->type == bt_enum && isint(typ2))
    {
        return TRUE;
    }
    else if (typ2->type == bt_enum && isint(typ1))
    {
        return TRUE;
    }
    return FALSE;
}
Ejemplo n.º 25
0
static void renameToTemps(SYMBOL *funcsp)
{
    HASHTABLE *temp = funcsp->inlineFunc.syms;
    if (!cparams.prm_optimize || functionHasAssembly)
        return;
    /* if there is a setjmp in the function, no variable gets moved into a reg */
    if (setjmp_used)
        return;
    while (temp)
    {
        HASHREC *hr = temp->table[0];
        while (hr)
        {
            SYMBOL *sp = (SYMBOL *)hr->p;
            TYPE *tp;
            /* needed for pointer aliasing */
            if (!sp->imvalue && basetype(sp->tp)->type != bt_memberptr && !isstructured(sp->tp) && sp->tp->type != bt_ellipse && sp->tp->type != bt_aggregate)
            {
                if (sp->storage_class != sc_auto && sp->storage_class !=
                    sc_register)
                {
                    IncGlobalFlag();
                }
                if (sp->imaddress)
                {
                    IMODE *im = Alloc(sizeof(IMODE));
                    *im = *sp->imaddress;
                    im->size = sizeFromType(sp->tp);
                    im->mode = i_direct;
                    sp->imvalue = im;
                }
                else if (sp->imind)
                {
                    IMODE *im = Alloc(sizeof(IMODE));
                    *im = *sp->imind->im;
                    im-> size = ISZ_ADDR;
                    im->mode = i_direct;
                    sp->imvalue = im;
                }
                else
                    sp->imvalue = tempreg(sizeFromType(sp->tp), FALSE);
                
                if (sp->storage_class != sc_auto && sp->storage_class !=
                    sc_register)
                {
                    DecGlobalFlag();
                }
            }
            tp = sp->tp;
            if (tp->type == bt_typedef)
                tp = tp->btp;
            if (!sp->pushedtotemp && sp->storage_class != sc_parameter && !sp->imaddress && !sp->inasm
                && ((chosenAssembler->arch->hasFloatRegs || tp->type < bt_float) && tp->type < bt_void  || basetype(tp)->type == bt_pointer && basetype(tp)->btp->type != bt_func
                    || isref(tp)) 
                && (sp->storage_class == sc_auto || sp->storage_class == sc_register)
                && !sp->usedasbit)
            {
                /* this works because all IMODES refering to the same
                 * variable are the same, at least until this point
                 * that will change when we start inserting temps
                 */
                EXPRESSION *ep = tempenode();
                ep->v.sp->tp = sp->tp;
                ep->right = (EXPRESSION *)sp;
                /* marking both the orignal var and the new temp as pushed to temp*/
                sp->pushedtotemp = TRUE ;
                ep->v.sp->pushedtotemp = TRUE;
                sp->allocate = FALSE;
                if (sp->imvalue)
                {
                    ep->isvolatile = sp->imvalue->offset->isvolatile;
                    ep->isrestrict = sp->imvalue->offset->isrestrict;
                    sp->imvalue->offset = ep ;
                }
                if (sp->imind)
                {
                    IMODELIST *iml = sp->imind;
                    ep->isvolatile = sp->imind->im->offset->isvolatile;
                    ep->isrestrict = sp->imind->im->offset->isrestrict;
                    while (iml)
                    {
                        iml->im->offset = ep;
                        iml = iml->next;
                    }
                }
                ep->v.sp->imvalue = sp->imvalue;
            }
            hr = hr->next;
        }
        temp = temp->next;
    }
}
Ejemplo n.º 26
0
TYPE *destSize(TYPE *tp1, TYPE *tp2, EXPRESSION **exp1, EXPRESSION **exp2, BOOLEAN minimizeInt, TYPE *atp)
/*
 * compare two types and determine if they are compatible for purposes
 * of the current operation.  Return an appropriate type.  Also checks for
 * dangerous pointer conversions...
 */
{
    int isctp1, isctp2;
    if (tp1->type == bt_any)
        return tp1;
    if (tp2->type == bt_any)
        return tp2;
    if (isvoid(tp1) || isvoid(tp2))
    {
        error(ERR_NOT_AN_ALLOWED_TYPE);
        return tp1;
    }
    if (isref(tp1))
        tp1 = basetype(tp1)->btp;
    if (isref(tp2))
        tp2 = basetype(tp2)->btp;
    tp1 = basetype(tp1);
    tp2 = basetype(tp2);
    isctp1 = isarithmetic(tp1);
    isctp2 = isarithmetic(tp2);
    
/*    if (isctp1 && isctp2 && tp1->type == tp2->type)
        return tp1 ;
*/
    if (tp1->type >= bt_float || tp2->type >= bt_float) {
    
        int isim1 = tp1->type >= bt_float_imaginary && tp1->type <= bt_long_double_imaginary;
        int isim2 = tp2->type >= bt_float_imaginary && tp2->type <= bt_long_double_imaginary;
        if (isim1 && !isim2 && tp2->type < bt_float_imaginary)
        {
            TYPE *tp ;
            if (tp1->type == bt_long_double_imaginary || tp2->type == bt_long_double)
                tp = &stdlongdoublecomplex;
            else if (tp1->type == bt_double_imaginary || tp2->type == bt_double
                || tp1->type == bt_long_long || tp1->type == bt_unsigned_long_long)
                tp = &stddoublecomplex;
            else
                tp = &stdfloatcomplex;
            if (exp1)
                 cast(tp, exp1);
            if (exp2)
                 cast(tp, exp2);
            return tp;
        }
        else if (isim2 && !isim1 && tp1->type < bt_float_imaginary)
        {
            TYPE *tp ;
            if (tp2->type == bt_long_double_imaginary || tp1->type == bt_long_double)
                tp = &stdlongdoublecomplex;
            else if (tp2->type == bt_double_imaginary || tp1->type == bt_double 
                || tp1->type == bt_long_long || tp1->type == bt_unsigned_long_long)
                tp = &stddoublecomplex;
            else
                tp = &stdfloatcomplex;
            if (exp1)
                 cast(tp, exp1);
            if (exp2)
                 cast(tp, exp2);
            return tp;
        }
        else if (tp1->type > tp2->type)
        {
            if (exp2)
                   cast(tp1, exp2);
        }
        else if (tp1->type < tp2->type)
        {
            if (exp1)
                cast(tp2, exp1);
        }

        if (tp1->type == bt_long_double_complex && isctp2)
            return tp1;
        if (tp2->type == bt_long_double_complex && isctp1)
            return tp2;
        
        if (tp1->type == bt_long_double_imaginary && isim2)
            return tp1;
        if (tp2->type == bt_long_double_imaginary && isim1)
            return tp2;
        if (tp1->type == bt_long_double && isctp2)
            return tp1;
        if (tp2->type == bt_long_double && isctp1)
            return tp2;
        if (tp1->type == bt_double_complex && isctp2)
            return tp1;
        if (tp2->type == bt_double_complex && isctp1)
            return tp2;
        if (tp1->type == bt_double_imaginary && isim2)
            return tp1;
        if (tp2->type == bt_double_imaginary && isim1)
            return tp2;
        if (tp1->type == bt_double && isctp2)
            return tp1;
        if (tp2->type == bt_double && isctp1)
            return tp2;
        if (tp1->type == bt_float_complex && isctp2)
            return tp1;
        if (tp2->type == bt_float_complex && isctp1)
            return tp2;
        if (tp1->type == bt_float_imaginary && isim2)
            return tp1;
        if (tp2->type == bt_float_imaginary && isim1)
            return tp2;
        if (tp1->type == bt_float && isctp2)
            return tp1;
        if (tp2->type == bt_float && isctp1)
            return tp2;
    }
    if (isctp1 && isctp2) {
        TYPE *rv ;
       enum e_bt t1, t2;
       t1 = tp1->type;
       t2 = tp2->type;
       /*
       if (cparams.prm_cplusplus && (t1 == bt_enum || t2 == bt_enum))
       {
           if (t1 == t2)
        {
            if (tp1->sp->mainsym == tp2->sp->mainsym)
            {
                return tp1;
            }
            genmismatcherror(ERR_ENUMMISMATCH, tp1, tp2);
        }			
       }
       */
        if (t1 == bt_enum)
            t1= bt_int;
        if (t2 == bt_enum)
            t2= bt_int;
        if (t1 == bt_wchar_t)
            t1 = bt_unsigned;
        if (t2 == bt_wchar_t)
            t2 = bt_unsigned;
        if (t1 < bt_int)
            t1= bt_int;
        if (t2 < bt_int)
            t2= bt_int;
        t1 = imax(t1, t2);
       rv = inttype(t1);
       if (rv->type != tp1->type && exp1)
         cast(rv, exp1);
       if (rv->type != tp2->type && exp2)
         cast(rv,exp2);
       return rv;
    } else { /* have a pointer or other exceptional case*/
        if (tp1->type == bt_void && tp2->type == bt_void)
            return tp1;
        if (tp1->type <= bt_unsigned_long_long && ispointer(tp2))
        {
            if (!ispointer(tp1))
                cast(tp2, exp1);
            return tp2;
        }
        if (tp2->type <= bt_unsigned_long_long && ispointer(tp1))
        {
            if (!ispointer(tp2))
                cast(tp1, exp2);
            return tp1;
        }
        if (isstructured(tp1)) {
            return tp2;
/*
            if (comparetypes(tp1, tp2, FALSE))
                return tp1;
            if (cparams.prm_cplusplus) {
                cppcast(tp2, tp1, exp1, FALSE, ERR_CPPMISMATCH);
            } else

                error(ERR_ILL_STRUCTURE_OPERATION);
            return tp2;
*/
        }
        if (isstructured(tp2)) {
            return tp1;
/*			
            if (comparetypes(tp1, tp2, FALSE))
                return tp2;
            if (cparams.prm_cplusplus) {
                cppcast(tp1, tp2, exp1, FALSE, ERR_CPPMISMATCH);
            } else

                error(ERR_ILL_STRUCTURE_OPERATION);
            return tp1;
*/
        }

        if (isfunction(tp1))
            if (isfunction(tp2) || ispointer(tp2))
                return tp1;
        if (isfunction(tp2))
            if (isfunction(tp1) || ispointer(tp1))
                return tp2;
        if (ispointer(tp1))
            if (ispointer(tp2))
            {
/*				if (tp1->type != tp2->type || !comparetypes(tp1->btp, tp2->btp, TRUE))
                    generror(ERR_SUSPICIOUS, 0, 0);
*/
                 return tp1;
            }
    }
    return tp1;
}
Ejemplo n.º 27
0
EXPRESSION *convertInitToExpression(TYPE *tp, SYMBOL *sp, SYMBOL *funcsp, INITIALIZER *init, EXPRESSION *thisptr, BOOLEAN isdest)
{
    EXPRESSION *rv = NULL, **pos = &rv;
    EXPRESSION *exp = NULL, **expp;
    EXPRESSION *expsym;
    BOOLEAN noClear = FALSE;
    if (sp)
        sp->destructed = FALSE;
    if (isstructured(tp) || isarray(tp))
    {
        INITIALIZER **i2 = &init;
        while (*i2)
            i2 = &(*i2)->next;
        initInsert(i2, NULL, NULL, tp->size, FALSE);
    }
    if (!sp)
    {
        if (thisptr)
            expsym = thisptr;
        else if (funcsp)
        {
            SYMBOL *sp = (SYMBOL *)basetype(funcsp->tp)->syms->table[0] ? (SYMBOL *)basetype(funcsp->tp)->syms->table[0]->p : NULL;
            if (sp && sp->thisPtr)
                expsym = varNode(en_auto, sp ); // this ptr
            else
                expsym = anonymousVar(sc_auto, tp);
        }
        else
        {
            expsym = intNode(en_c_i, 0);
            diag("convertInitToExpression: no this ptr");
        }
    }
    else switch (sp->storage_class)
    {
        case sc_auto:
        case sc_register:
        case sc_parameter:
            expsym = varNode(en_auto, sp);
            break;
        case sc_localstatic:
            if (sp->linkage3 == lk_threadlocal)
            {
                expsym = exprNode(en_add, thisptr, intNode(en_c_i, sp->offset));
            }
            else
            {
                expsym = varNode(en_label, sp);
            }
            break;
        case sc_static:
        case sc_global:
            if (sp->linkage3 == lk_threadlocal)
            {
                expsym = exprNode(en_add, thisptr, intNode(en_c_i, sp->offset));
            }
            else
            {
                expsym = varNode(en_global, sp);
            }
            break;
        case sc_member:
        case sc_mutable:
            if (thisptr)
                expsym = thisptr;
            else if (funcsp)
                expsym = varNode(en_auto, (SYMBOL *)basetype(funcsp->tp)->syms->table[0]->p); // this ptr
            else
            {
                expsym = intNode(en_c_i, 0);
                diag("convertInitToExpression: no this ptr");
            }
            expsym = exprNode(en_add, expsym, intNode(en_c_i, sp->offset));
            break;
        case sc_external:
/*			expsym = varNode(en_global, sp);
            break;
*/
        default:
            diag("convertInitToExpression: unknown sym type");
            expsym = intNode(en_c_i, 0);
            break;
    }	
    while (init)
    {
        exp = NULL;
        if (init->basetp)
        {
            if (init->noassign)
            {
                exp = init->exp;
                if (exp->type == en_thisref)
                    exp = exp->left;
                if (thisptr && exp->type == en_func)
                {
                    EXPRESSION *exp1 = init->offset ? exprNode(en_add, expsym, intNode(en_c_i, init->offset)) : expsym;
                    if (isarray(tp))
                    {
                        exp->v.func->arguments->exp = exp1;
                    }
                    else
                    {
                        exp->v.func->thisptr = exp1;
                    }
                }
                exp = init->exp;
            }
            else if (!init->exp)
            {
                // usually empty braces, coudl be an error though
                exp = exprNode(en_blockclear, expsym, NULL);
                exp->size = init->offset;
            }
            else if (isstructured(init->basetp) || isarray(init->basetp))
            {
                INITIALIZER *temp = init;
                if (isstructured(temp->basetp))
                {
                    EXPRESSION *exp2 = init->exp;
                    while(exp2->type == en_not_lvalue)
                        exp2 = exp2->left;
                    if (exp2->type == en_func && exp2->v.func->returnSP)
                    {
                        exp2->v.func->returnSP->allocate = FALSE;
                        exp2->v.func->returnEXP = expsym;
                        exp = exp2;
                        noClear = TRUE;
                    }
                    else if (exp2->type == en_thisref && exp2->left->v.func->returnSP)
                    {
                        exp2->left->v.func->returnSP->allocate = FALSE;
                        exp2->left->v.func->returnEXP = expsym;
                        exp = exp2;
                        noClear = TRUE;
                    }
                    else if (cparams.prm_cplusplus)
                    {
                        TYPE *ctype = init->basetp;
                        FUNCTIONCALL *funcparams = Alloc(sizeof(FUNCTIONCALL));
                        funcparams->arguments = Alloc(sizeof(INITLIST));
                        funcparams->arguments->tp = ctype;
                        funcparams->arguments->exp = exp2;
                        callConstructor(&ctype, &expsym, funcparams, FALSE, NULL, TRUE, FALSE, FALSE, FALSE, FALSE); 
                        exp = expsym;
                    }
                    else
                    {
                        exp = exprNode(en_blockassign, expsym, exp2);
                        exp->size = init->basetp->size;
                    }
                }
                else
                {
                    TYPE *btp = init->basetp;
                    while(isarray(btp))
                        btp = basetype(btp)->btp;
                    btp = basetype(btp);
                    while (temp)
                    {
                        if (temp->exp)
                            if (!isarithmeticconst(temp->exp) && !isconstaddress(temp->exp))
                                break;
                        temp = temp->next;
                    }
                    if (temp)
                    {
                        /* some members are non-constant expressions */
                        if (!cparams.prm_c99 && !cparams.prm_cplusplus)
                            error(ERR_C99_NON_CONSTANT_INITIALIZATION);
                        if (!sp)
                        {
                            expsym = anonymousVar(sc_auto, init->basetp);
                            sp = expsym->v.sp;
                        }
                        if (!isstructured(btp) || btp->sp->trivialCons)
                        {
                            exp = exprNode(en_blockclear, expsym, NULL);
                            exp->size = init->basetp->size;
                            exp = exprNode(en_void, exp, NULL);
                            expp = &exp->right;
                        }
                        else
                        {
                            expp = &exp;
                        }
                        {
                            EXPRESSION *right = init->exp;
                            if (!isstructured(btp))
                            {
                                EXPRESSION *asn = exprNode(en_add, expsym, intNode(en_c_i, init->offset));
                                deref(init->basetp, &asn);
                                cast(init->basetp, &right);
                                right = exprNode(en_assign, asn, right);
                            }
                            if (*expp)
                                *expp = exprNode(en_void, *expp, right);
                            else
                                *expp = right;
                            expp = &(*expp)->right;
                        }
                    }
                    else
                    {
                        /* constant expression */
                        SYMBOL *spc ;
                        IncGlobalFlag();
                        exp = anonymousVar(sc_localstatic, init->basetp);
                        spc = exp->v.sp;
                        spc->init = init ;
                        insertInitSym(spc);
                        insert(spc, localNameSpace->syms);
                        DecGlobalFlag();
                        spc->label =nextLabel++;
                        if (expsym)
                        {
                            if (cparams.prm_cplusplus && isstructured(init->basetp) && !init->basetp->sp->trivialCons)
                            {
                                TYPE *ctype = init->basetp;
                                FUNCTIONCALL *funcparams = Alloc(sizeof(FUNCTIONCALL));
                                funcparams->arguments = Alloc(sizeof(INITLIST));
                                funcparams->arguments->tp = ctype;
                                funcparams->arguments->exp = exp;
                                callConstructor(&ctype, &expsym, funcparams, FALSE, NULL, TRUE, FALSE, FALSE, FALSE, FALSE); 
                                exp = expsym;
                            }
                            else
                            {
                                exp = exprNode(en_blockassign, expsym, exp);
                                exp->size = init->basetp->size;
                            }
                        }
                    }
                }
            }
            else if (basetype(init->basetp)->type == bt_memberptr)
            {
                EXPRESSION *exp2 = init->exp;;
                while(exp2->type == en_not_lvalue)
                    exp2 = exp2->left;
                if (exp2->type == en_func && exp2->v.func->returnSP)
                {
                    exp2->v.func->returnSP->allocate = FALSE;
                    exp2->v.func->returnEXP = expsym;
                    exp = exp2;
                }
                else
                {
                    if (exp2->type == en_memberptr)
                    {
                        int lab = dumpMemberPtr(exp2->v.sp, init->basetp, TRUE);
                        exp2 = intNode(en_labcon, lab);
                    }
                    exp = exprNode(en_blockassign, expsym, exp2);
                    exp->size = init->basetp->size;
                }
            }
            else
            {
                EXPRESSION *exps = expsym;
                if (init->offset)
                    exps = exprNode(en_add, exps, intNode(en_c_i, init->offset));
                deref(init->basetp, &exps);
                exp = init->exp;
                if (exp->type == en_void)
                {
                    cast(init->basetp, &exp->right);
                    if (expsym)
                        exp->right = exprNode(en_assign, exps, exp->right);
                }
                else
                {
                    cast(init->basetp, &exp);
                    if (exps)
                        exp = exprNode(en_assign, exps, exp);
                }
            }
            if (sp && sp->init && isatomic(init->basetp) && needsAtomicLockFromType(init->basetp))
            {
                EXPRESSION *p1 = exprNode(en_add, expsym->left, intNode(en_c_i, init->basetp->size - ATOMIC_FLAG_SPACE));
                deref(&stdint, &p1);
                p1 = exprNode(en_assign, p1, intNode(en_c_i, 0));
                exp = exprNode(en_void, exp, p1);
            }
        }
        if (exp)
        {
            if (*pos)
            {
                *pos = exprNode(en_void, *pos, exp);
                pos = &(*pos)->right;
            }
            else
            {
                *pos = exp;
            }
        }
        init = init->next;
    }
    if (sp && sp->storage_class == sc_localstatic)
    {
        if (isdest)
        {
            rv = exprNode(en_voidnz, exprNode(en_void, sp->localInitGuard, rv), intNode(en_c_i, 0));        
        }
        else
        {
            EXPRESSION *guard = anonymousVar(sc_static, &stdint);
            insertInitSym(guard->v.sp);
            deref(&stdpointer, &guard);
            optimize_for_constants(&rv);
            rv = exprNode(en_voidnz, exprNode(en_void, 
                                              exprNode(en_not, guard, NULL), 
                                              exprNode(en_void, rv, exprNode(en_autoinc, guard, intNode(en_c_i, 1)))), intNode(en_c_i, 0));        
            sp->localInitGuard = guard;
        }
    }
    // plop in a clear block if necessary
    if (sp && !noClear && !isdest && (isarray(tp) || isstructured(tp) && (!cparams.prm_cplusplus || basetype(tp)->sp->trivialCons)))
    {
        EXPRESSION *fexp = expsym;
        EXPRESSION *exp;
        if (fexp->type == en_thisref)
            fexp = fexp->left->v.func->thisptr;
        exp = exprNode(en_blockclear, fexp, NULL); 
        exp->size = sp->tp->size;
        rv = exprNode(en_void, exp, rv);
    }
    if (isstructured(tp) && !cparams.prm_cplusplus)
    {
        if (*pos)
        {
            *pos = exprNode(en_void, *pos, expsym);
            pos = &(*pos)->right;
        }
        else
        {
            *pos = expsym;
        }
    }
    return rv;
}
Ejemplo n.º 28
0
void link_extendedtype(TYPE *tp1)
{
    TYPE *tp = basetype(tp1);
    if (tp->type == bt_pointer)
    {
        if (tp->vla)
        {
            int m = link_puttype(tp->btp);
            
            tp1->dbgindex = emit_type_ieee("T7,%X,T%X,T2A",tp->size,m);
        }
        else if (tp->array)
        {
            int m = link_puttype(tp->btp);
            tp1->dbgindex = emit_type_ieee("T6,%X,T%X,T2A,%d,%d",tp->size,m,0,tp->size/basetype(tp)->btp->size);
        }
        else
        {
            int m = link_puttype(tp->btp);
            tp1->dbgindex = emit_type_ieee("T1,%X,T%X",tp->size,m);
        }
        
    }
    else if (isfunction(tp))
    {
        tp1->dbgindex = dumpFunction(tp);
    }
    else 
    {
        int n = tp1->dbgindex = typeIndex++;
        if (tp->hasbits)
        {
            int m = link_BasicType(tp);
            emit_record_ieee("ATT%X,T3,%X,T%X,%d,%d.\r\n",n, tp->size, m, tp->startbit, tp->bits);
            
        }
        else if (isstructured(tp))
        {
            int sel;
            if (tp->type == bt_union)
            {
                sel = 5;
            }
            else
            {
                sel = 4;
            }
            if (tp->syms)
                dumpStructFields(sel, n, tp->size, tp->syms->table[0]);
            else
                dumpStructFields(sel, n, tp->size, NULL);
            emit_record_ieee("NT%X,%02X%s.\r\n", n, strlen(tp->sp->name), tp->sp->name);
        }
        else if (tp->type == bt_ellipse)
        {
           // ellipse results in no debug info
        }
        else // enum
        {
            int m;
            if (tp->type == bt_enum)
                if (tp->btp)
                    m  = link_BasicType(tp->btp);
                else
                    m = 42;
            else
                m = link_BasicType(tp);
    
            if (tp->syms)
                dumpEnumFields(8, n, m, tp->size, tp->syms->table[0]);
            else
                dumpEnumFields(8, n, m, tp->size, NULL);
            emit_record_ieee("NT%X,%02X%s.\r\n", n, strlen(tp->sp->name), tp->sp->name);
        }
    }
}
Ejemplo n.º 29
0
char *mangleType (char *in, TYPE *tp, BOOLEAN first)
{
    char nm[4096];
    int i;
    HASHREC *hr ;
    if(!tp)
    {
        sprintf(in, "%d%s", strlen("initializer-list"), "initializer-list");
        in += strlen(in);
    }
    else if (tp->type == bt_typedef)
    {
       in = mangleType(in, tp->btp, FALSE);
    }
    else if (isstructured(tp) && basetype(tp)->sp->templateLevel)
    {
        {
            if (isconst(tp))
                *in++ = 'x';
            if (isvolatile(tp))
                *in++ = 'y';
            if (islrqual(tp))
                *in++ = 'r';
            if (isrrqual(tp))
                *in++ = 'R';
        }
        in = mangleTemplate(in, basetype(tp)->sp, basetype(tp)->sp->templateParams);
    }
    else
    {
//        if (ispointer(tp) || isref(tp))
//        {
//            if (basetype(tp)->btp)
//            {
//                if (isconst(basetype(tp)->btp))
//                    *in++ = 'x';
//                if (isvolatile(basetype(tp)->btp))
//                    *in++ = 'y';
//            }
//        }
//        if (isfunction(tp))
        {
            if (isconst(tp))
                *in++ = 'x';
            if (isvolatile(tp))
                *in++ = 'y';
            if (islrqual(tp))
                *in++ = 'r';
            if (isrrqual(tp))
                *in++ = 'R';
        }
        tp = basetype(tp);
        switch (tp->type)
        {
        /*
            case bt_templateplaceholder:
                tplPlaceholder(nm, tp->lst.head->name, tp->lst.tail);
                sprintf(buf, "%d%s", strlen(nm), nm);
                buf += strlen(buf);
                break;
        */
            case bt_func:
            case bt_ifunc:
                if (basetype(tp)->sp && basetype(tp)->sp->parentClass && !first)
                {
                    *in++ = 'M';
                    in = getName(in, tp->sp->parentClass);
                    in += strlen(in);
                }
                *in++ = 'q';
                hr = tp->syms->table[0];
                while (hr)
                {
                    SYMBOL *sp = (SYMBOL *)hr->p;
                    if (!sp->thisPtr)
                        in = mangleType(in, sp->tp, TRUE);
                    hr = hr->next ;
                }
                *in++ = '$';
                // return value
                in = mangleType(in, tp->btp, TRUE);
                break;
            case bt_memberptr:
                *in++ = 'M';
                in = getName(in, tp->sp);
                if (isfunction(tp->btp))
                {
                    *in++ = 'q';
                    hr = basetype(tp->btp)->syms->table[0];
                    while (hr)
                    {
                        SYMBOL *sp = (SYMBOL *)hr->p;
                        if (!sp->thisPtr)
                            in = mangleType(in, sp->tp, TRUE);
                        hr = hr->next ;
                    }
                    *in++ = '$';
                    in = mangleType (in, tp->btp->btp, TRUE);
                }
                else
                {
                    *in++ = '$';
                    in = mangleType (in, basetype(tp)->btp, TRUE);
                }
                break;
            case bt_enum:
            case bt_struct:
            case bt_union:
            case bt_class:
                in = getName(in, tp->sp);
                break;
            case bt_bool:
                in = lookupName(in, "bool");
                in += strlen(in);
                break;
            case bt_unsigned_short:
                *in++ = 'u';
            case bt_short:
                *in++ = 's';
                break;
            case bt_unsigned:
                *in++ = 'u';
            case bt_int:
                *in++ = 'i';
                break;
            case bt_char16_t:
                *in++ = 'h';
                break;
            case bt_char32_t:
                *in++ = 'H';
                break;
            case bt_unsigned_long:
                *in++ = 'u';
            case bt_long:
                *in++ = 'l';
                break;
            case bt_unsigned_long_long:
                *in++ = 'u';
            case bt_long_long:
                *in++ = 'L';
                break;
            case bt_unsigned_char:
                *in++ = 'u';
            case bt_char:
                *in++ = 'c';
                break;
            case bt_signed_char:
                *in++ = 'S';
                *in++ = 'c';
                break;
            case bt_wchar_t:
                *in++ = 'C';
                break;
            case bt_float_complex:
                *in++ = 'F';
                break;
            case bt_double_complex:
                *in++ = 'D';
                break;
            case bt_long_double_complex:
                *in++ = 'G';
                break;
            case bt_float:
                *in++ = 'f';
                break;
            case bt_double:
                *in++ = 'd';
                break;
            case bt_long_double:
                *in++ = 'g';
                break;
            case bt_pointer:
                if (tp->nullptrType)
                {
                    in = lookupName(in, "nullptr_t");
                    in += strlen(in);
                }
                else
                {
                    if (first|| !tp->array)
                    {
                        *in++ = 'p';
                    }
                    else
                    {
                        sprintf(in,"A%ld",tp->btp->size ? tp->size / tp->btp->size : 0);
                        in += strlen(in);
                    }
                    in = mangleType(in, tp->btp, FALSE);
                }
                break;
            case bt_far:
                *in++ = 'P';
                in = mangleType(in, tp->btp, FALSE);
                break;
            case bt_lref:
                *in++ = 'r';
                in = mangleType(in, tp->btp, FALSE);
                break;
            case bt_rref:
                *in++ = 'R';
                in = mangleType(in, tp->btp, FALSE);
                break;
            case bt_ellipse:
                *in++ = 'e';
                break;
            case bt_void:
            case bt_any:
                *in++ = 'v';
                break;
            case bt_templateparam:
                in = getName(in, tp->templateParam->p->sym);
                break;
            case bt_templateselector:
            {
                TEMPLATESELECTOR *s = tp->sp->templateSelector;
                char *p;
                s = s->next;
                if (s->isTemplate)
                    p = mangleTemplate(nm, s->sym, s->templateParams);
                else
                    p = getName(nm, s->sym);
				p[0] =0;
				if (strlen(nm) > sizeof(nm))
                    p = mangleTemplate(nm, s->sym, s->templateParams);
                s = s->next ;
                while (s)
                {
                    strcat(nm , "@");
                    strcat(nm , s->name);
                    s= s->next;
                }
                p = nm;
                while (isdigit(*p))
                    p++;
                sprintf(in, "%d%s", strlen(p), p);
                in += strlen(in);
            }
                break;
            case bt_templatedecltype:
                // the index is being used to make names unique so two decltypes won't collide when storing them
                // in a symbol table...
                declTypeIndex = (declTypeIndex + 1) %1000;
                *in++ = 'E';
                sprintf(in, "%03d", declTypeIndex);
                in += 3;
                break;
            case bt_aggregate:
                in = getName(in, tp->sp);
                break;
            default:
                diag("mangleType: unknown type");
                break;
        }
    }
    *in= 0;
    return in;
}
Ejemplo n.º 30
0
static BOOLEAN is_convertible_to(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp)
{
    BOOLEAN rv = TRUE;
    FUNCTIONCALL funcparams;
    memset(&funcparams, 0, sizeof(funcparams));
    funcparams.sp = sym;
    *lex = getTypeList(*lex, funcsp, &funcparams.arguments);
    if (funcparams.arguments && funcparams.arguments->next && !funcparams.arguments->next->next) 
    {
        TYPE *from = funcparams.arguments->tp;
        TYPE *to = funcparams.arguments->next->tp;
        if (isref(from) && isref(to))
        {
            if (basetype(to)->type == bt_lref)
            {
                if (basetype(from)->type == bt_rref)
                    rv = FALSE;
            }
        }
        else if (isref(from))
            rv = FALSE;
        if (isfunction(from))
            from = basetype(from)->btp;
        if (rv)
        {
            while (isref(from))
                from = basetype(from)->btp;
            while (isref(to))
                to = basetype(to)->btp;
            rv = comparetypes(to, from, FALSE);
            if (!rv && isstructured(from) && isstructured(to))
			{
               if (classRefCount(basetype(to)->sp, basetype(from)->sp) == 1)
                   rv = TRUE;
			}
			if (!rv && isstructured(from))
			{
				SYMBOL *sp = search("$bcall", basetype(from)->syms);
				if (sp)
				{
					HASHREC *hr = sp->tp->syms->table[0];
					while (hr)
					{
						if (comparetypes(basetype(((SYMBOL *)hr->p)->tp)->btp, to, FALSE))
						{
							rv= TRUE;
							break;
						}
						hr = hr->next;
					}
				}
			}
        }
    }
    else
    {
        rv = FALSE;
    }
    *exp = intNode(en_c_i, rv);
    *tp = &stdint;
    return TRUE;
}