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

📄 cmath2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                            (newtyp->u.p.decl_flags & FLAG_FAR) ) {
                            opnd = BasedPtrNode( typ,opnd);
                            opnd->expr_type = newtyp;
                            opnd->op.result_type = newtyp;
                            return( opnd );
                        }
                        cast_op = 1;        /* force a convert */
                    }
                } else if( FuncPtr(typ) || FuncPtr(newtyp) ) {
                    cast_op = 1;    /* force a convert */
                } else if( TypeSize(typ) != TypeSize(newtyp) ) {
                                        /* 25-apr-88*/
                    cast_op = 1;    /* force a convert */
                } else if( typ->decl_type != TYPE_POINTER ||
                        newtyp->decl_type != TYPE_POINTER ) {
                    /* 19-jan-89 */
                    cast_op = 1;    /* force a convert */
                } else if( opr == OPR_PUSHADDR &&
                           opnd->op.opr == OPR_ADDROF ) {
                    opnd->expr_type = newtyp;
                    return( opnd );
                } else if( cast_op && CompFlags.extensions_enabled ) {
                    /* 15-oct-92: We know the following: */
                    /* - it is a cast operation  */
                    /* - both types are pointers */
                    /* - extensions are enabled  */
                    /* - both pointers are the same size */
                    /* - neither pointer is a function pointer */
                    /* So, if it is still an lvalue */
                    /* - then just update the type and leave it */
                    /* - as an lvalue. This will allow the */
                    /* - following statement to get through without */
                    /* - generating an error! */
                    /*              (char *)p += 2;  */
                    if( opr == OPR_PUSHADDR || IsLValue( opnd ) ) {
                        /* don't do it for based or far16. 27-oct-92*/
                        if( !Far16Pointer(opnd->op.flags) ) {
                            opnd->expr_type = newtyp;
                            opnd->op.opr = opr;
                            opnd->op.flags |= OPFLAG_LVALUE_CAST;
                            return( opnd );
                        }
                    }
                }
            }
            if( cast_op  ||  cnv != P2P ) {
/* convert: moved 30-aug-89 */
                if( opnd->op.opr == OPR_PUSHINT ||
                    opnd->op.opr == OPR_PUSHFLOAT ) {
                    CastConstValue( opnd, newtyp->decl_type );
                    opnd->expr_type = newtyp;
                } else {
                    pointer_class     new_class;
                    pointer_class     old_class;

                    new_class = ExprTypeClass( newtyp );
                    old_class = ExprTypeClass( typ );
                    if( new_class != old_class &&
                    (new_class == PTR_FAR16  ||  old_class == PTR_FAR16 ) ) {// foriegn pointers
                        opnd = ExprNode( NULL, OPR_CONVERT_PTR, opnd );
                        opnd->op.oldptr_class = old_class;
                        opnd->op.newptr_class = new_class;
                    } else {
                        opnd = ExprNode( NULL, OPR_CONVERT, opnd );
                        opnd->op.result_type = newtyp;
                    }
                    opnd->expr_type = newtyp;
                }
            }
        } else if( opnd->op.opr == OPR_PUSHINT ||
                   opnd->op.opr == OPR_PUSHFLOAT ) {
            CastConstValue( opnd, newtyp->decl_type );
            opnd->expr_type = newtyp;
        } else if( opnd->expr_type != newtyp ) {
            opnd = ExprNode( 0, OPR_CONVERT, opnd );
            opnd->expr_type = newtyp;
            opnd->op.result_type = newtyp;
        }else{ //NIL convert
            opnd->op.flags |= flags;
        }
    }
    return( opnd );
}

TREEPTR ParmAss( TREEPTR opnd, TYPEPTR newtyp )
{
//TODO check out base ptrs
    TYPEPTR             typ;
    enum conv_types     cnv;
    DATA_TYPE           decl1;
    DATA_TYPE           decl2;

    if( opnd->op.opr == OPR_ERROR )  return( opnd );
    opnd = BaseConv( newtyp, opnd );
    newtyp = SkipTypeFluff( newtyp );
    typ = SkipTypeFluff( opnd->expr_type );
    decl1 = DataTypeOf( typ->decl_type );
    decl2 = DataTypeOf( newtyp->decl_type );
    if( decl1 > TYPE_POINTER  || decl2 > TYPE_POINTER ){
        return( opnd );
    }
    cnv = CnvTable[ decl1 ][ decl2 ];
    if( cnv == CER ) {
        return(  opnd  );
    } else if( cnv == P2P  ){
        pointer_class     new_class;
        pointer_class     old_class;

        new_class = ExprTypeClass( newtyp );
        old_class = ExprTypeClass( typ );
        if( new_class != old_class  ){
            opnd = ExprNode( NULL, OPR_CONVERT_PTR, opnd );
            opnd->op.oldptr_class = old_class;
            opnd->op.newptr_class = new_class;
        } else {
            opnd = ExprNode( NULL, OPR_CONVERT, opnd );
            opnd->op.result_type = newtyp;
        }
    }else{
        if( opnd->op.opr == OPR_PUSHINT || opnd->op.opr == OPR_PUSHFLOAT ) {
            CastConstValue( opnd, newtyp->decl_type );
        }else{
            opnd = ExprNode( NULL, OPR_CONVERT, opnd );
            opnd->op.result_type = newtyp;
        }
    }
    opnd->expr_type = newtyp;
    return( opnd );
}

TREEPTR UMinus( TREEPTR opnd )
{
//  FLOATVAL        *flt;
    DATA_TYPE        t;

    opnd = RValue( opnd );
    if( opnd->op.opr != OPR_ERROR ){
        t = DataTypeOf( TypeOf( opnd )->decl_type );
        if( t != TYPE_VOID ){
            if( t >= TYPE_POINTER ) {
                CErr1( ERR_EXPR_MUST_BE_ARITHMETIC );
                opnd = ErrorNode( opnd );
            } else {
                opnd = ExprNode( 0, OPR_NEG, opnd );
                opnd->expr_type = GetType( SubResult[t][t] );
                opnd->op.result_type = opnd->expr_type;
            }
        }
    }
#if 0
    switch( opnd->op.opr ) {
    case OPR_ERROR:
        break;
    case OPR_PUSHINT:
        switch( opnd->op.const_type ) {
        case TYPE_CHAR:
        case TYPE_UCHAR:
            opnd->op.long_value =  -(char)opnd->op.long_value;
            break;
        case TYPE_SHORT:
        case TYPE_USHORT:
            opnd->op.long_value = -(short)opnd->op.long_value;
            break;
        case TYPE_INT:
            opnd->op.long_value = -(target_int)opnd->op.long_value;
            break;
        case TYPE_UINT:
            opnd->op.long_value =
                        (target_uint)( - (target_uint)opnd->op.long_value);
            break;
        case TYPE_LONG:
        case TYPE_ULONG:
            opnd->op.long_value = - opnd->op.long_value;
            break;
        }
        break;
    case OPR_PUSHFLOAT:
        flt = opnd->op.float_value;
        if( flt->len != 0 ) {           // if still in string form
            flt->string[0] ^= '+' ^ '-';// - change '+' to '-' and vice versa
        } else {                        // else
            #ifdef _LONG_DOUBLE_
                flt->ld.exponent ^= 0x8000;     // - flip binary sign bit
            #else
                flt->ld.word[1] ^= 0x80000000;  // - flip sign
            #endif
        }
        break;
    default:
        t = DataTypeOf( TypeOf( opnd )->decl_type );
        if( t == TYPE_VOID ) break;
        if( t >= TYPE_POINTER ) {
            CErr1( ERR_EXPR_MUST_BE_ARITHMETIC );
            opnd = ErrorNode( opnd );
        } else {
            opnd = ExprNode( 0, OPR_NEG, opnd );
            opnd->expr_type = GetType( SubResult[t][t] );
            opnd->op.result_type = opnd->expr_type;
        }
        break;
    }
#endif
    return( opnd );
}


TREEPTR UComplement( TREEPTR opnd )
{
    int         t;
    TYPEPTR     typ;

    opnd = RValue( opnd );
    if( opnd->op.opr != OPR_ERROR ){
        typ = opnd->expr_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        t = DataTypeOf( typ->decl_type );
        if( t != TYPE_VOID ){
            if( t >= TYPE_FLOAT ) {
                CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
                opnd = ErrorNode( opnd );
            } else {
                opnd = ExprNode( 0, OPR_COM, opnd );
                opnd->expr_type = GetType( SubResult[t][t] );
                opnd->op.result_type = opnd->expr_type;
            }
        }
    }
#if 0
    switch( opnd->op.opr ) {
    case OPR_ERROR:
        break;
    case OPR_PUSHINT:
        switch( opnd->op.const_type ) {
        case TYPE_CHAR:
        case TYPE_UCHAR:
            opnd->op.long_value = (char) ~ opnd->op.long_value;
            break;
        case TYPE_SHORT:
        case TYPE_USHORT:
            opnd->op.long_value = (short) ~ opnd->op.long_value;
            break;
        case TYPE_INT:
            opnd->op.long_value = (target_int) ~ opnd->op.long_value;
            break;
        case TYPE_UINT:
            opnd->op.ulong_value = (target_uint) ~ opnd->op.ulong_value;
            break;
        case TYPE_LONG:
        case TYPE_ULONG:
            opnd->op.ulong_value = ~ opnd->op.ulong_value;
            break;
        }
        break;
    default:
        typ = opnd->expr_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        t = DataTypeOf( typ->decl_type );
        if( t == TYPE_VOID ) break;
        if( t >= TYPE_FLOAT ) {
            CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
            opnd = ErrorNode( opnd );
        } else {
            opnd = ExprNode( 0, OPR_COM, opnd );
            opnd->expr_type = GetType( SubResult[t][t] );
            opnd->op.result_type = opnd->expr_type;
        }
        break;
    }
#endif
    return( opnd );
}

local TYPEPTR MergedType( TYPEPTR typ1, TYPEPTR typ2 )  /* 25-jul-90 */
{
    int         flags, new_flags;
    TYPEPTR     typ;
/*
(type huge *) : (type *)                        -> (type huge *)
(type *) : (type huge *)                        -> (type huge *)
(type far *) : (type *)                 -> (type far *)
(type *) : (type far *)                 -> (type far *)
(type const *) : (type *)                       -> (type const *)
(type *) : (type const *)                       -> (type const *)
(type volatile *) : (type *)                    -> (type volatile *)
(type *) : (type volatile *)                    -> (type volatile *)
            etc.
*/
    typ = typ1;
    flags = typ1->u.p.decl_flags | typ2->u.p.decl_flags;
    new_flags = flags & (FLAG_CONST | FLAG_VOLATILE);
    if( flags & FLAG_HUGE ) {
        new_flags |= FLAG_HUGE;
    } else if( flags & FLAG_FAR ) {
        new_flags |= FLAG_FAR;
    } else if( (typ1->u.p.decl_flags & FLAG_NEAR)   /* 12-may-91 */
           &&  (typ2->u.p.decl_flags & FLAG_NEAR) ) {
        new_flags |= FLAG_NEAR;
    }
    if( typ1->u.p.decl_flags != typ2->u.p.decl_flags ) {
        typ = PtrNode( typ1->object, new_flags, typ1->u.p.segment );
    }
    return( typ );
}


TYPEPTR TernType( TREEPTR true_part, TREEPTR false_part )
/*******************************************************/
{
    TYPEPTR          typ1;
    TYPEPTR          typ2;
    type_modifiers   dtype1, dtype2;

    typ1 = true_part->expr_type;
    while( typ1->decl_type == TYPE_TYPEDEF ) typ1 = typ1->object;
    typ2 = false_part->expr_type;
    while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
/*
    (type1) : (type1)                           -> (type1)
    nb. structs, unions, and identical pointers are handled here
*/
    if( typ1 == typ2 ) return( typ1 );
    dtype1 = DataTypeOf( typ1->decl_type );
    dtype2 = DataTypeOf( typ2->decl_type );
    if( dtype1 == TYPE_POINTER && false_part->op.opr == OPR_PUSHINT ){
        if( false_part->op.long_value != 0 ) {
            CWarn1( WARN_NONPORTABLE_PTR_CONV,
                    ERR_NONPORTABLE_PTR_CONV );
        }
        return( typ1 );
    }
    if( dtype2 == TYPE_POINTER && true_part->op.opr == OPR_PUSHINT ){
        if( true_part->op.long_value != 0 ) {
            CWarn1( WARN_NONPORTABLE_PTR_CONV,
                    ERR_NONPORTABLE_PTR_CONV );
        }
        return( typ2 );
    }
/*
    (arithmetic type) : (arithmetic type)       -> (promoted arithmetic type)
*/
    if(( dtype1 <= TYPE_DOUBLE )&&( dtype2 <= TYPE_DOUBLE )) {
        return( GetType( SubResult[dtype1][dtype2] ) );
    }
    TernChk( typ1, typ2 );
    if( dtype1 == TYPE_POINTER && dtype2 == TYPE_POINTER ) {
/*
    (void *) : (anything *)                     -> (void *)
*/

        if( typ1->object->decl_type == TYPE_VOID ) {
            return( MergedType( typ1, typ2 ) );
        } else if( typ2->object->decl_type == TYPE_VOID ) {
            return( MergedType( typ2, typ1 ) );
        } else {
            return( MergedType( typ1, typ2 ) );
        }
    }
    return( typ1 );
}

⌨️ 快捷键说明

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