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

📄 cmath2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        result_type = TYPE_VOID;
    } else if( op1_type == TYPE_UNION  ||
               op1_type == TYPE_STRUCT ||
               op2_type == TYPE_UNION  ||
               op2_type == TYPE_STRUCT ) {
        result_type = ERR;
    } else {
        result_type = BinResult[ op1_type ][ op2_type ];
        if( opr == T_PERCENT  &&  result_type >= TYPE_FLOAT ) {
            CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
        }
        if( result_type < INT ) result_type = INT;
    }
    if( result_type == ERR ) {
        CErr1( ERR_EXPR_MUST_BE_ARITHMETIC );
        result_type = INT;
    }
    switch( opr ) {
    case T_XOR_EQUAL:
    case T_OR_EQUAL:
        /* if op2 is a constant, check to see if constant truncated */
        if( op2->op.opr == OPR_PUSHINT ) {
            unsigned long       max_value;

            switch( TypeSize( typ ) ) {
            case 1:
                max_value = 0x000000FF;
                break;
            case 2:
                max_value = 0x0000FFFF;
                break;
            default:
                max_value = ~0ul;
                break;
            }
            if( op2->op.ulong_value > max_value ) {
                CWarn1( WARN_CONSTANT_TOO_BIG, ERR_CONSTANT_TOO_BIG );
            }
        }
    case T_AND_EQUAL:
    case T_RSHIFT_EQUAL:
    case T_LSHIFT_EQUAL:
    case T_PERCENT_EQUAL:
        /* check for integral operand.          16-nov-89 */
        result_type = IntResult[ op1_type ][ op2_type ];
        if( result_type == ERR ) {
            CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
        }
    case T_TIMES_EQUAL:
    case T_DIVIDE_EQUAL:
        result_type = op1_type;
        break;
    default:
        op1 = Convert( op1, op1_type, result_type );
        op2 = Convert( op2, op2_type, result_type );
        typ = GetType( result_type );
    }
    tree = ExprNode( op1, TokenToOperator( opr ), op2 );
    if( result_type == ERR ) {
        tree = ErrorNode( tree );
    } else {
        tree->expr_type = GetType( result_type );
        tree->op.result_type = typ;
    }
    return( tree );
}



local int LValue( TREEPTR op1 )
{
    TYPEPTR     typ;

    if( op1->op.opr == OPR_ERROR )  return( 1 );
    if( IsLValue( op1 ) ) {
        typ = TypeOf( op1 );
        if( typ->decl_type != TYPE_ARRAY ) {
            if( TypeSize(typ) == 0 ) {
                CErr1( ERR_INCOMPLETE_EXPR_TYPE );
            }
            if( op1->op.flags & OPFLAG_LVALUE_CAST ) {
                op1->op.flags &= ~(OPFLAG_LVALUE_CAST|OPFLAG_RVALUE);
                CWarn1( WARN_LVALUE_CAST, ERR_LVALUE_CAST );
            }
            return( 1 );
        }
    }
    CErr1( ERR_MUST_BE_LVALUE );
    return( 0 );
}

local void SetSymAssigned( TREEPTR opnd )
{
    auto SYM_ENTRY sym;

    while( opnd->op.opr == OPR_INDEX ) opnd = opnd->left;
    if( opnd->op.opr == OPR_PUSHADDR ) {
        SymGet( &sym, opnd->op.sym_handle );
        if( sym.level != 0 ) {
            if( !(sym.flags & SYM_ASSIGNED) ) {
                sym.flags |= SYM_ASSIGNED;
                SymReplace( &sym, opnd->op.sym_handle );
            }
        }
    }
}

TREEPTR InitAsgn( TYPEPTR typ,  TREEPTR op2 )
{
    if( op2->op.opr == OPR_ERROR ) {
        return( op2 );
    }
    op2 = RValue( op2 );
    if( !CompFlags.no_check_inits ){ // else fuck em
        ParmAsgnCheck( typ, op2, 0 );
    }
    return( op2 );
}


TREEPTR AsgnOp( TREEPTR op1, TOKEN opr, TREEPTR op2 )
{
    TYPEPTR         typ;
    pointer_class   op1_class;
    pointer_class   op2_class;
    int             isLValue;

    if( op1->op.opr == OPR_ERROR ) {
        FreeExprTree( op2 );
        return( op1 );
    }
    if( op2->op.opr == OPR_ERROR ) {
        FreeExprTree( op1 );
        return( op2 );
    }
    if(op1->op.flags & OPFLAG_LVALUE_CAST) {       /* 18-aug-95 */
        if( CompFlags.extensions_enabled ){
            op1->op.flags &= ~(OPFLAG_LVALUE_CAST|OPFLAG_RVALUE);
            if( op1->op.opr == OPR_PUSHSYM ){
                op1->op.opr = OPR_PUSHADDR;
            }
            CWarn1( WARN_LVALUE_CAST, ERR_LVALUE_CAST );
        }else{
            CErr1( ERR_CANT_TAKE_ADDR_OF_RVALUE );
        }
    }
    if( (op1->op.opr == OPR_CONVERT || op1->op.opr == OPR_CONVERT_PTR)
     && CompFlags.extensions_enabled ) {
        op1 = LCastAdj( op1 );
    }
    isLValue = LValue( op1 );
    if( isLValue ) {
        op_flags volatile_flag;

        volatile_flag = op1->op.flags & OPFLAG_VOLATILE;
        if( opr != T_EQUAL      &&  opr != T_ASSIGN_LAST ) {
            if( opr == T_PLUS_EQUAL  ||  opr == T_MINUS_EQUAL ) {
                op1 = AddOp( op1, opr, op2 );
            } else {
                op1 = BinOp( op1, opr, op2 );
            }
            op1->op.flags |= volatile_flag;
            return( op1 );
        }
        SetSymAssigned( op1 );
        typ = TypeOf( op1 );
        op2 = RValue( op2 );
        op2 = BaseConv( typ, op2 );
        ParmAsgnCheck( typ, op2, 0 );
        if( opr == T_ASSIGN_LAST ) opr = T_EQUAL;
        op1_class = ExprTypeClass( typ );
        op2_class = ExprTypeClass( op2->expr_type );
        if( op1_class != op2_class ) {
            if( op1_class == PTR_FAR16 || op2_class == PTR_FAR16 ) {  // if far16 pointer
                op2 = ExprNode( NULL, OPR_CONVERT_PTR, op2 );
                op2->op.oldptr_class = op2_class;
                op2->op.newptr_class = op1_class;
            } else {
                 op2 = ExprNode( NULL, OPR_CONVERT, op2 );
                 op2->op.result_type = typ;
            }
            op2->expr_type = typ;
        }
        op1 = ExprNode( op1, TokenToOperator( opr ), op2 );
        op1->op.flags |= volatile_flag;
        op1->expr_type = typ;
        op1->op.result_type = typ;
    } else {
        FreeExprTree( op2 );
    }
    return( op1 );
}


void ChkConst( TREEPTR opnd )
{
    if( opnd->op.opr != OPR_ERROR ) {
        if( opnd->op.flags & OPFLAG_CONST ) {
            CErr1( ERR_CANNOT_MODIFY_CONST );
        }
    }
}


TREEPTR IntOp( TREEPTR op1, TOKEN opr, TREEPTR op2 )
{
    type_modifiers  op1_type, op2_type, result_type;

    if( op1->op.opr == OPR_ERROR ) {
        FreeExprTree( op2 );
        return( op1 );
    }
    if( op2->op.opr == OPR_ERROR ) {
        FreeExprTree( op1 );
        return( op2 );
    }
    op1 = RValue( op1 );
    op2 = RValue( op2 );
    op1_type = DataTypeOf( TypeOf( op1 )->decl_type );
    op2_type = DataTypeOf( TypeOf( op2 )->decl_type );
    if( op1_type == TYPE_VOID  ||  op2_type == TYPE_VOID ) {
        result_type = TYPE_VOID;
    } else if( op1_type == TYPE_UNION  ||  op2_type == TYPE_UNION ) {
        result_type = ERR;
    } else {
        result_type = IntResult[ op1_type ][ op2_type ];
    }
    if( result_type == ERR ) {
        CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
        result_type = INT;
    }
    op1 = Convert( op1, op1_type, result_type );
    op2 = Convert( op2, op2_type, result_type );
    op1 = ExprNode( op1, TokenToOperator( opr ), op2 );
    if( result_type == ERR ) {
        op1 = ErrorNode( op1 );
    } else {
        op1->expr_type = GetType( result_type );
        op1->op.result_type = op1->expr_type;
    }
    return( op1 );
}


TREEPTR ShiftOp( TREEPTR op1, TOKEN opr, TREEPTR op2 )
{
    DATA_TYPE   op1_type, op2_type, result_type;

    if( op1->op.opr == OPR_ERROR ) {
        FreeExprTree( op2 );
        return( op1 );
    }
    if( op2->op.opr == OPR_ERROR ) {
        FreeExprTree( op1 );
        return( op2 );
    }
    op1 = RValue( op1 );
    op2 = RValue( op2 );
    op1_type = DataTypeOf( TypeOf( op1 )->decl_type );
    op2_type = DataTypeOf( TypeOf( op2 )->decl_type );
    if( op1_type == TYPE_VOID  ||  op2_type == TYPE_VOID ) {
        result_type = TYPE_VOID;
    } else {
        if( op1_type <= TYPE_STRUCT ) {
            result_type = ShiftResult[ op1_type ];
        } else {
            result_type = ERR;
        }
        if( result_type == ERR || op2_type > UL8 ) {
            CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
            result_type = INT;
        }
    }
    op1 = Convert( op1, op1_type, result_type );
    op1 = ExprNode( op1, TokenToOperator( opr ), op2 );
    if( result_type == ERR ) {
        op1 = ErrorNode( op1 );
    } else {
        op1->expr_type = GetType( result_type );
        op1->op.result_type = op1->expr_type;
    }
    return( op1 );
}


int FuncPtr( TYPEPTR typ )
{
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type != TYPE_POINTER ) return( 0 );
    typ = typ->object;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type != TYPE_FUNCTION ) return( 0 );
    return( 1 );
}


#define NEAR_FAR_HUGE   (FLAG_NEAR|FLAG_FAR|FLAG_HUGE|FLAG_FAR16)

TREEPTR CnvOp( TREEPTR opnd, TYPEPTR newtyp, int cast_op )
{
    TYPEPTR             typ;
    enum  conv_types    cnv;
    enum ops            opr;
    op_flags            flags;
    type_modifiers      opnd_type;

    if( opnd->op.opr == OPR_ERROR )  return( opnd );
    while( newtyp->decl_type == TYPE_TYPEDEF ) newtyp = newtyp->object;
    opr = opnd->op.opr;
    if( newtyp->decl_type == TYPE_VOID ) {              /* 26-oct-88 */
        typ = TypeOf( opnd );
        if( typ->decl_type == TYPE_VOID )  return( opnd );
    }
    flags = OPFLAG_NONE;
    if( cast_op && CompFlags.extensions_enabled ) {
        if( IsLValue( opnd ) ) {
            flags |= OPFLAG_LVALUE_CAST;
        }
    }
    opnd_type = opnd->expr_type->decl_type;
    if( ! CompFlags.pre_processing )  opnd = RValue( opnd );
    typ = TypeOf( opnd );
    if( newtyp->decl_type > TYPE_POINTER ) {
        if( newtyp->decl_type == TYPE_VOID ) {
            opnd = ExprNode( 0, OPR_CONVERT, opnd );
            opnd->expr_type = newtyp;
            opnd->op.result_type = newtyp;
            if( cast_op )  CompFlags.meaningless_stmt = 0;      /* 21-jul-89 */
        } else if( newtyp->decl_type == TYPE_ENUM ) {
            if( typ->decl_type == TYPE_POINTER ) {
                CWarn1( WARN_POINTER_TYPE_MISMATCH,
                        ERR_POINTER_TYPE_MISMATCH );
            }
            newtyp = newtyp->object;            /* 02-feb-93 */
            goto convert;
        } else {
            if( cast_op ) {
                CErr1( ERR_MUST_BE_SCALAR_TYPE );
                return( ErrorNode( opnd ) );
            } else if( typ != newtyp ) {        /* 16-aug-91, added cond */
                CErr1( ERR_TYPE_MISMATCH );
                return( ErrorNode( opnd ) );
            }
        }
    } else if( typ->decl_type != TYPE_VOID ) {
convert:                                /* moved here 30-aug-89 */
        cnv = CnvTable[ DataTypeOf( typ->decl_type ) ]
                      [ DataTypeOf( newtyp->decl_type ) ];
        if( cnv == CER ) {
            CErr1( ERR_INVALID_CONVERSION );
            return( ErrorNode( opnd ) );
        } else if( cnv != NIL ) {
            if( cnv == P2P ) {
                if( ( typ->u.p.decl_flags & NEAR_FAR_HUGE )
                    != ( newtyp->u.p.decl_flags & NEAR_FAR_HUGE )
                    || ( opnd_type == TYPE_ARRAY ) ) {
                    if( cast_op == 0 ) {
                        if( TypeSize(typ) > TypeSize(newtyp) ) {
                            CWarn1( WARN_POINTER_TRUNCATION,
                                    ERR_POINTER_TRUNCATION );
                        }
                        if( (typ->u.p.decl_flags & FLAG_BASED) &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -