?? cdecl.c
字號:
{ struct_t * S; int n; S = EiC_getInf(type); n = S->n; S->n = 1; /* force initialisation of first member only */ initstruct(type,addr,lev+1); S->n = n; } break; default: assign_var(type, *addr,0); break; }}static void initstruct(type_expr * type, void **addr, int lev){ if(EiC_lexan() == '{' ) { do_struct(type,addr,lev); if(lev > 1 && EiC_lexan() != ',') retractlexan(); EiC_match('}', " }"); } else { retractlexan(); if(lev > 0) do_struct(type,addr,lev); else /* else intializer must be an expression of the same type */ assign_var(type,*addr,1); }}static void do_struct(type_expr *type, void **addr,int lev){ struct_t *S; int i; S = EiC_getInf(type); for(i=0;i<S->n;i++) if(EiC_lexan() != '}') { retractlexan(); *addr = (char*)*addr + S->offset[i]; initglobal(S->type[i],addr,lev+1); *addr = (char*)*addr - S->offset[i]; if(EiC_lexan() != ',' && i != S->n-1) retractlexan(); } else { break; } retractlexan();}static int dostrlit(void ** addr,int ln, int sln, char * str){ /* * parse eg. char a[] = "hello world"; * or char a[5] = "hello world"; */ xmark(str,eicgstring); /* mark for garbage collector */ if(ln) { if(sln >= ln) EiC_warningerror("Array of chars is too long"); } else { ln = sln+1; /* allow for null at end */ *addr = xrealloc(*addr,ln); } if(sln < ln) memcpy(*addr,str,sln+1); else memcpy(*addr,str,ln); return ln;}static int initarray(type_expr * type, void ** addr, int size, int lev){ static int INCREMENT; if(EiC_gettype(type) == t_array) { int t,tok,s; if((tok =EiC_lexan()) == '{') { t = EiC_get_sizeof(type); if(lev == 0) INCREMENT = t == 0 ? EiC_get_sizeof(nextType(type)): 0; s = do_array(nextType(type),addr,t,lev,INCREMENT); if(t == 0) { int sz = EiC_get_sizeof(nextType(type)); if(sz) t = s/sz; else EiC_error("Ilegal array domain in initialisation"); setNumElems(type,t); } EiC_match('}'," }"); } else if(tok == STR) { /* handle string literals */ if(EiC_gettype(nextType(type)) == t_char) { size_t sln; t = EiC_get_sizeof(type); sln = (char*)token->Val.p.ep - (char*)token->Val.p.p - 1; s = dostrlit(addr,t,sln,token->Val.p.p); if(lev == 0 && t == 0) setNumElems(type,s); }else EiC_error("Illegal initialisation"); } else{ retractlexan(); if(lev > 0) /* lev indicates a recusive call */ size = do_array(nextType(type),addr,size,lev,INCREMENT); else EiC_error("missing { in initialisation of an array"); } } else initglobal(type,addr,lev+1); return size;}static int do_array(type_expr *type, void ** addr, int size, int lev, int inc){ int n = 0; while(EiC_lexan() != '}') { retractlexan(); if(n >= size) { if(inc) { size += inc; *addr = xrealloc(*addr, size); memset((char*)*addr + size - inc, 0, inc); } else { if(size) EiC_error("Too many initialisers"); else EiC_error("Illegal domain for initialisation"); } } *addr = (char*)*addr + n; size = initarray(type,addr, size,lev+1); *addr = (char*)*addr - n; n += EiC_get_sizeof(type); if (EiC_lexan() != ',') break; } retractlexan(); return size;}static void assign_var(type_expr *type, void *addr,int allow){ int t; token_t e1,e2; void *EiC_getaddress(token_t *); EiC_inittoken(&e2); EiC_assign_expr(&e2);#if 0 if(IsTemp(e2.Type)) EiC_clearTempories();#endif t = EiC_gettype(type); if (isconst(e2.Type)) { e1.Type = type; EiC_castconst(&e2,&e1,0); switch(t) { case t_char: case t_uchar: *(char*)addr = e2.Val.ival; break; case t_short: case t_ushort: *(short*)addr = e2.Val.ival; break; case t_int: case t_uint: *(int *)addr = e2.Val.ival; break; case t_long: case t_ulong: *(long*)addr = e2.Val.lval; break; case t_llong: *(eic_llong*)addr = e2.Val.llval; break; case t_float: *(float*)addr = e2.Val.dval; break; case t_double: *(double*)addr = e2.Val.dval; break; case t_pointer: if(EiC_S_LEVEL == 1 && EiC_gettype(e2.Type) == t_pointer && EiC_gettype(nextType(e2.Type)) == t_char && !e2.Sym) /* got string */ if(e2.Val.p.p) EiC_SaveGlobalString(&e2.Val.p); if(issafe(type)) *(ptr_t*)addr = e2.Val.p; else *(void**)addr = e2.Val.p.p; break; default: EiC_error("Unknown initialiserXXX"); } } else if(allow) { val_t h; token_t e3; EiC_inittoken(&e3); e3.Type = type; EiC_output(&e2); EiC_castvar(&e2,&e3,0); if (t == t_struct || t == t_union) structUnionCode(E1,&e2); h = E1->Val; E1->Val = E1->Sym->val; EiC_concode(&E1->Code,&e2.Code); EiC_do_stooutput(E1); E1->Val = h; } else { if(EiC_GI(&e2) != 0) /* global or static addresses only are allowed */ EiC_error("Illegal initialization: illegal address operation"); else { /*e1.Type = type;*/ /*EiC_output(&e2);*/ /*EiC_castvar(&e2,&e1,1);*/ if(EiC_gettype(type) == t_pointer || (e2.Sym && EiC_gettype(e2.Sym->type) == t_ref)) { ptr_t p; p.sp = p.p = EiC_getaddress(&e2); p.ep = (char*)p.p + EiC_get_sizeof(e2.Type); if(!EiC_sametypes(e2.Type,type)) EiC_warningerror("Suspicious pointer conversion"); if(issafe(type)) *(ptr_t*)addr = p; else *(void**)addr = p.p; EiC_freecode(&e2.Code); } else EiC_error("Expected constant expression as an" " initialiser"); } } EiC_freetoken(&e2);}static void decl(token_t * e1, int t){ type_expr *P = NULL; switch (t) { case '*': P = pointer(); dir_decl(e1, EiC_lexan()); if(P) e1->Type = EiC_catTypes(P,e1->Type); break; case ID: case '(': dir_decl(e1, t); break; default: EiC_error("Declarator error"); retractlexan(); }}static type_expr * pointer(void){ type_expr *t = NULL; do { t = EiC_addtype(t_pointer,t); if(EiC_lexan() == constsym || token->Tok == volatilesym) { if(token->Tok == constsym) { setConstp(t); } /*ignore volatilesym for now*/ EiC_lexan(); } /* pointer qualifer */ if(token->Tok == safesym) { unsetPtr(t); setSafe(t); EiC_lexan(); } else if(token->Tok == unsafesym) { unsetPtr(t); setUnSafe(t); EiC_lexan(); } } while (token->Tok == '*'); retractlexan(); return t;}static void dir_decl(token_t * e1, int t){ switch (t) { case '(': decl(e1, EiC_lexan()); EiC_match(')', " )"); f_dir_decl(e1); break; case ID: init_ident(e1, EiC_work_tab); f_dir_decl(e1); break; default: EiC_error("Direct declarator error"); break; }}static void f_dir_decl(token_t * e1){ while (1) switch (EiC_lexan()) { case '[': array_decl(e1); break; case '(': ff_dir_decl(e1); if(INPARMLIST) EiC_remlevel(EiC_S_LEVEL+1); break; default: retractlexan(); return; }}static void ff_dir_decl(token_t * e1){ int h; switch ((h=EiC_lexan())) { TYPEQUAL: STORECLASS: TYPESPEC: EiC_S_LEVEL++; RESET++; h = LSP; LSP = EiC_ENV->lsp; retractlexan(); EiC_make_func(e1); /* * Use INPARMLIST to inform other * modules that the following declarations * are function parameters. */ INPARMLIST++; PRAMHANDLE = e1->Type; parm_type_list(EiC_getInf(e1->Type)); /* * now pseudo reverse the parameter * order. */ EiC_reset_env_pointers(e1, LSP); LSP = h; RESET--; INPARMLIST--; EiC_S_LEVEL--; break; case ')': /* * This should really be made illegal, it allows * for function declarations with empty * paramater list, such as: * int f(); Therefore, force an implied t_var argument. */ { type_expr * type; EiC_make_func(e1); type = EiC_addtype(t_var,NULL); EiC_add_func_parm(EiC_getInf(e1->Type), &type, NULL); EiC_freetype(type); } return; default: if(h == ID) EiC_error("Unknown type '%s': possible " "old C type declaration", token->Val.sym->id); else EiC_error("Syntax error"); } EiC_match(')', " )");}static void UpDateParmSym(type_expr *ty, symentry_t *sym){ if(EiC_gettype(ty) == t_pointer && EiC_gettype(nextType(ty)) == t_funcdec) if(EiC_gettype(sym->type) != t_pointer) sym->type = EiC_addtype(t_pointer,sym->type);}static void parm_type_list(func_t * f){ extern int Pclash; char * name = NULL; token_t e2; EiC_inittoken(&e2); parm_decl(&e2); /* * Must watch out for void as a parameter. * The void paramater will have no sym entry. */ if(e2.Val.sym) { new_var(&e2);#if 1 { void EiC_adjustParam(type_expr **type); EiC_adjustParam(&e2.Sym->type); }#endif name = e2.Sym->id; } else /* still must reverse type if needed */ e2.Type = EiC_revtype(e2.Type); EiC_add_func_parm(f, &e2.Type,name); if(!e2.Val.sym) EiC_freetype(e2.Type); else UpDateParmSym(getFPty(f,getFNp(f)-1),e2.Val.sym); if(Pclash) Pclash = 0; if (EiC_lexan() == ',') f_parm_type_list(f); else retractlexan();}static void f_parm_type_list(func_t * f){ if (EiC_lexan() == '.') { if (EiC_lexan() == '.') if (EiC_lexan() == '.') { type_expr *type; type = EiC_addtype(t_var, NULL); EiC_add_func_parm(f, &type,NULL); EiC_freetype(type); return; } retractlexan(); EiC_error("Expected ..."); } else { retractlexan(); parm_type_list(f); }}static void fff_parm_decl(token_t *e1);static void ff_parm_decl(token_t *e1);static void f_parm_decl(token_t * e1);static void parm_decl(token_t * e1){ switch (EiC_lexan()) { TYPEQUAL: STORECLASS: TYPESPEC: decl_spec(e1); f_parm_decl(e1); break; default: if(token->Tok == ID) EiC_error("Unknown type '%s'",token->Val.sym->id); else EiC_error("Parameter declaration error"); }}static void f_parm_decl(token_t * e1){ if(EiC_lexan() == '*') { type_expr *P = NULL; P = pointer(); ff_parm_decl(e1); if(P) e1->Type = EiC_catTypes(P,e1->Type); } else { retractlexan(); ff_parm_decl(e1); }}static void ff_parm_decl(token_t *e1){ switch(EiC_lexan()) { case ID: init_ident(e1, EiC_work_tab); f_dir_decl(e1); break; case '(': fff_parm_decl(e1); break; case '[': retractlexan(); f_dir_decl(e1); break; default: /* null */ if(token->Tok != ',' && token->Tok != ')') EiC_error("Parameter declaration error"); else retractlexan(); return ; }}static void fff_parm_decl(token_t *e1){ switch(EiC_lexan()) { TYPEQUAL: STORECLASS: TYPESPEC: retractlexan(); ff_dir_decl(e1); EiC_remlevel(EiC_S_LEVEL+1); break; default: retractlexan(); f_parm_decl(e1); EiC_match(')', " ) "); break; } f_dir_decl(e1);}static void enum_spec(token_t * e1){ e1->Type = EiC_addtype(t_enum, NULL); f_enum_spec(e1);}static void f_enum_spec(token_t * e1){ int h, t, nxtt; h = EiC_work_tab; EiC_work_tab = tag_tab; switch (EiC_lexan()) { case ID: /* enumeration tag */ t = EiC_gettype(token->Val.sym->type); nxtt = EiC_lexan(); retractlexan(); if (nxtt == '{' || t == ID) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -