//
// Author:
// Miguel de Icaza (miguel@ximian.com)
-// Marek Safar (marek.safar@seznam.cz)
+// Marek Safar (marek.safar@gmail.com)
//
// Copyright 2001-2003 Ximian, Inc.
// Copyright 2003-2008 Novell, Inc.
+// Copyright 2011-2013 Xamarin Inc
//
using System;
}
#endif
- public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+ public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
if (!expl && IsLiteral &&
BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
- GetValueAsLiteral (), TypeManager.CSharpName (target));
+ GetValueAsLiteral (), target.GetSignatureForError ());
} else {
- base.Error_ValueCannotBeConverted (ec, loc, target, expl);
+ base.Error_ValueCannotBeConverted (ec, target, expl);
}
}
{
Constant c = ConvertImplicitly (type);
if (c == null)
- Error_ValueCannotBeConverted (ec, loc, type, false);
+ Error_ValueCannotBeConverted (ec, type, false);
return c;
}
+ public override bool ContainsEmitWithAwait ()
+ {
+ return false;
+ }
+
public virtual Constant ConvertImplicitly (TypeSpec type)
{
if (this.type == type)
return this;
- if (Convert.ImplicitNumericConversion (this, type) == null)
+ if (!Convert.ImplicitNumericConversionExists (this.type, type))
return null;
bool fail;
// reached, by calling Convert.ImplicitStandardConversionExists
//
throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
- TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
+ Type.GetSignatureForError (), type.GetSignatureForError ());
}
- return CreateConstant (type, constant_value, loc);
+ return CreateConstantFromValue (type, constant_value, loc);
}
//
// Returns a constant instance based on Type
//
- public static Constant CreateConstant (TypeSpec t, object v, Location loc)
- {
- return CreateConstantFromValue (t, v, loc);
- }
-
public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
{
switch (t.BuiltinType) {
return new NullConstant (t, loc);
}
- throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
- v, TypeManager.CSharpName (t));
+#if STATIC
+ throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
+#else
+ return null;
+#endif
}
public override Expression CreateExpressionTree (ResolveContext ec)
return this;
}
- /// <summary>
- /// Attempts to do a compile-time folding of a constant cast.
- /// </summary>
- public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
+ //
+ // Attempts to do a compile-time folding of a constant cast and handles
+ // error reporting for constant overlows only, on normal conversion
+ // errors returns null
+ //
+ public Constant Reduce (ResolveContext ec, TypeSpec target_type)
{
try {
- return TryReduce (ec, target_type);
- }
- catch (OverflowException) {
+ return TryReduceConstant (ec, target_type);
+ } catch (OverflowException) {
if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
ec.Report.Error (221, loc,
"Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
GetValueAsLiteral (), target_type.GetSignatureForError ());
} else {
- Error_ValueCannotBeConverted (ec, loc, target_type, false);
+ Error_ValueCannotBeConverted (ec, target_type, false);
}
return New.Constantify (target_type, loc);
}
}
- Constant TryReduce (ResolveContext ec, TypeSpec target_type)
+ public Constant TryReduce (ResolveContext rc, TypeSpec targetType)
+ {
+ try {
+ return TryReduceConstant (rc, targetType);
+ } catch (OverflowException) {
+ return null;
+ }
+ }
+
+ Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
{
- if (Type == target_type)
+ if (Type == target_type) {
+ //
+ // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
+ //
+ if (IsLiteral)
+ return CreateConstantFromValue (target_type, GetValue (), loc);
+
return this;
+ }
Constant c;
- if (TypeManager.IsEnumType (target_type)) {
- c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
+ if (target_type.IsEnum) {
+ c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
if (c == null)
return null;
eclass = ExprClass.Value;
}
- public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+ public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
try {
ConvertExplicitly (true, target);
- base.Error_ValueCannotBeConverted (ec, loc, target, expl);
+ base.Error_ValueCannotBeConverted (ec, target, expl);
}
catch
{
ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
- GetValue ().ToString (), TypeManager.CSharpName (target));
+ GetValue ().ToString (), target.GetSignatureForError ());
}
}