internal LoweredDynamicOperation MakeDynamicBinaryOperator(
            BinaryOperatorKind operatorKind,
            BoundExpression loweredLeft,
            BoundExpression loweredRight,
            bool isCompoundAssignment,
            TypeSymbol resultType
            )
        {
            Debug.Assert(operatorKind.IsDynamic());

            _factory.Syntax = loweredLeft.Syntax;

            CSharpBinderFlags binderFlags = 0;

            if (operatorKind.IsChecked())
            {
                binderFlags |= CSharpBinderFlags.CheckedContext;
            }

            if (operatorKind.IsLogical())
            {
                binderFlags |= CSharpBinderFlags.BinaryOperationLogical;
            }

            var loweredArguments = ImmutableArray.Create <BoundExpression>(
                loweredLeft,
                loweredRight
                );

            MethodSymbol argumentInfoFactory = GetArgumentInfoFactory();
            var          binderConstruction  =
                ((object)argumentInfoFactory != null)
                    ? MakeBinderConstruction(
                    WellKnownMember.Microsoft_CSharp_RuntimeBinder_Binder__BinaryOperation,
                    new[]
            {
                // flags:
                _factory.Literal((int)binderFlags),
                // expression type:
                _factory.Literal(
                    (int)operatorKind.ToExpressionType(isCompoundAssignment)
                    ),
                // context:
                _factory.TypeofDynamicOperationContextType(),
                // argument infos:
                MakeCallSiteArgumentInfos(argumentInfoFactory, loweredArguments)
            }
                    )
                    : null;

            return(MakeDynamicOperation(
                       binderConstruction,
                       null,
                       RefKind.None,
                       loweredArguments,
                       default(ImmutableArray <RefKind>),
                       null,
                       resultType
                       ));
        }
示例#2
0
        private static bool OperatorHasSideEffects(BinaryOperatorKind kind)
        {
            switch (kind.Operator())
            {
            case BinaryOperatorKind.Division:
            case BinaryOperatorKind.Remainder:
                return(true);

            default:
                return(kind.IsChecked());
            }
        }
示例#3
0
        public static bool EmitsAsCheckedInstruction(this BinaryOperatorKind kind)
        {
            if (!kind.IsChecked())
            {
                return(false);
            }

            switch (kind.Operator())
            {
            case BinaryOperatorKind.Addition:
            case BinaryOperatorKind.Subtraction:
            case BinaryOperatorKind.Multiplication:
                return(true);
            }

            return(false);
        }
        private static string GetBinaryOperatorName(BinaryOperatorKind opKind, out bool isChecked, out bool isLifted, out bool requiresLifted)
        {
            isChecked      = opKind.IsChecked();
            isLifted       = opKind.IsLifted();
            requiresLifted = opKind.IsComparison();

            switch (opKind.Operator())
            {
            case BinaryOperatorKind.Addition: return(isChecked ? "AddChecked" : "Add");

            case BinaryOperatorKind.Multiplication: return(isChecked ? "MultiplyChecked" : "Multiply");

            case BinaryOperatorKind.Subtraction: return(isChecked ? "SubtractChecked" : "Subtract");

            case BinaryOperatorKind.Division: return("Divide");

            case BinaryOperatorKind.Remainder: return("Modulo");

            case BinaryOperatorKind.And: return(opKind.IsLogical() ? "AndAlso" : "And");

            case BinaryOperatorKind.Xor: return("ExclusiveOr");

            case BinaryOperatorKind.Or: return(opKind.IsLogical() ? "OrElse" : "Or");

            case BinaryOperatorKind.LeftShift: return("LeftShift");

            case BinaryOperatorKind.RightShift: return("RightShift");

            case BinaryOperatorKind.Equal: return("Equal");

            case BinaryOperatorKind.NotEqual: return("NotEqual");

            case BinaryOperatorKind.LessThan: return("LessThan");

            case BinaryOperatorKind.LessThanOrEqual: return("LessThanOrEqual");

            case BinaryOperatorKind.GreaterThan: return("GreaterThan");

            case BinaryOperatorKind.GreaterThanOrEqual: return("GreaterThanOrEqual");

            default:
                throw ExceptionUtilities.UnexpectedValue(opKind.Operator());
            }
        }
        private BoundExpression RewritePointerNumericOperator(
            CSharpSyntaxNode syntax,
            BinaryOperatorKind kind,
            BoundExpression loweredLeft,
            BoundExpression loweredRight,
            TypeSymbol returnType,
            bool isPointerElementAccess,
            bool isLeftPointer)
        {
            if (isLeftPointer)
            {
                loweredRight = MakeSizeOfMultiplication(loweredRight, (PointerTypeSymbol)loweredLeft.Type, kind.IsChecked());
            }
            else
            {
                loweredLeft = MakeSizeOfMultiplication(loweredLeft, (PointerTypeSymbol)loweredRight.Type, kind.IsChecked());
            }

            if (isPointerElementAccess)
            {
                Debug.Assert(kind.Operator() == BinaryOperatorKind.Addition);

                // NOTE: This is here to persist a bug in Dev10.  checked(p[n]) should be equivalent to checked(*(p + n)),
                // but Dev10 omits the check on the addition (though it retains the check on the multiplication of n by
                // the size).
                kind = kind & ~BinaryOperatorKind.Checked;
            }

            return new BoundBinaryOperator(
                            syntax,
                            kind,
                            loweredLeft,
                            loweredRight,
                            ConstantValue.NotAvailable,
                            null,
                            LookupResultKind.Viable,
                            returnType);
        }
        private string GetBinaryOperatorName(BinaryOperatorKind opKind, out bool isChecked, out bool isLifted, out bool requiresLifted)
        {
            isChecked = opKind.IsChecked();
            isLifted = opKind.IsLifted();
            requiresLifted = opKind.IsComparison();

            switch (opKind.Operator())
            {
                case BinaryOperatorKind.Addition: return isChecked ? "AddChecked" : "Add";
                case BinaryOperatorKind.Multiplication: return isChecked ? "MultiplyChecked" : "Multiply";
                case BinaryOperatorKind.Subtraction: return isChecked ? "SubtractChecked" : "Subtract";
                case BinaryOperatorKind.Division: return "Divide";
                case BinaryOperatorKind.Remainder: return "Modulo";
                case BinaryOperatorKind.And: return opKind.IsLogical() ? "AndAlso" : "And";
                case BinaryOperatorKind.Xor: return "ExclusiveOr";
                case BinaryOperatorKind.Or: return opKind.IsLogical() ? "OrElse" : "Or";
                case BinaryOperatorKind.LeftShift: return "LeftShift";
                case BinaryOperatorKind.RightShift: return "RightShift";
                case BinaryOperatorKind.Equal: return "Equal";
                case BinaryOperatorKind.NotEqual: return "NotEqual";
                case BinaryOperatorKind.LessThan: return "LessThan";
                case BinaryOperatorKind.LessThanOrEqual: return "LessThanOrEqual";
                case BinaryOperatorKind.GreaterThan: return "GreaterThan";
                case BinaryOperatorKind.GreaterThanOrEqual: return "GreaterThanOrEqual";
                default:
                    throw ExceptionUtilities.UnexpectedValue(opKind.Operator());
            }
        }
        internal LoweredDynamicOperation MakeDynamicBinaryOperator(
            BinaryOperatorKind operatorKind,
            BoundExpression loweredLeft,
            BoundExpression loweredRight,
            bool isCompoundAssignment,
            TypeSymbol resultType)
        {
            Debug.Assert(operatorKind.IsDynamic());

            _factory.Syntax = loweredLeft.Syntax;

            CSharpBinderFlags binderFlags = 0;
            if (operatorKind.IsChecked())
            {
                binderFlags |= CSharpBinderFlags.CheckedContext;
            }

            if (operatorKind.IsLogical())
            {
                binderFlags |= CSharpBinderFlags.BinaryOperationLogical;
            }

            var loweredArguments = ImmutableArray.Create<BoundExpression>(loweredLeft, loweredRight);

            MethodSymbol argumentInfoFactory = GetArgumentInfoFactory();
            var binderConstruction = ((object)argumentInfoFactory != null) ? MakeBinderConstruction(WellKnownMember.Microsoft_CSharp_RuntimeBinder_Binder__BinaryOperation, new[]
            {
                // flags:
                _factory.Literal((int)binderFlags),

                // expression type:
                _factory.Literal((int)operatorKind.ToExpressionType(isCompoundAssignment)),

                // context:
                _factory.TypeofDynamicOperationContextType(),

                // argument infos:
                MakeCallSiteArgumentInfos(argumentInfoFactory, loweredArguments)
            }) : null;

            return MakeDynamicOperation(binderConstruction, null, RefKind.None, loweredArguments, ImmutableArray<RefKind>.Empty, null, resultType);
        }
示例#8
0
 private static bool OperatorHasSideEffects(BinaryOperatorKind kind)
 {
     switch (kind.Operator())
     {
         case BinaryOperatorKind.Division:
         case BinaryOperatorKind.Remainder:
             return true;
         default:
             return kind.IsChecked();
     }
 }