📄 decl.c
字号:
if (lastst == begin) {
temp1->type = bt_ifunc;
break;
}
}
else getsym();
}
}
else {
/* (In case a declaration is in parenthesis */
decl1();
needpunc(closepa,0);
decl2();
}
break;
default:
decl2();
break;
}
}
void decl2(void)
/*
* type modifiers that come AFTER the name of the variable
*/
{ TYP *temp1;
lp:
switch (lastst) {
case kw_const:
head->cflags |= DF_CONST;
getsym();
goto lp;
case kw_volatile:
head->cflags |= DF_VOL;
getsym();
goto lp;
case openbr:
decl3();
decl2();
break;
case openpa:
getsym();
temp1 = maketype(bt_func,0);
head->uflags |= UF_DEFINED;
temp1->val_flag = 1;
temp1->btp = head;
head = temp1;
head->uflags |= UF_DEFINED;
declfuncarg(intflag);
if (lastst == begin) {
temp1->type = bt_ifunc;
break;
}
break;
case colon:
getsym();
head->bits = intexpr(0);
if (head->type != bt_long && head->type != bt_unsigned
&& head->type != bt_short && head->type != bt_unsignedshort
&& head->type != bt_char && head->type != bt_unsignedchar) {
if (prm_ansi)
generror(ERR_INTBITFIELDS,0,0);
else
generror(ERR_BFTYPE,0,0);
head->bits = -1;
}
else
if (prm_ansi && head->size != stdintsize) {
generror(ERR_INTBITFIELDS,0,0);
head->bits = -1;
}
break;
}
}
void decl3(void)
/*
* Array index handling
*/
{
TYP *temp1, *list[40];
int count = 0,i;
int mustsize = 0;
head->uflags |= UF_DEFINED;
head->uflags &= ~UF_CANASSIGN;
while(lastst == openbr) {
getsym();
temp1 = maketype(bt_pointer,0);
temp1->val_flag = 1;
if(lastst == closebr) {
if (mustsize)
generror(ERR_SIZE,0,0);
temp1->size = 0;
getsym();
}
else {
temp1->size = intexpr(0);
needpunc(closebr,skm_declclosebr);
}
list[count++] = temp1;
mustsize = 1;
}
if (head != NULL) {
list[count-1]->size *= head->size;
if (tail == NULL)
tail = head;
}
for (i=count-1; i>0; i--) {
list[i-1]->size *= list[i]->size;
list[count-1]->uflags |= UF_DEFINED;
}
for (i=0; i < count-1; i++)
list[i]->btp = list[i+1];
list[count-1]->btp = head;
head = list[0];
if (tail == NULL)
tail = list[count-1];
}
int bitsize(int type)
/*
* Max bit field depends on the type
*/
{
switch (type) {
case bt_char:
case bt_unsignedchar:
return 8;
case bt_short:
case bt_unsignedshort:
return 16;
case bt_long:
case bt_unsigned:
return 32;
}
return 0;
}
int oksize(void)
/*
* See if the size field is ok or if we should gen a message
*/
{
TYP *q = head;
while (q->type == bt_pointer) {
if (q->val_flag)
return 1;
q = q->btp;
}
return head->size != 0;
}
int basedeclare(TABLE *table,int al,long ilc,int ztype, int flags)
/*
* Once a type declarator is found we come here to get the remainder of the
* declaration and allocate spae
*
*/
{ SYM *sp=0, *sp1;
TYP *dhead;
int nbytes,ufsave;
nbytes = 0;
dhead = head;
ufsave = head->uflags;
for(;;) {
sp1 = 0;
declid[0] = 0;
decl1();
/* stupid C standard uses a proper function name
** as an alias for a pointer to a func when is a member...
*/
if (al == sc_member)
if (head->type == bt_func) {
head->type = bt_ptrfunc;
head->size = 4;
}
else if (head->type == bt_ifunc)
generror(ERR_NOFUNCSTRUCT,0,0);
/* In case they put the extern tag on an ifunc */
if (head->type == bt_ifunc && al == sc_external)
al = sc_global;
if (declid[0] == 0) {
if ((flags & DF_FUNCPARMS)) {
sprintf(declid,"**ARG%d**",pcount++);
}
}
head->cflags |= flags;
if( declid[0] != 0) { /* otherwise just struct tag... */
sp = xalloc(sizeof(SYM));
if (head->type == bt_func || head->type == bt_ifunc)
#ifdef CPLUSPLUS
if (prm_cplusplus)
if (!strcmp(declid,"_main")) {
SYM *sp1;
head->sname = sp->name = litlate(declid);
sp1 = search(sp->name,&gsyms);
if (sp1 && sp1->tp->type == bt_ifunc)
generror(ERR_NOOVERMAIN,0,0);
}
else if (mangleflag && !ispascal)
head->sname = sp->name = cppmangle(declid,head);
else
head->sname = sp->name = litlate(declid);
else
#endif
head->sname = sp->name = litlate(declid);
else
sp->name = litlate(declid);
sp->defalt = 0;
sp->storage_class = al;
sp->tp = head;
sp->extflag = FALSE;
sp->absflag = (al == sc_abs);
sp->intflag = flags &DF_INT;
sp->pascaldefn = ispascal;
sp->init = 0;
sp->indecltable = 0;
sp->funcparm = 0;
sp->inreg = 0;
sp->staticlabel = FALSE;
if (al == sc_external && lastst == assign)
sp->storage_class = sc_global;
if (sp->intflag && ispascal)
generror(ERR_PASCAL_NO_INT,0,0);
if (al == sc_autoreg) {
if (head->size > 4) {
sp->storage_class = sc_auto;
gensymerror(ERR_ILLREGISTER,sp->name);
}
head->sname = sp->name;
}
if (al != sc_type && (oksize() || sp->tp->type == bt_func || sp->tp->type == bt_ifunc)) {
if (al == sc_abs)
sp->value.i = ilc;
else
if (head->type != bt_func && head->type != bt_ifunc)
if (sp->storage_class == sc_static && table == &lsyms) {
sp->value.i = nextlabel++;
sp->staticlabel = TRUE;
}
else
sp->value.i = block_nesting;
else
sp->value.i = 0;
{
int align = getalign(al,head);
int noadj = FALSE;
if (al != sc_member || (head->bits != -1 && bittype != head->type && head->bits +curbit > bitsize(head->type))) {
bittype = head->type;
curbit = 0;
}
else
noadj = head->bits != -1;
if (al == sc_member) {
int val;
if (!noadj) {
val = (ilc + nbytes) %align;
if (val) val = align - val;
nbytes += val;
}
sp->value.i = nbytes + ilc;
if (!noadj)
if(ztype == bt_union)
nbytes = imax(nbytes,sp->tp->size);
else if(al != sc_external)
nbytes += sp->tp->size;
}
}
if (head->bits != -1) {
if (al != sc_member) {
generror(ERR_BFILLEGAL,0,0);
head->bits = -1;
}
else if (head->bits > bitsize(head->type)) {
generror(ERR_BFTOOBIG,0,0);
head->bits = -1;
}
else {
if (prm_revbits)
head->startbit = head->size*8-curbit-head->bits;
else
head->startbit = curbit;
curbit+=head->bits;
}
}
if (sp->absflag &&( sp->tp->type == bt_func || sp->tp->type == bt_ifunc))
gensymerror(ERR_ILLCLASS,lastid);
if (sp->intflag &&( sp->tp->type != bt_func && sp->tp->type != bt_ifunc))
gensymerror(ERR_ILLCLASS,lastid);
if( sp->tp->type == bt_func && al != sc_static)
sp->storage_class = sc_externalfunc;
sp1 = search(sp->name,table);
if (sp->name[0] == '@' && !sp1)
funcrefinsert(declid,sp->name,head,table);
if (!sp1 || (sp1->tp->type != bt_func && sp1->tp->type != bt_ifunc)) {
if (!sp1 || al == sc_auto || al == sc_autoreg)
insert(sp,table);
else {
if (!exactype(sp->tp,sp1->tp))
gensymerror(ERR_DECLMISMATCH,sp->name);
if (sp1->tp->size == 0)
sp1->tp = sp->tp;
if (sp1->storage_class == sc_external || sp1->storage_class == sc_externalfunc) {
sp1->storage_class = sp->storage_class;
sp1->tp = sp->tp;
sp1->value.i = sp->value.i;
}
}
}
else
join:
if (sp1->tp->type == bt_func && sp->tp->type == bt_ifunc){
if (sp1->storage_class == sc_external || sp1->storage_class == sc_externalfunc || sp1->storage_class == sc_static)
if (al == sc_static || sp1->storage_class == sc_static)
sp->storage_class = sp1->storage_class = sc_static;
else
sp->storage_class = sp1->storage_class = sc_global;
}
if( sp->tp->type == bt_ifunc) { /* function body follows */
if (sp1)
if (sp1->tp->type == bt_ifunc)
gensymerror(ERR_MULTIPLEINIT,sp->name);
else
sp1->tp->type = bt_ifunc;
funcbody(sp);
lastdecl = sp1;
return nbytes;
}
if( (sp->storage_class == sc_global || sp->storage_class == sc_static) &&
sp->tp->type != bt_func && sp->tp->type != bt_ifunc
&& !(flags & DF_FUNCPARMS)) {
if (sp->tp->type == bt_ref && lastst != assign)
gensymerror(ERR_REFMUSTINIT,lastid);
if (!sp1)
sp1 = sp;
doinit(sp1);
}
else
if (al == sc_auto || al == sc_autoreg) {
#ifdef CPLUSPLUS
if (prm_cplusplus &&(flags & DF_FUNCPARMS)) {
dodefaultinit(sp);
}
else{
if (sp->tp->type == bt_ref && lastst != assign)
gensymerror(ERR_REFMUSTINIT,lastid);
}
#endif
doautoinit(sp);
}
}
else if (al != sc_type) {
gensymerror(ERR_SIZE,declid);
expskim(skm_declclosepa);
}
else if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
gensymerror(ERR_ILLTYPE,declid);
expskim(skm_declclosepa);
}
else {
if (sp->tp->size) {
sp->tp = copytype(sp->tp,0);
sp->tp->sname = sp->name;
}
insert(sp,table);
}
}
if (!(flags & DF_FUNCPARMS)) {
if(lastst == semicolon)
break;
dhead = copytype(dhead,0);
needpunc(comma,0);
}
else {
if(lastst == comma)
break;
if (sp1)
lastdecl = sp1;
else
lastdecl = sp;
return(nbytes);
}
if(declbegin(lastst) == 0)
break;
head = dhead;
head->uflags = ufsave;
}
getsym();
if (sp1)
lastdecl = sp1;
else
lastdecl = sp;
return nbytes;
}
int declare(TABLE *table,int al,int ztype, int flags)
/*
* In this wrapper we do an ENTIRE declaration
*/
{
int old_gf = global_flag,rv;
if (al != sc_member)
active_table = table;
if (al == sc_static)
global_flag ++;
decl(table);
rv = basedeclare(table,al,0,ztype,flags);
global_flag = old_gf;
return rv;
}
int declare2(TABLE *table,int al,int ztype, int flags, long val)
/*
* In this wrapper we do an ENTIRE declaration
*/
{
int old_gf = global_flag,rv;
if (al != sc_member)
active_table = table;
if (al == sc_static)
global_flag ++;
decl(table);
rv = basedeclare(table,al,val,ztype,flags);
global_flag = old_gf;
return rv;
}
int declbegin(int st)
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -