?? cdecl.c
字號:
static void f_ext_decl(token_t * e1)
{
switch (EiC_lexan()) {
DECL:
decl(e1, token->Tok);
ff_ext_decl(e1);
break;
case ';':
break;
default:
EiC_error("Declaration error");
EiC_match(';', " ; ");
}
}
token_t *EiC_genTemporay(type_expr *type, int level)
{
token_t *e1 = xcalloc(sizeof(token_t),1);
extern symentry_t * EiC_nxtTemp(int obj, int level);
symentry_t * sym;
sym = EiC_nxtTemp(ID,level);
EiC_inittoken(e1);
SetTemp(type);
e1->Type = EiC_copytype(type);
e1->Val.sym = sym;
e1->Tab = sym->nspace;
new_var(e1);
e1->Val = sym->val;
return e1;
}
static void do_Gotos(code_t *c)
{
if(c->gotos) {
Label_t *go, *lab;
while(go) {
lab = c->labels;
while(lab && strcmp(lab->name,go->name) != 0)
lab = lab->nxt;
if(lab)
ivalcode(c,go->loc) = lab->loc - go->loc;
else
EiC_error("Missing label `%s' defined at line %d",go->name,instline(c,go->loc));
go = go->nxt;
}
}
}
static void ff_ext_decl(token_t * e1)
{
extern void EiC_UpdateEntry(symentry_t * sym);
int t;
switch (EiC_lexan()) {
case '{': /* handle funtion definition */
if (EiC_S_LEVEL > 1) {
EiC_error("Illegal function definition in %s",EiC_RETURNEXPR->Sym->id);
break;
}
new_var(e1);
if((t = EiC_gotMissingNames(EiC_getInf(e1->Type))))
EiC_error("Missing name for Paramater %d",t);
if(EiC_ErrorRecover) /* force recovery */
EiC_ErrorRecover = 0;
if((t = EiC_gettype(e1->Type)) == t_funcdec || t == t_func) {
token_t e2;
code_t *code;
EiC_inittoken(&e2);
if(EiC_HasHiddenParm(e1->Type))
EiC_addoffsettolevel(stand_tab, EiC_S_LEVEL+1,2);
else
EiC_addoffsettolevel(stand_tab, EiC_S_LEVEL+1,1);
retractlexan();
if (e1->Sym->ass) {
EiC_warningerror("Function Re-definition of %s",e1->Sym->id);
EiC_freeFuncComments(EiC_getInf(e1->Type));
}
/* Update declaration to definition. */
EiC_exchtype(t_func, e1->Type);
EiC_INFUNC = 1;
EiC_RETURNON++;
EiC_RETURNEXPR = e1;
EiC_stmt(&e2);
EiC_RETURNON--;
EiC_reset_env_pointers(e1, LSP);
do_Gotos(&e2.Code);
/* remove reducear, if present */
if(e2.Code.nextinst != 0) {
if (e2.Code.inst[e2.Code.nextinst - 1].opcode ==
reducear)
e2.Code.nextinst--;
addreturn(e1,&e2.Code);
} else {
EiC_warningerror("Empty function definition");
EiC_generate(&e2.Code, eicreturn, &e2.Val, 0);
}
if(!EiC_ParseError) {
if(e1->Sym->ass)
EiC_killcode(e1->Sym);
code = (code_t *) xcalloc(1, sizeof(code_t));
e1->Sym->ass = 1;
*code = e2.Code;
EiC_ENV->AR[e1->Sym->val.ival].v.p.p = code;
codeName(code) = CurrentFileName();
} else {
void EiC_cleancode(code_t *);
EiC_cleancode(&e2.Code);
EiC_freecode(&e2.Code);
}
EiC_freetype(e2.Type);
EiC_INFUNC = 0;
} else {
e1->Type = NULL;
retractlexan();
}
break;
default:
if (e1->Val.sym) {
if(token->Tok == '@') { /* watch for reference declaration */
e1->Type = EiC_revtype(e1->Type);
e1->Type = EiC_addtype(t_ref,e1->Type);
EiC_setAsBaseType(e1->Type);
}
new_var(e1);
}
EiC_remlevel(EiC_S_LEVEL + 1);
if(token->Tok == ASS) {
initialiser(e1);
EiC_lexan();
} else if(token->Tok == '@') {
handle_address_operator(e1);
EiC_lexan();
}
fff_ext_decl(e1);
}
}
static void fff_ext_decl(token_t * e1)
{
if (RESET) {
EiC_reset_env_pointers(e1, LSP);
RESET--;
}
setBoundaryLimits(e1);
if(EiC_gettype(e1->Type) == t_array &&
!EiC_get_sizeof(nextType(e1->Type)))
EiC_error("Ilegal size specified for %s", e1->Sym->id);
if (token->Tok == ',') {
init_decl_list(e1);
e1->Type = NULL; /* hide new type */
EiC_match(';', " ;");
} else {
retractlexan();
semi_colon(e1);
}
}
static void semi_colon(token_t * e1)
{
e1->Type = NULL; /* hide new type */
if(!EiC_match(';', ";"))
retractlexan();
}
static void decl_spec(token_t * e1)
{
int sclass = 0;
void specifier(token_t *e1, int,int *sclass);
switch (token->Tok) {
STORECLASS:
TYPEQUAL:
TYPESPEC:
specifier(e1, token->Tok,&sclass);
if ((sclass == c_auto || sclass == c_register)
&& !(EiC_INFUNC || EiC_S_LEVEL > 1))
EiC_error("Illegal storage class usage");
else if(INPARMLIST && sclass && sclass != c_register)
EiC_error("Illegal storage class for parameter %s",EiC_LEXEM);
else
e1->Sclass = sclass;
EiC_setAsBaseType(e1->Type);
/* default:
retractlexan();
*/
}
}
static void specifier(token_t *e1, int t,int *sclass)
{
/* This function was modelled from lcc32's
* specifier function
*/
int cls, cons, sign, size, type, vol,ty;
cls = ty = vol = cons = sign = size = type=0;
if(sclass == NULL)
cls = c_auto;
while(1){
int *p, tt = t;
switch (t) {
case autosym: tt = c_auto; p = &cls; break;
case externsym: tt = c_extern; p = &cls; break;
case registersym: tt = c_register; p = &cls; break;
case staticsym: tt = c_static; p = &cls; break;
case typedefsym: tt = c_typedef; p = &cls; break;
case constsym: p = &cons; break;
case volatilesym:p = &vol; break;
case signedsym:
case unsignedsym:p = &sign; break;
case longsym:
if(size == longsym) {
size = 0;
tt = longsym+longsym;
}
case shortsym: p = &size; break;
case voidsym: ty = t_void; p = &type; break;
case charsym: ty = t_char; p = &type; break;
case intsym: ty = t_int; p = &type; break;
case floatsym: ty = t_float; p = &type; break;
case doublesym: ty = t_double; p = &type; break;
case enumsym:
case structsym:
case unionsym: {
token_t e2;
p = &type;
EiC_inittoken(&e2);
if (t == enumsym)
enum_spec(&e2);
else
st_un_spec(&e2, t);
/*
* test tag name.
*/
if (e2.Val.sym) {
e1->Type = EiC_copytype(e2.Type);
e1->Tab = stand_tab;
if(INSTUN)
addst_un_tag(e2.Val.sym);
} else {
int sclass = e1->Sclass;
*e1 = e2;
e1->Sclass = sclass;
if(t == enumsym)
cast_t_enum(e1);
}
}
break;
case TYPENAME:
if(type == 0 && p != &sign && p != &size) {
e1->Type = EiC_copytype(token->Val.sym->type);
p = &type;
} else { /* allow for masking and redeclarations */
#if 1
if(checklevel(e1,token->Val.sym,EiC_S_LEVEL) ||
cls == c_typedef) {
token->Tok = ID;
retractlexan();
} else
EiC_error("Illegal use of typedef %s",token->Val.sym->id);
p = NULL;
#else
token->Tok = ID;
retractlexan();
p = NULL;
#endif
}
break;
default:
retractlexan();
p = NULL;
}
if (p == NULL)
break;
if (*p)
EiC_error("invalid specification");
*p = tt;
t = EiC_lexan();
}
if(sclass)
*sclass = cls;
if(type == 0) {
type = intsym;
ty = t_int;
}
if ((size == shortsym && type != intsym)
|| (size == longsym && type != intsym && type != doublesym)
|| (sign && type != intsym && type != charsym))
EiC_error("invalid type specification");
if (type == charsym && sign)
ty = sign == unsignedsym ? t_uchar : t_char;
else if (size == shortsym)
ty = sign == unsignedsym ? t_ushort : t_short;
else if (size == longsym && type == doublesym)
ty = t_double;
else if (size == longsym+longsym) {
#ifndef NO_LONG_LONG
ty = t_llong;
#else
ty = sign == unsignedsym ? t_ulong : t_long;
#endif
} else if (size == longsym)
ty = sign == unsignedsym ? t_ulong : t_long;
else if (sign == unsignedsym && type == intsym)
ty = t_uint;
if(ty)
e1->Type = EiC_addtype(ty,e1->Type);
if (cons == constsym) {
if(INPARMLIST || EiC_INFUNC) /* */
setConstp(e1->Type);
else
setConst(e1->Type);
/*
if(EiC_INFUNC && !INPARMLIST && sclass)
*sclass = c_static;
*/
}
/* ignore volatile for now;
if (vol == VOLATILE)
ty = qual(VOLATILE, ty);
*/
}
static void init_decl_list(token_t * e1)
{
token_t e2;
do {
EiC_inittoken(&e2);
switch (EiC_lexan()) {
DECL:
e2.Type = EiC_copyBaseType(e1->Type);
e2.Sclass = e1->Sclass;
init_decl(&e2, token->Tok);
if (RESET) {
EiC_reset_env_pointers(&e2, LSP);
RESET--;
}
EiC_concode(&e1->Code, &e2.Code);
EiC_remlevel(EiC_S_LEVEL+1);
setBoundaryLimits(&e2);
break;
default:
EiC_error("Init decl list error");
}
if(EiC_gettype(e2.Type) == t_array &&
!EiC_get_sizeof(nextType(e2.Type)))
EiC_error("Ilegal size specified for %s", e2.Sym->id);
} while (EiC_lexan() == ',');
retractlexan();
}
static void init_decl(token_t * e1, int ty)
{
int t;
decl(e1, ty);
#if 1
t = EiC_lexan();
if(t == '@') { /* watch for reference declaration */
e1->Type = EiC_addtype(t_ref,e1->Type);
EiC_setAsBaseType(e1->Type);
}
#endif
new_var(e1);
#if 1
if(t == ASS)
initialiser(e1);
else if(t == '@') {
handle_address_operator(e1);
} else
retractlexan();
#else
if (EiC_lexan() == ASS) {
initialiser(e1);
} else
retractlexan();
#endif
}
static void initglobal(type_expr * type, void **addr,int lev);
static void initstruct(type_expr * type, void **addr,int lev);
static void do_struct(type_expr *type, void **addr,int lev);
static int initarray(type_expr * type, void ** addr, int size, int lev);
static void assign_var(type_expr *type, void *addr,int allow);
static int do_array(type_expr *type, void ** addr, int size, int lev, int inc);
static void structUnionCode(token_t * e1, token_t *e2)
{
val_t v;
v = e1->Val;
e1->Val = e1->Sym->val;
EiC_output(e1);
e1->Val = v;
v.ival = 1;
EiC_generate(&e1->Code, bump, &v, 0);
v.ival = EiC_get_sizeof(e2->Type);
EiC_generate(&e2->Code,refmem,&v,0);
}
static token_t * E1;
static void initialiser(token_t * e1)
{
int t;
int peek = EiC_lexan();
retractlexan();
if(EiC_GI(e1) == 0) { /* global or static local variable */
E1 = e1;
if ((t =EiC_gettype(e1->Type)) <= t_pointer) { /* get scalars */
int v = 1;
if(e1->Sclass & c_static) /* catch statics */
v = 0;
if(!isconst(e1->Type))
assign_var(e1->Type,&EiC_ENV->AR[e1->Sym->val.ival].v,v);
else {
assign_var(e1->Type,&e1->Sym->val,v);
switch(EiC_gettype(e1->Type)) {
case t_char: e1->Sym->val.ival = e1->Sym->val.cval;break;
case t_uchar: e1->Sym->val.ival = e1->Sym->val.ucval;break;
case t_short: e1->Sym->val.ival = e1->Sym->val.sval;break;
case t_ushort: e1->Sym->val.ival = e1->Sym->val.usval;break;
case t_float: e1->Sym->val.dval = e1->Sym->val.fval;break;
}
}
} else {
if(!isconst(e1->Type))
initglobal(e1->Type,&EiC_ENV->AR[e1->Sym->val.ival].v.p.p,0);
else {
initglobal(e1->Type,&e1->Sym->val.p.p,0);
}
}
} else {
if ((t =EiC_gettype(e1->Type)) <= t_pointer /* local scalar types */
|| ((t == t_struct || t==t_union) && peek != '{')
) {
if(isconst(e1->Type))
assign_var(e1->Type,&e1->Sym->val,0);
else {
token_t e2;
val_t h;
EiC_inittoken(&e2);
EiC_assign_expr(&e2);
if (isconst(e2.Type)) {
EiC_castconst(&e2,e1,0);
h = e1->Val;
e1->Val = e1->Sym->val;
EiC_generate(&e1->Code,pushval,&e2.Val,0);
EiC_do_stooutput(e1);
e1->Val = h;
EiC_freetoken(&e2);
} else {
EiC_output(&e2);
EiC_castvar(&e2,e1,0);
if (t == t_struct || t == t_union)
structUnionCode(e1,&e2);
EiC_concode(&e1->Code,&e2.Code);
h = e1->Val;
e1->Val = e1->Sym->val;
EiC_do_stooutput(e1);
e1->Val = h;
}
EiC_freetoken(&e2);
}
} else if(EiC_INFUNC) {
/* code for initialising automatic aggregate types */
extern unsigned EiC_ASPOT;
int s2, s1 = EiC_get_sizeof(e1->Type);
val_t v;
E1 = e1;
if(s1)
v.p.p = xcalloc(1,s1);
else
v.p.p = NULL;
initglobal(e1->Type,&v.p.p,0);
if((s2 = EiC_get_sizeof(e1->Type)) > s1)
EiC_ASPOT += s2 - s1;
EiC_add_func_initialiser(EiC_getInf(EiC_RETURNEXPR->Type),v.p.p);
EiC_generate(&e1->Code,minit,&v,s2);
} else
EiC_error("Initialisation not "
"supported for non scalar local types");
}
}
static void initglobal(type_expr * type, void **addr, int lev)
{
switch(EiC_gettype(type)) {
case t_array:
initarray(type,addr,0,lev); break;
case t_struct:
initstruct(type,addr,lev); break;
case t_union:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -