X-Git-Url: http://git.maemo.org/git/?p=opencv;a=blobdiff_plain;f=apps%2FHawk%2FCVEiCL%2FEiC%2Fsrc%2Fcdecl.c;fp=apps%2FHawk%2FCVEiCL%2FEiC%2Fsrc%2Fcdecl.c;h=0000000000000000000000000000000000000000;hp=6ee51b256c5a5f1247511ac74fd47ee154e10003;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hpb=454138ff8a20f6edb9b65a910101403d8b520643 diff --git a/apps/Hawk/CVEiCL/EiC/src/cdecl.c b/apps/Hawk/CVEiCL/EiC/src/cdecl.c deleted file mode 100644 index 6ee51b2..0000000 --- a/apps/Hawk/CVEiCL/EiC/src/cdecl.c +++ /dev/null @@ -1,2177 +0,0 @@ -/* cdecl.c - * - * (C) Copyright Apr 15 1995, Edmond J. Breen. - * ALL RIGHTS RESERVED. - * This code may be copied for personal, non-profit use only. - * - */ - -/* Modified by Intel OpenCV team. Added lines 528-531 in order to prevent - the parser exceptions throwing in specific cases. No guarantee that this - is the fix for all cases. */ - - -#include -#include -#include - -#include "MachSet.h" -#include "global.h" -#include "lexer.h" -#include "typemod.h" -#include "func.h" -#include "xalloc.h" -#include "cdecl.h" -#include "preproc.h" -#include "error.h" -#include "typesets.h" -#include "parser.h" -#include "symbol.h" - -int EiC_work_tab; -static int LSP, RESET = 0; -int EiC_RETURNON = 0; -int EiC_INFUNC = 0; -static int ABSDECL = 0; /* constant for abstract declorator */ -static int INPARMLIST = 0; -static token_t * INSTUN = 0; -static type_expr *PRAMHANDLE; -token_t *EiC_RETURNEXPR; - -/* TODO: external functions that need to be declared in a header somewhere */ -void EiC_SaveGlobalString(ptr_t *s); -void EiC_reset_env_pointers(token_t *, int bp); - -/** PROTOTYPES from cdecl.c **/ -static int isredec(token_t * e1); -static void establish_id(token_t * e1); -static void new_var(token_t * e1); -static void addreturn(token_t *,code_t * c); -static void f_ext_decl(token_t * e1); -static void ff_ext_decl(token_t * e1); -static void fff_ext_decl(token_t * e1); -static void semi_colon(token_t * e1); -static void decl_spec(token_t * e1); -static void specifier(token_t *e1, int t,int *sclass); -static void init_decl_list(token_t * e1); -static void init_decl(token_t * e1, int t); -static void initialiser(token_t * e1); -static void decl(token_t * e1, int t); -static type_expr * pointer(void); -static void dir_decl(token_t * e1, int t); -static void f_dir_decl(token_t * e1); -static void ff_dir_decl(token_t * e1); -static void parm_type_list(func_t * f); -static void f_parm_type_list(func_t * f); -static void parm_decl(token_t * e1); -static void enum_spec(token_t * e1); -static void f_enum_spec(token_t * e1); -static void enum_list(token_t * e1); -static void array_decl(token_t * e1); -static void st_un_spec(token_t * e1, int t); -static void f_st_un_spec(token_t * e1); -static void s_decl_list(token_t * e1); -static void st_decl(token_t * e1, int t); -static void spec_qual_list(token_t * e1, int t); -static void r_spec_qual_list(token_t * e1); -static void addst_un_tag(symentry_t *sym); -static void addst_un_mem(token_t * e1, token_t * e2); -static void spec_declor_list(token_t * e1, token_t * e2); -static void st_declor(token_t * e1, int t); -static void f_st_declor(); -static void abs_decl(token_t * e1, int t); -static void f_abs_decl(token_t * e1); -static void dir_abs_decl(token_t * e1, int t); -static void f1_dir_abs(token_t * e1); -static void EiC_f2_dir_abs(token_t * e1); - - -/* RoundUp returns x rounded to the next multiple - * of n, which must be a power of two. - */ -#define RoundUp(x,n) (((x)+((n)-1))&(~((n)-1))) -#define init_ident(e,t) (e)->Val = token->Val; (e)->Tab = (t) - -static int isredec(token_t * e1) -{ - /* test for re declaration. */ - return EiC_sametypes(e1->Type, e1->Val.sym->type); -} - -#if 0 - -#define setBoundaryLimits(x) - -#else -static void setBoundaryLimits(token_t *e1) -{ - int t = EiC_gettype(e1->Type); - if(e1->Sclass == c_typedef) /* watch out for typedefs */ - return; - if((!EiC_INFUNC || EiC_GI(e1) == 0) && t > t_pointer && - !(t == t_func || t == t_funcdec || t == t_builtin)) { - ptr_t *p; - int s = EiC_get_sizeof(e1->Type); - - if(!isconst(e1->Type)) - p = &EiC_ENV->AR[e1->Sym->val.ival].v.p; - else - p = &e1->Sym->val.p; - - p->sp = p->p; - p->ep = (char*)p->p + s; - - } - /* automatic aggregate - * types are done on the fly. - */ - -} -#endif - -static void handle_address_operator(token_t *e1) -{ - extern int TREFON; - int h = TREFON; - TREFON = 1; - - EiC_exchtype(t_pointer,e1->Type); - initialiser(e1); - EiC_exchtype(t_ref,e1->Type); - - TREFON = h; - -} - - -static void cast_t_enum(token_t *e1) -{ - /* enumeration types into ints */ - e1->Type = EiC_addtype(t_int, EiC_freetype(e1->Type)); - EiC_setAsBaseType(e1->Type); -} - - -static int checklevel(token_t *e1,symentry_t * sym, int level) -{ - /* - * Checks to see if there is a true difference between - * the current scope and the declaration scope. - */ - - if(sym->level != level) { - int t = EiC_gettype(e1->Type); - if((t == t_func || t == t_funcdec) && !INPARMLIST) { - return 0; - } else - return 1; - } else -#if 0 - if(level == 1 && sym->id != CurrentFileName()) { - if (e1->Sclass & c_static) - return 1; - } -#endif - return 0; -} - -static void setscope(symentry_t * sym,int level, int t) -{ - void EiC_UpdateSymPos(symentry_t * sym); - if((t == t_func || t == t_funcdec) && !INPARMLIST) { - sym->level = 1; - } else if(sym->sclass == c_extern) - sym->level = 1; - else - sym->level = level; - if(sym->level < level || - (sym->next && sym->next->level > sym->level)) - EiC_UpdateSymPos(sym); -} - -static void freeArray(token_t *e1) -{ - if(EiC_get_sizeof(e1->Val.sym->type)) - xfree(EiC_ENV->AR[e1->Val.sym->val.ival].v.p.p); - EiC_ENV->AR[e1->Val.sym->val.ival].v.p.p = NULL; -} - -static void check_decl(token_t * e1) -{ - int t; - type_expr *ty = e1->Type; - for(;ty;ty=nextType(ty)) - if((t=EiC_gettype(ty)) == t_funcdec || t == t_func) { - t = EiC_gettype(nextType(ty)); - if(t == t_array || t == t_funcdec) - EiC_error("Illegal return type for %s", - e1->Val.sym->id); - } -} - -static void doBuiltin(token_t * e1) -{ - void EiC_UpdateEntry(symentry_t * sym); - if(token->Tok == ';') { /* must be a prototype */ - EiC_UpdateEntry(e1->Val.sym); - if(nextType(e1->Val.sym->type)) { - EiC_warningerror("2nd prototype for builtin -> %s", - e1->Val.sym->id); - } - EiC_freetype(e1->Val.sym->type); - EiC_exchtype(t_builtin,e1->Type); - e1->Val.sym->type = e1->Type; - e1->Sym = e1->Val.sym; - }else - EiC_error("Illegal redefinition of builtin function %s", - e1->Val.sym->id); -} - -static void showRedec(token_t *e1) -{ - char * EiC_getClashedfname(char nspace,char *id); - extern int Pclash; - char *fn; - - if(Pclash) - fn = EiC_getClashedfname(EiC_work_tab,e1->Val.sym->id); - else - fn = e1->Val.sym->fname; - - EiC_error(" Redeclaration of parameter `%s'\n" - "Previously declared in: %s",e1->Val.sym->id,fn); - - - /* generate a dummy entry */ - e1->Val.sym = EiC_insertLUT(e1->Tab, - e1->Val.sym->id, ID); -} - -static void establish_id(token_t * e1) -{ - /* e1->Val.sym->type is the previous or - stored type - e1->Type is the new type - */ - - extern int Pclash; - int level,t; - void EiC_UpdateEntry(symentry_t * sym); - - if ((t=EiC_gettype(e1->Val.sym->type)) == ID) { - /* variable not declared previously, - * but check for possible clashes with - * previously declared static variables - */ - - if(Pclash && !(e1->Sclass & c_static) && !(EiC_INFUNC || INPARMLIST || INSTUN)) - showRedec(e1); - - } else if(e1->Sclass != c_extern && - ( checklevel(e1,e1->Val.sym,EiC_S_LEVEL) - || e1->Tab != e1->Val.sym->nspace)) - e1->Val.sym = EiC_insertLUT(e1->Tab, e1->Val.sym->id, ID); - else if (isredec(e1)) { - if(EiC_INFUNC && EiC_S_LEVEL == 2 && e1->Val.sym->val.ival < 0) - showRedec(e1); - /* catch declaration after definition */ - if(t == t_func) { - /* Swap Parmameter Lists */ - - if(token->Tok == '{') { /* is definition */ - if(e1->Val.sym->fname == CurrentFileName()) { - func_t *f2 = (func_t *)EiC_getInf(e1->Type); - if(EiC_hasPrototype(f2)) - EiC_swapFPLists(EiC_getInf(e1->Val.sym->type),f2); - EiC_UpdateEntry(e1->Val.sym); - } else - showRedec(e1); - } - - EiC_freetype(e1->Type); - e1->Type = e1->Val.sym->type ; - e1->Sym = e1->Val.sym; - return; - - } else if(t == t_builtin) { - doBuiltin(e1); - return; - } else if(CurrentFileName() != e1->Val.sym->fname && - (e1->Sclass & c_static)) { - e1->Val.sym = EiC_insertLUT(e1->Tab, e1->Val.sym->id, ID); - } else if(CurrentFileName() != e1->Val.sym->fname && - e1->Sclass != c_extern && - e1->Val.sym->sclass != c_extern && - t != t_funcdec) { - showRedec(e1); - } else { - EiC_UpdateEntry(e1->Val.sym); - if((t=EiC_gettype(e1->Type)) == t_array) { - if(e1->Sclass != c_extern) - freeArray(e1); - } else if(t == t_struct || (t == t_union)) { - /* use original copy */ - EiC_freetype(e1->Type); - e1->Type = e1->Val.sym->type ; - } if(t == t_funcdec) { - func_t *f1, *f2; - f1 = EiC_getInf(e1->Type); - f2 = EiC_getInf(e1->Val.sym->type); - setFcallBack(f1,getFcallBack(f2)); - setFcallBack(f2,NULL); - } - - - e1->Sym = e1->Val.sym; - return; - } - } else if(t == t_builtin) { - doBuiltin(e1); - return; - } else if(t == t_ref) { - if((e1->Sclass & c_extern) && - EiC_sametypes(e1->Type,nextType(e1->Val.sym->type))) { - e1->Sym = e1->Val.sym; - EiC_freetype(e1->Type); - e1->Type = e1->Sym->type; - return; - } else /* error */ - showRedec(e1); - } else { - if(e1->Val.sym->level == EiC_S_LEVEL && - !(e1->Sclass & c_static && - e1->Val.sym->fname != CurrentFileName())) - showRedec(e1); - else - /* generate space in lookup table */ - e1->Val.sym = EiC_insertLUT(e1->Tab, e1->Val.sym->id, ID); - } - e1->Val.sym->sclass = e1->Sclass; - setscope(e1->Val.sym,EiC_S_LEVEL,EiC_gettype(e1->Type)); - e1->Val.sym->nspace = e1->Tab; - e1->Sym = e1->Val.sym; - if (e1->Sclass == c_static) { - level = 1; - if(EiC_S_LEVEL == 1) { - /* mark as private */ - e1->Sym->sclass |= c_private; - } - - } else - level = e1->Val.sym->level; /*EiC_S_LEVEL;*/ - /* - * N.B. if changes are made to the condition - * for stacking, make sure that the free_sym - * function remains consistent. - */ - if (!isconst(e1->Type) && - e1->Tab == stand_tab && e1->Sclass != c_typedef && - e1->Val.sym->val.ival == -1) - EiC_stackit(e1->Val.sym, level); -} - -#if 1 - - -static size_t TempSz = 0; - -void EiC_clearTempories(void) -{ - void EiC_updateLocals(void); - extern unsigned CurTemp,EiC_ASPOT; - if(CurTemp) { - EiC_updateLocals(); - EiC_ENV->lsp = EiC_ENV->lsp > CurTemp ? EiC_ENV->lsp - CurTemp: 0; - EiC_ASPOT = EiC_ASPOT > TempSz ? EiC_ASPOT - TempSz : 0; - TempSz = CurTemp = 0; - } -} - -static void newSlot(token_t * E, size_t sz, val_t *v, int align) -{ - extern unsigned EiC_ASPOT; - /* Non static locals */ - static val_t v2; - - if(IsTemp(E->Type)) - TempSz += (sz + RoundUp(EiC_ASPOT,align) - EiC_ASPOT); - - if (EiC_ASPOT != 0) - EiC_ASPOT = RoundUp(EiC_ASPOT,align); - - v2.ival = -1; - - /* the lda instruction relies on stoptr - * being the next instruction, so don't change - * unless made compatible with 'lda' usage - * in interpret.c. - */ - - EiC_generate(&E->Code,lda,&v2,EiC_ASPOT); - EiC_generate(&E->Code, stoptr, v, 1); - EiC_ASPOT += sz; - -} -#endif - -static void new_var(token_t * e1) -{ - int t = EiC_gettype(e1->Type); - - e1->Type = EiC_revtype(e1->Type); - establish_id(e1); - check_decl(e1); - if (e1->Sym) { - if(EiC_gettype(e1->Type) == t_enum && e1->Tab != tag_tab) - cast_t_enum(e1); - - EiC_newsymtype(e1->Sym, e1->Type); - if (!(e1->Sym->sclass == c_typedef) && !INPARMLIST) - if (e1->Tab == stand_tab && - ((t = EiC_gettype(e1->Type)) == t_array || - t == t_struct || t == t_union)) { - val_t v; - token_t *E; - v.ival = EiC_get_sizeof(e1->Sym->type); - /* - * Here we must consider 3 types - * of aggregate data: (1) local, - * (2) local but static and - * (3) global. - * Global and local static data - * get placed on the global stack. - * Local data goes on the local stack. - */ - if (EiC_INFUNC && (e1->Sym->sclass & c_static)) { - E = EiC_RETURNEXPR; - EiC_add_func_static(EiC_getInf(EiC_RETURNEXPR->Type), - e1->Sym->val.ival); - } else - E = e1; - - if (/*IsTemp(E->type) ||*/ (E->Sym->level > 1 && E != EiC_RETURNEXPR)) { - - newSlot(E,v.ival,&e1->Sym->val,EiC_get_align(e1->Type)); - - } else { - /* - * Globals and static local arrays/structs - * are made on the fly. However, if not - * NULL, assume memory has already been allocated. - */ - int sz; - sz = v.ival > 1? v.ival:1; - - if(isconst(e1->Type)) { - if(e1->Sym->val.ival == -1) /* not very safe ! */ - e1->Sym->val.p.p = (void*) - xcalloc(1,sz); - } else { - if(!EiC_ENV->AR[e1->Sym->val.ival].v.p.p) - EiC_ENV->AR[e1->Sym->val.ival].v.p.p - = (void*)xcalloc(1,sz); - } - } - } - } -} - -static void addreturn(token_t * e1, code_t * c) -{ - val_t v; - int i, n, lcode, rtn; - int err = 1; /* expect an error */ - int EiC_analyseCode(code_t *c); - - if(EiC_ParseError) - return; - - n = nextinst(c) - 1; - lcode = opcode(c,n); - rtn = EiC_analyseCode(c); - - if(lcode == eicreturn && rtn <= n) - return; - /*printf("rtn = %d possible %s\n",rtn,e1->Sym->id);*/ - - if (lcode == fmem) { /* free memory */ - /* The last instruction is fmem. Thus, force all - * return calls within the function - * to exit via fmem - */ - if(rtn <= n - 1 && opcode(c,n-1) == eicreturn) - err=0; /* no possible error */ - for(i = 0; i < n; ++i) - if(c->inst[i].opcode == eicreturn) { - c->inst[i].opcode = jmpu; - c->inst[i].val.ival = n - i; - } - rtn = n; - } - if(rtn >= n) { - EiC_generate(c, eicreturn, &v, 0); - if(EiC_gettype(nextType(e1->Type)) != t_void && err) - EiC_warningerror("Flow reaches end " - "of non-void function `%s'", - e1->Sym->id); - } -} - -int EiC_ext_decl(token_t * e1) -{ - int h; - e1->Pflag = 0; - switch (EiC_lexan()) { - TYPEQUAL: - STORECLASS: - TYPESPEC: - h = RESET; - RESET = 0; - decl_spec(e1); - f_ext_decl(e1); - /* Hawk change */ - if(e1->Sym && e1->Sym->type) - e1->Sym->type->sym = e1->Sym; - /* Hawk end change */ - EiC_clearTempories(); - RESET = h; - break; - default: - retractlexan(); - return 0; - } - return 1; -} - -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; - go = c->gotos; - 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); - e1->Type = NULL; /* hide new 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: - { - 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;in;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) { - - init_ident(e1, EiC_work_tab); - - - new_var(e1); - EiC_work_tab = h; - - if (EiC_lexan() == '{') { - enum_list(e1); - EiC_match('}', " }"); - e1->Type = e1->Val.sym->type; - } else - retractlexan(); - break; - } else if (t == t_enum) { - EiC_freetype(e1->Type); - e1->Type = EiC_copytype(token->Val.sym->type); - } else - EiC_error("Enumeration declaration error"); - - break; - case '{': - EiC_work_tab = h; - enum_list(e1); - EiC_match('}', " }"); - break; - - default: - EiC_error("Enumeration declaration error"); - retractlexan(); - } - EiC_work_tab = h; -} - -static void enum_list(token_t * e1) -{ - int ENUMVAL = 0; - token_t e2; - token_t e3; - do { - EiC_inittoken(&e2); - /* - * now do enumerator part - */ - if (EiC_lexan() == ID) { - e2.Type = EiC_addtype(t_int, NULL); - setConst(e2.Type); - EiC_setAsBaseType(e2.Type); - e2.Sclass = c_enum; - init_ident(&e2, EiC_work_tab); - new_var(&e2); - if (EiC_lexan() == ASS) { - EiC_inittoken(&e3); - cond_expr(&e3); - if (isconst(e3.Type) && EiC_gettype(e3.Type) == t_int) - ENUMVAL = e3.Val.ival; - else { - EiC_freetoken(&e3); - EiC_error("Assignment must be constant"); - break; - } - EiC_freetoken(&e3); - } else - retractlexan(); - e2.Sym->val.ival = ENUMVAL++; - } else { - EiC_error("Expected identifier in enumeration"); - break; - } - } while (EiC_lexan() == ','); - retractlexan(); -} - -static void array_decl(token_t * e1) -{ - int t; - token_t e2; - EiC_inittoken(&e2); - EiC_assign_expr(&e2); - if (isconst(e2.Type)) { - if ((t=EiC_gettype(e2.Type)) != t_int && t != t_uint) { - if(sizeof(int) != sizeof(long) || t != t_ulong) { - EiC_error("Constant int expression needed"); - e2.Val.ival = 0; - } - } - } else { - if(!ABSDECL && /*((t == t_void && EiC_INFUNC) || */ - EiC_gettype(e2.Type) != t_void ) - EiC_error("Constant int expression needed"); - e2.Val.ival = 0; - } - e1->Type = EiC_addtype(t_array, e1->Type); - setNumElems(e1->Type,e2.Val.ival); - EiC_freetoken(&e2); - EiC_match(']', " ] "); -} - - -static void st_un_spec(token_t * e1, int t) -{ - switch (t) { - case structsym: - e1->Type = EiC_addtype(t_struct, e1->Type); - break; - case unionsym: - e1->Type = EiC_addtype(t_union, e1->Type); - break; - } - f_st_un_spec(e1); -} - -static eicstack_t stun; -static void f_st_un_spec(token_t * e1) -{ - val_t val; - int t,nxtt; - symentry_t *sym; - int h = EiC_work_tab; - EiC_work_tab = tag_tab; - - val.p.p = INSTUN; - INSTUN = e1; - EiC_eicpush(&stun,val); - switch (EiC_lexan()) { - case ID: /* struct or union tag */ - EiC_work_tab = h; - sym = token->Val.sym; - t = EiC_gettype(sym->type); - - nxtt = EiC_lexan(); - retractlexan(); - - if(t==ID || (nxtt == '{' && token->Val.sym->levelType,xcalloc(1, sizeof(struct_t))); - if(nxtt == '{') { - - EiC_lexan(); - EiC_S_LEVEL++; - s_decl_list(e1); - EiC_match('}', " }"); - EiC_S_LEVEL--; - if(EiC_lexan() == ';' && EiC_S_LEVEL == 1) - e1->Type = NULL; - retractlexan(); - - } - - } else { - if (t == t_struct || t == t_union) { - EiC_freetype(e1->Type); - e1->Type = EiC_copytype(sym->type); - } else { - init_ident(e1, tag_tab); - new_var(e1); - setInf(e1->Type,xcalloc(1, sizeof(struct_t))); - } - if(nxtt == '{') { - EiC_lexan(); - EiC_S_LEVEL++; - s_decl_list(e1); - EiC_match('}', " }"); - EiC_S_LEVEL--; - if(EiC_lexan() == ';' && EiC_S_LEVEL == 1) { - EiC_freetype(e1->Type); - e1->Type = NULL; - } - retractlexan(); - } - - } - break; - case '{': - EiC_work_tab = h; - EiC_S_LEVEL++; - s_decl_list(e1); - EiC_match('}', " }"); - EiC_S_LEVEL--; - break; - } - EiC_work_tab = h; - EiC_eicpop(&stun,&val); - INSTUN = val.p.p; - -} - - -static void s_decl_list(token_t * e1) -{ - int f = 0, bp = EiC_ENV->lsp; - struct_t *S; - - - if(!EiC_getInf(e1->Type)) - setInf(e1->Type,xcalloc(1, sizeof(struct_t))); - /* - if(((struct_t*)EiC_getInf(e1->Type))->cl) { - EiC_error("Illegal use of struct/union"); - return; - } - */ - - while (1) { - switch (EiC_lexan()) { - TYPESPEC: - TYPEQUAL: - f = 1; - st_decl(e1, token->Tok); - break; - default: - if (!f) - EiC_error("Struct/Union list declaration error"); - S = EiC_getInf(e1->Type); - S->cl = 1; - /* - * determine structure alignment. - */ - - S->tsize = RoundUp(S->tsize,S->align); - retractlexan(); - EiC_reset_env_pointers(e1, bp); - return; - } - } -} - -static void st_decl(token_t * e1, int t) -{ - token_t e2; - EiC_inittoken(&e2); - spec_qual_list(&e2, t); - EiC_setAsBaseType(e2.Type); - spec_declor_list(e1, &e2); - EiC_freetype(e2.Type); - - EiC_match(';', " ; "); -} - -static void spec_qual_list(token_t * e1, int t) -{ - /*type_spec(e1, t);*/ - specifier(e1,t,NULL); - r_spec_qual_list(e1); -} - -static void r_spec_qual_list(token_t * e1) -{ - switch (EiC_lexan()) { - TYPESPEC: - spec_qual_list(e1, token->Tok); - break; - default: - retractlexan(); - } -} - -void EiC_free_un_mem(type_expr * e) -{ - struct_t *S = EiC_getInf(e); - if (S) { - int i; - if(S->n) { - for (i = 0; i < S->n; i++) { - xfree(S->id[i]); - EiC_freetype(S->type[i]); - } - xfree(S->offset); - xfree(S->id); - xfree(S->type); - } - if(S->ntags) { - for(i=0;intags;++i) - EiC_freetype(S->tag[i]); - xfree(S->tag); - } - xfree(S); - } -} - -static void addst_un_tag(symentry_t *sym) -{ - struct_t *S; - S = EiC_getInf(INSTUN->Val.sym->type); - S->ntags++; - if(S->ntags == 1) - S->tag = (type_expr**)xmalloc(sizeof(type_expr*)); - else - S->tag = (type_expr**)xrealloc(S->tag, - sizeof(type_expr*)*S->ntags); - S->tag[S->ntags - 1] = EiC_transtype(sym->type); - EiC_setaliases(sym->type,1); -} - -static void addst_un_mem(token_t * e1, token_t * e2) -{ - struct_t *S; - int off, s; - - S = EiC_getInf(e1->Type); - if (S->n == 0) { - S->id = (char **) xcalloc(1, sizeof(char *)); - S->offset = (int *) xcalloc(1, sizeof(int)); - S->type = (type_expr **) xcalloc(1, sizeof(type_expr *)); - } else { - /* - * first check for duplication of names - */ - int i; - for(i=0;in;++i) - if(strcmp(S->id[i], e2->Val.sym->id) == 0) - EiC_error("Duplication of identifier in struct/union"); - - S->id = (char **) xrealloc(S->id, - (S->n + 1) * sizeof(char *)); - S->offset = (int *) xrealloc(S->offset, - (S->n + 1) * sizeof(int)); - S->type = (type_expr **) xrealloc(S->type, - (S->n + 1) * sizeof(type_expr *)); - } - - if(isconst(e2->Type)) { - unsetConst(e2->Type); - setConstp(e2->Type); - } - - if(EiC_gettype(e2->Type) == t_enum) - cast_t_enum(e2); - - S->id[S->n] = (char *) EiC_strsave(e2->Val.sym->id); - S->type[S->n] = EiC_transtype(e2->Type); - - - if(!(s = EiC_get_sizeof(S->type[S->n]))) { - EiC_error("Incomplete data type for struct/union member %s",S->id[S->n]); - } - off = EiC_get_align(e2->Type); - - if (EiC_gettype(e1->Type) == t_struct) { - - S->offset[S->n] = RoundUp(S->tsize,off); - S->tsize += s + S->offset[S->n] - S->tsize; - } else { /* handle union */ - S->offset[S->n] = 0; - S->tsize = S->tsize > s ? S->tsize : s; - } - /* - * structure alignment is equal to the - * maximum alignment of its members. - */ - if(S->align < off) - S->align = off; - S->n++; -} - -static void spec_declor_list(token_t * e1, token_t * e2) -{ - int ftime = 1, cl; - token_t e3; - cl = ((struct_t*)EiC_getInf(e1->Type))->cl; - do { - switch (EiC_lexan()) { - case '*': - case ID: - case '(': - case ':': - EiC_inittoken(&e3); - e3.Type = EiC_transtype(e2->Type); - st_declor(&e3, token->Tok); - if (EiC_gettype(e3.Type) == t_struct || - EiC_gettype(e3.Type) == t_union) { - struct_t *S; - S = EiC_getInf(e3.Type); - if (!S->cl) /* check for closure */ - EiC_error("Illegal Struct/Union member"); - } - /* if structure/union is already closed, - * then assume structure is being re-entered. - */ - if (e3.Val.sym && !cl) { - e3.Type = EiC_revtype(e3.Type); - if (ftime) - EiC_setaliases(e2->Type, 1); - addst_un_mem(e1, &e3); - if (ftime) { - EiC_setaliases(e3.Type, 1); - ftime = 0; - } - } - EiC_freetype(e3.Type); - EiC_remsym(e3.Val.sym); - break; - default: - retractlexan(); - EiC_error("Struct/Union member declaration error"); - } - } while (EiC_lexan() == ','); - retractlexan(); -} - -static void st_declor(token_t * e1, int t) -{ - switch (t) { - case '*': - case ID: - case '(': - decl(e1, t); - /*setBoundaryLimits(e1);*/ - f_st_declor(); - establish_id(e1); - break; - case ':': - EiC_error("Bit fields not supported"); - break; - } -} - -static void f_st_declor() -{ - if (EiC_lexan() == ':') - EiC_error("Bit fields not supported"); - else - retractlexan(); -} - -int EiC_type_name(token_t * e1) -{ - switch (EiC_lexan()) { - TYPEQUAL: - TYPESPEC: - spec_qual_list(e1, token->Tok); - EiC_setAsBaseType(e1->Type); - switch (EiC_lexan()) { - case '*': - case '(': - case '[': - abs_decl(e1, token->Tok); - e1->Type = EiC_revtype(e1->Type); - break; - default: - retractlexan(); - } - break; - default: - retractlexan(); - return 0; - } - return 1; -} - -static void abs_decl(token_t * e1, int t) -{ - type_expr *P = NULL; - ABSDECL++; - switch (t) { - case '*': - P = pointer(); - f_abs_decl(e1); - if(P) - e1->Type = EiC_catTypes(P,e1->Type); - break; - case '(': - case '[': - dir_abs_decl(e1, t); - break; - case ID: - EiC_error("extraneous identifier `%s'",token->Val.sym->id); - break; - } - ABSDECL--; -} - -static void f_abs_decl(token_t * e1) -{ - switch (EiC_lexan()) { - case '(': - case '[': - dir_abs_decl(e1, token->Tok); - break; - case ID: - EiC_error("extraneous identifier `%s'",token->Val.sym->id); - break; - default: - retractlexan(); - } -} - -static void dir_abs_decl(token_t * e1, int t) -{ - switch (t) { - case '(': - f1_dir_abs(e1); - EiC_f2_dir_abs(e1); - break; - case '[': - array_decl(e1); - EiC_f2_dir_abs(e1); - break; - - } -} - -static void f1_dir_abs(token_t * e1) -{ - switch (EiC_lexan()) { - case ')': - TYPEQUAL: - STORECLASS: - TYPESPEC: - retractlexan(); - ff_dir_decl(e1); - EiC_remlevel(EiC_S_LEVEL+1); - break; - case '*': - case '(': - case '[': - abs_decl(e1, token->Tok); - EiC_match(')', " )"); - break; - - default: - EiC_error("Abstract declaration error"); - } -} - -static void EiC_f2_dir_abs(token_t * e1) -{ - switch (EiC_lexan()) { - case '[': - array_decl(e1); - EiC_f2_dir_abs(e1); - break; - case '(': - ff_dir_decl(e1); - EiC_remlevel(EiC_S_LEVEL+1); - EiC_f2_dir_abs(e1); - break; - default: - retractlexan(); - } -}