--- /dev/null
--- /dev/null
++// cs0019-10.cs: Operator `+' cannot be applied to operands of type `A' and `B'
++// Line : 20
++
++enum A
++{
++ A1,
++ A2
++}
++
++enum B
++{
++ B1,
++ B2
++}
++
++class C
++{
++ static void Main ()
++ {
++ System.Console.WriteLine (A.A1 - B.B1);
++ }
++}
--- /dev/null
--- /dev/null
++// cs0029-3.cs: Cannot implicitly convert type `string' to `int'
++// Line : 7
++
++public class Blah {
++
++ public enum MyEnum {
++ Foo = "foo",
++ Bar
++ }
++
++ public static void Main ()
++ {
++ }
++}
--- /dev/null
--- /dev/null
++// cs0031.cs: Constant value `256' cannot be converted to a `byte'
++// Line : 7
++
++public class Blah {
++
++ public enum MyEnum : byte {
++ Foo = null,
++ Bar
++ }
++
++ public static void Main ()
++ {
++ }
++}
--- /dev/null
--- /dev/null
++// cs0037-4.cs: Cannot convert null to `int' because it is a value type
++// Line: 9
++
++class X {
++ static void Main ()
++ {
++ int s = 44;
++ switch (s) {
++ case null: break;
++ }
++ }
++}
--- /dev/null
--- /dev/null
++// cs0110.cs: The evaluation of the constant value for `E.a' involves a circular definition
++// Line: 6
++
++enum E
++{
++ a = b,
++ b = c,
++ c = a
++}
--- /dev/null
--- /dev/null
++// cs0133-5.cs: The expression being assigned to `i' must be constant
++// Line: 12
++
++class T
++{
++ const decimal[] i = new decimal [] { 2m };
++}
--- /dev/null
--- /dev/null
++// cs0159-3.cs: No such label `case null:' within the scope of the goto statement
++// Line: 10
++
++class y {
++ static void Main ()
++ {
++ string x = null;
++
++ switch (x){
++ case "": goto case null;
++ }
++ }
++}
++
--// cs0619-19.cs: `MainClass' is obsolete: `'
--// Line: 8
++// cs0619-19.cs: `O' is obsolete: `'
++// Line: 12
[System.Obsolete("", true)]
++class O
++{
++}
++
class MainClass {
public void Method ()
{
-- lock (new MainClass ()) {
++ lock (new O ()) {
}
}
}
--- /dev/null
--- /dev/null
++// cs0619-39.cs: `c.ob' is obsolete: `ooo'
++// Line: 13
++
++using System;
++
++class C
++{
++ [Obsolete("ooo", true)]
++ const int ob = 4;
++
++ public int Prop {
++ get {
++ return ob;
++ }
++ }
++}
--- /dev/null
--- /dev/null
++// cs0619-39.cs: `c.ob' is obsolete: `ooo'
++// Line: 13
++
++using System;
++
++class C
++{
++ [Obsolete("ooo", true)]
++ const int ob = 4;
++
++ public void Test (int arg)
++ {
++ switch (arg) {
++ case ob: return;
++ }
++ }
++}
+++ /dev/null
--// cs1008.cs: Type byte, sbyte, short, ushort, int, uint, long or ulong expected
--// Line : 7
--
--public class Blah {
--
-- public enum MyEnum {
-- Foo = "foo",
-- Bar
-- }
--
-- public static void Main ()
-- {
-- }
--}
# csXXXX.cs NO ERROR : error test case doesn't report any error. An exception is considered
# as NO ERROR and CS5001 is automatically ignored.
++cs0029-3.cs
cs0037-2.cs
++cs0037-3.cs
++cs0037-4.cs
cs0118.cs
cs0118-3.cs
cs0118-4.cs
cs0122-17.cs NO ERROR
cs0133-4.cs
cs0136-6.cs NO ERROR
++cs0159-3.cs
cs0201.cs
cs0202.cs # new in GMCS
cs0229-2.cs
cs0548.cs
cs0560.cs
cs0567.cs
++cs0619-39.cs NO ERROR
++cs0619-40.cs NO ERROR
cs0642-2.cs NO ERROR
cs0642-3.cs
cs0642-4.cs
cs0548.cs
cs0560.cs
cs0567.cs
++cs0619-31.cs NO ERROR
cs0642.cs NO ERROR
cs0642-2.cs NO ERROR
cs0642-3.cs
++2005-08-16 Marek Safar <marek.safar@seznam.cz>
++
++ The big constants rewrite
++ Fix #75746, #75685 and more
++ As a side effect saved 1MB for MWF ;-)
++
++ * attribute.cs (GetAttributeArgumentExpression): Use ToType, GetTypedValue.
++ (GetMarshal, GetMethodImplOptions, GetLayoutKindValue): Values are not
++ enum based for corlib compilation.
++
++ * cfold.cs (BinaryFold): Convert operand for enum additions. Fixed enum
++ subtractions.
++
++ * class.cs (FixedField.Define): Use ResolveAsConstant.
++
++ * const.cs (IConstant): Interface constants and enums.
++ (Const.ResolveValue): New method for constant resolvning.
++ (ExternalConstant): Constants from imported assemblies.
++
++ * constant.cs (Constant.GetTypedValue): Used to get constant with forced
++ conversion; like enums.
++ (Constant.ToType): Converts this constant to different type.
++ (Constant.Increment): Adds 1.
++
++ * convert.cs (ImplicitConversionRequired): Simplified.
++
++ * cs-parser.jay: Create EnumMember directly.
++
++ * decl.cs (MemberCore.CheckObsoleteness): Checks for ObsoleteAttribute presence.
++
++ * doc.cs (GenerateEnumDocComment): Removed.
++
++ * ecore.cs (Expression.ResolveAsConstant): New constant specific method.
++ (ConvertIntLiteral): Removed.
++ (FieldExpr.ResolveMemberAccess): Refactored to remove constant specific if(s).
++
++ * enum.cs (EnumMember): Implement IConstant.
++ (Enum.IsValidEnumConstant): Removed.
++ (Enum.GetNextDefaultValue): Removed.
++ (Enum.FindMembers): Updated.
++ (Enum.GenerateDocComment): Iterate enum members.
++
++ * expression.cs (Cast.TryReduce): Handle enums correctly.
++ (New.Constantify): Made public.
++ (MemberAccess.DoResolve): Removed contant specific if(s).
++
++ * literal.cs (NullLiteral): Implement new abstract methods.
++
++ * statement.cs (GotoCase.Resolve): Use new constant methods.
++ (SwitchLabel.ResolveAndReduce): Use new constant methods.
++
++ * typemanager.cs (LookupEnum): Removed.
++ (IsEnumType): Fixed to work with corlib.
++ (RegisterConstant): Removed.
++ (LookupConstant): Removed.
++ (GetConstant): Changed to work with IConstant.
++
2005-08-04 Atsushi Enomoto <atsushi@ximian.com>
* location.cs : Fixed overflown (>255) column number.
//
public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
{
-- if (e is EnumConstant) {
-- if (RootContext.StdLib)
-- result = ((EnumConstant)e).GetValueAsEnumType ();
-- else
-- result = ((EnumConstant)e).GetValue ();
--
-- return true;
-- }
--
Constant constant = e as Constant;
if (constant != null) {
-- if (e.Type != arg_type) {
-- constant = Const.ChangeType (loc, constant, arg_type);
-- if (constant == null) {
-- result = null;
-- Error_AttributeArgumentNotValid (loc);
-- return false;
-- }
++ constant = constant.ToType (arg_type, loc);
++ if (constant == null) {
++ result = null;
++ return false;
}
-- result = constant.GetValue ();
++ result = constant.GetTypedValue ();
return true;
} else if (e is TypeOf) {
result = ((TypeOf) e).TypeArg;
public UnmanagedMarshal GetMarshal (Attributable attr)
{
-- UnmanagedType UnmanagedType = (UnmanagedType)System.Enum.Parse (typeof (UnmanagedType), pos_values [0].ToString ());
++ UnmanagedType UnmanagedType;
++ if (!RootContext.StdLib || pos_values [0].GetType () != typeof (UnmanagedType))
++ UnmanagedType = (UnmanagedType)System.Enum.ToObject (typeof (UnmanagedType), pos_values [0]);
++ else
++ UnmanagedType = (UnmanagedType) pos_values [0];
object value = GetFieldValue ("SizeParamIndex");
if (value != null && UnmanagedType != UnmanagedType.LPArray) {
public MethodImplOptions GetMethodImplOptions ()
{
-- return (MethodImplOptions)System.Enum.Parse (typeof (MethodImplOptions), pos_values [0].ToString ());
++ if (pos_values [0].GetType () != typeof (MethodImplOptions))
++ return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]);
++ return (MethodImplOptions)pos_values [0];
}
public LayoutKind GetLayoutKindValue ()
{
-- return (LayoutKind)System.Enum.Parse (typeof (LayoutKind), pos_values [0].ToString ());
++ if (!RootContext.StdLib || pos_values [0].GetType () != typeof (LayoutKind))
++ return (LayoutKind)System.Enum.ToObject (typeof (LayoutKind), pos_values [0]);
++
++ return (LayoutKind)pos_values [0];
}
/// <summary>
if (right is EnumConstant){
return null;
}
-- if (((EnumConstant) left).Child.Type != right.Type)
++
++ right = right.ToType (((EnumConstant) left).Child.Type, loc);
++ if (right == null)
return null;
wrap_as = left.Type;
} else if (right is EnumConstant){
-- if (((EnumConstant) right).Child.Type != left.Type)
++ left = left.ToType (((EnumConstant) right).Child.Type, loc);
++ if (left == null)
return null;
++
wrap_as = right.Type;
}
wrap_as = null;
if (left is EnumConstant){
if (right is EnumConstant){
-- if (left.Type == right.Type)
-- wrap_as = TypeManager.EnumToUnderlying (left.Type);
-- else
++ if (left.Type != right.Type) {
++ Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
++ return null;
++ }
++
++ wrap_as = TypeManager.EnumToUnderlying (left.Type);
++ right = ((EnumConstant) right).Child.ToType (wrap_as, loc);
++ if (right == null)
++ return null;
++
++ left = ((EnumConstant) left).Child.ToType (wrap_as, loc);
++ if (left == null)
return null;
}
-- if (((EnumConstant) left).Child.Type != right.Type)
-- return null;
++ else {
++ right = right.ToType (((EnumConstant) left).Child.Type, loc);
++ if (right == null)
++ return null;
-- wrap_as = left.Type;
++ wrap_as = left.Type;
++ }
} else if (right is EnumConstant){
-- if (((EnumConstant) right).Child.Type != left.Type)
++ left = left.ToType (((EnumConstant) right).Child.Type, loc);
++ if (left == null)
return null;
++
wrap_as = right.Type;
}
return false;
}
-- Expression e = size_expr.Resolve (Parent.EmitContext);
-- if (e == null)
++ Constant c = size_expr.ResolveAsConstant (Parent.EmitContext, this);
++ if (c == null)
return false;
-- Constant c = e as Constant;
-- if (c == null) {
-- Const.Error_ExpressionMustBeConstant (e.Location, GetSignatureForError ());
-- return false;
-- }
--
IntConstant buffer_size_const = c.ToInt (Location);
if (buffer_size_const == null)
return false;
//
//
--//
--// This is needed because the following situation arises:
--//
--// The FieldBuilder is declared with the real type for an enumeration
--//
--// When we attempt to set the value for the constant, the FieldBuilder.SetConstant
--// function aborts because it requires its argument to be of the same type
--//
--
namespace Mono.CSharp {
using System;
using System.Reflection.Emit;
using System.Collections;
-- public class Const : FieldMember {
-- public Expression Expr;
-- EmitContext const_ec;
--
-- bool resolved = false;
-- object ConstantValue = null;
++ public interface IConstant
++ {
++ void CheckObsoleteness (Location loc);
++ bool ResolveValue ();
++ Constant Value { get; }
++ }
-- bool in_transit = false;
++ public class Const : FieldMember, IConstant {
++ Expression Expr;
++ Constant value;
++ bool in_transit;
public const int AllowedModifiers =
Modifiers.NEW |
ModFlags |= Modifiers.STATIC;
}
--#if DEBUG
-- void dump_tree (Type t)
-- {
-- Console.WriteLine ("Dumping hierarchy");
-- while (t != null){
-- Console.WriteLine (" " + t.FullName + " " +
-- (t.GetType ().IsEnum ? "yes" : "no"));
-- t = t.BaseType;
-- }
-- }
--#endif
--
protected override bool CheckBase ()
{
// Constant.Define can be called when the parent type hasn't yet been populated
if (!base.Define ())
return false;
-- const_ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
--
Type ttype = MemberType;
while (ttype.IsArray)
ttype = TypeManager.GetElementType (ttype);
--
-- if (!TypeManager.IsBuiltinType(ttype) && (!ttype.IsSubclassOf(TypeManager.enum_type)) && !(Expr is NullLiteral)){
-- Report.Error (
-- -3, Location,
-- "Constant type is not valid (only system types are allowed)");
-- return false;
-- }
FieldAttributes field_attr = FieldAttributes.Static | Modifiers.FieldAttr (ModFlags);
// Decimals cannot be emitted into the constant blob. So, convert to 'readonly'.
return true;
}
--
-- //
-- // Changes the type of the constant expression `expr' to the Type `type'
-- // Returns null on failure.
-- //
-- public static Constant ChangeType (Location loc, Constant expr, Type type)
++
++ /// <summary>
++ /// Emits the field value by evaluating the expression
++ /// </summary>
++ public override void Emit ()
{
-- if (type == TypeManager.object_type)
-- return expr;
--
-- bool fail;
--
-- // from the null type to any reference-type.
-- if (expr.Type == TypeManager.null_type && !type.IsValueType && !TypeManager.IsEnumType (type))
-- return NullLiteral.Null;
++ if (!ResolveValue ())
++ return;
-- if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, expr, type)){
-- Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
-- return null;
-- }
--
-- // Special-case: The 0 literal can be converted to an enum value,
-- // and ImplicitStandardConversionExists will return true in that case.
-- if (expr.Type == TypeManager.int32_type && TypeManager.IsEnumType (type)){
-- if (expr is IntLiteral && ((IntLiteral) expr).Value == 0)
-- return new EnumConstant (expr, type);
++ if (value.Type == TypeManager.decimal_type) {
++ Decimal d = ((DecimalConstant)value).Value;
++ int[] bits = Decimal.GetBits (d);
++ object[] args = new object[] { (byte)(bits [3] >> 16), (byte)(bits [3] >> 31), (uint)bits [2], (uint)bits [1], (uint)bits [0] };
++ CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.decimal_constant_attribute_ctor, args);
++ FieldBuilder.SetCustomAttribute (cab);
}
--
-- object constant_value = TypeManager.ChangeType (expr.GetValue (), type, out fail);
-- if (fail){
-- Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
--
-- //
-- // We should always catch the error before this is ever
-- // reached, by calling Convert.ImplicitStandardConversionExists
-- //
-- throw new Exception (
-- String.Format ("LookupConstantValue: This should never be reached {0} {1}", expr.Type, type));
++ else{
++ FieldBuilder.SetConstant (value.GetTypedValue ());
}
-- Constant retval;
-- if (type == TypeManager.int32_type)
-- retval = new IntConstant ((int) constant_value);
-- else if (type == TypeManager.uint32_type)
-- retval = new UIntConstant ((uint) constant_value);
-- else if (type == TypeManager.int64_type)
-- retval = new LongConstant ((long) constant_value);
-- else if (type == TypeManager.uint64_type)
-- retval = new ULongConstant ((ulong) constant_value);
-- else if (type == TypeManager.float_type)
-- retval = new FloatConstant ((float) constant_value);
-- else if (type == TypeManager.double_type)
-- retval = new DoubleConstant ((double) constant_value);
-- else if (type == TypeManager.string_type)
-- retval = new StringConstant ((string) constant_value);
-- else if (type == TypeManager.short_type)
-- retval = new ShortConstant ((short) constant_value);
-- else if (type == TypeManager.ushort_type)
-- retval = new UShortConstant ((ushort) constant_value);
-- else if (type == TypeManager.sbyte_type)
-- retval = new SByteConstant ((sbyte) constant_value);
-- else if (type == TypeManager.byte_type)
-- retval = new ByteConstant ((byte) constant_value);
-- else if (type == TypeManager.char_type)
-- retval = new CharConstant ((char) constant_value);
-- else if (type == TypeManager.bool_type)
-- retval = new BoolConstant ((bool) constant_value);
-- else if (type == TypeManager.decimal_type)
-- retval = new DecimalConstant ((decimal) constant_value);
-- else
-- throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
--
-- return retval;
++ base.Emit ();
}
--
-- /// <summary>
-- /// Looks up the value of a constant field. Defines it if it hasn't
-- /// already been. Similar to LookupEnumValue in spirit.
-- /// </summary>
-- public bool LookupConstantValue (out object value)
++
++ public static void Error_ExpressionMustBeConstant (Location loc, string e_name)
++ {
++ Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
++ }
++
++ public static void Error_CyclicDeclaration (MemberCore mc)
{
-- if (resolved) {
-- value = ConstantValue;
++ Report.Error (110, mc.Location, "The evaluation of the constant value for `{0}' involves a circular definition",
++ mc.GetSignatureForError ());
++ }
++
++ #region IConstant Members
++
++ public bool ResolveValue ()
++ {
++ if (value != null)
return true;
-- }
++ SetMemberIsUsed ();
if (in_transit) {
-- Report.Error (110, Location,
-- "The evaluation of the constant value for `" +
-- Name + "' involves a circular definition.");
-- value = null;
++ Error_CyclicDeclaration (this);
++ // Suppress cyclic errors
++ value = New.Constantify (MemberType);
return false;
}
in_transit = true;
-- int errors = Report.Errors;
--
-- //
-- // We might have cleared Expr ourselves in a recursive definition
-- //
-- if (Expr == null){
-- value = null;
++ EmitContext ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
++ value = Expr.ResolveAsConstant (ec, this);
++ if (value == null)
return false;
-- }
-- Expr = Expr.Resolve (const_ec);
++ value = value.ToType (MemberType, Location);
++ if (value == null)
++ return false;
in_transit = false;
++ return true;
++ }
-- if (Expr == null) {
-- Error_ExpressionMustBeConstant (Location, GetSignatureForError ());
-- value = null;
-- return false;
++ public Constant Value {
++ get {
++ return value;
}
++ }
-- Expression real_expr = Expr;
--
-- Constant ce = Expr as Constant;
-- if (ce == null){
-- UnCheckedExpr un_expr = Expr as UnCheckedExpr;
-- CheckedExpr ch_expr = Expr as CheckedExpr;
-- EmptyCast ec_expr = Expr as EmptyCast;
--
-- if ((un_expr != null) && (un_expr.Expr is Constant))
-- Expr = un_expr.Expr;
-- else if ((ch_expr != null) && (ch_expr.Expr is Constant))
-- Expr = ch_expr.Expr;
-- else if ((ec_expr != null) && (ec_expr.Child is Constant))
-- Expr = ec_expr.Child;
-- else if (Expr is ArrayCreation){
-- Report.Error (133, Location, "Arrays can not be constant");
-- } else {
-- if (errors == Report.Errors)
-- Report.Error (150, Location, "A constant value is expected");
-- value = null;
-- return false;
-- }
--
-- ce = Expr as Constant;
-- }
++ #endregion
++ }
-- if (MemberType != real_expr.Type) {
-- ce = ChangeType (Location, ce, MemberType);
-- if (ce == null){
-- value = null;
-- return false;
-- }
-- Expr = ce;
-- }
++ public class ExternalConstant: IConstant
++ {
++ FieldInfo fi;
++ Constant value;
-- if (ce != null)
-- ConstantValue = ce.GetValue ();
--
-- if (MemberType.IsEnum){
-- //
-- // This sadly does not work for our user-defined enumerations types ;-(
-- //
-- try {
-- ConstantValue = System.Enum.ToObject (
-- MemberType, ConstantValue);
-- } catch (ArgumentException){
-- Report.Error (
-- -16, Location,
-- ".NET SDK 1.0 does not permit to create the constant "+
-- " field from a user-defined enumeration");
-- }
-- }
++ public ExternalConstant (FieldInfo fi)
++ {
++ this.fi = fi;
++ }
-- if (ce is DecimalConstant) {
-- Decimal d = ((DecimalConstant)ce).Value;
-- int[] bits = Decimal.GetBits (d);
-- object[] args = new object[] { (byte)(bits [3] >> 16), (byte)(bits [3] >> 31), (uint)bits [2], (uint)bits [1], (uint)bits [0] };
-- CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.decimal_constant_attribute_ctor, args);
-- FieldBuilder.SetCustomAttribute (cab);
-- }
-- else{
-- FieldBuilder.SetConstant (ConstantValue);
-- }
++ #region IConstant Members
-- if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue))
-- throw new Exception ("Cannot register const value");
++ public void CheckObsoleteness (Location loc)
++ {
++ ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (fi);
++ if (oa == null) {
++ return;
++ }
-- value = ConstantValue;
-- resolved = true;
-- return true;
++ AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (fi), loc);
}
--
--
-- /// <summary>
-- /// Emits the field value by evaluating the expression
-- /// </summary>
-- public override void Emit ()
++
++ public bool ResolveValue ()
{
-- object value;
-- LookupConstantValue (out value);
-- base.Emit ();
++ if (value != null)
++ return true;
++
++ if (fi.DeclaringType.IsEnum) {
++ value = Expression.Constantify (fi.GetValue (fi), TypeManager.EnumToUnderlying (fi.FieldType));
++ value = new EnumConstant (value, fi.DeclaringType);
++ return true;
++ }
++
++ value = Expression.Constantify (fi.GetValue (fi), fi.FieldType);
++ return true;
}
-- public static void Error_ExpressionMustBeConstant (Location loc, string e_name)
-- {
-- Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
++ public Constant Value {
++ get {
++ return value;
++ }
}
++ #endregion
}
--}
--
++}
/// </summary>
public abstract object GetValue ();
++ public virtual object GetTypedValue ()
++ {
++ return GetValue ();
++ }
++
/// <summary>
/// Constants are always born in a fully resolved state
/// </summary>
return this;
}
-- public virtual void Error_ConstantValueCannotBeConverted (Location loc, Type t)
++ public override void Error_ValueCannotBeConverted (Location loc, Type t)
{
-- Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
-- AsString (), TypeManager.CSharpName (t));
++ // string is not real constant
++ if (type == TypeManager.string_type)
++ base.Error_ValueCannotBeConverted (loc, t);
++ else
++ Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
++ AsString (), TypeManager.CSharpName (t));
}
return c;
}
++ public virtual Constant ToType (Type type, Location loc)
++ {
++ if (Type == type)
++ return this;
++
++ if (type == TypeManager.object_type)
++ return this;
++
++ if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){
++ Error_ValueCannotBeConverted (loc, type);
++ return null;
++ }
++
++ // Special-case: The 0 literal can be converted to an enum value,
++ // and ImplicitStandardConversionExists will return true in that case.
++ if (IsZeroInteger && Type == TypeManager.int32_type && TypeManager.IsEnumType (type)) {
++ return new EnumConstant (this, type);
++ }
++
++ bool fail;
++ object constant_value = TypeManager.ChangeType (GetValue (), type, out fail);
++ if (fail){
++ Convert.Error_CannotImplicitConversion (loc, Type, type);
++
++ //
++ // We should always catch the error before this is ever
++ // reached, by calling Convert.ImplicitStandardConversionExists
++ //
++ throw new Exception (
++ String.Format ("LookupConstantValue: This should never be reached {0} {1}", Type, type));
++ }
++
++ Constant retval;
++ if (type == TypeManager.int32_type)
++ retval = new IntConstant ((int) constant_value);
++ else if (type == TypeManager.uint32_type)
++ retval = new UIntConstant ((uint) constant_value);
++ else if (type == TypeManager.int64_type)
++ retval = new LongConstant ((long) constant_value);
++ else if (type == TypeManager.uint64_type)
++ retval = new ULongConstant ((ulong) constant_value);
++ else if (type == TypeManager.float_type)
++ retval = new FloatConstant ((float) constant_value);
++ else if (type == TypeManager.double_type)
++ retval = new DoubleConstant ((double) constant_value);
++ else if (type == TypeManager.string_type)
++ retval = new StringConstant ((string) constant_value);
++ else if (type == TypeManager.short_type)
++ retval = new ShortConstant ((short) constant_value);
++ else if (type == TypeManager.ushort_type)
++ retval = new UShortConstant ((ushort) constant_value);
++ else if (type == TypeManager.sbyte_type)
++ retval = new SByteConstant ((sbyte) constant_value);
++ else if (type == TypeManager.byte_type)
++ retval = new ByteConstant ((byte) constant_value);
++ else if (type == TypeManager.char_type)
++ retval = new CharConstant ((char) constant_value);
++ else if (type == TypeManager.bool_type)
++ retval = new BoolConstant ((bool) constant_value);
++ else if (type == TypeManager.decimal_type)
++ retval = new DecimalConstant ((decimal) constant_value);
++ else
++ throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
++
++ return retval;
++ }
++
public virtual DecimalConstant ConvertToDecimal ()
{
return null;
{
return null;
}
++
++ public abstract Constant Increment ();
public abstract bool IsDefaultValue {
get;
else
ec.ig.Emit (OpCodes.Ldc_I4_0);
}
++
++ public override Constant Increment ()
++ {
++ throw new NotSupportedException ();
++ }
public override bool IsDefaultValue {
get {
return new IntConstant (Value);
}
++ public override Constant Increment ()
++ {
++ return new ByteConstant (checked ((byte)(Value + 1)));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
{
return new IntConstant (Value);
}
++
++ public override Constant Increment ()
++ {
++ return new CharConstant (checked ((char)(Value + 1)));
++ }
public override bool IsDefaultValue {
get {
return new IntConstant (Value);
}
++ public override Constant Increment ()
++ {
++ return new SByteConstant (checked((sbyte)(Value + 1)));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
return new IntConstant (Value);
}
++ public override Constant Increment ()
++ {
++ return new ShortConstant (checked((short)(Value + 1)));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
return new IntConstant (Value);
}
++ public override Constant Increment ()
++ {
++ return new UShortConstant (checked((ushort)(Value + 1)));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
return this;
}
++ public override Constant Increment ()
++ {
++ return new IntConstant (checked(Value + 1));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
{
return null;
}
--
++
++ public override Constant Increment ()
++ {
++ return new UIntConstant (checked(Value + 1));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
{
return null;
}
++
++ public override Constant Increment ()
++ {
++ return new LongConstant (checked(Value + 1));
++ }
public override bool IsDefaultValue {
get {
return null;
}
++ public override Constant Increment ()
++ {
++ return new ULongConstant (checked(Value + 1));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
return null;
}
++ public override Constant Increment ()
++ {
++ return new FloatConstant (checked(Value + 1));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
return null;
}
++ public override Constant Increment ()
++ {
++ return new DoubleConstant (checked(Value + 1));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
}
++ public override Constant Increment ()
++ {
++ return new DecimalConstant (checked (Value + 1));
++ }
++
public override bool IsDefaultValue {
get {
return Value == 0;
ec.ig.Emit (OpCodes.Ldstr, Value);
}
++ public override Constant Increment ()
++ {
++ throw new NotSupportedException ();
++ }
++
public override bool IsDefaultValue {
get {
return Value == null;
}
}
-- if (source is Constant){
-- Constant c = (Constant) source;
--
-- c.Error_ConstantValueCannotBeConverted (loc, target_type);
-- return null;
-- }
--
-- Error_CannotImplicitConversion (loc, source.Type, target_type);
--
++ source.Error_ValueCannotBeConverted (loc, target_type);
return null;
}
if (ne != null)
return ne;
-- if (expr is NullLiteral){
-- ((NullLiteral)expr).Error_ConstantValueCannotBeConverted (loc, target_type);
-- return null;
-- }
--
-- Error_CannotConvertType (loc, original_expr_type, target_type);
++ if (expr is Constant)
++ expr.Error_ValueCannotBeConverted (loc, target_type);
++ else
++ Error_CannotConvertType (loc, original_expr_type, target_type);
return null;
}
if (RootContext.Documentation != null)
e.DocComment = enumTypeComment;
++
++ EnumMember em = null;
foreach (VariableDeclaration ev in (ArrayList) $8) {
-- e.AddEnumMember (ev.identifier,
-- (Expression) ev.expression_or_array_initializer,
-- ev.Location, ev.OptAttributes,
-- ev.DocComment);
++ em = new EnumMember (e, em, (Expression) ev.expression_or_array_initializer,
++ new MemberName (ev.identifier, ev.Location), ev.OptAttributes);
++
++// if (RootContext.Documentation != null)
++ em.DocComment = ev.DocComment;
++
++ e.AddEnumMember (em);
}
current_container.AddEnum (e);
return obsolete;
}
++ /// <summary>
++ /// Checks for ObsoleteAttribute presence. It's used for testing of all non-types elements
++ /// </summary>
++ public void CheckObsoleteness (Location loc)
++ {
++ ObsoleteAttribute oa = GetObsoleteAttribute (Parent);
++ if (oa == null) {
++ return;
++ }
++
++ AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
++ }
++
/// <summary>
/// Analyze whether CLS-Compliant verification must be execute for this MemberCore.
/// </summary>
}
}
-- // Enum
-- public static void GenerateEnumDocComment (Enum e, DeclSpace ds)
-- {
-- GenerateDocComment (e, ds);
-- foreach (string name in e.ordered_enums) {
-- MemberCore mc = e.GetDefinition (name);
-- GenerateDocComment (mc, e);
-- }
-- }
--
private static void Normalize (MemberCore mc, ref string name)
{
if (name.Length > 0 && name [0] == '@')
if (root.Enums != null)
foreach (Enum e in root.Enums)
-- DocUtil.GenerateEnumDocComment (e, null);
++ e.GenerateDocComment (null);
IDictionary table = new ListDictionary ();
foreach (ClassPart cp in PartialComments.Keys) {
Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", name);
}
++ public virtual void Error_ValueCannotBeConverted (Location loc, Type t)
++ {
++ Convert.Error_CannotImplicitConversion (loc, Type, t);
++ }
++
ResolveFlags ExprClassToResolveFlags ()
{
switch (eclass) {
return e;
}
++ public Constant ResolveAsConstant (EmitContext ec, MemberCore mc)
++ {
++ Expression e = Resolve (ec);
++ if (e != null) {
++ Constant c = e as Constant;
++ if (c != null)
++ return c;
++
++ EmptyCast empty = e as EmptyCast;
++ if (empty != null) {
++ c = empty.Child as Constant;
++ if (c != null) {
++ // TODO: not sure about this maybe there is easier way how to use EmptyCast
++ if (e.Type.IsEnum)
++ c.Type = e.Type;
++
++ return c;
++ }
++ }
++ }
++
++ Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ());
++ return null;
++ }
++
/// <summary>
/// Resolves an expression for LValue assignment
/// </summary>
{
Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
}
--
-- /// <summary>
-- /// Converts the IntConstant, UIntConstant, LongConstant or
-- /// ULongConstant into the integral target_type. Notice
-- /// that we do not return an `Expression' we do return
-- /// a boxed integral type.
-- ///
-- /// FIXME: Since I added the new constants, we need to
-- /// also support conversions from CharConstant, ByteConstant,
-- /// SByteConstant, UShortConstant, ShortConstant
-- ///
-- /// This is used by the switch statement, so the domain
-- /// of work is restricted to the literals above, and the
-- /// targets are int32, uint32, char, byte, sbyte, ushort,
-- /// short, uint64 and int64
-- /// </summary>
-- public static object ConvertIntLiteral (Constant c, Type target_type, Location loc)
-- {
-- if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, c, target_type)){
-- Convert.Error_CannotImplicitConversion (loc, c.Type, target_type);
-- return null;
-- }
--
-- if (c.Type == target_type)
-- return ((Constant) c).GetValue ();
--
-- //
-- // Make into one of the literals we handle, we dont really care
-- // about this value as we will just return a few limited types
-- //
-- if (c is EnumConstant)
-- c = ((EnumConstant)c).WidenToCompilerConstant ();
--
-- if (c is IntConstant){
-- int v = ((IntConstant) c).Value;
--
-- if (target_type == TypeManager.uint32_type){
-- if (v >= 0)
-- return (uint) v;
-- } else if (target_type == TypeManager.char_type){
-- if (v >= Char.MinValue && v <= Char.MaxValue)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v >= Byte.MinValue && v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v >= SByte.MinValue && v <= SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.short_type){
-- if (v >= Int16.MinValue && v <= UInt16.MaxValue)
-- return (short) v;
-- } else if (target_type == TypeManager.ushort_type){
-- if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
-- return (ushort) v;
-- } else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type){
-- if (v > 0)
-- return (ulong) v;
-- }
--
-- } else if (c is UIntConstant){
-- uint v = ((UIntConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type){
-- if (v <= Int32.MaxValue)
-- return (int) v;
-- } else if (target_type == TypeManager.char_type){
-- if (v >= Char.MinValue && v <= Char.MaxValue)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v <= SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.short_type){
-- if (v <= UInt16.MaxValue)
-- return (short) v;
-- } else if (target_type == TypeManager.ushort_type){
-- if (v <= UInt16.MaxValue)
-- return (ushort) v;
-- } else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type)
-- return (ulong) v;
-- } else if (c is LongConstant){
-- long v = ((LongConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type){
-- if (v >= UInt32.MinValue && v <= UInt32.MaxValue)
-- return (int) v;
-- } else if (target_type == TypeManager.uint32_type){
-- if (v >= 0 && v <= UInt32.MaxValue)
-- return (uint) v;
-- } else if (target_type == TypeManager.char_type){
-- if (v >= Char.MinValue && v <= Char.MaxValue)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v >= Byte.MinValue && v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v >= SByte.MinValue && v <= SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.short_type){
-- if (v >= Int16.MinValue && v <= UInt16.MaxValue)
-- return (short) v;
-- } else if (target_type == TypeManager.ushort_type){
-- if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
-- return (ushort) v;
-- } else if (target_type == TypeManager.uint64_type){
-- if (v > 0)
-- return (ulong) v;
-- }
-- } else if (c is ULongConstant){
-- ulong v = ((ULongConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type){
-- if (v <= Int32.MaxValue)
-- return (int) v;
-- } else if (target_type == TypeManager.uint32_type){
-- if (v <= UInt32.MaxValue)
-- return (uint) v;
-- } else if (target_type == TypeManager.char_type){
-- if (v >= Char.MinValue && v <= Char.MaxValue)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v >= Byte.MinValue && v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v <= (int) SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.short_type){
-- if (v <= UInt16.MaxValue)
-- return (short) v;
-- } else if (target_type == TypeManager.ushort_type){
-- if (v <= UInt16.MaxValue)
-- return (ushort) v;
-- } else if (target_type == TypeManager.int64_type){
-- if (v <= Int64.MaxValue)
-- return (long) v;
-- }
-- } else if (c is ByteConstant){
-- byte v = ((ByteConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type)
-- return (int) v;
-- else if (target_type == TypeManager.uint32_type)
-- return (uint) v;
-- else if (target_type == TypeManager.char_type)
-- return (char) v;
-- else if (target_type == TypeManager.sbyte_type){
-- if (v <= SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.short_type)
-- return (short) v;
-- else if (target_type == TypeManager.ushort_type)
-- return (ushort) v;
-- else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type)
-- return (ulong) v;
-- } else if (c is SByteConstant){
-- sbyte v = ((SByteConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type)
-- return (int) v;
-- else if (target_type == TypeManager.uint32_type){
-- if (v >= 0)
-- return (uint) v;
-- } else if (target_type == TypeManager.char_type){
-- if (v >= 0)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v >= 0)
-- return (byte) v;
-- } else if (target_type == TypeManager.short_type)
-- return (short) v;
-- else if (target_type == TypeManager.ushort_type){
-- if (v >= 0)
-- return (ushort) v;
-- } else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type){
-- if (v >= 0)
-- return (ulong) v;
-- }
-- } else if (c is ShortConstant){
-- short v = ((ShortConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type){
-- return (int) v;
-- } else if (target_type == TypeManager.uint32_type){
-- if (v >= 0)
-- return (uint) v;
-- } else if (target_type == TypeManager.char_type){
-- if (v >= 0)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v >= Byte.MinValue && v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v >= SByte.MinValue && v <= SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.ushort_type){
-- if (v >= 0)
-- return (ushort) v;
-- } else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type)
-- return (ulong) v;
-- } else if (c is UShortConstant){
-- ushort v = ((UShortConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type)
-- return (int) v;
-- else if (target_type == TypeManager.uint32_type)
-- return (uint) v;
-- else if (target_type == TypeManager.char_type){
-- if (v >= Char.MinValue && v <= Char.MaxValue)
-- return (char) v;
-- } else if (target_type == TypeManager.byte_type){
-- if (v >= Byte.MinValue && v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v <= SByte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.short_type){
-- if (v <= Int16.MaxValue)
-- return (short) v;
-- } else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type)
-- return (ulong) v;
--
-- } else if (c is CharConstant){
-- char v = ((CharConstant) c).Value;
--
-- if (target_type == TypeManager.int32_type)
-- return (int) v;
-- else if (target_type == TypeManager.uint32_type)
-- return (uint) v;
-- else if (target_type == TypeManager.byte_type){
-- if (v >= Byte.MinValue && v <= Byte.MaxValue)
-- return (byte) v;
-- } else if (target_type == TypeManager.sbyte_type){
-- if (v <= SByte.MaxValue)
-- return (sbyte) v;
-- } else if (target_type == TypeManager.short_type){
-- if (v <= Int16.MaxValue)
-- return (short) v;
-- } else if (target_type == TypeManager.ushort_type)
-- return (short) v;
-- else if (target_type == TypeManager.int64_type)
-- return (long) v;
-- else if (target_type == TypeManager.uint64_type)
-- return (ulong) v;
--
-- }
-- c.Error_ConstantValueCannotBeConverted (loc, target_type);
-- return null;
-- }
//
// Load the object from the pointer.
child.Emit (ec);
}
++ public override Constant Increment ()
++ {
++ throw new NotSupportedException ();
++ }
++
public override bool IsDefaultValue {
get {
throw new NotImplementedException ();
return Child.GetValue ();
}
-- public object GetValueAsEnumType ()
++ public override object GetTypedValue ()
{
++ // FIXME: runtime is not ready to work with just emited enums
++ if (!RootContext.StdLib) {
++ return Child.GetValue ();
++ }
++
return System.Enum.ToObject (type, Child.GetValue ());
}
--
-- //
-- // Converts from one of the valid underlying types for an enumeration
-- // (int32, uint32, int64, uint64, short, ushort, byte, sbyte) to
-- // one of the internal compiler literals: Int/UInt/Long/ULong Literals.
-- //
-- public Constant WidenToCompilerConstant ()
++
++ public override void Error_ValueCannotBeConverted (Location loc, Type t)
{
-- Type t = TypeManager.EnumToUnderlying (Child.Type);
-- object v = ((Constant) Child).GetValue ();;
--
-- if (t == TypeManager.int32_type)
-- return new IntConstant ((int) v);
-- if (t == TypeManager.uint32_type)
-- return new UIntConstant ((uint) v);
-- if (t == TypeManager.int64_type)
-- return new LongConstant ((long) v);
-- if (t == TypeManager.uint64_type)
-- return new ULongConstant ((ulong) v);
-- if (t == TypeManager.short_type)
-- return new ShortConstant ((short) v);
-- if (t == TypeManager.ushort_type)
-- return new UShortConstant ((ushort) v);
-- if (t == TypeManager.byte_type)
-- return new ByteConstant ((byte) v);
-- if (t == TypeManager.sbyte_type)
-- return new SByteConstant ((sbyte) v);
--
-- throw new Exception ("Invalid enumeration underlying type: " + t);
++ Convert.Error_CannotImplicitConversion (loc, Type, t);
}
-- //
-- // Extracts the value in the enumeration on its native representation
-- //
-- public object GetPlainValue ()
-- {
-- Type t = TypeManager.EnumToUnderlying (Child.Type);
-- object v = ((Constant) Child).GetValue ();;
--
-- if (t == TypeManager.int32_type)
-- return (int) v;
-- if (t == TypeManager.uint32_type)
-- return (uint) v;
-- if (t == TypeManager.int64_type)
-- return (long) v;
-- if (t == TypeManager.uint64_type)
-- return (ulong) v;
-- if (t == TypeManager.short_type)
-- return (short) v;
-- if (t == TypeManager.ushort_type)
-- return (ushort) v;
-- if (t == TypeManager.byte_type)
-- return (byte) v;
-- if (t == TypeManager.sbyte_type)
-- return (sbyte) v;
--
-- return null;
-- }
--
public override string AsString ()
{
return Child.AsString ();
return Child.ConvertToInt ();
}
++ public override Constant Increment()
++ {
++ return new EnumConstant (Child.Increment (), type);
++ }
++
public override bool IsDefaultValue {
get {
return Child.IsDefaultValue;
return Child.IsNegative;
}
}
++
++ public override Constant ToType (Type type, Location loc)
++ {
++ if (Type == type) {
++ // This is workaround of mono bug. It can be removed when the latest corlib spreads enough
++ if (TypeManager.IsEnumType (type.UnderlyingSystemType))
++ return this;
++
++ if (type.UnderlyingSystemType != Child.Type)
++ Child = Child.ToType (type.UnderlyingSystemType, loc);
++ return this;
++ }
++
++ if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, this, type)){
++ Error_ValueCannotBeConverted (loc, type);
++ return null;
++ }
++
++ return Child.ToType (type, loc);
++ }
++
}
/// <summary>
public override Expression ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
SimpleName original)
{
-- bool left_is_type = left is TypeExpr;
++ if (FieldInfo.IsLiteral) {
++ IConstant ic = TypeManager.GetConstant (FieldInfo);
++ if (ic == null) {
++ ic = new ExternalConstant (FieldInfo);
++ TypeManager.RegisterConstant (FieldInfo, ic);
++ }
-- Type decl_type = FieldInfo.DeclaringType;
--
-- bool is_emitted = FieldInfo is FieldBuilder;
-- Type t = FieldInfo.FieldType;
--
-- if (is_emitted) {
-- Const c = TypeManager.LookupConstant ((FieldBuilder) FieldInfo);
--
-- if (c != null) {
-- object o;
-- if (!c.LookupConstantValue (out o))
-- return null;
++ bool left_is_type = left is TypeExpr;
++ if (!left_is_type && (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
++ Report.SymbolRelatedToPreviousError (FieldInfo);
++ error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
++ return null;
++ }
-- c.SetMemberIsUsed ();
-- object real_value = ((Constant) c.Expr).GetValue ();
++ if (ic.ResolveValue ())
++ ic.CheckObsoleteness (loc);
-- Expression exp = Constantify (real_value, t);
--
-- if (!left_is_type &&
-- (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
-- Report.SymbolRelatedToPreviousError (c);
-- error176 (loc, c.GetSignatureForError ());
-- return null;
-- }
--
-- return exp;
-- }
++ return ic.Value;
}
++ bool is_emitted = FieldInfo is FieldBuilder;
++ Type t = FieldInfo.FieldType;
++
//
// Decimal constants cannot be encoded in the constant blob, and thus are marked
// as IsInitOnly ('readonly' in C# parlance). We get its value from the
// DecimalConstantAttribute metadata.
//
++ //TODO: incorporare in GetContant otherwise we miss all error checks + obsoleteness check
if (FieldInfo.IsInitOnly && !is_emitted && t == TypeManager.decimal_type) {
object[] attrs = FieldInfo.GetCustomAttributes (TypeManager.decimal_constant_attribute_type, false);
if (attrs.Length == 1)
return new DecimalConstant (((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value);
}
-- if (FieldInfo.IsLiteral) {
-- object o;
--
-- if (is_emitted)
-- o = TypeManager.GetValue ((FieldBuilder) FieldInfo);
-- else
-- o = FieldInfo.GetValue (FieldInfo);
--
-- if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
-- if (!left_is_type &&
-- (original == null || !original.IdenticalNameAndTypeName (ec, left, loc))) {
-- error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
-- return null;
-- }
--
-- Expression enum_member = MemberLookup (
-- ec, decl_type, "value__", MemberTypes.Field,
-- AllBindingFlags | BindingFlags.NonPublic, loc);
--
-- Enum en = TypeManager.LookupEnum (decl_type);
--
-- Constant c;
-- if (en != null)
-- c = Constantify (o, en.UnderlyingType);
-- else
-- c = Constantify (o, enum_member.Type);
--
-- return new EnumConstant (c, decl_type);
-- }
--
-- Expression exp = Constantify (o, t);
--
-- if (!left_is_type) {
-- error176 (loc, TypeManager.GetFullNameSignature (FieldInfo));
-- return null;
-- }
--
-- return exp;
-- }
--
if (t.IsPointer && !ec.InUnsafe) {
UnsafeError (loc);
return null;
ObsoleteAttribute oa;
FieldBase f = TypeManager.GetField (FieldInfo);
if (f != null) {
-- oa = f.GetObsoleteAttribute (f.Parent);
-- if (oa != null)
-- AttributeTester.Report_ObsoleteMessage (oa, f.GetSignatureForError (), loc);
++ f.CheckObsoleteness (loc);
// To be sure that type is external because we do not register generated fields
} else if (!(FieldInfo.DeclaringType is TypeBuilder)) {
namespace Mono.CSharp {
-- class EnumMember: MemberCore {
++ public class EnumMember: MemberCore, IConstant {
static string[] attribute_targets = new string [] { "field" };
-- Enum parent_enum;
public FieldBuilder builder;
-- internal readonly Expression Type;
-- public EnumMember (Enum parent_enum, Expression expr, string name, Location loc,
-- Attributes attrs):
-- base (null, new MemberName (name, loc), attrs)
++ readonly Enum parent_enum;
++ readonly Expression ValueExpr;
++ readonly EnumMember prev_member;
++
++ Constant value;
++ bool in_transit;
++
++ public EnumMember (Enum parent_enum, EnumMember prev_member, Expression expr,
++ MemberName name, Attributes attrs):
++ base (parent_enum.Parent, name, attrs)
{
this.parent_enum = parent_enum;
this.ModFlags = parent_enum.ModFlags;
-- this.Type = expr;
++ this.ValueExpr = expr;
++ this.prev_member = prev_member;
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
}
}
-- public void DefineMember (TypeBuilder tb)
++ bool IsValidEnumType (Type t)
++ {
++ return (t == TypeManager.int32_type || t == TypeManager.uint32_type || t == TypeManager.int64_type ||
++ t == TypeManager.byte_type || t == TypeManager.sbyte_type || t == TypeManager.short_type ||
++ t == TypeManager.ushort_type || t == TypeManager.uint64_type || t == TypeManager.char_type ||
++ t.IsEnum);
++ }
++
++ public override bool Define ()
{
-- FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
-- | FieldAttributes.Literal;
--
++ const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
++ TypeBuilder tb = parent_enum.TypeBuilder;
builder = tb.DefineField (Name, tb, attr);
++
++ TypeManager.RegisterConstant (builder, this);
++ return true;
}
-- public override bool Define ()
++ public bool ResolveValue ()
{
-- throw new NotImplementedException ();
++ if (value != null)
++ return true;
++
++ if (in_transit) {
++ // suppress cyclic errors
++ value = new EnumConstant (New.Constantify (parent_enum.UnderlyingType), parent_enum.TypeBuilder);
++ Const.Error_CyclicDeclaration (this);
++ return false;
++ }
++
++ if (ValueExpr != null) {
++ in_transit = true;
++
++ Constant c = ValueExpr.ResolveAsConstant (parent_enum.EmitContext, this);
++ if (c == null)
++ return false;
++
++ if (c is EnumConstant)
++ c = ((EnumConstant)c).Child;
++
++ c = c.ToType (parent_enum.UnderlyingType, Location);
++ if (c == null)
++ return false;
++
++ if (!IsValidEnumType (c.Type)) {
++ Report.Error (1008, Location, "Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
++ return false;
++ }
++
++ in_transit = false;
++ value = new EnumConstant (c, parent_enum.TypeBuilder);
++ return true;
++ }
++
++ if (prev_member == null) {
++ value = new EnumConstant (New.Constantify (parent_enum.UnderlyingType), parent_enum.TypeBuilder);
++ return true;
++ }
++
++ if (!prev_member.ResolveValue ())
++ return false;
++
++ in_transit = true;
++
++ try {
++ value = prev_member.value.Increment ();
++ }
++ catch (OverflowException) {
++ Report.Error (543, Location, "The enumerator value `{0}' is too large to fit in its type `{1}'",
++ GetSignatureForError (), TypeManager.CSharpName (parent_enum.UnderlyingType));
++ return false;
++ }
++ in_transit = false;
++
++ return true;
}
public void Emit (EmitContext ec)
if (OptAttributes != null)
OptAttributes.Emit (ec, this);
++ if (ResolveValue ())
++ builder.SetConstant (value.GetValue ());
++
Emit ();
}
public override string DocCommentHeader {
get { return "F:"; }
}
++
++ #region IConstant Members
++
++ public Constant Value {
++ get {
++ return value;
++ }
++ }
++
++ #endregion
}
/// <summary>
/// Enumeration container
/// </summary>
public class Enum : DeclSpace {
-- public ArrayList ordered_enums;
--
-- public Expression BaseType;
--
++ Expression BaseType;
public Type UnderlyingType;
-- Hashtable member_to_location;
--
-- //
-- // This is for members that have been defined
-- //
-- Hashtable member_to_value;
--
-- //
-- // This is used to mark members we're currently defining
-- //
-- Hashtable in_transit;
--
-- ArrayList field_builders;
++ static MemberList no_list = new MemberList (new object[0]);
public const int AllowedModifiers =
Modifiers.NEW |
this.BaseType = type;
ModFlags = Modifiers.Check (AllowedModifiers, mod_flags,
IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, name.Location);
--
-- ordered_enums = new ArrayList ();
-- member_to_location = new Hashtable ();
-- member_to_value = new Hashtable ();
-- in_transit = new Hashtable ();
-- field_builders = new ArrayList ();
}
-- /// <summary>
-- /// Adds @name to the enumeration space, with @expr
-- /// being its definition.
-- /// </summary>
-- public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs, string documentation)
++ public void AddEnumMember (EnumMember em)
{
-- if (name == "value__") {
-- Report.Error (76, loc, "An item in an enumeration cannot have an identifier `value__'");
++ if (em.Name == "value__") {
++ Report.Error (76, em.Location, "An item in an enumeration cannot have an identifier `value__'");
return;
}
-- EnumMember em = new EnumMember (this, expr, name, loc, opt_attrs);
-- em.DocComment = documentation;
-- if (!AddToContainer (em, name))
++ if (!AddToContainer (em, em.Name))
return;
--
--
-- // TODO: can be almost deleted
-- ordered_enums.Add (name);
-- member_to_location.Add (name, loc);
}
public override TypeBuilder DefineType ()
TypeManager.AddUserType (Name, this);
-- return TypeBuilder;
-- }
--
-- bool IsValidEnumConstant (Expression e)
-- {
-- if (!(e is Constant))
-- return false;
--
-- if (e is IntConstant || e is UIntConstant || e is LongConstant ||
-- e is ByteConstant || e is SByteConstant || e is ShortConstant ||
-- e is UShortConstant || e is ULongConstant || e is EnumConstant ||
-- e is CharConstant)
-- return true;
-- else
-- return false;
-- }
--
-- object GetNextDefaultValue (object default_value)
-- {
-- if (UnderlyingType == TypeManager.int32_type) {
-- int i = (int) default_value;
--
-- if (i < System.Int32.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.uint32_type) {
-- uint i = (uint) default_value;
--
-- if (i < System.UInt32.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.int64_type) {
-- long i = (long) default_value;
--
-- if (i < System.Int64.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.uint64_type) {
-- ulong i = (ulong) default_value;
--
-- if (i < System.UInt64.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.short_type) {
-- short i = (short) default_value;
--
-- if (i < System.Int16.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.ushort_type) {
-- ushort i = (ushort) default_value;
--
-- if (i < System.UInt16.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.byte_type) {
-- byte i = (byte) default_value;
--
-- if (i < System.Byte.MaxValue)
-- return ++i;
-- else
-- return null;
-- } else if (UnderlyingType == TypeManager.sbyte_type) {
-- sbyte i = (sbyte) default_value;
--
-- if (i < System.SByte.MaxValue)
-- return ++i;
-- else
-- return null;
-- }
--
-- return null;
-- }
--
-- /// <summary>
-- /// Determines if a standard implicit conversion exists from
-- /// expr_type to target_type
-- /// </summary>
-- public static bool ImplicitConversionExists (Type expr_type, Type target_type)
-- {
-- expr_type = TypeManager.TypeToCoreType (expr_type);
--
-- if (expr_type == TypeManager.void_type)
-- return false;
--
-- if (expr_type == target_type)
-- return true;
--
-- // First numeric conversions
--
-- if (expr_type == TypeManager.sbyte_type){
-- //
-- // From sbyte to short, int, long, float, double.
-- //
-- if ((target_type == TypeManager.int32_type) ||
-- (target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.short_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.byte_type){
-- //
-- // From byte to short, ushort, int, uint, long, ulong, float, double
-- //
-- if ((target_type == TypeManager.short_type) ||
-- (target_type == TypeManager.ushort_type) ||
-- (target_type == TypeManager.int32_type) ||
-- (target_type == TypeManager.uint32_type) ||
-- (target_type == TypeManager.uint64_type) ||
-- (target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.short_type){
-- //
-- // From short to int, long, float, double
-- //
-- if ((target_type == TypeManager.int32_type) ||
-- (target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.ushort_type){
-- //
-- // From ushort to int, uint, long, ulong, float, double
-- //
-- if ((target_type == TypeManager.uint32_type) ||
-- (target_type == TypeManager.uint64_type) ||
-- (target_type == TypeManager.int32_type) ||
-- (target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.int32_type){
-- //
-- // From int to long, float, double
-- //
-- if ((target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.uint32_type){
-- //
-- // From uint to long, ulong, float, double
-- //
-- if ((target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.uint64_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if ((expr_type == TypeManager.uint64_type) ||
-- (expr_type == TypeManager.int64_type)) {
-- //
-- // From long/ulong to float, double
-- //
-- if ((target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.char_type){
-- //
-- // From char to ushort, int, uint, long, ulong, float, double
-- //
-- if ((target_type == TypeManager.ushort_type) ||
-- (target_type == TypeManager.int32_type) ||
-- (target_type == TypeManager.uint32_type) ||
-- (target_type == TypeManager.uint64_type) ||
-- (target_type == TypeManager.int64_type) ||
-- (target_type == TypeManager.float_type) ||
-- (target_type == TypeManager.double_type) ||
-- (target_type == TypeManager.decimal_type))
-- return true;
--
-- } else if (expr_type == TypeManager.float_type){
-- //
-- // float to double
-- //
-- if (target_type == TypeManager.double_type)
-- return true;
-- }
--
-- return false;
-- }
--
-- /// <summary>
-- /// This is used to lookup the value of an enum member. If the member is undefined,
-- /// it attempts to define it and return its value
-- /// </summary>
-- public object LookupEnumValue (string name, Location loc)
-- {
-- if (ec == null)
-- Report.Error (-1, loc, "Enum.LookupEnumValue () called too soon");
--
-- object default_value = null;
-- Constant c = null;
--
-- default_value = member_to_value [name];
--
-- if (default_value != null)
-- return default_value;
--
-- //
-- // This may happen if we're calling a method in System.Enum, for instance
-- // Enum.IsDefined().
-- //
-- if (!defined_names.Contains (name))
-- return null;
--
-- if (in_transit.Contains (name)) {
-- Report.Error (110, loc, "The evaluation of the constant value for `" +
-- Name + "." + name + "' involves a circular definition.");
-- return null;
-- }
--
-- //
-- // So if the above doesn't happen, we have a member that is undefined
-- // We now proceed to define it
-- //
-- Expression val = this [name];
--
-- if (val == null) {
--
-- int idx = ordered_enums.IndexOf (name);
--
-- if (idx == 0)
-- default_value = 0;
-- else {
-- for (int i = 0; i < idx; ++i) {
-- string n = (string) ordered_enums [i];
-- Location m_loc = (Mono.CSharp.Location)
-- member_to_location [n];
-- in_transit.Add (name, true);
-- default_value = LookupEnumValue (n, m_loc);
-- in_transit.Remove (name);
-- if (default_value == null)
-- return null;
-- }
--
-- default_value = GetNextDefaultValue (default_value);
-- }
--
-- } else {
-- in_transit.Add (name, true);
-- val = val.Resolve (EmitContext);
-- in_transit.Remove (name);
--
-- if (val == null)
-- return null;
--
-- if (!IsValidEnumConstant (val)) {
-- Report.Error (1008, loc,
-- "Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
-- return null;
-- }
--
-- c = (Constant) val;
-- default_value = c.GetValue ();
--
-- if (default_value == null) {
-- c.Error_ConstantValueCannotBeConverted (loc, UnderlyingType);
++ foreach (EnumMember em in defined_names.Values) {
++ if (!em.Define ())
return null;
-- }
--
-- if (val is EnumConstant){
-- Type etype = TypeManager.EnumToUnderlying (c.Type);
--
-- if (!ImplicitConversionExists (etype, UnderlyingType)){
-- Convert.Error_CannotImplicitConversion (
-- loc, c.Type, UnderlyingType);
-- return null;
-- }
-- }
}
-- EnumMember em = (EnumMember) defined_names [name];
-- em.DefineMember (TypeBuilder);
--
-- bool fail;
-- default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail);
-- if (fail){
-- c.Error_ConstantValueCannotBeConverted (loc, UnderlyingType);
-- return null;
-- }
--
-- em.builder.SetConstant (default_value);
-- field_builders.Add (em.builder);
-- member_to_value [name] = default_value;
--
-- if (!TypeManager.RegisterFieldValue (em.builder, default_value))
-- return null;
--
-- return default_value;
++ return TypeBuilder;
}
public override bool Define ()
{
-- //
-- // If there was an error during DefineEnum, return
-- //
-- if (TypeBuilder == null)
-- return false;
--
-- if (ec == null)
-- throw new InternalErrorException ("Enum.Define () called too soon");
--
-- object default_value = 0;
--
--
-- foreach (string name in ordered_enums) {
-- //
-- // Have we already been defined, thanks to some cross-referencing ?
-- //
-- if (member_to_value.Contains (name))
-- continue;
--
-- Location loc = (Mono.CSharp.Location) member_to_location [name];
--
-- if (this [name] != null) {
-- default_value = LookupEnumValue (name, loc);
--
-- if (default_value == null)
-- return true;
-- } else {
-- EnumMember em = (EnumMember) defined_names [name];
--
-- em.DefineMember (TypeBuilder);
-- FieldBuilder fb = em.builder;
--
-- if (default_value == null) {
-- Report.Error (543, loc, "The enumerator value `{0}.{1}' is too large to fit in its type `{2}'",
-- GetSignatureForError (), name, TypeManager.CSharpName (this.UnderlyingType));
-- return false;
-- }
--
-- bool fail;
-- default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail);
-- if (fail){
-- //TODO: really interested if can be reached
-- throw new NotImplementedException ();
-- }
--
-- fb.SetConstant (default_value);
-- field_builders.Add (fb);
-- member_to_value [name] = default_value;
--
-- if (!TypeManager.RegisterFieldValue (fb, default_value))
-- return false;
-- }
--
-- default_value = GetNextDefaultValue (default_value);
-- }
--
return true;
}
base.Emit ();
}
--
++
++ //
++ // IMemberFinder
++ //
++ public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
++ MemberFilter filter, object criteria)
++ {
++ if ((mt & MemberTypes.Field) == 0)
++ return no_list;
++
++ EnumMember em = defined_names [criteria] as EnumMember;
++ if (em == null)
++ return no_list;
++
++ FieldBuilder[] fb = new FieldBuilder[] { em.builder };
++ return new MemberList (fb);
++ }
++
void VerifyClsName ()
{
HybridDictionary dict = new HybridDictionary (defined_names.Count, true);
return true;
}
--
-- //
-- // IMemberFinder
-- //
-- public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
-- MemberFilter filter, object criteria)
-- {
-- ArrayList members = new ArrayList ();
--
-- if ((mt & MemberTypes.Field) != 0) {
-- if (criteria is string && member_to_value [criteria] == null) {
-- LookupEnumValue ((string) criteria, Location.Null);
-- }
--
-- foreach (FieldBuilder fb in field_builders)
-- if (filter (fb, criteria) == true)
-- members.Add (fb);
-- }
--
-- return new MemberList (members);
-- }
++
public override MemberCache MemberCache {
get {
}
}
-- public ArrayList ValueNames {
-- get {
-- return ordered_enums;
-- }
-- }
--
-- // indexer
-- public Expression this [string name] {
-- get {
-- return ((EnumMember) defined_names [name]).Type;
-- }
-- }
--
public override AttributeTargets AttributeTargets {
get {
return AttributeTargets.Enum;
}
}
--
protected override void VerifyObsoleteAttribute()
{
// UnderlyingType is never obsolete
//
internal override void GenerateDocComment (DeclSpace ds)
{
-- DocUtil.GenerateEnumDocComment (this, ds);
++ base.GenerateDocComment (ds);
++
++ foreach (EnumMember em in defined_names.Values) {
++ em.GenerateDocComment (this);
++ }
}
//
return true;
}
++ // TODO: move to constant
/// <summary>
/// Attempts to do a compile-time folding of a constant cast.
/// </summary>
Expression TryReduce (EmitContext ec, Type target_type)
{
++ if (expr.Type == target_type)
++ return expr;
++
++ if (TypeManager.IsEnumType (target_type))
++ return new EnumConstant ((Constant)expr, target_type);
++
Expression real_expr = expr;
if (real_expr is EnumConstant)
real_expr = ((EnumConstant) real_expr).Child;
}
if (rc != null && lc != null){
++ int prev_e = Report.Errors;
Expression e = ConstantFold.BinaryFold (
ec, oper, lc, rc, loc);
-- if (e != null)
++ if (e != null || Report.Errors != prev_e)
return e;
}
}
/// <summary>
-- /// Determines "better conversion" as specified in 7.4.2.3
++ /// Determines "better conversion" as specified in 14.4.2.3
///
/// Returns : p if a->p is better,
/// q if a->q is better,
/// <summary>
/// Converts complex core type syntax like 'new int ()' to simple constant
/// </summary>
-- Expression Constantify (Type t)
++ public static Constant Constantify (Type t)
{
if (t == TypeManager.int32_type)
return new IntConstant (0);
/// Implements the member access expression
/// </summary>
public class MemberAccess : Expression {
-- public readonly string Identifier;
++ public readonly string Identifier; // TODO: LocatedToken
Expression expr;
public MemberAccess (Expression expr, string id, Location l)
get { return expr; }
}
++ // TODO: this method has very poor performace for Enum fields and
++ // probably for other constants as well
Expression DoResolve (EmitContext ec, Expression right_side)
{
if (type != null)
return retval;
}
-- //
-- // TODO: I mailed Ravi about this, and apparently we can get rid
-- // of this and put it in the right place.
-- //
-- // Handle enums here when they are in transit.
-- // Note that we cannot afford to hit MemberLookup in this case because
-- // it will fail to find any members at all
-- //
--
Type expr_type = new_expr.Type;
-- if (new_expr is TypeExpr){
-- if (!ec.DeclSpace.CheckAccessLevel (expr_type)){
-- ErrorIsInaccesible (loc, TypeManager.CSharpName (expr_type));
-- return null;
-- }
--
-- if (expr_type == TypeManager.enum_type || expr_type.IsSubclassOf (TypeManager.enum_type)){
-- Enum en = TypeManager.LookupEnum (expr_type);
--
-- if (en != null) {
-- object value = en.LookupEnumValue (Identifier, loc);
-- if (value != null){
-- MemberCore mc = en.GetDefinition (Identifier);
-- ObsoleteAttribute oa = mc.GetObsoleteAttribute (en);
-- if (oa != null) {
-- AttributeTester.Report_ObsoleteMessage (oa, mc.GetSignatureForError (), Location);
-- }
-- oa = en.GetObsoleteAttribute (en);
-- if (oa != null) {
-- AttributeTester.Report_ObsoleteMessage (oa, en.GetSignatureForError (), Location);
-- }
--
-- Constant c = Constantify (value, en.UnderlyingType);
-- return new EnumConstant (c, expr_type);
-- }
-- } else {
-- CheckObsoleteAttribute (expr_type);
--
-- FieldInfo fi = expr_type.GetField (Identifier);
-- if (fi != null) {
-- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (fi);
-- if (oa != null)
-- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (fi), Location);
-- }
-- }
-- }
-- }
--
if (expr_type.IsPointer){
Error (23, "The `.' operator can not be applied to pointer operands (" +
TypeManager.CSharpName (expr_type) + ")");
ec.ig.Emit (OpCodes.Ldnull);
}
++ public override Constant Increment ()
++ {
++ throw new NotSupportedException ();
++ }
++
public override bool IsDefaultValue {
get {
return true;
return "null";
}
-- public override void Error_ConstantValueCannotBeConverted (Location loc, Type t)
++ public override void Error_ValueCannotBeConverted (Location loc, Type t)
{
Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
TypeManager.CSharpName (t));
}
++
++ public override Constant ToType (Type type, Location loc)
++ {
++ if (!type.IsValueType && !TypeManager.IsEnumType (type))
++ return NullLiteral.Null;
++
++ return base.ToType (type, loc);
++ }
++
}
//
if (expr == null)
return false;
-- if (!(expr is Constant)){
++ Constant c = expr as Constant;
++ if (c == null) {
Error (150, "A constant value is expected");
return false;
}
-- object val = Expression.ConvertIntLiteral (
-- (Constant) expr, ec.Switch.SwitchType, loc);
++ c = c.ToType (ec.Switch.SwitchType, loc);
++ if (c == null)
++ return false;
++ object val = c.GetValue ();
if (val == null)
-- return false;
++ val = c;
sl = (SwitchLabel) ec.Switch.Elements [val];
if (sl == null){
-- Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", val);
++ Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val);
return false;
}
continue;
}
-- if (e.Type != variable_type){
-- e = Const.ChangeType (vi.Location, ce, variable_type);
-- if (e == null)
-- continue;
-- }
++ e = ce.ToType (variable_type, vi.Location);
++ if (e == null)
++ continue;
constants.Remove (name);
constants.Add (name, e);
return false;
}
-- if (required_type == TypeManager.string_type) {
-- if (c.Type == TypeManager.string_type) {
-- converted = c.GetValue ();
-- return true;
-- }
--
-- if (e is NullLiteral) {
-- converted = e;
-- return true;
-- }
++ if (required_type == TypeManager.string_type && e is NullLiteral) {
++ converted = e;
++ return true;
}
-- converted = Expression.ConvertIntLiteral (c, required_type, loc);
-- return converted != null;
++ c = c.ToType (required_type, loc);
++ if (c == null)
++ return false;
++
++ converted = c.GetValue ();
++ return true;
}
public void Erorr_AlreadyOccurs ()
builder_to_method = null;
fields = null;
-- builder_to_constant = null;
fieldbuilders_to_fields = null;
events = null;
priv_fields_events = null;
return builder_to_declspace [t] as Delegate;
}
-- public static Enum LookupEnum (Type t)
-- {
-- return builder_to_declspace [t] as Enum;
-- }
--
public static Class LookupClass (Type t)
{
return (Class) builder_to_declspace [t];
public static bool IsEnumType (Type t)
{
-- if (t.IsSubclassOf (TypeManager.enum_type))
++ if (builder_to_declspace [t] is Enum)
return true;
-- else
-- return false;
++
++ return t.IsEnum;
}
++
public static bool IsBuiltinOrEnum (Type t)
{
if (IsBuiltinType (t))
{
return t.IsArray || t.IsPointer || t.IsByRef;
}
--
-- static Hashtable builder_to_constant;
--
-- public static void RegisterConstant (FieldBuilder fb, Const c)
-- {
-- if (builder_to_constant == null)
-- builder_to_constant = new PtrHashtable ();
--
-- if (builder_to_constant.Contains (fb))
-- return;
--
-- builder_to_constant.Add (fb, c);
-- }
--
-- public static Const LookupConstant (FieldBuilder fb)
-- {
-- if (builder_to_constant == null)
-- return null;
--
-- return (Const) builder_to_constant [fb];
-- }
/// <summary>
/// Gigantic work around for missing features in System.Reflection.Emit follows.
}
}
-- // <remarks>
-- // This is a workaround the fact that GetValue is not
-- // supported for dynamic types
-- // </remarks>
-- static public bool RegisterFieldValue (FieldBuilder fb, object value)
++ public static void RegisterConstant (FieldInfo fb, IConstant ic)
{
-- if (fields.Contains (fb))
-- return false;
--
-- fields.Add (fb, value);
--
-- return true;
++ fields.Add (fb, ic);
}
-- static public object GetValue (FieldBuilder fb)
++ public static IConstant GetConstant (FieldInfo fb)
{
-- return fields [fb];
++ if (fb == null)
++ return null;
++
++ return (IConstant)fields [fb];
}
static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
endif
run-test-local: ilasm
-- MONO_RUNTIME='$(RUNTIME)' $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/compiler-tester.exe positive $(TEST_PATTERN) $(COMPILER) known-issues-$(COMPILER_NAME) $(COMPILER_NAME).log
++ MONO_RUNTIME='mono' $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/compiler-tester.exe positive $(TEST_PATTERN) $(COMPILER) known-issues-$(COMPILER_NAME) $(COMPILER_NAME).log
# do nothing for this target
run-test-ondotnet-local:
test-434.cs
test-435.cs
test-436.cs
++test-437.cs
++
test-50.cs IGNORE # Windows-only test
test-67.cs IGNORE # Windows-only test
test-anon-27.cs
test-50.cs IGNORE # Windows-only tests
test-67.cs IGNORE # Windows-only test
--test-308.cs
++test-49.cs IGNORE
++
test-377.cs
test-anon-27.cs
test-xml-027.cs
--- /dev/null
--- /dev/null
++using System;
++using System.Runtime.InteropServices;
++
++class T2
++{
++ public enum E2: sbyte
++ {
++ A = Test.E.d,
++ B = Test.E.a,
++ C = Test.Constant
++ }
++
++}
++
++class Test
++{
++ public const UnmanagedType UnmanagedType_80 = (UnmanagedType) 80;
++ public const sbyte Constant = (sbyte)T2.E2.A;
++
++ public enum E: sbyte
++ {
++ a = -3,
++ b = d,
++ c = T2.E2.B,
++ d,
++ e,
++ f = -Constant,
++ g = checked (3 * 4),
++ h = unchecked ((sbyte)(250 + 10))
++ }
++
++ public static void Main ()
++ {
++ Console.WriteLine (E.d.ToString ());
++ Console.WriteLine (Constant.ToString ());
++ object o = E.a;
++ Console.WriteLine (E.a);
++ Console.WriteLine (System.Reflection.BindingFlags.NonPublic);
++ }
++}
return 5;
case null:
return 9;
++ case "new":
++ goto case null;
default:
return 6;
}
return 20;
case TestEnum.c:
-- return 30;
++ goto case TestEnum.b;
default:
return 40;
return 1;
if (testSwitchEnumLong (TestEnum.b) != 20)
return 2;
-- if (testSwitchEnumLong (TestEnum.c) != 30)
++ if (testSwitchEnumLong (TestEnum.c) != 20)
return 3;
if (testSwitchEnumLong ((TestEnum)5) != 40)
return 4;
return 10;
if (tests ("blah") != 6)
return 11;
++ if (tests ("new") != 9)
++ return 110;
++
if (testn ("one") != 1)
return 12;