⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inline.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 2 页
字号:
            DIAG("Invalid expr type in inlineexpr");
    }
    return temp;
}

//-------------------------------------------------------------------------

ENODE *asm_inlinestmt(ENODE *e)
{
    return e;
}

//-------------------------------------------------------------------------

SNODE *inlinestmt(SNODE *block)
/*
 *      scan will gather all optimizable expressions into the expression
 *      list for a block of statements.
 */
{
    SNODE *out = 0,  **outptr = &out;
    while (block != 0)
    {
        *outptr = xalloc(sizeof(SNODE));
        memcpy(*outptr, block, sizeof(SNODE));
        (*outptr)->next = NULL;
        switch (block->stype)
        {
            case st_tryblock:
                break;
            case st_throw:
                if (block->exp)
                {
                    (*outptr)->exp = inlineexpr(block->exp);
                    opt4(&(*outptr)->exp);
                }
                break;
            case st_return:
            case st_expr:
                (*outptr)->exp = inlineexpr(block->exp);
                opt4(&(*outptr)->exp);
                break;
            case st_while:
            case st_do:
                (*outptr)->exp = inlineexpr(block->exp);
                (*outptr)->s1 = inlinestmt(block->s1);
                opt4(&(*outptr)->exp);
                break;
            case st_for:
                (*outptr)->label = inlineexpr(block->label);
                (*outptr)->exp = inlineexpr(block->exp);
                (*outptr)->s1 = inlinestmt(block->s1);
                (*outptr)->s2 = inlineexpr(block->s2);
                opt4(&(*outptr)->exp);
                opt4(&(*outptr)->label);
                break;
            case st_if:
                (*outptr)->exp = inlineexpr(block->exp);
                (*outptr)->s1 = inlinestmt(block->s1);
                (*outptr)->s2 = inlinestmt(block->s2);
                opt4(&(*outptr)->exp);
                break;
            case st_switch:
                (*outptr)->exp = inlineexpr(block->exp);
                (*outptr)->s1 = inlinestmt(block->s1);
                opt4(&(*outptr)->exp);
                break;
            case st_case:
                (*outptr)->s1 = inlinestmt(block->s1);
                break;
            case st_block:
                (*outptr)->exp = inlinestmt(block->exp);
                break;
            case st_asm:
                if (block->exp)
                    (*outptr)->exp = asm_inlinestmt(block->exp);
                break;
            case st_line:
                break;
            default:
                DIAG("Invalid block type in inlinestmt");
                break;
        }
        block = block->next;
        outptr = &(*outptr)->next;
    }
    return out;
}

//-------------------------------------------------------------------------

ENODE *inlinefuncargs(ENODE *node, SYM *sp)
{
    ENODE *xnode,  *tnode;
    if (!node)
        return node;
    xnode = node->v.p[0];
    if (node->v.p[1])
        inlinefuncargs(node->v.p[1], sp->next);

    if (sp->tp->uflags &UF_ALTERED)
        goto dodef;
    tnode = xnode;
    while (castvalue(tnode))
        tnode = tnode->v.p[0];
    if (lvalue(tnode))
    {
        switch (tnode->v.p[0]->nodetype)
        {
            case en_napccon:
            case en_autocon:
            case en_autoreg:
            case en_labcon:
                xnode = tnode->v.p[0];
                break;
            default:
                dodef: xnode = makenode(en_autocon, sp, 0);
                sp->funcparm = FALSE;
                sp->value.i = block_nesting + 1;
                tnode = xnode;
                deref(&tnode, sp->tp);
                tnode = makenode(en_assign, tnode, node->v.p[0]);
                opt4(&tnode);
                *argnext = xalloc(sizeof(SNODE));
                (*argnext)->stype = st_expr;
                (*argnext)->exp = tnode;
                argnext = &(*argnext)->next;
                break;
        }
    }
    else
    {
        goto dodef;
        //		if (isintconst(tnode->nodetype))
        //			xnode = node->v.p[0] ;
        //		else
        //			goto dodef;
    }
    sp->value.classdata.inlinefunc = xnode;
    return node;
}

//-------------------------------------------------------------------------

void inlinereblock(SYM *sp)
/* Copy all the func args into the xsyms table.
 * This copies the function parameters twice...
 */
{
    SYM *head = sp->tp->lst.head;
    LIST *l;
    xsyms.head = xsyms.tail = 0;
    if (head != (SYM*) - 1)
    while (head)
    {
        SYM *v = copysym(head);
        if (!v->funcparm)
        {
            v->value.i += block_nesting;
        }
        inlineinsert(v);
        head = head->next;
    }
    global_flag++;
    l = sp->value.classdata.inlinefunc->syms;
    while (l)
    {
        head = l->data;
        if (head != (SYM*) - 1)
        {
            while (head)
            {
                if (!inlineSearch(head))
                {
                    SYM *v = copysym(head);
                    if (!v->funcparm)
                    {
                        v->value.i += block_nesting;
                    }
                    inlineinsert(v);
                }
                head = head->next;
            }
        }
        l = l->link;
    }
    global_flag--;
}

//-------------------------------------------------------------------------

#ifdef XXXXX
    void inlinerename(TABLE *xsyms)
    {
        SYM *head = xsyms->head;
        char buf[100];
        while (head)
        {
            sprintf(buf, "$TEMPARG%d", namenumber++);
            head->name = litlate(buf);
            head = head->next;
        }
    }
