Пример #1
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;
}
Пример #2
0
LEXEME *concatStrings(LEXEME *lex, EXPRESSION **expr, enum e_lexType *tp, int *elems)
{
    STRING *data;
    lex = concatStringsInternal(lex, &data, elems);
    IncGlobalFlag();
    *expr = stringlit(data);
    DecGlobalFlag();
    *tp = data->strtype;
    return lex;
}
Пример #3
0
LEXEME *concatStringsInternal(LEXEME *lex, STRING **str, int *elems)
{
    SLCHAR **list;
    char *suffix = NULL;
    int count = 3;
    int pos = 0 ;
    enum e_lexType type = l_astr;
    STRING *string;
    IncGlobalFlag();
    list = (SLCHAR **)Alloc(sizeof(SLCHAR *) * count);
    while (lex && (lex->type == l_astr || lex->type == l_wstr || lex->type == l_ustr || lex->type == l_Ustr))
    {
        
        if (lex->type == l_Ustr)
            type = l_Ustr;
        else if (type != l_Ustr && lex->type == l_ustr)
            type = l_ustr;
        else if (type != l_Ustr && type != l_ustr && lex->type == l_wstr)
            type = l_wstr;
        if (lex->suffix)
        {
            if (suffix)
            {
                if (strcmp(lex->suffix, suffix) != 0)
                    error(ERR_LITERAL_SUFFIX_MISMATCH);
            }
            else
            {
                suffix = lex->suffix;
            }
        }
        if (pos >= count)
        {
            SLCHAR **h = (SLCHAR **)Alloc(sizeof(SLCHAR *) * (count + 10));
            memcpy(h, list, sizeof(SLCHAR *) * count);
            list = h;
            count += 10;
        }
        if (elems)
            *elems += ((SLCHAR *)lex->value.s.w)->count;
        list[pos++] = (SLCHAR *)lex->value.s.w;
        lex = getsym();
    }
    string = (STRING *)Alloc(sizeof(STRING));
    string->strtype = type;
    string->size = pos;
    string->pointers = Alloc(pos * sizeof(SLCHAR * ));
    string->suffix = suffix;
    memcpy(string->pointers, list, pos * sizeof(SLCHAR *));
    *str = string;
    DecGlobalFlag();
    return lex;
}
Пример #4
0
/*-------------------------------------------------------------------------*/
void gather_cases(CASEDATA *cd, struct cases *cs)
{
    int pos = 0;
    if (!cs->ptrs) {
        IncGlobalFlag();
        cs->ptrs = (struct caseptrs *)Alloc((cs->count) * sizeof(struct caseptrs));
        DecGlobalFlag();
    }
    while (cd)
    {
        cs->ptrs[pos].label = cd->label;
        cs->ptrs[pos++].id = cd->val;
        cd = cd->next;
    }
}
Пример #5
0
LCHAR *wlitlate(LCHAR *name)
{
    LCHAR *p = name;
    int count=0;
    LCHAR *rv;
    while (*p)
        p++, count++;
    IncGlobalFlag();
    rv = (LCHAR *)Alloc((count + 1) * sizeof(LCHAR));
    DecGlobalFlag();
    p = name;
    count = 0;
    while (*p)
        rv[count++] = *p++;
    rv[count] = 0;
    return rv;
}
Пример #6
0
SYMBOL *gen_vsn_virtual_thunk(SYMBOL *func, int ofs)
{
        QUAD *oi = intermed_head, *ot = intermed_tail;		
        SYMBOL *sp;
        IMODE *ap1,  *ap2;
        char buf[256];
        //sprintf(buf, "@$vsn%s$%d", func->decoratedName, ofs);
        sp = search(buf, gsyms);
        if (sp)
            return sp;
        intermed_head = intermed_tail = NULL;
        blockMax = 0;
        blockCount = tempCount = 0;
        exitBlock = 0;
        IncGlobalFlag();
        sp = Alloc(sizeof(SYMBOL));
        sp->storage_class = sc_static;
        sp->value.i = ofs;
        sp->name = sp->decoratedName = litlate(buf);
        sp->errname = sp->decoratedName;
        sp->staticlabel = FALSE;
        sp->tp = func->tp;
        sp->gennedvirtfunc = TRUE;
        insert(sp, gsyms);
        DecGlobalFlag();
        gen_virtual(sp, FALSE);
        addblock(i_goto);
        gen_icode(i_substack, NULL, ap2 = tempreg(ISZ_ADDR, 0), NULL );
        gen_icode(i_add, ap1 = tempreg(ISZ_ADDR, 0), ap2, make_immed(ISZ_NONE, getSize(bt_pointer)));
        ap1 = indnode(ap1, ISZ_ADDR);
        gen_icode(i_add, ap1, ap1 , make_immed(ISZ_NONE, - ofs));
        ap1 = make_imaddress(varNode(en_napccon, func), 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;
}
Пример #7
0
IMODE *set_symbol(char *name, int isproc)
/*
 *      generate a call to a library routine.
 */
{
    SYMBOL *sp;
    IMODE *result;
    (void) isproc;
    sp = gsearch(name);
    if (sp == 0)
    {
        LIST *l1;
        IncGlobalFlag();
        sp = (SYMBOL *)Alloc(sizeof(SYMBOL));
        sp->storage_class = sc_external;
        sp->name = sp->errname = sp->decoratedName = litlate(name);
        sp->genreffed = TRUE;
        sp->tp = (TYPE *)Alloc(sizeof(TYPE));
        sp->tp->type = isproc ? bt_func : bt_int;
        sp->safefunc = TRUE;
        insert(sp, globalNameSpace->syms);
        InsertExtern(sp);
        DecGlobalFlag();
    }
    else
    {
        if (sp->storage_class == sc_overloads)
            sp = (SYMBOL *)(sp->tp->syms->table[0]->p);
    }
    result = (IMODE *)Alloc(sizeof(IMODE));
    result->offset = varNode(en_global, sp);
    result->mode = i_direct;
    if (isproc)
    {
        result->offset->type = en_pc;
        if (chosenAssembler->arch->libsasimports)
            result->mode = i_direct;
        else
            result->mode = i_immed;
    }
    return result;
}
Пример #8
0
LCHAR *wlitlate(LCHAR *name)
{
#ifndef BORLAND
    extern int wcslen(short *);
#endif
    LCHAR *p = name;
    int count;
    LCHAR *rv;
    count = wcslen(name);
    while (*p)
        p++, count++;
    IncGlobalFlag();
    rv = (LCHAR *)Alloc((count + 1) * sizeof(LCHAR));
    DecGlobalFlag();
    p = name;
    count = 0;
    while (*p)
        rv[count++] = *p++;
    rv[count] = 0;
    return rv;
}
Пример #9
0
LEXEME *expression_lambda(LEXEME *lex, SYMBOL *funcsp, TYPE *atp, TYPE **tp, EXPRESSION **exp, int flags)
{
    LAMBDA *self;
    SYMBOL *vpl, *ths;
    HASHREC *hrl;
    TYPE *ltp;
    STRUCTSYM ssl;
    if (funcsp)
        funcsp->noinline = TRUE;
    IncGlobalFlag();
    self = Alloc(sizeof(LAMBDA));
    ltp = Alloc(sizeof(TYPE));
    ltp->type = bt_struct;
    ltp->syms = CreateHashTable(1);
    ltp->tags = CreateHashTable(1);
    ltp->size = 0;
    self->captured = CreateHashTable(1);
    self->oldSyms = localNameSpace->syms;
    self->oldTags = localNameSpace->tags;
    self->index = lambdaIndex;
    self->captureMode = cmNone;
    self->isMutable = FALSE;
    self->captureThis = FALSE;
    self->cls = makeID(sc_type, ltp, NULL, LambdaName());
    ltp->sp = self->cls;
    SetLinkerNames(self->cls, lk_cdecl);
    self->cls->islambda = TRUE;
    self->cls->structAlign = getAlign(sc_global, &stdpointer);
    self->func = makeID(sc_member, ltp, NULL, "$internalFunc");
    self->func->parentClass = self->cls;
    self->functp = &stdauto;
    self->enclosingFunc = theCurrentFunc;
    if (lambdas)
        lambdas->prev = self;
    self->next = lambdas;
    lambdas = self;
    
    localNameSpace->syms = CreateHashTable(1);
    localNameSpace->tags = CreateHashTable(1);
    if (lambdas->next)
    {
        self->lthis = lambdas->next->lthis;
    }
    else if (funcsp && funcsp->parentClass)
    {
        self->lthis = ((SYMBOL *)funcsp->tp->syms->table[0]->p);
    }
    lex = getsym(); // past [
    if (funcsp)
    {
        // can have a capture list;
        if (MATCHKW(lex, assign))
        {
            lex = getsym();
            if (MATCHKW(lex, comma) || MATCHKW(lex, closebr))
            {
                self->captureMode = cmValue;
                skip(&lex, comma);
            }
            else
            {
                lex = backupsym();
            }
        }
        else if (MATCHKW(lex, and))
        {
            lex = getsym();
            if (MATCHKW(lex, comma) || MATCHKW(lex, closebr))
            {
                self->captureMode = cmRef;
                skip(&lex, comma);
            }
            else
            {
                lex = backupsym();
            }
        }
        if (!MATCHKW(lex, comma) && !MATCHKW(lex, closebr))
        {
            do            
            {
                enum e_cm localMode = self->captureMode;
                if (MATCHKW(lex, comma))
                    skip(&lex, comma);
                if (MATCHKW(lex, kw_this))
                {
                    lex = getsym();
                    if (localMode == cmValue || !self->lthis)
                    {
                        error(ERR_CANNOT_CAPTURE_THIS);
                    }
                    else
                    {
                        if (self->captureThis)
                        {
                            error(ERR_CAPTURE_ITEM_LISTED_MULTIPLE_TIMES);
                        }
                        self->captureThis = TRUE;
                        lambda_capture(NULL, cmThis, TRUE);
                    }
                    continue;
                }
                else if (MATCHKW(lex, and))
                {
                    if (localMode == cmRef)
                    {
                        error(ERR_INVALID_LAMBDA_CAPTURE_MODE);
                    }
                    localMode = cmRef;
                    lex = getsym();
                }
                else 
                {
                    if (localMode == cmValue)
                    {
                        error(ERR_INVALID_LAMBDA_CAPTURE_MODE);
                    }
                    localMode = cmValue;
                }
                if (ISID(lex))
                {
                    SYMBOL *sp = search(lex->value.s.a, localNameSpace->syms);
                    LAMBDA *current = lambdas;
                    while (current && !sp)
                    {
                        sp = search(lex->value.s.a, current->oldSyms);
                        current = current->next;
                        
                    }
                    lex = getsym();
                    if (sp)
                    {
                        if (sp->packed)
                        {
                            if (!MATCHKW(lex, ellipse))
                                error(ERR_PACK_SPECIFIER_REQUIRED_HERE);
                            else
                                lex = getsym();
                        }
                        if (sp->packed)
                        {
                            int n;
                            TEMPLATEPARAMLIST * templateParam = sp->tp->templateParam->p->byPack.pack;
                            HASHREC *hr;
                            for (n=0; templateParam; templateParam = templateParam->next, n++);
                            hr = funcsp->tp->syms->table[0];
                            while (hr && ((SYMBOL *)hr->p) != sp)
                                hr = hr->next;
                            while (hr && n)
                            {
                                lambda_capture((SYMBOL *)hr->p, localMode, TRUE);
                                hr = hr->next;
                                n--;
                            }
                        }
                        else
                        {
                            lambda_capture(sp, localMode, TRUE);
                        }
                    }
                    else
                        errorstr(ERR_UNDEFINED_IDENTIFIER, lex->value.s.a);
                }
                else
                {
                    error(ERR_INVALID_LAMBDA_CAPTURE_MODE);
                }
            } while (MATCHKW(lex, comma));
        }
        needkw(&lex, closebr);
    }
    else
    {
        if (!MATCHKW(lex, closebr))
        {
            error(ERR_LAMBDA_CANNOT_CAPTURE);
        }
        else
        {
            lex = getsym();
        }
    }
    if (MATCHKW(lex, openpa))
    {
        TYPE *tpx = &stdvoid;
        HASHREC *hr;
        lex = getFunctionParams(lex, NULL, &self->func, &tpx, FALSE, sc_auto);
        self->funcargs = self->func->tp->syms->table[0];
        hr = self->func->tp->syms->table[0];
        while (hr)
        {
            SYMBOL *sym = (SYMBOL *)hr->p;
            if (sym->init)
            {
                error(ERR_CANNOT_DEFAULT_PARAMETERS_WITH_LAMBDA);
            }
            hr = hr->next;
        }
        if (MATCHKW(lex, kw_mutable))
        {
            HASHREC *hr = self->captured->table[0];
            while (hr)
            {
                LAMBDASP *lsp = (LAMBDASP *)hr->p;
                if (lsp->sym->lambdaMode == cmValue)
                {
                    lsp->sym->tp = basetype(lsp->sym->tp);
                }
                hr = hr->next;
            }
            self->isMutable = TRUE;
            
            lex = getsym();
        }
        ParseAttributeSpecifiers(&lex, funcsp, TRUE);
        if (MATCHKW(lex, pointsto))
        {
            lex = getsym();
            lex = get_type_id(lex, &self->functp, funcsp, sc_cast, FALSE, TRUE);
        }
    }
    else
    {
        TYPE *tp1 = Alloc(sizeof(TYPE));
        SYMBOL *spi;
        tp1->type = bt_func;
        tp1->size = getSize(bt_pointer);
        tp1->btp = &stdvoid;
        tp1->sp = self->func;
        self->func->tp = tp1;
        spi = makeID(sc_parameter, tp1, NULL, AnonymousName());
        spi->anonymous = TRUE;
        spi->tp = Alloc(sizeof(TYPE));
        spi->tp->type = bt_void;
        insert(spi, localNameSpace->syms);
        SetLinkerNames(spi, lk_cpp);
        self->func->tp->syms = localNameSpace->syms;
        self->funcargs = self->func->tp->syms->table[0];
        self->func->tp->syms->table[0] = NULL;
    }
    vpl = makeID(sc_parameter, &stdpointer, NULL, AnonymousName());
    vpl->assigned = vpl->used = TRUE;
    SetLinkerNames(vpl, lk_cdecl);
    hrl = Alloc(sizeof(HASHREC));
    hrl->p = (struct _hrintern_ *)vpl;
    hrl->next = lambdas->func->tp->syms->table[0];
    lambdas->func->tp->syms->table[0] = hrl;
    vpl = makeID(sc_parameter, &stdpointer, NULL, AnonymousName());
    vpl->assigned = vpl->used = TRUE;
    SetLinkerNames(vpl, lk_cdecl);
    hrl = Alloc(sizeof(HASHREC));
    hrl->p = (struct _hrintern_ *)vpl;
    hrl->next = lambdas->func->tp->syms->table[0];
    lambdas->func->tp->syms->table[0] = hrl;
    SetLinkerNames(lambdas->func, lk_cdecl);
    injectThisPtr(lambdas->func, basetype(lambdas->func->tp)->syms);
    lambdas->func->tp->btp = self->functp;
    lambdas->func->linkage = lk_virtual;
    lambdas->func->isInline = TRUE;
    ssl.str = self->cls;
    ssl.tmpl = NULL;
    addStructureDeclaration(&ssl);
    ths = makeID(sc_member, &stdpointer, NULL, "$this");
    lambda_insert(ths, lambdas);
    if (MATCHKW(lex, begin))
    {
        lex = body(lex, self->func);
    }
    else
    {
        error(ERR_LAMBDA_FUNCTION_BODY_EXPECTED);
    }
    dropStructureDeclaration();
    localNameSpace->syms = self->oldSyms;
    localNameSpace->tags = self->oldTags;
    inferType();
    finishClass();
    *exp = createLambda(0);
    *tp = lambdas->cls->tp;
    lambdas = lambdas->next;
    if (lambdas)
        lambdas->prev = NULL;
    DecGlobalFlag();
    return lex;
}
Пример #10
0
SYMBOL *lambda_capture(SYMBOL *sym, enum e_cm mode, BOOLEAN isExplicit)
{
    if (lambdas)
    {
        if (mode == cmThis)
        {
            if (!sym || (lambdas->lthis && sym->parentClass == basetype(lambdas->lthis->tp)->btp->sp))
            {
                if (lambdas->captureThis)
                {
                    BOOLEAN errorflg = FALSE;
                    LAMBDA *check = lambdas;
                    // have to try to replicate the symbol into the current context
                    while (check && !error)
                    {
                        if (check->captureMode == cmNone)
                        {
                            if (isExplicit)
                            {
                                if (lambdas->prev)
                                {
                                    errorflg = TRUE;
                                    errorstr(ERR_EXPLICIT_CAPTURE_BLOCKED, "this");
                                }
                            }
                            else
                            {
                                errorflg = TRUE;
                                errorstr(ERR_IMPLICIT_CAPTURE_BLOCKED, "this");
                            }
                        }
                        else if (check->captureMode == cmValue && isExplicit)
                        {
                            errorflg = TRUE;
                            errorstr(ERR_EXPLICIT_CAPTURE_BLOCKED, "this");
                        }
                        check = check->next;
                    }
                    if (!errorflg)
                    {
                        check = lambdas;
                        while (check)
                        {
                            check->captureThis = TRUE;
                            check = check->next;
                        }
                    }
                }
                else
                {
                     errorstr(ERR_IMPLICIT_CAPTURE_BLOCKED, "this");
                }
            }
        }
        else
        {
            if (sym->parent != lambdas->func)
            {
                if (sym->storage_class != sc_auto && sym->storage_class != sc_parameter)
                {
                    error(ERR_MUST_CAPTURE_AUTO_VARIABLE);
                }
                else
                {
                    LAMBDA *current = lambdas;
                    SYMBOL *sym2 = NULL;
                    LAMBDA *check;
                    while (current)
                    {
                        LAMBDASP *lsp = (LAMBDASP *)search(sym->name, current->captured);
                        if (lsp)
                        {
                            sym2 = lsp->sym;
                            break;
                        }
                        current = current->next;
                    }
                    if (sym2)
                    {
                        if (lambdas == current && isExplicit)
                        {
                            error(ERR_CAPTURE_ITEM_LISTED_MULTIPLE_TIMES);        
                        }
                        sym = sym2;
                        current = current->prev;
                    }
                    else
                    {
                        current = lambdas;
                        while (current->next) current = current->next;
                    }
                    check = current;
                    // have to try to replicate the symbol into the current context
                    while (check)
                    {
                        if (check->captureMode == cmNone)
                        {
                            if (isExplicit)
                            {
                                if (check->prev)
                                {
                                    check = NULL;
                                    errorsym(ERR_EXPLICIT_CAPTURE_BLOCKED, sym);
                                }
                            }
                            else
                            {
                                check = NULL;
                                errorsym(ERR_IMPLICIT_CAPTURE_BLOCKED, sym);
                            }
                        }
                        if (check)
                            check = check->prev;
                    }
                    IncGlobalFlag();
                    while (current)
                    {
                        // we are replicating captures through intermediate lambdas
                        // to make it easier to handle inner lambda creation.
                        LAMBDASP *ins = Alloc(sizeof(LAMBDASP));
                        ins->name = sym->name;
                        ins->parent = sym;
                        sym = clonesym(sym);
                        sym->lambdaMode = mode == cmNone ? current->captureMode : mode;
                        sym->tp = lambda_type(sym->tp, sym->lambdaMode);
                        sym->storage_class = sc_member;
                        sym->parent = current->func;
                        sym->init = NULL;
                        lambda_insert(sym, current);
                        ins->sym = sym;
                        ins->enclosing = current;
                        insert((SYMBOL *)ins, current->captured);
                        current = current->prev;
                    }
                    DecGlobalFlag();
                }
            }
        }
    }
    return sym;
}
Пример #11
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;
}
Пример #12
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;
    }
}