📄 decl.c
字号:
* This determines if another variable is being declared of the same type
*/
{ return st == star || st == id || st == openpa ||
st == openbr;
}
void declenum(TABLE *table)
/*
* declare enums
*/
{ SYM *sp;
TYP *tp;
char *nm;
if( lastst == id) {
/* tagged */
if((sp = search(nm = litlate(lastid),&tagtable)) == 0) {
sp = xalloc(sizeof(SYM));
sp->tp = xalloc(sizeof(TYP));
sp->tp->type = bt_enum;
sp->tp->size = 2;
sp->tp->lst.head = sp->tp->btp = 0;
sp->storage_class = sc_type;
sp->name = nm;
sp->tp->sname = sp->name;
sp->tp->bits = sp->tp->startbit = -1;
#ifdef CPLUSPLUS
/* tags are also typedefs in C++ */
if (prm_cplusplus)
insert(sp,active_table);
#endif
getsym();
if( lastst != begin)
generror(ERR_PUNCT,begin,skm_declend);
else {
insert(sp,&tagtable);
getsym();
enumbody(table);
}
}
else
getsym();
head = sp->tp;
}
else {
/* untagged */
tp = xalloc(sizeof(TYP));
tp->type = bt_enum;
tp->lst.head = tp->btp = 0;
tp->size = 2;
tp->bits = tp->startbit = -1;
tp->sname = 0;
if( lastst != begin)
generror(ERR_PUNCT,begin,skm_declend);
else {
getsym();
enumbody(table);
}
head = tp;
}
}
void enumbody(TABLE *table)
/*
* read the enumeration constants in
*/
{ long evalue;
SYM *sp;
evalue = 0;
while(lastst == id) {
sp = xalloc(sizeof(SYM));
sp->value.i = evalue++;
sp->name = litlate(lastid);
sp->storage_class = sc_const;
sp->tp = &stdconst;
insert(sp,active_table);
getsym();
if (lastst == assign) {
getsym();
evalue = sp->value.i = intexpr(0);
sp->value.i = evalue++;
if (sp->value.i < SHRT_MIN || sp->value.i >SHRT_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
}
if( lastst == comma)
getsym();
else if(lastst != end)
break;
}
needpunc(end,skm_declend);
}
void declstruct(TABLE *table, int ztype, int flags)
/*
* declare a structure or union type
*/
{ SYM *sp;
TYP *tp;
char *nm = litlate(lastid);
if(lastst == id) {
/* tagged */
if((sp = search(nm,&tagtable)) == 0) {
/* if tag was never defined */
sp = xalloc(sizeof(SYM));
sp->name = nm;
sp->tp = xalloc(sizeof(TYP));
sp->tp->type = ztype;
sp->tp->lst.head = 0;
sp->storage_class = sc_type;
sp->tp->sname = sp->name;
sp->tp->cflags = flags;
sp->tp->uflags = UF_DEFINED;
sp->tp->size = 0;
#ifdef CPLUSPLUS
/* tags are also typedefs in C++ */
if (prm_cplusplus)
insert(sp,table);
#endif
getsym();
if(lastst != begin) {
insert(sp,&tagtable);
/* if (lastst != semicolon)
generror(ERR_PUNCT,semicolon,skm_declend);
*/ }
else {
insert(sp,&tagtable);
getsym();
structbody(sp->tp,sp->name,ztype);
}
}
else {
/* Allow redefinition if it was forward declared */
getsym();
if (lastst == begin) {
getsym();
if (sp->tp->size == 0)
structbody(sp->tp,sp->name,ztype);
else {
gensymerror(ERR_DUPSYM,sp->name);
expskim(skm_declclosebr);
}
}
}
if (flags & (DF_CONST | DF_VOL))
head = copytype(sp->tp,flags);
else
head = sp->tp;
head->bits = head->startbit = -1;
}
else {
/* untagged */
tp = xalloc(sizeof(TYP));
tp->type = ztype;
tp->cflags = flags;
tp->uflags = UF_DEFINED;
tp->sname = 0;
tp->lst.head = 0;
tp->bits = tp->startbit =-1;
if( lastst != begin)
generror(ERR_PUNCT,begin,skm_declend);
else {
getsym();
structbody(tp,tn_unnamed,ztype);
}
head = tp;
}
}
void structbody(TYP *tp,char *name,int ztype)
/*
* read in the structure/union elements and calculate the total size
*/
{ int slc;
slc = 0;
tp->val_flag = 1;
tp->uflags &= ~UF_CANASSIGN;
while( lastst != end) {
int flags=0;
if(ztype == bt_struct)
slc += declare2(&tp->lst,sc_member,ztype,flags,slc);
else
slc = imax(slc,declare2(&tp->lst,sc_member,ztype,flags,0));
if (tp->lst.tail->tp->type == bt_ref)
genclasserror(ERR_REFNOCONS,name,tp->lst.tail->name);
tp->lst.tail->tp->uflags |= UF_DEFINED;
}
if (!prm_packing)
tp->size = (slc+strucadd)&strucmod;
else
tp->size = slc;
getsym();
}
void check_used(void)
/*
* At the end of compilition we check for some common cases where
* module-scoped variables are either missing or unused
*/
{
int i;
SYM *sp;
for (i=0; i < HASHTABLESIZE; i++) {
if ((sp=(SYM *) globalhash[i]) != 0) {
while (sp) {
if (sp->storage_class == sc_static)
if (sp->tp->uflags & UF_USED) {
if (sp->tp->type == bt_func)
gensymerror(ERR_NOSTATICFUNC,sp->name);
}
else
if (sp->tp->type == bt_ifunc || sp->tp->type == bt_func)
gensymerror(ERR_FUNCUNUSED,sp->name);
else
gensymerror(ERR_STATICSYMUNUSED,sp->name);
sp = sp->next;
}
}
}
sp = tagtable.head;
while (sp) {
if (sp->tp->size == 0)
gensymerror(ERR_NEVERSTRUCT,sp->name);
sp = sp->next;
}
}
void compile(void)
/*
* Main compiler routine
*/
{ while(lastst != eof) {
dodecl(sc_global);
if (lastst != eof) {
generror(ERR_DECLEXPECT,0,0);
getsym();
}
}
flush_peep();
dumplits();
initrundown();
dumpstartups();
check_used();
putexterns();
}
void dodecl(int defclass)
/*
* Declarations come here, ALWAYS
*/
{
SYM *sp;
int flags = 0;
long val;
char *nm;
cbautoinithead = 0;
for(;;) {
ispascal = FALSE;
switch(lastst) {
case semicolon:
getsym();
break;
case kw_typedef:
getsym();
if (defclass == sc_global)
declare(&gsyms,sc_type,bt_struct, 0);
else
declare(&lsyms,sc_type,bt_struct, 0);
break;
case kw_register:
if( defclass != sc_auto || flags & DF_VOL) {
gensymerror(ERR_ILLCLASS,lastid);
getsym();
}
else {
getsym();
declare(&lsyms,sc_autoreg,bt_struct,flags | DF_AUTOREG);
};
break;
case id:
if (defclass == sc_auto)
if (!(((sp = search(nm = litlate(lastid),&gsyms)) != 0 && sp->storage_class == sc_type)
|| ((sp = search(nm,&lsyms)) != 0 && sp->storage_class == sc_type)))
return;
case kw_volatile:
case kw_const:
case kw_char: case kw_int: case kw_short: case kw_unsigned:
case kw_long: case kw_struct: case kw_union: case kw_signed:
case kw_enum: case kw_void:
case kw_float: case kw_double:
if( defclass == sc_global)
declare(&gsyms,sc_global,bt_struct,flags | DF_GLOBAL);
else if( defclass == sc_auto)
declare(&lsyms,sc_auto,bt_struct,flags);
else
declare(&lsyms,sc_auto,bt_struct,flags);
break;
case kw_static:
if( defclass == sc_member) {
gensymerror(ERR_ILLCLASS,lastid);
getsym();
break;
}
getsym();
if( defclass == sc_auto)
declare(&lsyms,sc_static,bt_struct,flags | DF_GLOBAL);
else
declare(&gsyms,sc_static,bt_struct,flags | DF_GLOBAL);
break;
case kw_extern: {
int thismangle = FALSE;
getsym();
#ifdef CPLUSPLUS
if (prm_cplusplus && lastst == sconst) {
if (!strcmp(laststr,Cstr)) {
mangleflag = FALSE;
manglelevel++;
getsym();
if (lastst == begin) {
getsym();
thismangle = FALSE;
}
else thismangle = TRUE;
}
}
#endif
if( defclass == sc_member) {
gensymerror(ERR_ILLCLASS,lastid);
break;
}
++global_flag;
declare(&gsyms,sc_external,bt_struct,flags);
--global_flag;
if (thismangle && !--manglelevel)
mangleflag = TRUE;
}
break;
case end:
#ifdef CPLUSPLUS
if (prm_cplusplus && manglelevel) {
mangleflag = (!--manglelevel);
getsym();
continue;
}
#endif
return;
case kw__interrupt:
intflag = 1;
flags |= DF_INT;
getsym();
continue;
case kw__abs:
++global_flag;
getsym();
if (lastst != openpa) {
generror(ERR_PUNCT,openpa,0);
}
else {
getsym();
val = intexpr(0);
if (lastst != closepa)
generror(ERR_PUNCT,closepa,skm_declclosepa);
}
getsym();
declare2(&gsyms,sc_abs,bt_struct,flags,val);
--global_flag;
break;
default:
return;
}
flags = 0;
intflag = 0;
}
}
void doargdecl(int defclass, char *names[], int *nparms, TABLE *table, int isinline)
/*
* Function arguments are declared here
*/
{
SYM *sp;
int flags = isinline ? DF_FUNCPARMS : 0;
for(;;) {
switch(lastst) {
case ellipse: {
sprintf(declid,"**ELLIPSE%d**",pcount++);
sp = xalloc(sizeof(SYM));
sp->name = litlate(declid);
sp->storage_class = sc_auto;
sp->tp = maketype(bt_ellipse,0);
sp->tp->uflags |= UF_DEFINED | UF_USED;
insert(sp,table);
if (ispascal)
generror(ERR_PASCAL_NO_ELLIPSE,0,0);
getsym();
goto exit;
}
case kw_const:
case id:
case kw_char: case kw_int: case kw_short: case kw_unsigned:
case kw_long: case kw_struct: case kw_union: case kw_signed:
case kw_enum: case kw_void:
case kw_float: case kw_double:
declare(table,sc_auto,bt_struct,flags);
break;
case kw_static:
case kw_auto:
case kw_register:
gensymerror(ERR_ILLCLASS,lastid);
getsym();
continue;
default:
goto exit;
}
if (isinline) {
names[(*nparms)++] = litlate(declid);
}
flags &= ~DF_CONST;
}
exit:
#ifdef CPLUSPLUS
if (prm_cplusplus) {
SYM *sp = table->head;
int found = FALSE;
while (sp) {
if (sp->defalt)
found = TRUE;
else
if (found)
gensymerror(ERR_MISSINGDEFAULT,sp->name);
sp = sp->next;
}
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -