?? cdecl.c
字號:
/* 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 <stdio.h>#include <stdlib.h>#include <string.h>#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)#elsestatic 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. */}#endifstatic 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 1static 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; }#endifstatic 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;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -