⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdecl.c

📁 微软的基于HMM的人脸识别原代码, 非常经典的说
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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 + -