?? 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)
#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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -