📄 inline.c
字号:
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 + -