📄 typesets.c
字号:
/* typesets.c
*
* (C) Copyright Apr 15 1995, Edmond J. Breen.
* ALL RIGHTS RESERVED.
* This code may be copied for personal, non-profit use only.
*
* Documentation in: ../doc/tech_doc/typesets.doc
*
*/
/* Modified by Intel OpenCV team. The bug fix has been applied to EiC_castvar function
in order to prevent throwing of errors while parsing ISO C compatible input. */
#include <stdio.h>
#include <stdlib.h>
#include "MachSet.h"
#include "global.h"
#include "lexer.h"
#include "typemod.h"
#include "xalloc.h"
#include "typesets.h"
#include "symbol.h"
#include "parser.h"
#include "error.h"
static void binhint(), binhuint();
static void binhlong(), binhulong(), binhdouble(), binhconst(), binhllong();
extern void EiC_binhlval();
void (*BINFUN[]) () = {
NULL, NULL, /* t_error, t_bool, */
binhint, binhint, /* t_char, t_uchar, */
binhint, binhint, /* t_short, t_ushort */
binhint, binhint, /* t_int, t_enum, */
binhuint, /* t_uint, */
binhlong, binhulong, /* t_long, t_ulong, */
binhllong, /* t_llong */
binhdouble, binhdouble, /* t_float, t_double, */
EiC_binhlval, NULL, /* t_pointer, t_void */
NULL,NULL, /* t_struct, t_union */
NULL,EiC_binhlval, /* t_lval, t_array */
};
typedef unsigned long set_t;
#define ismem(S,m) (((long)1 << (m)) & (S))
#define I(x) ((long)1 << (x))
#define SETNUM I(t_char)+I(t_short)+I(t_int)+I(t_enum)+I(t_long)+I(t_llong)
#define SETUNUM I(t_uchar)+I(t_ushort)+I(t_uint)+I(t_ulong)
#define SETFLOAT I(t_float)+I(t_double)
typedef struct {
set_t Lset;
set_t Rset;
} LRset_t;
LRset_t modLR[] =
{
{SETNUM + SETUNUM,
SETNUM + SETUNUM,}
};
/*
* two pointers cannot be added together
*/
LRset_t addLR[] =
{
{SETNUM + SETUNUM + SETFLOAT,
SETNUM + SETUNUM + SETFLOAT},
{I(t_pointer) + I(t_array),
SETNUM + SETUNUM},
{SETNUM + SETUNUM,
I(t_pointer) + I(t_array)},
};
/*
* integrals can be subtracted from a pointer
* but not visa a versa
*/
LRset_t subLR[] =
{
{SETNUM + SETUNUM + SETFLOAT,
SETNUM + SETUNUM + SETFLOAT},
{I(t_pointer) + I(t_array),
I(t_pointer) + I(t_array) + SETNUM + SETUNUM},
};
LRset_t multLR[] =
{
{SETNUM + SETUNUM + SETFLOAT ,
SETNUM + SETUNUM + SETFLOAT }};
LRset_t divLR[] =
{
{SETNUM + SETUNUM + SETFLOAT ,
SETNUM + SETUNUM + SETFLOAT}};
LRset_t LTLR[] =
{
{I(t_pointer) + I(t_array) + SETNUM + SETUNUM + SETFLOAT ,
I(t_pointer) + I(t_array) + SETNUM + SETUNUM + SETFLOAT}};
val_t VAL;
typedef struct {
unsigned oper;
LRset_t *LRset;
unsigned N;
} Binset;
Binset BINSET[] =
{
{'+', addLR, sizeof(addLR) / sizeof(LRset_t),},
{'-', subLR, sizeof(subLR) / sizeof(LRset_t),},
{'*', multLR, sizeof(multLR) / sizeof(LRset_t),},
{'/', divLR, sizeof(divLR) / sizeof(LRset_t),},
{'%', modLR, sizeof(modLR) / sizeof(LRset_t),},
{LSHT, modLR, sizeof(modLR) / sizeof(LRset_t),},
{RSHT, modLR, sizeof(modLR) / sizeof(LRset_t),},
{BOR, modLR, sizeof(modLR) / sizeof(LRset_t),},
{XOR, modLR, sizeof(modLR) / sizeof(LRset_t),},
{AND, modLR, sizeof(modLR) / sizeof(LRset_t),},
{LT, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{LE, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{EQ, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{NE, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{GT, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{GE, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{LOR, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
{LAND, LTLR, sizeof(LTLR) / sizeof(LRset_t),},
};
void EiC_castvar(token_t * e1,
token_t * e2, int explicit)
{
/* cast e1 into e2 */
type_expr *t;
if (EiC_gettype(e2->Type) == t_func) {
token_t e3;
EiC_inittoken(&e3);
e3.Type = EiC_copytype(nextType(e2->Type));
EiC_castvar(e1, &e3, explicit);
EiC_freetype(e3.Type);
return;
}
if (EiC_gettype(e2->Type) == t_lval) {
t = e2->Type;
e2->Type = nextType(e2->Type);
EiC_castvar(e1, e2, explicit);
e2->Type = t;
return;
}
if(EiC_gettype(e2->Type) == t_void) {
e1->Type = EiC_addtype(t_void,EiC_freetype(e1->Type));
return;
}
switch (EiC_gettype(e1->Type)) {
CASE_INT:
switch (EiC_gettype(e2->Type)) {
case t_uchar:
EiC_generate(&e1->Code,int2uchar,&e1->Val,0);
break;
case t_ushort:
EiC_generate(&e1->Code,int2ushort,&e1->Val,0);
break;
case t_char: case t_short: case t_int: case t_uint:
break;
CASE_LONG: CASE_ULONG:
if(sizeof(int) != sizeof(long))
EiC_generate(&e1->Code, int2long, &e1->Val, 0);
break;
case t_llong:
if(sizeof(int) != sizeof(eic_llong))
EiC_generate(&e1->Code, int2llong, &e1->Val, 0);
break;
CASE_FLOAT:
EiC_generate(&e1->Code, int2double, &e1->Val, 0);
break;
case t_pointer:
EiC_generate(&e1->Code, int2ptr, &e1->Val, 0);
e1->Type = EiC_addtype(t_pointer,e1->Type);
if (!explicit)
EiC_warningerror("Suspicious pointer conversion");
return;
default:
EiC_error("Illegal cast operation");
}
break;
CASE_UINT:
switch (EiC_gettype(e2->Type)) {
CASE_INT: CASE_UINT:
break;
CASE_LONG: CASE_ULONG:
if(sizeof(int) != sizeof(long))
EiC_generate(&e1->Code, uint2long, &e1->Val, 0);
break;
case t_llong:
if(sizeof(int) != sizeof(eic_llong))
EiC_generate(&e1->Code, uint2llong, &e1->Val, 0);
break;
CASE_FLOAT:
EiC_generate(&e1->Code, uint2double, &e1->Val, 0);
break;
case t_pointer:
EiC_generate(&e1->Code, int2ptr, &e1->Val, 0);
e1->Type = EiC_addtype(t_pointer,e1->Type);
if (!explicit)
EiC_warningerror("Suspicious pointer conversion");
return;
default:
EiC_error("Illegal cast operation");
}
break;
CASE_LONG:
switch (EiC_gettype(e2->Type)) {
CASE_INT: CASE_UINT:
if(sizeof(int) != sizeof(long))
EiC_generate(&e1->Code, long2int, &e1->Val, 0);
break;
CASE_LONG: CASE_ULONG:
break;
CASE_FLOAT:
EiC_generate(&e1->Code, long2double, &e1->Val, 0);
break;
case t_llong:
EiC_generate(&e1->Code, long2llong, &e1->Val, 0); break;
case t_pointer:
EiC_generate(&e1->Code, int2ptr, &e1->Val, 0);
e1->Type = EiC_addtype(t_pointer,e1->Type);
if (!explicit)
EiC_warningerror("Suspicious pointer conversion");
return;
default:
EiC_error("Illegal cast operation");
}
break;
CASE_ULONG:
switch (EiC_gettype(e2->Type)) {
CASE_INT: CASE_UINT:
if(sizeof(int) != sizeof(long))
EiC_generate(&e1->Code, ulong2int, &e1->Val, 0);
break;
CASE_LONG: CASE_ULONG:
break;
CASE_FLOAT:
EiC_generate(&e1->Code, ulong2double, &e1->Val, 0);
break;
case t_llong:
EiC_generate(&e1->Code, ulong2llong, &e1->Val, 0); break;
case t_pointer:
EiC_generate(&e1->Code, int2ptr, &e1->Val, 0);
e1->Type = EiC_addtype(t_pointer,e1->Type);
if (!explicit)
EiC_warningerror("Suspicious pointer conversion");
return;
default:
EiC_error("Illegal cast operation");
}
break;
case t_llong:
switch (EiC_gettype(e2->Type)) {
CASE_INT:
CASE_UINT:
if(sizeof(int) != sizeof(eic_llong))
EiC_generate(&e1->Code, llong2int, &e1->Val, 0);
break;
CASE_LONG: CASE_ULONG:
if(sizeof(long) != sizeof(eic_llong))
EiC_generate(&e1->Code, llong2long, &e1->Val, 0);
break;
case t_llong: break;
default:
EiC_error("Illegal cast operation");
}
break;
CASE_FLOAT:
switch (EiC_gettype(e2->Type)) {
CASE_INT: CASE_UINT:
EiC_generate(&e1->Code, double2int, &e1->Val, 0);
break;
CASE_LONG: CASE_ULONG:
EiC_generate(&e1->Code, double2long, &e1->Val, 0);
break;
case t_llong:
EiC_generate(&e1->Code, double2llong, &e1->Val, 0);
break;
CASE_FLOAT:
/*
if(EiC_gettype(e1->Type) == t_double
&& EiC_gettype(e2->Type) == t_float)
EiC_generate(&e1->Code, double2float, &e1->Val, 0);
else
return;
break;
*/
return;
default:
EiC_error("Illegal cast operation");
}
break;
case t_pointer:
switch (EiC_gettype(e2->Type)) {
case t_uchar:
case t_char:
EiC_error("Illegal cast operation");
return;
case t_short:
case t_int:
case t_ushort:
case t_uint:
EiC_generate(&e1->Code, ptr2int, &e1->Val, 0);
break;
CASE_LONG:
case t_ulong:
EiC_generate(&e1->Code, ptr2long, &e1->Val, 0);
break;
CASE_FLOAT:EiC_error("Illegal cast operation");
return;
case t_pointer:
if (!EiC_sametypes(e1->Type, e2->Type)) {
if (EiC_gettype(e2->Type) != t_pointer)
EiC_error("Illegal cast operation");
else if (!explicit)
EiC_warningerror("Suspicious pointer conversion");
} else if(!explicit)
if(ConstIntegrity(nextType(e2->Type),nextType(e1->Type)))
EiC_error("Cast loses const qualifier");
if(!EiC_compareSafe(nextType(e1->Type),nextType(e2->Type)))
EiC_error("Casting between safe and unsafe address");
break;
default:
EiC_error("Illegal cast operation");
return;
}
EiC_freetype(e1->Type);
e1->Type = EiC_copytype(e2->Type);
return;
case t_array:
if (EiC_gettype(e2->Type) == t_pointer) {
EiC_exchtype(t_pointer, e1->Type);
if (!EiC_sametypes(e1->Type, e2->Type) && !explicit)
EiC_warningerror("Suspicious pointer conversion");
} else if(EiC_gettype(e2->Type) == t_array) {
if (!EiC_sametypes(e1->Type, e2->Type))
EiC_error("Illegal cast operation");
} else
EiC_error("Illegal cast operation");
return;
case t_lval:
e1->Type = EiC_succType(e1->Type);
EiC_castvar(e1, e2, explicit);
setConst(e1->Type);
return;
case t_union:
case t_struct:
if (EiC_gettype(e2->Type) == t_lval) {
if (!EiC_sametypes(e1->Type, nextType(e2->Type)))
EiC_error("Illegal cast operation");
} else if (!EiC_sametypes(e1->Type, e2->Type))
EiC_error("Illegal cast operation");
return;
default:
EiC_error("Illegal cast operation");
}
EiC_set_bastype(EiC_bastype(e2->Type), e1->Type);
}
int TREFON=0;
void EiC_castconst(token_t * e1, token_t * e2, int explicit)
{
/*
* cast e1 type into an e2 type and
* where e1 is a constant
*/
unsigned t;
if (EiC_gettype(e2->Type) == t_func) {
token_t e3;
e3.Type = EiC_copytype(nextType(e2->Type));
EiC_castconst(e1, &e3, explicit);
EiC_freetype(e3.Type);
return;
}
if (e1->Pflag) {
EiC_castvar(e1, e2, explicit);
return;
}
if(EiC_gettype(e2->Type) == t_void) {
e1->Type = EiC_addtype(t_void,EiC_freetype(e1->Type));
setConst(e1->Type);
return;
}
switch ((t = EiC_gettype(e2->Type))) {
CASE_INT: CASE_UINT:
switch (EiC_gettype(e1->Type)) {
CASE_INT: CASE_UINT: break;
CASE_LONG:e1->Val.ival = (int) e1->Val.lval; break;
CASE_ULONG:e1->Val.ival = (int) e1->Val.ulval; break;
CASE_FLOAT:e1->Val.ival = (int) e1->Val.dval; break;
case t_llong: e1->Val.ival = (int)e1->Val.llval; break;
default:
EiC_error("Illegal cast operation");
}
break;
CASE_LONG:
switch (EiC_gettype(e1->Type)) {
CASE_INT:e1->Val.lval = (long) e1->Val.ival;
break;
CASE_UINT:e1->Val.lval = (long) e1->Val.uival;
break;
CASE_LONG:return;
case t_ulong:
break;
case t_llong:e1->Val.lval = (long)e1->Val.llval;
break;
CASE_FLOAT:e1->Val.lval = (long) e1->Val.dval;
break;
default:
EiC_error("Illegal cast operation");
}
break;
case t_ulong:
switch (EiC_gettype(e1->Type)) {
CASE_INT:e1->Val.ulval = (unsigned long) e1->Val.ival;
break;
CASE_UINT:e1->Val.ulval = (unsigned long) e1->Val.uival;
break;
CASE_LONG:break;
case t_ulong:
return;
case t_llong: e1->Val.ulval = (long)e1->Val.llval; break;
CASE_FLOAT:e1->Val.ulval = (unsigned long) e1->Val.dval;
break;
default:
EiC_error("Illegal cast operation");
}
break;
case t_llong:
switch (EiC_gettype(e1->Type)) {
CASE_INT: e1->Val.llval = (eic_llong) e1->Val.ival; break;
CASE_UINT: e1->Val.llval = (eic_llong) e1->Val.uival; break;
CASE_LONG: e1->Val.llval = (eic_llong) e1->Val.lval; break;
case t_ulong:e1->Val.llval =(eic_llong) e1->Val.ulval; break;
case t_llong: break;
CASE_FLOAT:e1->Val.llval = (eic_llong)e1->Val.dval;
break;
default:
EiC_error("Illegal cast operation");
}
break;
CASE_FLOAT:
switch (EiC_gettype(e1->Type)) {
CASE_INT:e1->Val.dval = (double) e1->Val.ival;
break;
CASE_UINT:e1->Val.dval = (double) e1->Val.uival;
break;
CASE_LONG:e1->Val.dval = (double) e1->Val.lval;
break;
case t_ulong:
e1->Val.dval = (double) e1->Val.ulval;
break;
case t_llong: e1->Val.dval = (double)e1->Val.llval; break;
case t_pointer:
EiC_error("Illegal floating point operation");
break;
case t_float:
e1->Val.dval = (float)e1->Val.dval; break;
case t_double:
return;
}
break;
case t_lval:
e2->Type = EiC_succType(e2->Type);
EiC_castconst(e1, e2, explicit);
e2->Type = EiC_addtype(t, e2->Type);
return;
case t_pointer:
if (EiC_gettype(e1->Type) != t_pointer && !explicit
&& e1->Val.ival != 0 && !TREFON)
EiC_warningerror("Suspicious pointer conversion");
switch (EiC_gettype(e1->Type)) {
CASE_INT: e1->Val.p.sp = e1->Val.p.p = (void *) e1->Val.ival;
if(EiC_gettype(nextType(e2->Type)) != t_void)
e1->Val.p.ep = (void *) (e1->Val.ival + EiC_get_sizeof(nextType(e2->Type)));
else
e1->Val.p.ep = (void *) (e1->Val.ival + sizeof(void *));
break;
CASE_UINT: e1->Val.p.sp = e1->Val.p.p = (void *) e1->Val.uival;
if(EiC_gettype(nextType(e2->Type)) != t_void)
e1->Val.p.ep = (void *) (e1->Val.uival + EiC_get_sizeof(nextType(e2->Type)));
else
e1->Val.p.ep = (void *) (e1->Val.uival + sizeof(void *));
break;
CASE_LONG:
case t_ulong:
e1->Val.p.sp = e1->Val.p.p = (void *) e1->Val.ulval;
if(EiC_gettype(nextType(e2->Type)) != t_void)
e1->Val.p.ep = (void *) (e1->Val.ulval + EiC_get_sizeof(nextType(e2->Type)));
else
e1->Val.p.ep = (void *) (e1->Val.ulval + sizeof(void *));
break;
case t_pointer:
if (!EiC_sametypes(e2->Type,e1->Type))
EiC_warningerror("Suspicious pointer conversion");
e1->Type = EiC_freetype(e1->Type);
e1->Type = EiC_copytype(e2->Type);
setConst(e1->Type);
return;
default:
EiC_error("Illegal cast operation");
break;
}
EiC_exchtype(t_pointer, e1->Type);
/*if(!explicit) */
if(!issafe(e2->Type))
setUnSafe(e1->Type);
setConst(e1->Type);
return;
case t_union:
case t_struct:
if (EiC_gettype(e2->Type) == t_lval) {
if (!EiC_sametypes(e1->Type, nextType(e2->Type)))
EiC_error("Illegal cast operation");
} else if (!EiC_sametypes(e1->Type, e2->Type))
EiC_error("Illegal cast operation");
return;
default:
EiC_error("Illegal cast operation");
}
EiC_set_bastype(EiC_bastype(e2->Type), e1->Type);
}
void EiC_do_lor(token_t *e1, int n)
{
int inst;
val_t u1;
EiC_output(e1);
switch(EiC_gettype(e1->Type)) {
CASE_INT:
CASE_UINT: inst = jmpTint; break;
CASE_LONG:
CASE_ULONG: inst = jmpTlng; break;
CASE_FLOAT: inst = jmpTdbl; break;
case t_pointer: inst = jmpTptr;break;
default:
EiC_error("syntax error near '||'");
return;
}
EiC_exchtype(t_int,e1->Type);
u1.ival = n;
EiC_generate(&e1->Code, inst, &u1, 0);
}
void EiC_do_land(token_t *e1, int n)
{
int inst;
val_t u1;
EiC_output(e1);
switch(EiC_gettype(e1->Type)) {
CASE_INT:
CASE_UINT: inst = jmpFint; break;
CASE_LONG:
CASE_ULONG: inst = jmpFlng; break;
CASE_FLOAT: inst = jmpFdbl; break;
case t_pointer: inst = jmpFptr;break;
default:
EiC_error("syntax error associated near '&&'");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -