CreateConstant() public method

public CreateConstant ( CType pType ) : Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCONSTANT
pType CType
return Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCONSTANT
Example #1
0
            private bool bindImplicitConversionToEnum(AggregateType aggTypeSrc)
            {
                // The spec states:
                // *****************
                // 13.1.3 Implicit enumeration conversions
                //
                // An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any
                // enum-type.
                // *****************
                // However, we actually allow any constant zero, not just the integer literal zero, to be converted
                // to enum.  The reason for this is for backwards compatibility with a premature optimization
                // that used to be in the binding layer.  We would optimize away expressions such as 0 | blah to be
                // just 0, but not erase the "is literal" bit.  This meant that expression such as 0 | 0 | E.X
                // would succeed rather than correctly producing an error pointing out that 0 | 0 is not a literal
                // zero and therefore does not convert to any enum.
                //
                // We have removed the premature optimization but want old code to continue to compile. Rather than
                // try to emulate the somewhat complex behaviour of the previous optimizer, it is easier to simply
                // say that any compile time constant zero is convertible to any enum.  This means unfortunately
                // expressions such as (7-7) * 12 are convertible to enum, but frankly, that's better than having
                // some terribly complex rule about what constitutes a legal zero and what doesn't.

                // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
                if (
                    aggTypeSrc.OwningAggregate.GetPredefType() != PredefinedType.PT_BOOL &&
                    _exprSrc != null &&
                    _exprSrc.IsZero() &&
                    _exprSrc.Type.IsNumericType &&
                    /*(exprSrc.flags & EXF_LITERALCONST) &&*/
                    0 == (_flags & CONVERTTYPE.STANDARD))
                {
                    // NOTE: This allows conversions from uint, long, ulong, float, double, and hexadecimal int
                    // NOTE: This is for backwards compatibility with Everett

                    // This is another place where we lose Expr fidelity. We shouldn't fold this
                    // into a constant here - we should move this to a later pass.
                    if (_needsExprDest)
                    {
                        _exprDest = ExprFactory.CreateConstant(_typeDest, ConstVal.GetDefaultValue(_typeDest.ConstValKind));
                    }
                    return(true);
                }
                return(false);
            }
Example #2
0
            /////////////////////////////////////////////////////////////////////////////////

            private static EXPR GenerateOptionalArgument(
                    SymbolLoader symbolLoader,
                    ExprFactory exprFactory,
                    MethodOrPropertySymbol methprop,
                    CType type,
                    int index)
            {
                CType pParamType = type;
                CType pRawParamType = type.IsNullableType() ? type.AsNullableType().GetUnderlyingType() : type;

                EXPR optionalArgument = null;
                if (methprop.HasDefaultParameterValue(index))
                {
                    CType pConstValType = methprop.GetDefaultParameterValueConstValType(index);
                    CONSTVAL cv = methprop.GetDefaultParameterValue(index);

                    if (pConstValType.isPredefType(PredefinedType.PT_DATETIME) &&
                        (pRawParamType.isPredefType(PredefinedType.PT_DATETIME) || pRawParamType.isPredefType(PredefinedType.PT_OBJECT) || pRawParamType.isPredefType(PredefinedType.PT_VALUE)))
                    {
                        // This is the specific case where we want to create a DateTime
                        // but the constval that stores it is a long.

                        AggregateType dateTimeType = symbolLoader.GetReqPredefType(PredefinedType.PT_DATETIME);
                        optionalArgument = exprFactory.CreateConstant(dateTimeType, new CONSTVAL(DateTime.FromBinary(cv.longVal)));
                    }
                    else if (pConstValType.isSimpleOrEnumOrString())
                    {
                        // In this case, the constval is a simple type (all the numerics, including
                        // decimal), or an enum or a string. This covers all the substantial values,
                        // and everything else that can be encoded is just null or default(something).

                        // For enum parameters, we create a constant of the enum type. For everything
                        // else, we create the appropriate constant.

                        if (pRawParamType.isEnumType() && pConstValType == pRawParamType.underlyingType())
                        {
                            optionalArgument = exprFactory.CreateConstant(pRawParamType, cv);
                        }
                        else
                        {
                            optionalArgument = exprFactory.CreateConstant(pConstValType, cv);
                        }
                    }
                    else if ((pParamType.IsRefType() || pParamType.IsNullableType()) && cv.IsNullRef())
                    {
                        // We have an "= null" default value with a reference type or a nullable type.

                        optionalArgument = exprFactory.CreateNull();
                    }
                    else
                    {
                        // We have a default value that is encoded as a nullref, and that nullref is
                        // interpreted as default(something). For instance, the pParamType could be
                        // a type parameter type or a non-simple value type.

                        optionalArgument = exprFactory.CreateZeroInit(pParamType);
                    }
                }
                else
                {
                    // There was no default parameter specified, so generally use default(T),
                    // except for some cases when the parameter type in metatdata is object.

                    if (pParamType.isPredefType(PredefinedType.PT_OBJECT))
                    {
                        if (methprop.MarshalAsObject(index))
                        {
                            // For [opt] parameters of type object, if we have marshal(iunknown),
                            // marshal(idispatch), or marshal(interface), then we emit a null.

                            optionalArgument = exprFactory.CreateNull();
                        }
                        else
                        {
                            // Otherwise, we generate Type.Missing

                            AggregateSymbol agg = symbolLoader.GetOptPredefAgg(PredefinedType.PT_MISSING);
                            Name name = symbolLoader.GetNameManager().GetPredefinedName(PredefinedName.PN_CAP_VALUE);
                            FieldSymbol field = symbolLoader.LookupAggMember(name, agg, symbmask_t.MASK_FieldSymbol).AsFieldSymbol();
                            FieldWithType fwt = new FieldWithType(field, agg.getThisType());
                            EXPRFIELD exprField = exprFactory.CreateField(0, agg.getThisType(), null, 0, fwt, null);

                            if (agg.getThisType() != type)
                            {
                                optionalArgument = exprFactory.CreateCast(0, type, exprField);
                            }
                            else
                            {
                                optionalArgument = exprField;
                            }
                        }
                    }
                    else
                    {
                        // Every type aside from object that doesn't have a default value gets
                        // its default value.

                        optionalArgument = exprFactory.CreateZeroInit(pParamType);
                    }
                }

                Debug.Assert(optionalArgument != null);
                optionalArgument.IsOptionalArgument = true;
                return optionalArgument;
            }