📄 inline.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "diag.h"
extern int block_nesting;
extern SYM *currentfunc, *declclass;
extern TABLE lsyms;
extern int stdretblocksize, stdaddrsize, stdintsize;
extern int global_flag;
extern TYP stdint;
extern LIST *instantiated_inlines;
static TABLE xsyms;
static SNODE *argstmt, **argnext;
static ENODE *thisn;
static int namenumber;
static SYM *inlinesp;
void inlineinit(void)
{
namenumber = 0;
}
//-------------------------------------------------------------------------
void addvariables(LIST *syms)
{
LIST *news = 0, **p = &news;
SYM *sp;
while (syms)
{
*p = xalloc(sizeof(LIST));
(*p)->data = sp = copysym(syms);
p = &(*p)->link;
syms = syms->link;
}
if (news)
addblocklist(news, 0);
}
//-------------------------------------------------------------------------
SYM *inlineSearch(SYM *name)
{
SYM *sp = xsyms.head;
while (sp)
{
if (sp->mainsym == name->mainsym)
return sp;
sp = sp->next;
}
return 0;
}
//-------------------------------------------------------------------------
void inlineinsert(SYM *sp)
{
if (xsyms.head)
xsyms.tail = xsyms.tail->next = sp;
else
xsyms.head = xsyms.tail = sp;
#ifdef XXXXX
SYM **p = &xsyms.head;
while (*p)
{
if (!(*p)->funcparm && (*p)->storage_class == sc_auto)
{
if ((*p)->value.i > sp->value.i)
{
sp->next = (*p);
*p = sp;
return ;
}
}
p = &(*p)->next;
}
*p = xsyms.tail = sp;
#endif
}
//-------------------------------------------------------------------------
ENODE *inlineexpr(ENODE *node)
{
/*
* routine takes an enode tree and replaces it with a copy of itself.
* Used because we have to munge the block_nesting field (value.i) of each
* sp in an inline function to force allocation of the variables
*/
ENODE *temp, *temp1;
if (node == 0)
return 0;
temp = xalloc(sizeof(ENODE));
memcpy(temp, node, sizeof(ENODE));
switch (temp->nodetype)
{
case en_structret:
break;
case en_autoreg:
case en_autocon:
if (!strcmp(temp->v.sp->name, "**THIS**"))
{
temp = copy_enode(thisn);
}
else
{
/* this should never fail */
temp->v.sp = inlineSearch(node->v.sp);
if (!temp->v.sp)
{
DIAG("Unfound SP in inlineexpr");
temp = dummyvar(4, &stdint, 0);
}
else if (temp->v.sp->funcparm)
temp = temp->v.sp->value.classdata.inlinefunc;
}
break;
case en_llcon:
case en_llucon:
case en_rcon:
case en_lrcon:
case en_fcon:
case en_rcomplexcon:
case en_lrcomplexcon:
case en_fcomplexcon:
case en_rimaginarycon:
case en_lrimaginarycon:
case en_fimaginarycon:
case en_icon:
case en_lcon:
case en_iucon:
case en_lucon:
case en_ccon:
case en_boolcon:
case en_cucon:
break;
case en_nacon:
case en_absacon:
case en_napccon:
break;
case en_fp_ref:
case en_bits:
case en_floatref:
case en_doubleref:
case en_longdoubleref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
case en_b_ref:
case en_w_ref:
case en_ul_ref:
case en_l_ref:
case en_a_ref:
case en_ua_ref:
case en_i_ref:
case en_ui_ref:
case en_ub_ref:
case en_uw_ref:
case en_bool_ref:
case en_ll_ref:
case en_ull_ref:
temp1 = temp;
while (temp1->nodetype == en_a_ref) // explicitly ignoring the UAREF nodes here to keep from collapsing them
temp1 = temp1->v.p[0];
if (temp1->nodetype == en_autocon && !strcmp(temp1->v.sp->name,
"**THIS**"))
{
temp = copy_enode(thisn);
break;
}
temp1 = temp->v.p[0] = inlineexpr(node->v.p[0]);
#ifdef XXXXX
while (castvalue(temp1))
temp1 = temp1->v.p[0];
if (isintconst(temp1->nodetype) /*|| temp1 == thisn */)
temp = copynode(temp->v.p[0]);
#endif
break;
case en_uminus:
case en_asuminus:
case en_ascompl:
case en_compl:
case en_not:
case en_cf:
case en_cd:
case en_cld:
case en_cfi:
case en_cri:
case en_clri:
case en_cfc:
case en_crc:
case en_clrc:
case en_cll:
case en_cull:
case en_ci:
case en_cui:
case en_cb:
case en_cub:
case en_cbool:
case en_cw:
case en_cuw:
case en_cl:
case en_cul:
case en_cp:
case en_cfp:
case en_csp:
case en_trapcall:
case en_cl_reg:
case en_movebyref:
case en_substack:
temp->v.p[0] = inlineexpr(node->v.p[0]);
break;
case en_asadd:
case en_assub:
case en_ainc:
case en_adec:
case en_add:
case en_sub:
case en_addstruc:
en_addcast: case en_asalsh:
case en_asarsh:
case en_alsh:
case en_arsh:
case en_arshd:
case en_asarshd:
case en_asmul:
case en_asdiv:
case en_asmod:
case en_aslsh:
case en_asumod:
case en_asudiv:
case en_asumul:
case en_asrsh:
case en_asand:
case en_assign:
case en_refassign:
case en_lassign:
case en_asor:
case en_asxor:
case en_void:
case en_dvoid:
case en_pmul:
case en_arrayindex:
case en_pdiv:
case en_mul:
case en_div:
case en_umul:
case en_udiv:
case en_umod:
case en_lsh:
case en_rsh:
case en_mod:
case en_and:
case en_or:
case en_xor:
case en_lor:
case en_land:
case en_eq:
case en_ne:
case en_gt:
case en_ge:
case en_lt:
case en_le:
case en_ugt:
case en_uge:
case en_ult:
case en_ule:
case en_cond:
case en_intcall:
case en_moveblock:
case en_stackblock:
case en_thiscall:
case en_repcons:
case en_callblock:
case en_pcallblock:
case en_scallblock:
case en_array:
temp->v.p[1] = inlineexpr(node->v.p[1]);
case en_clearblock:
temp->v.p[0] = inlineexpr(node->v.p[0]);
break;
case en_fcall:
case en_fcallb:
case en_pfcall:
case en_pfcallb:
case en_sfcall:
case en_sfcallb:
temp->v.p[0] = inlineexpr(node->v.p[0]);
temp->v.p[1] = inlineexpr(node->v.p[1]);
if (temp->v.p[1]->v.p[0]->v.p[0]->nodetype == en_napccon)
{
SYM *sp = temp->v.p[1]->v.p[0]->v.p[0]->v.sp;
if (sp->value.classdata.inlinefunc && (sp
->value.classdata.cppflags &PF_INLINE) && !(sp
->value.classdata.cppflags &PF_INSTANTIATED))
{
INLINEFUNC *old = sp->value.classdata.inlinefunc;
sp = copysym(sp);
sp->value.classdata.inlinefunc = xalloc(sizeof(INLINEFUNC));
sp->value.classdata.inlinefunc->stmt = inlinestmt(old->stmt)
;
sp->value.classdata.inlinefunc->syms = old->syms;
// addvariables(old->syms);
temp->v.p[1]->v.p[0]->v.p[0]->v.sp = sp;
}
}
break;
case en_conslabel:
case en_destlabel:
temp->v.p[0] = inlineexpr(node->v.p[0]);
temp->v.p[1] = node->v.p[1];
break;
case en_labcon:
break;
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -