📄 declass.c
字号:
if (offset != - 1)
{
exp2 = makenode(en_addstruc, thisn, makeintnode(en_icon, (offset)));
exp1 = makenode(en_addstruc, argn, makeintnode(en_icon, (offset)));
exp2 = makenode(en_moveblock, exp2, exp1);
exp2->size = sp_in->tp->size - offset;
if (! *exps)
*exps = exp2;
else
*exps = makenode(en_void, (void*)exp2, (void*) * exps);
}
}
/* things are placed in the constructor expression in backwards order */
void thunkConstructors(SNODE *snp3, SYM *sp_in, int ofs, int checkaccess)
{
CLASSLIST *l;
ENODE *thisn = copynode(thisenode);
ENODE *exp1, *exp2, *exps;
sp_in = sp_in->mainsym;
thisn = makenode(en_a_ref, thisn, 0);
/* prev constructors */
l = sp_in->value.classdata.baseclass->link;
exps = 0;
if (l)
prevcons(sp_in, &exps, l, thisn, checkaccess, ofs);
if (exps)
if (!snp3->exp)
snp3->exp = exps;
else
snp3->exp = makenode(en_void, (void*)snp3->exp, (void*)exps);
/* current constructor vtab updates */
l = sp_in->value.classdata.baseclass;
exps = 0;
if (l)
curcons(sp_in, sp_in->value.classdata.baseclass->vtabsp, &exps, l,
thisn, checkaccess, ofs);
if (exps)
if (!snp3->exp)
snp3->exp = exps;
else
snp3->exp = makenode(en_void, (void*)snp3->exp, (void*)exps);
/* embedded data for this class */
exps = 0;
embeddedcons(sp_in, snp3, &exps, thisn);
if (exps)
if (!snp3->exp)
snp3->exp = exps;
else
snp3->exp = makenode(en_void, (void*)snp3->exp, (void*)exps);
}
void thunkCopyConstructors(SNODE *snp3, SYM *sp_in, SYM *arg, int ofs, int
checkaccess)
{
CLASSLIST *l;
ENODE *thisn = copynode(thisenode);
ENODE *argn = makenode(en_autocon, (void*)arg, 0);
ENODE *exp1, *exp2, *exps;
argn = makenode(en_a_ref, argn, 0);
// argn = makenode(en_l_ref, argn, 0);
// argn = makenode(en_void, argn, 0);
sp_in = sp_in->mainsym;
thisn = makenode(en_a_ref, thisn, 0);
/* prev constructors */
l = sp_in->value.classdata.baseclass->link;
exps = 0;
if (l)
prevcopycons(sp_in, argn, &exps, l, thisn, checkaccess, ofs);
if (exps)
if (!snp3->exp)
snp3->exp = exps;
else
snp3->exp = makenode(en_void, (void*)snp3->exp, (void*)exps);
/* embedded data for this class */
exps = 0;
embeddedcopycons(sp_in, argn, snp3, &exps, thisn);
if (exps)
if (!snp3->exp)
snp3->exp = exps;
else
snp3->exp = makenode(en_void, (void*)snp3->exp, (void*)exps);
}
void thunkDestructors(SNODE *snp3, SYM *sp_in, int ofs, int checkaccess,
int skipself)
{
CLASSLIST *l;
ENODE *thisn = copynode(thisenode);
ENODE *exp1, *exp2;
SYM *spt = sp_in->tp->lst.head;
sp_in = sp_in->mainsym;
thisn = makenode(en_a_ref, thisn, 0);
// embedded classes
while (spt)
{
if (!(spt->value.classdata.cppflags &PF_INHERITED) && isstructured
(spt->tp))
thunkDestructors(snp3, spt->tp->sp, spt->value.i, TRUE, FALSE);
spt = spt->next;
}
l = sp_in->value.classdata.baseclass;
if (skipself)
l = l->link;
/* base classes */
while (l)
{
SYM *sp1 = search(cpp_funcname_tab[CI_DESTRUCTOR], &l->data->tp
->lst);
if (sp1)
{
sp1 = funcovermatch(sp1, &functovoidtype, 0, FALSE, FALSE);
if (sp1 && !(sp1->value.classdata.cppflags &PF_DUMDEST))
{
if (!(l->data->value.classdata.cppflags &PF_TEMPCONSALREADY)
)
{
if (!isaccessible(sp1))
genclasserror(ERR_NOTACCESSIBLE, fullcppmangle(sp1
->parentclass, sp1->name, 0));
exp2 = makenode(en_addstruc, thisn, makeintnode(en_icon,
(l->offset + ofs)));
exp2 = conscall(exp2, sp1, 0);
if (!snp3->exp)
snp3->exp = exp2;
else
snp3->exp = makenode(en_void, (void*)exp2, (void*)
snp3->exp);
setthunkflags(l->data->tp->sp, TRUE);
}
}
}
l = l->link;
}
}
void CreateBaseConstructor(SYM *sp_in)
{
SYM *sp = search(cpp_funcname_tab[CI_CONSTRUCTOR], &sp_in->tp->lst);
if (!sp)
{
SNODE *snp3;
sp = makesym(sc_externalfunc);
sp->name = fullcppmangle(sp_in, cpp_funcname_tab[CI_CONSTRUCTOR],
&vtyp);
sp->tp = copytype(&functovoidtype, 0);
sp->value.classdata.cppflags = PF_INLINE | PF_CONSTRUCTOR |
PF_MEMBER | PF_PUBLIC;
sp->parentclass = sp_in;
snp3 = xalloc(sizeof(SNODE));
snp3->stype = st_expr;
snp3->exp = 0;
setthunkflags(sp_in, FALSE);
thunkConstructors(snp3, sp_in, 0, FALSE);
sp->value.classdata.inlinefunc = xalloc(sizeof(INLINEFUNC));
sp->value.classdata.inlinefunc->stmt = snp3;
sp->value.classdata.inlinefunc->syms = 0;
funcrefinsert(cpp_funcname_tab[CI_CONSTRUCTOR], sp, &sp_in->tp->lst,
sp_in);
}
if (!lookupcopycons(sp_in, 0))
{
{
SNODE *snp3;
SYM *fsym = makesym(sc_auto); /* fsym and ftype only used for
error messages */
TYP *ftype = maketype(bt_ifunc, 0);
ftype->lst.head = ftype->lst.tail = fsym;
fsym->tp = maketype(bt_ref, 4);
;
fsym->tp->btp = copytype(sp_in->tp, 0);
fsym->tp->btp->cflags |= DF_CONST;
fsym->value.i = stdaddrsize * 3;
fsym->funcparm = TRUE;
fsym->next = 0;
fsym->name = "dumcopyconsarg";
snp3 = xalloc(sizeof(SNODE));
snp3->stype = st_expr;
snp3->exp = 0;
thunkCopyConstructors(snp3, sp_in, fsym, 0, FALSE);
sp = makesym(sc_externalfunc);
sp->name = fullcppmangle(sp_in,
cpp_funcname_tab[CI_CONSTRUCTOR], ftype);
sp->tp = ftype;
sp->value.classdata.cppflags = PF_INLINE | PF_CONSTRUCTOR |
PF_MEMBER | PF_PUBLIC;
sp->parentclass = sp_in;
sp->value.classdata.inlinefunc = xalloc(sizeof(INLINEFUNC));
sp->value.classdata.inlinefunc->stmt = snp3;
sp->value.classdata.inlinefunc->syms = xalloc(sizeof(LIST));
sp->value.classdata.inlinefunc->syms->data = fsym;
funcrefinsert(cpp_funcname_tab[CI_CONSTRUCTOR], sp, &sp_in->tp
->lst, sp_in);
}
}
sp = search(cpp_funcname_tab[CI_DESTRUCTOR], &sp_in->tp->lst);
if (!sp)
{
SNODE *snp3;
snp3 = xalloc(sizeof(SNODE));
snp3->stype = st_expr;
snp3->exp = 0;
setthunkflags(sp_in, FALSE);
thunkDestructors(snp3, sp_in, 0, FALSE, FALSE);
if (snp3->exp)
{
sp = makesym(sc_externalfunc);
sp->name = fullcppmangle(sp_in, cpp_funcname_tab[CI_DESTRUCTOR],
&vtyp);
sp->tp = copytype(&functovoidtype, 0);
sp->value.classdata.cppflags = PF_INLINE | PF_DESTRUCTOR |
PF_MEMBER | PF_PUBLIC | PF_DUMDEST;
sp->parentclass = sp_in;
sp->value.classdata.inlinefunc = xalloc(sizeof(INLINEFUNC));
sp->value.classdata.inlinefunc->stmt = snp3;
sp->value.classdata.inlinefunc->syms = 0;
funcrefinsert(cpp_funcname_tab[CI_DESTRUCTOR], sp, &sp_in->tp
->lst, sp_in);
}
}
}
void classbaseasn(SYM *sp, SYM *func)
/*
* handles a list of constructor base assignment operators
*/
{
CLASSLIST *ls;
sp = sp->mainsym;
getsym();
if (func->tp->lst.head != (SYM*) - 1)
baseasnsymtbl = &func->tp->lst;
currentfunc = func;
ls = sp->value.classdata.baseclass;
while (TRUE)
{
ls = 0;
if (lastst != id)
{
generror(ERR_IDEXPECT, 0, 0);
basicskim(skm_declbegin);
baseasnsymtbl = 0;
return ;
}
else
{
int discard = FALSE;
SYM *sp1 = search(lastid, &sp->tp->lst);
if (sp1)
{
if (sp1->value.classdata.cppflags &PF_INHERITED)
{
discard = TRUE;
doubleerr(ERR_NOTUNAMBIGUOUSBASE, lastid, sp->name);
}
}
else
{
CLASSLIST *l = sp->value.classdata.baseclass->link;
while (l)
{
if (!strcmp(l->data->name, lastid))
break;
l = l->link;
}
if (!l /* || !(l->flags & CL_VTAB)*/)
{
discard = TRUE;
doubleerr(ERR_NOTUNAMBIGUOUSBASE, lastid, sp->name);
}
else
{
sp1 = l->data->tp->sp;
ls = l;
}
}
getsym();
if (needpunc(openpa, skm_closepa))
{
ENODE *expr;
TYP *tp;
if (!discard)
{
typequal = 0;
if (sp1->value.classdata.consbuild)
gensymerror(ERR_MEMBERREINIT, sp1->name);
if (isstructured(sp1->tp))
{
ENODE *qnode;
TYP *tp1;
expr_runup[expr_updowncount] = 0;
expr_rundown[expr_updowncount++] = 0;
tp1 = gatherparms(&qnode, FALSE);
if (ls)
expr = do_constructor(sp, tp1, sp1->tp, qnode,
1, ls->offset, FALSE, FALSE);
else
expr = do_constructor(sp, tp1, sp1->tp, qnode,
1, sp1->value.i, FALSE, FALSE);
expr_updowncount--;
if (expr_runup[expr_updowncount] ||
expr_rundown[expr_updowncount])
{
expr = makenode(en_dvoid, expr,
expr_rundown[expr_updowncount]);
(expr)->cflags |= DF_ACTUALEXPR;
}
if (expr_runup[expr_updowncount])
expr = makenode(en_void,
expr_runup[expr_updowncount], expr);
if (expr)
expr = repcallb(expr);
sp1->value.classdata.consbuild = expr;
}
else
{
tp = exprnc(&expr);
if (!exactype(sp1->tp, tp, FALSE) && (expr->nodetype !=
en_icon || expr->v.i != 0))
genmismatcherror(tp, sp1->tp);
else if (sp1->value.classdata.cppflags &PF_STATIC)
gensymerror(ERR_NOINITSTATICMEMBER, sp1->name);
else
sp1->value.classdata.consbuild = expr;
needpunc(closepa, 0);
}
}
else
{
tp = expression(&expr, 0);
needpunc(closepa, 0);
}
}
}
if (lastst != comma)
break;
getsym();
}
baseasnsymtbl = 0;
currentfunc = 0;
}
void setRefFlags(SYM *sp)
{
sp = sp->tp->lst.head;
while (sp)
{
if (sp->tp->type == bt_ref || (sp->tp->cflags &DF_CONST))
sp->value.classdata.cppflags &= ~PF_TEMPCONSREFALREADY;
sp = sp->next;
}
}
void RefErrs(SYM *sp)
{
sp = sp->tp->lst.head;
while (sp)
{
if (!(sp->value.classdata.cppflags &(PF_TEMPCONSREFALREADY |
PF_INHERITED)))
{
if (sp->tp->type == bt_ref)
gensymerror(ERR_CONSNOREFINIT, sp->name);
else if (sp->tp->cflags &DF_CONST)
gensymerror(ERR_CONSNOCONSTINIT, sp->name);
}
sp = sp->next;
}
}
void gen_vtab(SYM *sp)
{
SYM *head;
LIST *lst;
CLASSLIST *l;
l = sp->value.classdata.baseclass;
if ((l->flags &CL_VTAB))
{
sp->value.classdata.baseclass->vtabsp->gennedvirtfunc = TRUE;
gen_virtual(sp->value.classdata.baseclass->vtabsp, FALSE);
if (prm_xcept)
genref(getxtsym(sp->tp), 0);
/* space for exception handling */
else
genlong(0);
genlong(0);
genlong(0); /* reserved as a beginning of vtab marker */
lst = l->vtablist;
while (lst)
{
SYM *sp = lst->data;
if ((int)sp < VTABVALTHRESH)
{
genlong((int)sp);
}
else
{
SetExtFlag(sp, TRUE);
genpcref(sp, 0);
}
lst = lst->link;
}
gen_endvirtual(sp->value.classdata.baseclass->vtabsp);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -