public EXPRCONSTANT CreateConstant(CType pType, CONSTVAL constVal, EXPR pOriginal)
        {
            EXPRCONSTANT rval = CreateConstant(pType);

            rval.setVal(constVal);
            Debug.Assert(rval != null);
            return(rval);
        }
        public EXPRCONSTANT CreateConstant(CType pType)
        {
            EXPRCONSTANT rval = new EXPRCONSTANT();

            rval.kind  = ExpressionKind.EK_CONSTANT;
            rval.type  = pType;
            rval.flags = 0;
            return(rval);
        }
 protected override EXPR VisitCONSTANT(EXPRCONSTANT expr)
 {
     Debug.Assert(expr != null);
     Debug.Assert(alwaysRewrite || currentAnonMeth != null);
     return GenerateConstant(expr);
 }
        private EXPR CreateZeroInit(EXPRTYPEORNAMESPACE pTypeExpr, EXPR pOptionalOriginalConstructorCall, bool isConstructor)
        {
            Debug.Assert(pTypeExpr != null);
            CType pType    = pTypeExpr.TypeOrNamespace.AsType();
            bool  bIsError = false;

            if (pType.isEnumType())
            {
                // For enum types, we create a constant that has the default value
                // as an object pointer.
                ConstValFactory factory = new ConstValFactory();
                EXPRCONSTANT    expr    = CreateConstant(pType, factory.Create(Activator.CreateInstance(pType.AssociatedSystemType)));
                return(expr);
            }

            switch (pType.fundType())
            {
            default:
                bIsError = true;
                break;

            case FUNDTYPE.FT_PTR:
            {
                CType nullType = GetTypes().GetNullType();

                // UNDONE:  I think this if is always false ...
                if (nullType.fundType() == pType.fundType())
                {
                    // Create a constant here.

                    EXPRCONSTANT expr = CreateConstant(pType, ConstValFactory.GetDefaultValue(ConstValKind.IntPtr));
                    return(expr);
                }

                // Just allocate a new node and fill it in.

                EXPRCAST cast = CreateCast(0, pTypeExpr, CreateNull());         // UNDONE:  should pTree be passed in here?
                return(cast);
            }

            case FUNDTYPE.FT_REF:
            case FUNDTYPE.FT_I1:
            case FUNDTYPE.FT_U1:
            case FUNDTYPE.FT_I2:
            case FUNDTYPE.FT_U2:
            case FUNDTYPE.FT_I4:
            case FUNDTYPE.FT_U4:
            case FUNDTYPE.FT_I8:
            case FUNDTYPE.FT_U8:
            case FUNDTYPE.FT_R4:
            case FUNDTYPE.FT_R8:
            {
                EXPRCONSTANT expr           = CreateConstant(pType, ConstValFactory.GetDefaultValue(pType.constValKind()));
                EXPRCONSTANT exprInOriginal = CreateConstant(pType, ConstValFactory.GetDefaultValue(pType.constValKind()));
                exprInOriginal.SetOptionalConstructorCall(pOptionalOriginalConstructorCall);
                return(expr);
                // UNDONE: Check other bogus casts
            }

            case FUNDTYPE.FT_STRUCT:
                if (pType.isPredefType(PredefinedType.PT_DECIMAL))
                {
                    EXPRCONSTANT expr         = CreateConstant(pType, ConstValFactory.GetDefaultValue(pType.constValKind()));
                    EXPRCONSTANT exprOriginal = CreateConstant(pType, ConstValFactory.GetDefaultValue(pType.constValKind()));
                    exprOriginal.SetOptionalConstructorCall(pOptionalOriginalConstructorCall);
                    return(expr);
                }
                break;

            case FUNDTYPE.FT_VAR:
                break;
            }

            EXPRZEROINIT rval = new EXPRZEROINIT();

            rval.kind  = ExpressionKind.EK_ZEROINIT;
            rval.type  = pType;
            rval.flags = 0;
            rval.OptionalConstructorCall = pOptionalOriginalConstructorCall;
            rval.IsConstructor           = isConstructor;

            if (bIsError)
            {
                rval.SetError();
            }

            Debug.Assert(rval != null);
            return(rval);
        }
Example #5
0
 ////////////////////////////////////////////////////////////////////////////////
 // Check to see if an integral constant is within range of a integral 
 // destination type.
 public static bool isConstantInRange(EXPRCONSTANT exprSrc, CType typeDest)
 {
     return isConstantInRange(exprSrc, typeDest, false);
 }
Example #6
0
        public static bool isConstantInRange(EXPRCONSTANT exprSrc, CType typeDest, bool realsOk)
        {
            FUNDTYPE ftSrc = exprSrc.type.fundType();
            FUNDTYPE ftDest = typeDest.fundType();

            if (ftSrc > FUNDTYPE.FT_LASTINTEGRAL || ftDest > FUNDTYPE.FT_LASTINTEGRAL)
            {
                if (!realsOk)
                {
                    return false;
                }
                else if (ftSrc > FUNDTYPE.FT_LASTNUMERIC || ftDest > FUNDTYPE.FT_LASTNUMERIC)
                {
                    return false;
                }
            }

            // if converting to a float type, this always succeeds...
            if (ftDest > FUNDTYPE.FT_LASTINTEGRAL)
            {
                return true;
            }

            // if converting from float to an integral type, we need to check whether it fits
            if (ftSrc > FUNDTYPE.FT_LASTINTEGRAL)
            {
                double dvalue = (exprSrc.asCONSTANT().getVal().doubleVal);

                switch (ftDest)
                {
                    case FUNDTYPE.FT_I1:
                        if (dvalue > -0x81 && dvalue < 0x80)
                            return true;
                        break;
                    case FUNDTYPE.FT_I2:
                        if (dvalue > -0x8001 && dvalue < 0x8000)
                            return true;
                        break;
                    case FUNDTYPE.FT_I4:
                        if (dvalue > I64(-0x80000001) && dvalue < I64(0x80000000))
                            return true;
                        break;
                    case FUNDTYPE.FT_I8:
                        // 0x7FFFFFFFFFFFFFFFFFFF is rounded to 0x800000000000000000000 in 64 bit double precision
                        // floating point representation. The conversion back to ulong is not possible.
                        if (dvalue >= -9223372036854775808.0 && dvalue < 9223372036854775808.0)
                        {
                            return true;
                        }
                        break;
                    case FUNDTYPE.FT_U1:
                        if (dvalue > -1 && dvalue < 0x100)
                            return true;
                        break;
                    case FUNDTYPE.FT_U2:
                        if (dvalue > -1 && dvalue < 0x10000)
                            return true;
                        break;
                    case FUNDTYPE.FT_U4:
                        if (dvalue > -1 && dvalue < I64(0x100000000))
                            return true;
                        break;
                    case FUNDTYPE.FT_U8:
                        // 0xFFFFFFFFFFFFFFFFFFFF is rounded to 0x100000000000000000000 in 64 bit double precision
                        // floating point representation. The conversion back to ulong is not possible.
                        if (dvalue > -1.0 && dvalue < 18446744073709551616.0)
                        {
                            return true;
                        }
                        break;
                    default:
                        break;
                }
                return false;
            }

            // U8 src is unsigned, so deal with values > MAX_LONG here.
            if (ftSrc == FUNDTYPE.FT_U8)
            {
                ulong value = exprSrc.asCONSTANT().getU64Value();

                switch (ftDest)
                {
                    case FUNDTYPE.FT_I1:
                        if (value <= (ulong)SByte.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_I2:
                        if (value <= (ulong)Int16.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_I4:
                        if (value <= Int32.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_I8:
                        if (value <= Int64.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_U1:
                        if (value <= Byte.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_U2:
                        if (value <= UInt16.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_U4:
                        if (value <= UInt32.MaxValue)
                            return true;
                        break;
                    case FUNDTYPE.FT_U8:
                        return true;
                    default:
                        break;
                }
            }
            else
            {
                long value = exprSrc.asCONSTANT().getI64Value();

                switch (ftDest)
                {
                    case FUNDTYPE.FT_I1:
                        if (value >= -128 && value <= 127)
                            return true;
                        break;
                    case FUNDTYPE.FT_I2:
                        if (value >= -0x8000 && value <= 0x7fff)
                            return true;
                        break;
                    case FUNDTYPE.FT_I4:
                        if (value >= I64(-0x80000000) && value <= I64(0x7fffffff))
                            return true;
                        break;
                    case FUNDTYPE.FT_I8:
                        return true;
                    case FUNDTYPE.FT_U1:
                        if (value >= 0 && value <= 0xff)
                            return true;
                        break;
                    case FUNDTYPE.FT_U2:
                        if (value >= 0 && value <= 0xffff)
                            return true;
                        break;
                    case FUNDTYPE.FT_U4:
                        if (value >= 0 && value <= I64(0xffffffff))
                            return true;
                        break;
                    case FUNDTYPE.FT_U8:
                        if (value >= 0)
                            return true;
                        break;
                    default:
                        break;
                }
            }
            return false;
        }
Example #7
0
        private EXPR FoldConstI8Op(ExpressionKind kind, EXPR op1, EXPRCONSTANT opConst1, EXPR op2, EXPRCONSTANT opConst2, PredefinedType ptOp)
        {
            Debug.Assert(ptOp == PredefinedType.PT_LONG || ptOp == PredefinedType.PT_ULONG);
            Debug.Assert(opConst1.isCONSTANT_OK());
            Debug.Assert(op1.type.isPredefType(ptOp) && op1.type == opConst1.type);
            Debug.Assert(op2 == null && opConst2 == null ||
                   op2 != null && opConst2 != null && opConst2.isCONSTANT_OK() && op1.type == op2.type && op1.type == opConst2.type);

            bool fSigned = (ptOp == PredefinedType.PT_LONG);
            bool fRes = false;
            // Allocate the result node.
            CType typeDest;
            CONSTVAL cv = new CONSTVAL();


            if (fSigned)
            {
                // long.
                long u1 = opConst1.asCONSTANT().getVal().longVal;
                long u2 = opConst2 != null ? opConst2.asCONSTANT().getVal().longVal : 0;
                long uRes = 0;
                switch (kind)
                {
                    case ExpressionKind.EK_ADD:
                        uRes = u1 + u2;
                        break;

                    case ExpressionKind.EK_SUB:
                        uRes = u1 - u2;
                        break;

                    case ExpressionKind.EK_MUL:
                        uRes = u1 * u2;
                        break;

                    case ExpressionKind.EK_DIV:
                        Debug.Assert(u2 != 0); // Caller should have handled this.
                        uRes = u1 / u2;
                        break;

                    case ExpressionKind.EK_MOD:
                        Debug.Assert(u2 != 0); // Caller should have handled this.
                        uRes = u1 % u2;
                        break;

                    case ExpressionKind.EK_NEG:
                        uRes = -u1;
                        break;

                    case ExpressionKind.EK_UPLUS:
                        uRes = u1;
                        break;
                    case ExpressionKind.EK_BITAND:
                        uRes = u1 & u2;
                        break;
                    case ExpressionKind.EK_BITOR:
                        uRes = u1 | u2;
                        break;
                    case ExpressionKind.EK_BITXOR:
                        uRes = u1 ^ u2;
                        break;
                    case ExpressionKind.EK_BITNOT:
                        uRes = ~u1;
                        break;
                    case ExpressionKind.EK_EQ:
                        fRes = (u1 == u2);
                        break;
                    case ExpressionKind.EK_NE:
                        fRes = (u1 != u2);
                        break;
                    case ExpressionKind.EK_LE:
                        fRes = u1 <= u2;
                        break;
                    case ExpressionKind.EK_LT:
                        fRes = u1 < u2;
                        break;
                    case ExpressionKind.EK_GE:
                        fRes = u1 >= u2;
                        break;
                    case ExpressionKind.EK_GT:
                        fRes = u1 > u2;
                        break;
                    default:
                        VSFAIL("Unknown op");
                        uRes = 0;
                        break;
                }

                if (kind.isRelational())
                {
                    cv.iVal = fRes ? 1 : 0;
                    typeDest = GetReqPDT(PredefinedType.PT_BOOL);
                }
                else
                {
                    cv = GetExprConstants().Create(uRes);
                    typeDest = GetOptPDT(ptOp);
                    Debug.Assert(typeDest != null);
                }
            }
            else
            {
                // ulong.
                // Get the operands
                ulong u1 = opConst1.asCONSTANT().getVal().ulongVal;
                ulong u2 = opConst2 != null ? opConst2.asCONSTANT().getVal().ulongVal : 0;
                ulong uRes = 0;

                // Do the operation.
                switch (kind)
                {
                    case ExpressionKind.EK_ADD:
                        uRes = u1 + u2;
                        break;

                    case ExpressionKind.EK_SUB:
                        uRes = u1 - u2;
                        break;

                    case ExpressionKind.EK_MUL:
                        uRes = u1 * u2;
                        break;

                    case ExpressionKind.EK_DIV:
                        Debug.Assert(u2 != 0); // Caller should have handled this.
                        uRes = u1 / u2;
                        break;

                    case ExpressionKind.EK_MOD:
                        Debug.Assert(u2 != 0); // Caller should have handled this.
                        uRes = u1 % u2;
                        break;

                    case ExpressionKind.EK_NEG:
                        // You can't do this!
                        return BadOperatorTypesError(kind, op1, op2);

                    case ExpressionKind.EK_UPLUS:
                        uRes = u1;
                        break;
                    case ExpressionKind.EK_BITAND:
                        uRes = u1 & u2;
                        break;
                    case ExpressionKind.EK_BITOR:
                        uRes = u1 | u2;
                        break;
                    case ExpressionKind.EK_BITXOR:
                        uRes = u1 ^ u2;
                        break;
                    case ExpressionKind.EK_BITNOT:
                        uRes = ~u1;
                        break;
                    case ExpressionKind.EK_EQ:
                        fRes = (u1 == u2);
                        break;
                    case ExpressionKind.EK_NE:
                        fRes = (u1 != u2);
                        break;
                    case ExpressionKind.EK_LE:
                        fRes = u1 <= u2;
                        break;
                    case ExpressionKind.EK_LT:
                        fRes = u1 < u2;
                        break;
                    case ExpressionKind.EK_GE:
                        fRes = u1 >= u2;
                        break;
                    case ExpressionKind.EK_GT:
                        fRes = u1 > u2;
                        break;
                    default:
                        VSFAIL("Unknown op");
                        uRes = 0;
                        break;
                }

                if (kind.isRelational())
                {
                    cv.iVal = fRes ? 1 : 0;
                    typeDest = GetReqPDT(PredefinedType.PT_BOOL);
                }
                else
                {
                    cv = GetExprConstants().Create(uRes);
                    typeDest = GetOptPDT(ptOp);
                    Debug.Assert(typeDest != null);
                }
            }


            // Allocate the result node.
            EXPR exprRes = GetExprFactory().CreateConstant(typeDest, cv);

            return exprRes;
        }
Example #8
0
        private EXPR FoldConstI4Op(ExpressionKind kind, EXPR op1, EXPRCONSTANT opConst1, EXPR op2, EXPRCONSTANT opConst2, PredefinedType ptOp)
        {
            Debug.Assert(ptOp == PredefinedType.PT_INT || ptOp == PredefinedType.PT_UINT);
            Debug.Assert(opConst1.isCONSTANT_OK());
            Debug.Assert(op1.type.isPredefType(ptOp) && op1.type == opConst1.type);
            Debug.Assert(op2 == null && opConst2 == null ||
                   op2 != null && opConst2 != null && opConst2.isCONSTANT_OK() && op1.type == op2.type && op1.type == opConst2.type);

            bool fSigned = (ptOp == PredefinedType.PT_INT);

            // Get the operands
            uint u1 = opConst1.asCONSTANT().getVal().uiVal;
            uint u2 = opConst2 != null ? opConst2.asCONSTANT().getVal().uiVal : 0;
            uint uRes;

            // The code below doesn't work if uint isn't 4 bytes!
            Debug.Assert(sizeof(uint) == 4);

            // The sign bit.
            uint uSign = 0x80000000;

            // Do the operation.
            switch (kind)
            {
                case ExpressionKind.EK_ADD:
                    uRes = u1 + u2;
                    // For signed, we want either sign(u1) != sign(u2) or sign(u1) == sign(uRes).
                    // For unsigned, the result should be at least as big as either operand (if it's bigger than
                    // one, it will be bigger than the other as well).
                    if (fSigned)
                    {
                        EnsureChecked(0 != (((u1 ^ u2) | (u1 ^ uRes ^ uSign)) & uSign));
                    }
                    else
                    {
                        EnsureChecked(uRes >= u1);
                    }
                    break;

                case ExpressionKind.EK_SUB:
                    uRes = u1 - u2;
                    // For signed, we want either sign(u1) == sign(u2) or sign(u1) == sign(uRes).
                    // For unsigned, the result should be no bigger than the first operand.
                    if (fSigned)
                    {
                        EnsureChecked(0 != (((u1 ^ u2 ^ uSign) | (u1 ^ uRes ^ uSign)) & uSign));
                    }
                    else
                    {
                        EnsureChecked(uRes <= u1);
                    }
                    break;

                case ExpressionKind.EK_MUL:
                    // Multiply mod 2^32 doesn't depend on signed vs unsigned.
                    uRes = u1 * u2;
                    // Note that divide depends on signed-ness.
                    // For signed, the first check detects 0x80000000 / 0xFFFFFFFF == 0x80000000.
                    // This test needs to come first to avoid an integer overflow exception - yes we get this
                    // in native code.
                    if (u1 == 0 || u2 == 0)
                    {
                        break;
                    }

                    if (fSigned)
                    {
                        EnsureChecked((u2 != uRes || u1 == 1) && (int)uRes / (int)u1 == (int)u2);
                    }
                    else
                    {
                        EnsureChecked(uRes / u1 == u2);
                    }
                    break;

                case ExpressionKind.EK_DIV:
                    Debug.Assert(u2 != 0); // Caller should have handled this.
                    if (!fSigned)
                    {
                        uRes = u1 / u2;
                    }
                    else if (u2 != 0)
                    {
                        uRes = (uint)((int)u1 / (int)u2);
                    }
                    else
                    {
                        uRes = (uint)-(int)u1;
                        EnsureChecked(u1 != uSign);
                    }
                    break;

                case ExpressionKind.EK_MOD:
                    Debug.Assert(u2 != 0); // Caller should have handled this.
                    if (!fSigned)
                    {
                        uRes = u1 % u2;
                    }
                    else if (u2 != 0)
                    {
                        uRes = (uint)((int)u1 % (int)u2);
                    }
                    else
                    {
                        uRes = 0;
                    }
                    break;

                case ExpressionKind.EK_NEG:
                    if (!fSigned)
                    {
                        // Special case: a unary minus promotes a uint to a long
                        CONSTVAL cv = GetExprConstants().Create(-(long)u1);
                        EXPRCONSTANT foldedConst = GetExprFactory().CreateConstant(GetReqPDT(PredefinedType.PT_LONG), cv);

                        return foldedConst;
                    }

                    uRes = (uint)-(int)u1;
                    EnsureChecked(u1 != uSign);
                    break;

                case ExpressionKind.EK_UPLUS:
                    uRes = u1;
                    break;
                case ExpressionKind.EK_BITAND:
                    uRes = u1 & u2;
                    break;
                case ExpressionKind.EK_BITOR:
                    uRes = u1 | u2;
                    break;
                case ExpressionKind.EK_BITXOR:
                    uRes = u1 ^ u2;
                    break;
                case ExpressionKind.EK_BITNOT:
                    uRes = ~u1;
                    break;
                case ExpressionKind.EK_EQ:
                    uRes = (uint)((u1 == u2) ? 1 : 0);
                    break;
                case ExpressionKind.EK_NE:
                    uRes = (uint)((u1 != u2) ? 1 : 0);
                    break;
                case ExpressionKind.EK_LE:
                    uRes = (uint)((fSigned ? (int)u1 <= (int)u2 : u1 <= u2) ? 1 : 0);
                    break;
                case ExpressionKind.EK_LT:
                    uRes = (uint)((fSigned ? (int)u1 < (int)u2 : u1 < u2) ? 1 : 0);
                    break;
                case ExpressionKind.EK_GE:
                    uRes = (uint)((fSigned ? (int)u1 >= (int)u2 : u1 >= u2) ? 1 : 0);
                    break;
                case ExpressionKind.EK_GT:
                    uRes = (uint)((fSigned ? (int)u1 > (int)u2 : u1 > u2) ? 1 : 0);
                    break;
                default:
                    VSFAIL("Unknown op");
                    uRes = 0;
                    break;
            }

            CType typeDest = GetOptPDT(kind.isRelational() ? PredefinedType.PT_BOOL : ptOp);
            Debug.Assert(typeDest != null);

            // Allocate the result node.
            EXPR exprRes = GetExprFactory().CreateConstant(typeDest, ConstValFactory.GetUInt(uRes));

            return exprRes;
        }
Example #9
0
 protected virtual EXPR VisitCONSTANT(EXPRCONSTANT pExpr)
 {
     return VisitEXPR(pExpr);
 }
Example #10
0
 protected virtual EXPR VisitCONSTANT(EXPRCONSTANT pExpr)
 {
     return(VisitEXPR(pExpr));
 }
Example #11
0
 public EXPRCONSTANT CreateConstant(CType pType)
 {
     EXPRCONSTANT rval = new EXPRCONSTANT();
     rval.kind = ExpressionKind.EK_CONSTANT;
     rval.type = pType;
     rval.flags = 0;
     return rval;
 }