📄 func.c
字号:
}
infuncargs--;
}
//-------------------------------------------------------------------------
void check_funcused(TABLE *oldlsym, TABLE *lsyms)
{
/* oldlsym Must BE 0 at the end of a function */
SYM *sym1;
if (oldlsym && oldlsym->head == lsyms->head)
{
return ;
}
sym1 = lsyms->head;
while (sym1 && (!oldlsym || sym1 != oldlsym->head))
{
if (sym1->tp->type != bt_func && sym1->tp->type != bt_ifunc && sym1
->storage_class != sc_type)
{
if (!(sym1->tp->uflags &UF_USED))
{
if (sym1->storage_class == sc_label)
{
if (!oldlsym)
gensymerror(ERR_UNUSEDLABEL, sym1->name);
}
else
if (sym1->funcparm)
gensymerror(ERR_PARAMUNUSED, sym1->name);
else
gensymerror(ERR_SYMUNUSED, sym1->name);
}
if (sym1->tp->uflags &UF_ASSIGNED)
gensymerror(ERR_SYMASSIGNED, sym1->name);
if (!oldlsym && sym1->storage_class == sc_ulabel)
gensymerror(ERR_UNDEFLABEL, sym1->name);
}
sym1 = sym1->next;
}
}
//-------------------------------------------------------------------------
void dump_instantiates(void)
{
SYM *oldfunc = currentfunc;
LIST *oldvar = varlisthead;
while (instantiated_inlines)
{
currentfunc = instantiated_inlines->data;
instantiated_inlines = instantiated_inlines->link;
if (!currentfunc->value.classdata.inlinefunc) {
char *nm = currentfunc->name;
currentfunc = 0 ;
gensymerror(ERR_INLINENOBODY,nm);
} else {
conscount = 0;
varlisthead = currentfunc->value.classdata.inlinefunc->syms;
genfunc(currentfunc->value.classdata.inlinefunc->stmt);
}
// release_local() ;
}
varlisthead = oldvar;
currentfunc = oldfunc;
}
//-------------------------------------------------------------------------
void funcbody(SYM *sp)
/*
*/
{
SYM *sp1, *sp2;
int xglob = global_flag;
SNODE *vlaparminit = 0;
funcnesting++;
// instantiated_inlines = 0 ;
goodcode = 0;
typequal = 0;
conscount = 0;
try_block_list = 0;
/* 1 if inline, 0 if local define */
global_flag = !!(sp->value.classdata.cppflags &PF_INLINE);
/* Have to defer old style argument gathering until now
* because of the pointer-to func syntax
*/
if (sp->oldstyle)
{
SYM *spsave[50], *sp1;
int nparms, i;
int poffset = stdretblocksize; /* size of return block */
char **names;
global_flag++;
doargdecl(sc_member, 0, 0, &sp->tp->lst, FALSE); /* declare parameters
*/
global_flag--;
if (!ispascal && isstructured(sp->tp->btp))
{
poffset += stdaddrsize;
sp->calleenearret = TRUE;
}
if (sp->farproc)
poffset += stdintsize;
nparms = (int)sp->oldstyle[0];
names = &sp->oldstyle[1];
for (i = 0; i < nparms; ++i)
{
if ((sp1 = search(names[i], &sp->tp->lst)) == 0)
sp1 = makeint(litlate(names[i]), &sp->tp->lst);
if (sp1->tp)
sp1->tp->uflags |= UF_DEFINED;
sp1->funcparm = TRUE;
spsave[i] = sp1;
sp1->storage_class = sc_auto;
}
/*
* parameter allocation. Have to do things backwards if this
* function has the pascal declarator
*/
for (i = 0; i < nparms; ++i)
{
sp1 = spsave[i];
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;
}
}
sp->paramsize = poffset;
}
else
{
if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
if (!sp->pascaldefn && (sp->value.classdata.cppflags &PF_MEMBER) &&
!(sp->value.classdata.cppflags &PF_STATIC))
{
SYM *s1 = sp->tp->lst.head;
while (s1 && s1 != (SYM*) - 1)
{
s1->value.i += stdaddrsize;
s1 = s1->next;
}
}
}
sp1 = sp->tp->lst.head;
if (sp1 != (SYM*) - 1)
{
SNODE *vlaparmtail;
while (sp1)
{
if (sp1->name[0] != '*' || sp1->tp->type == bt_ellipse)
{
TYP *tp;
sp2 = copysym(sp1);
insert(sp2, &lsyms);
tp = sp2->tp;
if (tp->type == bt_pointer && !(tp->val_flag &VARARRAY))
tp = tp->btp;
if (tp->val_flag &VARARRAY)
{
SNODE *snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_expr;
snp->exp = createVarArray(sp2, tp, FALSE, FALSE);
snp->flags |= ST_VARARRAY ;
if (vlaparminit == 0)
vlaparminit = vlaparmtail = snp;
else
{
vlaparmtail->next = snp;
vlaparmtail = snp;
}
}
browse_variable(sp2, lineno);
}
else
if (!prm_cplusplus)
generror(ERR_PARAMMISSINGNAME, 0, 0);
sp1 = sp1->next;
}
}
currentfunc = sp;
firstlabel = nextlabel;
goodcode &= ~GF_RETURN;
block(vlaparminit);
check_funcused(0, &lsyms);
if (prm_listfile && varlisthead)
{
LIST *q = varlisthead;
fprintf(listFile, "\n\n*** local symbol table ***\n\n");
while (q)
{
SYM *sp = q->data;
while (sp)
{
list_var(sp, 0);
sp = sp->next;
}
q = q->link;
}
list_table(<ags,0);
}
if (sp->tp->btp->type != bt_void && !(goodcode &(GF_RETURN | GF_UNREACH)))
if (!prm_cplusplus || strcmp(currentfunc->name + prm_cmangle, "main"))
generror(ERR_FUNCRETVAL, 0, 0);
nl();
local_using_list = 0;
local_tag_using_list = 0;
#ifdef ICODE
dag_rundown();
#endif
lsyms.head = 0;
ltags.head = 0;
oldlsym.head = oldlsym.tail = 0;
lastfunc = currentfunc;
// dump_instantiates() ;
while (lastst == semicolon)
getsym();
varlisthead = varlisttail = 0;
if (!--funcnesting)
{
release_local(); /* release local symbols */
release_opt();
release_oc();
}
currentfunc = 0;
global_flag = xglob;
}
//-------------------------------------------------------------------------
SYM *makeint(char *name, TABLE *table)
{
SYM *sp;
TYP *tp;
global_flag++;
sp = makesym(sc_auto);
tp = xalloc(sizeof(TYP));
global_flag--;
tp->type = bt_int;
tp->size = stdintsize;
tp->btp = tp->lst.head = 0;
tp->sp = 0;
sp->name = name;
tp->bits = tp->startbit = - 1;
sp->tp = tp;
insert(sp, table);
return sp;
}
/* a little ditty to add C++ destructors on the tail of a block
*/
void addrundown(SNODE *snp)
{
if (block_rundown && snp)
{
SNODE *snp2;
snp2 = xalloc(sizeof(SNODE));
snp2->next = 0;
snp2->stype = st_expr;
snp2->exp = block_rundown;
block_rundown = 0;
while (snp->next)
snp = snp->next;
snp->next = snp2;
}
}
//-------------------------------------------------------------------------
void addblocklist(SYM *sp, SYM *old)
{
LIST *l;
if (!sp)
return ;
if (!currentfunc)
return ;
if (varlisthead && sp == varlisttail->data)
return ;
if (sp == old)
return ;
if (currentfunc->value.classdata.cppflags &PF_INLINE)
{
global_flag++;
l = xalloc(sizeof(LIST));
global_flag--;
}
else
l = xalloc(sizeof(LIST));
l->link = 0;
l->data = sp;
if (varlisthead)
varlisttail = varlisttail->link = l;
else
varlisthead = varlisttail = l;
if (old)
while (sp)
{
if (sp->next == old)
{
sp->next = 0;
break;
}
sp = sp->next;
}
}
//-------------------------------------------------------------------------
int scanforgoto(SNODE *block, SNODE *root, DLIST **data, int id)
/*
* scan a statement tree for gotos. We are going to put out an error if
* a goto tries to bypass a VLA initialization
*/
{
static DLIST *labelList;
static SNODE *gotoPos ;
int rv = TRUE ;
DLIST *m = xalloc(sizeof(DLIST)) ;
m->fwd = *data ;
m->back = 0 ;
if (*data)
(*data)->back = m ;
*data = m ;
m->data = block ;
while (block != 0 && rv)
{
m->current = block ;
switch (block->stype)
{
case st_goto:
if (id == -1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -