* expression.cs (CheckedExpr, UnCheckedExpr): If we have a
constant inside, return it.
+2002-09-12 Martin Baulig <martin@gnome.org>
+
+ * cfold.cs (ConstantFold.DoConstantNumericPromotions): Check whether an
+ implicit conversion can be done between enum types.
+
+ * enum.cs (Enum.LookupEnumValue): If the value is an EnumConstant,
+ check whether an implicit conversion to the current enum's UnderlyingType
+ exists and report an error if not.
+
+ * codegen.cs (CodeGen.Init): Delete the symbol file when compiling
+ without debugging support.
+
+ * delegate.cs (Delegate.CloseDelegate): Removed, use CloseType instead.
+ Fixes bug #30235. Thanks to Ricardo Fernández Pascual.
+
2002-09-12 Martin Baulig <martin@gnome.org>
* typemanager.cs (TypeManager.IsNestedChildOf): New method.
// (uint, uint)
// (int, int)
//
- static void DoConstantNumericPromotions (Binary.Operator oper,
+ static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
ref Constant left, ref Constant right,
Location loc)
{
}
return;
+ } else if (left is EnumConstant || right is EnumConstant){
+ //
+ // If either operand is an enum constant, the other one must
+ // be implicitly convertable to that enum's underlying type.
+ //
+ EnumConstant match;
+ Constant other;
+ if (left is EnumConstant){
+ other = right;
+ match = (EnumConstant) left;
+ } else {
+ other = left;
+ match = (EnumConstant) right;
+ }
+
+ bool need_check = (other is EnumConstant) ||
+ ((oper != Binary.Operator.Addition) &&
+ (oper != Binary.Operator.Subtraction));
+
+ if (need_check &&
+ !Expression.ImplicitConversionExists (ec, match, other.Type)) {
+ Expression.Error_CannotConvertImplicit (loc, match.Type, other.Type);
+ left = null;
+ right = null;
+ return;
+ }
+
+ if (left is EnumConstant)
+ left = ((EnumConstant) left).Child;
+ if (right is EnumConstant)
+ right = ((EnumConstant) right).Child;
+ return;
+
} else {
//
// Force conversions to int32
switch (oper){
case Binary.Operator.BitwiseOr:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.BitwiseAnd:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.ExclusiveOr:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
}
result = null;
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return result;
case Binary.Operator.Subtraction:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.Multiply:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.Division:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.Modulus:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
}
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
((StringConstant) right).Value);
}
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.LessThan:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.GreaterThan:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.GreaterThanOrEqual:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.LessThanOrEqual:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
if (Delegates != null)
foreach (Delegate d in Delegates)
- d.CloseDelegate ();
+ d.CloseType ();
}
public string MakeName (string n)
//
using System;
+using System.IO;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
//
// This routine initializes the Mono runtime SymbolWriter.
//
- static bool InitMonoSymbolWriter (string basename, string output_file,
- string[] debug_args)
+ static bool InitMonoSymbolWriter (string basename, string symbol_output,
+ string exe_output_file, string[] debug_args)
{
- string symbol_output = basename + ".dbg";
-
Type itype = SymbolWriter.GetType ();
if (itype == null)
return false;
return false;
object[] args = new object [3];
- args [0] = output_file;
+ args [0] = exe_output_file;
args [1] = symbol_output;
args [2] = debug_args;
//
// Initializes the symbol writer
//
- static void InitializeSymbolWriter (string basename, string output_file,
- string[] args)
+ static void InitializeSymbolWriter (string basename, string symbol_output,
+ string exe_output_file, string[] args)
{
SymbolWriter = ModuleBuilder.GetSymWriter ();
switch (sym_type.Name){
case "MonoSymbolWriter":
- if (!InitMonoSymbolWriter (basename, output_file, args))
+ if (!InitMonoSymbolWriter (basename, symbol_output,
+ exe_output_file, args))
Report.Error (
-18, "Cannot initialize the symbol writer");
break;
ModuleBuilder = AssemblyBuilder.DefineDynamicModule (
Basename (name), Basename (output), want_debugging_support);
- if (want_debugging_support) {
- int pos = output.LastIndexOf (".");
+ int pos = output.LastIndexOf (".");
- string basename;
- if (pos > 0)
- basename = output.Substring (0, pos);
- else
- basename = output;
+ string basename;
+ if (pos > 0)
+ basename = output.Substring (0, pos);
+ else
+ basename = output;
- InitializeSymbolWriter (basename, output, debug_args);
+ string symbol_output = basename + ".dbg";
+
+ if (want_debugging_support)
+ InitializeSymbolWriter (basename, symbol_output, output, debug_args);
+ else {
+ try {
+ File.Delete (symbol_output);
+ } catch {
+ // Ignore errors.
+ }
}
}
}\r
}\r
\r
- public void CloseDelegate ()\r
- {\r
- TypeBuilder.CreateType ();\r
- }\r
- \r
public Expression InstanceExpression {\r
get {\r
return instance_expr;\r
return false;
}
-
+
/// <summary>
/// Determines if a standard implicit conversion exists from
/// expr_type to target_type
if (!me.IsStatic && (me.InstanceExpression == null))
return e;
- Report.Debug (8, "RESOLVE", e, me, me.InstanceExpression, right_side);
-
if (!me.IsStatic &&
TypeManager.IsNestedChildOf (me.InstanceExpression.Type, me.DeclaringType)) {
Error (38, "Cannot access a nonstatic member of outer type `" +
return;
}
+ /// <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
val = val.Resolve (ec);
in_transit.Remove (name);
ec.InEnumContext = old;
-
+
if (val == null)
return null;
- if (IsValidEnumConstant (val)) {
- c = (Constant) val;
- default_value = c.GetValue ();
-
- if (default_value == null) {
- Error_ConstantValueCannotBeConverted (c, loc);
- return null;
- }
-
- } else {
+ if (!IsValidEnumConstant (val)) {
Report.Error (
1008, loc,
"Type byte, sbyte, short, ushort, int, uint, long, or " +
"ulong expected (have: " + val + ")");
return null;
}
+
+ c = (Constant) val;
+ default_value = c.GetValue ();
+
+ if (default_value == null) {
+ Error_ConstantValueCannotBeConverted (c, loc);
+ return null;
+ }
+
+ if ((val is EnumConstant) &&
+ !ImplicitConversionExists (default_value.GetType (), UnderlyingType)) {
+ Expression.Error_CannotConvertImplicit (
+ loc, default_value.GetType (), UnderlyingType);
+ return null;
+ }
}
FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
if (root.Delegates != null)
foreach (Delegate d in root.Delegates)
- d.CloseDelegate ();
+ d.CloseType ();
//