#endif 
void redoParameters(SYM *sp)
{
    SYM *sp1 = sp->tp->lst.head;
    int poffset = 0;
    poffset = stdretblocksize; /* size of return block */
    if (!sp->pascaldefn && isstructured(sp->tp->btp))
    {
        poffset += stdaddrsize;
    }
    if ((sp->value.classdata.cppflags &PF_MEMBER) && !(sp
        ->value.classdata.cppflags &PF_STATIC))
        poffset += stdaddrsize;
    if (sp->farproc)
        poffset += stdintsize;
    if (!sp->pascaldefn)
    while (sp1)
    {
        if (sp1->tp->type != bt_pointer && sp1->tp->type != bt_farpointer &&
            sp1->tp->type != bt_segpointer && sp1->tp->size < stdintsize)
        {
            sp1->value.i = poffset + funcvaluesize(sp1->tp->size);
            poffset += stdintsize;
        }
        else
        {
            sp1->value.i = poffset;
            if (sp1->tp->type == bt_pointer)
                poffset += stdaddrsize;
            else
            {
                poffset += sp1->tp->size;
                if (poffset % stdintsize)
                    poffset += stdintsize - poffset % stdintsize;
            }
        }
        sp1 = sp1->next;
    }

}

//-------------------------------------------------------------------------

ENODE *doinline(ENODE *node)
{
    SYM *lastinlinesp;
    ENODE *out,  *xnode,  *revarg = 0,  *arg;
    SYM *sp,  *newsp,  *dc;
    argstmt = 0;
    argnext = &argstmt;
    thisn = 0;
    if (node->nodetype == en_thiscall)
    {
        thisn = node->v.p[0];
        xnode = node->v.p[1];
        if (!xnode)
        {
            return node;
        }
    }
    else
        xnode = node;
    if (xnode->nodetype != en_pfcall && xnode->nodetype != en_fcall && xnode
        ->nodetype != en_sfcall)
    {
        return node;
    }
    if (xnode->v.p[1]->v.p[0]->v.p[0]->nodetype != en_nacon && xnode->v.p[1]
        ->v.p[0]->v.p[0]->nodetype != en_napccon)
    {
        return node;
    }
    sp = xnode->v.p[1]->v.p[0]->v.p[0]->v.sp;
    if (!(sp->value.classdata.cppflags &PF_INLINE) || (sp
        ->value.classdata.cppflags &PF_INSTANTIATED))
    {
        return node;
    }
    if (!(sp->value.classdata.inlinefunc))
    {
//        gensymerror(ERR_UNDEFINED, sp->name);
        LIST *l;
        sp->value.classdata.cppflags &= ~PF_INLINE;
        sp->value.classdata.cppflags |= PF_INSTANTIATED;
        global_flag++;
        l = xalloc(sizeof(LIST));
        global_flag--;
        l->data = sp;
        l->link = instantiated_inlines;
        instantiated_inlines = l;
        return node;
    }
    if (thisn)
    if (thisn->nodetype == en_conslabel || thisn->nodetype == en_thiscall ||
        thisn->nodetype == en_callblock || thisn->nodetype == en_scallblock ||
        thisn->nodetype == en_pcallblock)
    {
        LIST *l;
        sp->value.classdata.cppflags &= ~PF_INLINE;
        sp->value.classdata.cppflags |= PF_INSTANTIATED;
        global_flag++;
        l = xalloc(sizeof(LIST));
        global_flag--;
        l->data = sp;
        l->link = instantiated_inlines;
        instantiated_inlines = l;
        return node;
    }
    lastinlinesp = inlinesp;
    inlinesp = sp;
    dc = declclass;
    declclass = sp->parentclass;
    if (sp->recalculateParameters)
        redoParameters(sp);
    sp->recalculateParameters = FALSE;
    inlinereblock(sp);
    newsp = copysym(sp);
    arg = xnode->v.p[1]->v.p[1]->v.p[0];
    while (arg)
    {
        ENODE *temp = arg->v.p[1];
        arg->v.p[1] = revarg;
        revarg = arg;
        arg = temp;
    }
    xnode->v.p[1]->v.p[1]->v.p[0] = 0;
    out = inlinefuncargs(revarg, xsyms.head);
    newsp->value.classdata.inlinefunc = xalloc(sizeof(INLINEFUNC));
    newsp->value.classdata.inlinefunc->stmt = inlinestmt(sp
        ->value.classdata.inlinefunc->stmt);
    out = makenode(en_void, copy_enode(xnode->v.p[1]->v.p[0]), 0);
    out = makenode(xnode->nodetype, inlineexpr(xnode->v.p[0]), out);
    out->v.p[1]->v.p[0]->v.p[0]->v.sp = newsp;
    if (argstmt)
    {
        *argnext = newsp->value.classdata.inlinefunc->stmt;
        newsp->value.classdata.inlinefunc->stmt = argstmt;
    }
    if (thisn)
        out = makenode(en_thiscall, thisn, out);
    //   inlinerename(&xsyms);
    addblocklist(xsyms.head, 0);
    //   /* quick check against nested inlines */
    //   if (currentfunc)
    //      currentfunc->value.classdata.cppflags &= ~PF_INLINE;
    declclass = dc;
    inlinesp = lastinlinesp;
    return out;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -