private void UnaryOperatorEasyOut(UnaryOperatorKind kind, BoundExpression operand, UnaryOperatorOverloadResolutionResult result) { var operandType = operand.Type; if ((object)operandType == null) { return; } var easyOut = UnopEasyOut.OpKind(kind, operandType); if (easyOut == UnaryOperatorKind.Error) { return; } UnaryOperatorSignature signature = this.Compilation.builtInOperators.GetSignature(easyOut); Conversion?conversion = Conversions.FastClassifyConversion(operandType, signature.OperandType); Debug.Assert(conversion.HasValue && conversion.Value.IsImplicit); result.Results.Add(UnaryOperatorAnalysisResult.Applicable(signature, conversion.Value)); }
private static UnaryOperatorSignature?GetPointerOperation(UnaryOperatorKind kind, BoundExpression operand) { Debug.Assert(operand != null); var pointerType = operand.Type as PointerTypeSymbol; if ((object)pointerType == null) { return(null); } UnaryOperatorSignature?op = null; switch (kind) { case UnaryOperatorKind.PostfixIncrement: case UnaryOperatorKind.PostfixDecrement: case UnaryOperatorKind.PrefixIncrement: case UnaryOperatorKind.PrefixDecrement: op = new UnaryOperatorSignature(kind | UnaryOperatorKind.Pointer, pointerType, pointerType); break; } return(op); }
/// <summary> /// Produce an element-wise comparison and logic to ensure the result is a bool type. /// /// If an element-wise comparison doesn't return bool, then: /// - if it is dynamic, we'll do <c>!(comparisonResult.false)</c> or <c>comparisonResult.true</c> /// - if it implicitly converts to bool, we'll just do the conversion /// - otherwise, we'll do <c>!(comparisonResult.false)</c> or <c>comparisonResult.true</c> (as we'd do for <c>if</c> or <c>while</c>) /// </summary> private BoundExpression RewriteTupleSingleOperator(TupleBinaryOperatorInfo.Single single, BoundExpression left, BoundExpression right, TypeSymbol boolType, BinaryOperatorKind operatorKind) { if (single.Kind.IsDynamic()) { // Produce // !((left == right).op_false) // (left != right).op_true BoundExpression dynamicResult = _dynamicFactory.MakeDynamicBinaryOperator(single.Kind, left, right, isCompoundAssignment: false, _compilation.DynamicType).ToExpression(); if (operatorKind == BinaryOperatorKind.Equal) { return(_factory.Not(MakeUnaryOperator(UnaryOperatorKind.DynamicFalse, left.Syntax, method: null, dynamicResult, boolType))); } else { return(MakeUnaryOperator(UnaryOperatorKind.DynamicTrue, left.Syntax, method: null, dynamicResult, boolType)); } } if (left.IsLiteralNull() && right.IsLiteralNull()) { // For `null == null` this is special-cased during initial binding return(new BoundLiteral(left.Syntax, ConstantValue.Create(operatorKind == BinaryOperatorKind.Equal), boolType)); } // We leave both operands in nullable-null conversions unconverted, MakeBinaryOperator has special for null-literal bool isNullableNullConversion = single.Kind.OperandTypes() == BinaryOperatorKind.NullableNull; BoundExpression convertedLeft = isNullableNullConversion ? left : MakeConversionNode(left.Syntax, left, single.LeftConversion, single.LeftConvertedTypeOpt, @checked: false); BoundExpression convertedRight = isNullableNullConversion ? right : MakeConversionNode(right.Syntax, right, single.RightConversion, single.RightConvertedTypeOpt, @checked: false); BoundExpression binary = MakeBinaryOperator(_factory.Syntax, single.Kind, convertedLeft, convertedRight, single.MethodSymbolOpt?.ReturnType.TypeSymbol ?? boolType, single.MethodSymbolOpt); UnaryOperatorSignature boolOperator = single.BoolOperator; Conversion boolConversion = single.ConversionForBool; BoundExpression result; if (boolOperator.Kind != UnaryOperatorKind.Error) { // Produce // !((left == right).op_false) // (left != right).op_true BoundExpression convertedBinary = MakeConversionNode(_factory.Syntax, binary, boolConversion, boolOperator.OperandType, @checked: false); Debug.Assert(boolOperator.ReturnType.SpecialType == SpecialType.System_Boolean); result = MakeUnaryOperator(boolOperator.Kind, binary.Syntax, boolOperator.Method, convertedBinary, boolType); if (operatorKind == BinaryOperatorKind.Equal) { result = _factory.Not(result); } } else if (!boolConversion.IsIdentity) { // Produce // (bool)(left == right) // (bool)(left != right) result = MakeConversionNode(_factory.Syntax, binary, boolConversion, boolType, @checked: false); } else { result = binary; } return(result); }
public static UnaryOperatorAnalysisResult Inapplicable(UnaryOperatorSignature signature, Conversion conversion) { return(new UnaryOperatorAnalysisResult(OperatorAnalysisResultKind.Inapplicable, signature, conversion)); }
private UnaryOperatorAnalysisResult(OperatorAnalysisResultKind kind, UnaryOperatorSignature signature, Conversion conversion) { this.Kind = kind; this.Signature = signature; this.Conversion = conversion; }