📄 cexpr2.c
字号:
if( sym.stg_class == SC_EXTERN && sym.level > 0 ) {
sym0_handle = Sym0Look( hash, Buffer );
if( sym0_handle != 0 ) {
sym_handle = sym0_handle;
SymGet( &sym, sym_handle );
}
}
if( sym.stg_class == SC_TYPEDEF ) {
CErr2p( ERR_CANT_USE_TYPEDEF_AS_VAR, Buffer );
return( IntLeaf( 0 ) );
}
}
NextToken();
}
/* if( SizeOfCount == 0 ) */ /* causes defined but not referenced */
/* always turning it on can cause referenced but not assigned */
/* for the case: int i; j = sizeof(i); */
/* sym.flags |= SYM_REFERENCED; 07-jun-89 */
sym.flags |= SYM_REFERENCED;
if( sym_handle == 0 ) {
if( CurToken == T_LEFT_PAREN ) {
sym.stg_class = SC_FORWARD; /* indicate forward decl */
sym_handle = SymAddL0( hash, &sym ); /* add symbol to level 0 */
sym.flags |= SYM_FUNCTION;
sym.sym_type = FuncNode( GetType( TYPE_INT ), 0, NULL );
} else {
sym.stg_class = SC_EXTERN; /* indicate extern decl */
CErr2p( ERR_UNDECLARED_SYM, sym.name );
sym_handle = SymAdd( hash, &sym ); /* add sym to current level*/
sym.sym_type = GetType( TYPE_INT );
}
}
IncSymWeight( &sym );
tree = VarLeaf( &sym, sym_handle );
SymReplace( &sym, sym_handle );
return( tree );
}
local void IncSymWeight( SYMPTR sym )
{
static int LoopWeights[] = { 1, 0x10, 0x100, 0x1000 };
if( sym->level != 0 ) {
if( ! (sym->flags & SYM_FUNCTION) ) {
if( LoopDepth > 3 ) {
sym->u.var.offset = ~0u >> 1;
} else {
sym->u.var.offset += LoopWeights[ LoopDepth ];
}
}
}
}
//-----------------------------CMATH------------------------------------
static bool IsStruct( TYPEPTR typ ){
/*********************************/
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_STRUCT ||
typ->decl_type == TYPE_UNION ) {
return( TRUE );
}
return( FALSE );
}
int IsLValue( TREEPTR tree )
{
switch( tree->op.opr ) {
case OPR_ERROR:
case OPR_ARROW:
case OPR_INDEX:
case OPR_PUSHADDR:
case OPR_POINTS:
return( 1 );
case OPR_DOT:
while( tree->op.opr == OPR_DOT ) tree = tree->left;
switch( tree->op.opr ) {
case OPR_CALL:
case OPR_QUESTION:
case OPR_COMMA:
// These are not lvalues
break;
default:
return( 1 );
break;
}
break;
}
return( 0 );
}
static bool IsCallValue( TREEPTR tree )
{
int ret;
while( tree->op.opr == OPR_DOT || tree->op.opr == OPR_INDEX ){
tree = tree->left;
}
if( tree->op.opr == OPR_CALL ) {
ret = TRUE;
}else{
ret = FALSE;
}
return( ret );
}
// This RVALUE thing is backwards -mjc
local TREEPTR TakeRValue( TREEPTR tree, int void_ok )
{
TYPEPTR typ;
char sym_flags;
type_modifiers decl_flags;
target_uint value;
SYM_ENTRY sym;
if( tree->op.opr == OPR_ERROR ) return( tree ); /* 16-mar-88*/
if( CompFlags.pre_processing ) { /* 07-feb-89 */
if( tree->op.opr == OPR_PUSHFLOAT ) {
CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
return( ErrorNode( tree ) );
}
}
typ = tree->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_VOID ) {
if( ! void_ok ) {
CErr1( ERR_EXPR_HAS_VOID_TYPE );
return( ErrorNode( tree ) );
}
} else if( typ->decl_type == TYPE_ARRAY ) {
if( tree->op.opr == OPR_PUSHSTRING ) {
if( typ->object->decl_type == TYPE_USHORT ) { /* 02-aug-91 */
typ = PtrNode( typ->object, 0, SEG_DATA );
} else {
StringArrayType = typ;
typ = StringType;
}
tree->expr_type = typ;
} else {
decl_flags = FlagOps( tree->op.flags );
if( tree->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, tree->op.sym_handle );
sym_flags = sym.flags;
sym.flags |= SYM_REFERENCED | SYM_ASSIGNED;
if( sym_flags != sym.flags ) {
SymReplace( &sym, tree->op.sym_handle );
}
}
if( IsCallValue( tree ) ){
CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
}
tree = ExprNode( NULL, OPR_ADDROF, tree );
tree->expr_type = PtrNode( typ->object, decl_flags, SEG_DATA );
}
} else if( typ->decl_type == TYPE_FUNCTION ) {
sym_flags = FLAG_NONE;
if( tree->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, tree->op.sym_handle );
decl_flags = sym.attrib;
sym_flags = sym.flags;
sym.flags |= SYM_REFERENCED | SYM_ADDR_TAKEN;
if( sym_flags != sym.flags ) {
SymReplace( &sym, tree->op.sym_handle );
}
}else if( tree->op.opr == OPR_POINTS ){
decl_flags = tree->op.result_type->u.p.decl_flags;
}
tree = ExprNode( NULL, OPR_ADDROF, tree );
tree->expr_type = PtrNode( typ, decl_flags, 0 );
} else if( TypeSize(typ) == 0 ) {
CErr1( ERR_INCOMPLETE_EXPR_TYPE );
return( ErrorNode( tree ) );
} else {
if( SizeOfCount == 0 ) { /* 05-jan-89 */
if( tree->op.flags & OPFLAG_VOLATILE){ /* 02-nov-91 */
CompFlags.useful_side_effect = 1;
}
}
if( tree->op.opr == OPR_PUSHSYM || tree->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, tree->op.sym_handle );
sym_flags = sym.flags;
sym.flags |= SYM_REFERENCED; /* 07-jun-89 */
if( CompFlags.label_dropped == 0 && SizeOfCount == 0 ) {
if( sym.level != 0 &&
sym.stg_class != SC_STATIC && /* 15-feb-88 */
sym.stg_class != SC_EXTERN ) {
if( !( sym.flags & SYM_ASSIGNED ) ) {
/* turn on flag so msg only comes out once per sym */
sym.flags |= SYM_ASSIGNED;
CWarn( WARN_SYM_NOT_ASSIGNED,
ERR_SYM_NOT_ASSIGNED,
SymName( &sym, tree->op.sym_handle ) );
}
}
}
if( sym_flags != sym.flags ) {
SymReplace( &sym, tree->op.sym_handle );
}
}
}
switch( tree->op.opr ) {
case OPR_PUSHADDR:
tree->op.opr = OPR_PUSHSYM;
break;
case OPR_QUESTION:
case OPR_COMMA:
case OPR_EQUALS:
if( IsStruct( tree->expr_type ) ){
tree->op.flags |= OPFLAG_RVALUE;
}
break;
case OPR_DOT: // sym.field
case OPR_ARROW: // ptr->field
case OPR_INDEX: // array[index]
tree->op.flags |= OPFLAG_RVALUE;
break;
case OPR_CALL: // func()
tree->op.flags |= OPFLAG_RVALUE;
if( tree->left->op.opr == OPR_FUNCNAME ) {
SymGet( &sym, tree->left->op.sym_handle );
if( sym.stg_class == SC_FORWARD && !(sym.flags & SYM_TYPE_GIVEN ) ){
sym.flags |= SYM_TYPE_GIVEN;
SymReplace( &sym, tree->left->op.sym_handle );
}
}
break;
case OPR_POINTS:
if( tree->left->op.opr == OPR_PUSHSTRING ) { // *"abc"
STRING_LITERAL *string;
string = tree->left->op.string_handle;
value = string->literal[0];
typ = tree->left->expr_type;
if( typ->object->decl_type == TYPE_USHORT ) { /* 24-jul-92 */
value = (string->literal[1] << 8) | value;
}
FreeExprTree( tree );
tree = IntLeaf( value );
} else {
tree->op.flags |= OPFLAG_RVALUE;
}
break;
}
return( tree );
}
TREEPTR VoidRValue( TREEPTR tree )
{
tree = TakeRValue( tree, 1 );
return( tree );
}
TREEPTR RValue( TREEPTR tree )
{
tree = TakeRValue( tree, 0 );
return( tree );
}
//-----------------------------COPS------------------------------------
static TREEPTR AddrOp( TREEPTR tree )
{
TYPEPTR typ;
TREEPTR leaf;
type_modifiers modifiers;
int segid;
SYM_HANDLE based_sym;
SYM_ENTRY sym;
if( tree->op.opr == OPR_ERROR ) return( tree );
typ = tree->expr_type;
if( typ->decl_type == TYPE_FIELD || typ->decl_type == TYPE_UFIELD ) {
CErr1( ERR_CANT_TAKE_ADDR_OF_BIT_FIELD );
return( ErrorNode( tree ) );
}else if( typ->decl_type == TYPE_VOID ){
CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
return( ErrorNode( tree ) );
}
if(tree->op.flags & OPFLAG_LVALUE_CAST) { /* 18-aug-95 */
if( CompFlags.extensions_enabled ){
tree->op.flags &= ~(OPFLAG_LVALUE_CAST|OPFLAG_RVALUE);
CWarn1( WARN_LVALUE_CAST, ERR_LVALUE_CAST );
}else{
CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
return( ErrorNode( tree ) );
}
}
if( (tree->op.opr == OPR_CONVERT || tree->op.opr == OPR_CONVERT_PTR)
&& CompFlags.extensions_enabled ) {
tree = LCastAdj( tree );
}
leaf = tree;
if( tree->op.opr == OPR_DOT ) {
if( tree->left->op.opr == OPR_PUSHADDR ) {
leaf = tree->left;
}
} else if( tree->op.opr == OPR_ARROW ) {
// checking for offsetof macro construct
// #define offsetof(typ,field) (size_t)&(((typ*)0)->field)
if( tree->left->op.opr == OPR_PUSHINT ) {
leaf = tree->left;
leaf->op.ulong_value += tree->right->op.ulong_value;
tree->left = NULL;
FreeExprTree( tree );
leaf->expr_type = PtrNode( typ, 0, SEG_DATA );
return( leaf );
}
}
based_sym = 0;
modifiers = FLAG_NONE;
segid = SEG_DATA;
if( leaf->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, leaf->op.sym_handle );
if( sym.stg_class == SC_REGISTER ) {
CErr1( ERR_CANT_TAKE_ADDR_OF_REGISTER );
}
if( sym.level != 0 ) {
sym.flags |= SYM_ASSIGNED;
}
sym.flags |= SYM_ADDR_TAKEN | SYM_REFERENCED;
SymReplace( &sym, leaf->op.sym_handle );
}
if( tree->op.opr == OPR_PUSHADDR ) {
SymGet( &sym, leaf->op.sym_handle );
modifiers = sym.attrib;
if( sym.stg_class == SC_AUTO ) {
segid = SEG_STACK;
CompFlags.addr_of_auto_taken = 1; /* 23-oct-91 */
if( TargetSwitches & FLOATING_SS ) { /* 05-oct-88 */
modifiers |= FLAG_FAR;
}
}
typ = PtrNode( typ, modifiers, segid );
} else if( tree->op.opr == OPR_POINTS ) {
typ = tree->op.result_type;
} else {
modifiers = FlagOps( tree->op.flags );
typ = PtrNode( typ, modifiers, SEG_DATA );
}
if( IsLValue( tree ) ) {
tree = ExprNode( NULL, OPR_ADDROF, tree );
} else {
CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
return( ErrorNode( tree ) );
}
tree->expr_type = typ;
return( tree );
}
static TREEPTR FarPtrCvt( SYMPTR sym, SYM_HANDLE sym_handle )
{
TYPEPTR typ;
TREEPTR tree;
typ = sym->sym_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
if( typ->decl_type == TYPE_POINTER ){
if( (typ->u.p.decl_flags & FLAG_FAR) ){
tree = VarLeaf( sym, sym_handle );
tree->op.opr = OPR_PUSHSYM;
}else if( typ->u.p.decl_flags & FLAG_BASED ){
tree = VarLeaf( sym, sym_handle );
tree->op.opr = OPR_PUSHSYM;
tree = BasedPtrNode( typ, tree );
}else{
tree = VarLeaf( sym, sym_handle );
tree->op.opr = OPR_PUSHSYM;
tree = ExprNode( NULL, OPR_CONVERT, tree );
tree->expr_type = typ;
tree->op.result_type = PtrNode( typ->object, FLAG_FAR, 0 );
}
}
return( tree );
}
static TREEPTR MakeFarOp( TREEPTR based_sym, TREEPTR tree )
{
TYPEPTR typ;
typ = tree->expr_type;
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
typ = PtrNode( typ->object, FLAG_FAR, 0 );
tree = ExprNode( based_sym, OPR_FARPTR, tree );
tree->expr_type = typ;
return( tree );
}
TREEPTR BasedPtrNode( TYPEPTR ptrtyp, TREEPTR tree )
{
TREEPTR based_sym;
SYM_HANDLE sym_handle;
SYMPTR sym;
int segid;
sym_handle = ptrtyp->u.p.based_sym;
segid = ptrtyp->u.p.segment;
switch( ptrtyp->u.p.based_kind ){
case BASED_VOID: //__based( void ) segment:>offset base op
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -