+2003-11-06 Miguel de Icaza <miguel@ximian.com>
+
+ * expression.cs (New.DoResolve): Do not dereference value that
+ might be a null return.
+
+ * statement.cs (Block.EmitMeta): Use the Const.ChangeType to make
+ sure that the constant value has the right type. Fixes an
+ unreported bug, similar to 50425.
+
+ * const.cs (Const.LookupConstantValue): Call
+ ImplicitStandardConversionExists before doing a conversion to
+ avoid havng the TypeManager.ChangeType do conversions.
+
+ Reduced the number of casts used
+
+ (Const.ChangeType): New routine to enable reuse of the constant
+ type changing code from statement.
+
+ * typemanager.cs (ChangeType): Move common initialization to
+ static global variables.
+
+ Fixes #50425.
+
+ * convert.cs (ImplicitReferenceConversion): Somehow we allowed
+ every value type to go through, even if it was void. Fix that.
+
+ * cs-tokenizer.cs: Use is_identifier_start_character on the start
+ character of the define, and the is_identifier_part_character for
+ the rest of the string.
+
+2003-11-05 Miguel de Icaza <miguel@ximian.com>
+
+ * expression.cs (UnaryMutator.EmitCode): When I updated
+ LocalVariableReference.DoResolve, I overdid it, and dropped an
+ optimization done on local variable references.
+
+2003-11-04 Miguel de Icaza <miguel@ximian.com>
+
+ * ecore.cs: Convert the return from Ldlen into an int.
+
+2003-10-20 Miguel de Icaza <miguel@ximian.com>
+
+ * decl.cs (DeclSpace.GetAccessLevel): Handle NotPublic case for
+ the accessibility, this is a special case for toplevel non-public
+ classes (internal for instance).
+
+2003-10-20 Nick Drochak <ndrochak@gol.com>
+
+ * ecore.cs: Fix typo and build. Needed another right paren.
+
+2003-10-19 Miguel de Icaza <miguel@ximian.com>
+
+ * ecore.cs: Applied fix from Ben Maurer. We were handling in the
+ `internal' case regular and protected, but not allowing protected
+ to be evaluated later. Bug 49840
+
+2003-10-15 Miguel de Icaza <miguel@ximian.com>
+
+ * statement.cs (Switch.TableSwitchEmit): Compare the upper bound
+ to kb.Nlast, and not the kb.nFirst to isolate the switch
+ statement.
+
+ Extract the underlying type, so enumerations of long/ulong are
+ treated like long/ulong.
+
+2003-10-14 Miguel de Icaza <miguel@ximian.com>
+
+ * expression.cs (New): Overload the meaning of RequestedType to
+ track the possible creation of the NewDelegate type, since
+ DoResolve is invoked more than once for new constructors on field
+ initialization.
+
+ See bugs: #48800 and #37014
+
+ * cs-parser.jay (declare_local_constants): Take an arraylist
+ instead of a single constant.
+
+ (local_constant_declaration): It should take a
+ constant_declarators, not a constant_declarator. Fixes 49487
+
+ * convert.cs: Fix error report.
+
+2003-10-13 Jackson Harper <jackson@ximian.com>
+
+ * typemanager.cs (TypeToCoreType): Add float and double this fixes
+ bug #49611
+
2003-11-03 Martin Baulig <martin@ximian.com>
* expression.cs (ArrayAccess.GetStoreOpcode): Added
$(MKINSTALLDIRS) $(DESTDIR)$(prefix)/bin
$(INSTALL_BIN) gmcs.exe $(DESTDIR)$(prefix)/bin
+uninstall-local:
+ -rm -f $(DESTDIR)$(prefix)/bin/mcs.exe
+
test-local run-test-local:
clean-local:
// Don't know what to do here\r
//\r
Report.Warning (\r
- -100, Location, "NullReferenceException while trying to create attribute." +\r
+ -101, Location, "NullReferenceException while trying to create attribute." +\r
"Something's wrong!");\r
} catch (Exception e) {\r
//\r
\r
try {\r
((TypeBuilder) builder).SetCustomAttribute (cb);\r
- } catch (System.ArgumentException) {\r
+ } catch (System.ArgumentException e) {\r
Report.Warning (\r
-21, loc,\r
"The CharSet named property on StructLayout\n"+\r
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)
+ {
+ bool fail;
+
+ // from the null type to any reference-type.
+ if (expr is NullLiteral && !type.IsValueType && !TypeManager.IsEnumType (type))
+ return NullLiteral.Null;
+
+ if (!Convert.ImplicitStandardConversionExists (expr, type)){
+ Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
+ return null;
+ }
+
+ 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));
+ }
+
+ 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
+ throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
+
+ return retval;
+ }
+
/// <summary>
/// Looks up the value of a constant field. Defines it if it hasn't
/// already been. Similar to LookupEnumValue in spirit.
return null;
}
- if (!(Expr is Constant)) {
+ Constant ce = Expr as Constant;
+ if (ce == null){
UnCheckedExpr un_expr = Expr as UnCheckedExpr;
CheckedExpr ch_expr = Expr as CheckedExpr;
}
}
- ConstantValue = ((Constant) Expr).GetValue ();
-
- if (type != Expr.Type) {
- bool fail;
-
- // from the null type to any reference-type.
- if (Expr is NullLiteral && !type.IsValueType &&
- !TypeManager.IsEnumType (type)){
- return NullLiteral.Null;
- }
-
- ConstantValue = TypeManager.ChangeType (ConstantValue, type, out fail);
- if (fail){
- Convert.Error_CannotImplicitConversion (Location, Expr.Type, type);
+ if (type != ce.Type) {
+ ce = ChangeType (Location, ce, type);
+ if (ce == null)
return null;
- }
-
- if (type == TypeManager.int32_type)
- Expr = new IntConstant ((int) ConstantValue);
- else if (type == TypeManager.uint32_type)
- Expr = new UIntConstant ((uint) ConstantValue);
- else if (type == TypeManager.int64_type)
- Expr = new LongConstant ((long) ConstantValue);
- else if (type == TypeManager.uint64_type)
- Expr = new ULongConstant ((ulong) ConstantValue);
- else if (type == TypeManager.float_type)
- Expr = new FloatConstant ((float) ConstantValue);
- else if (type == TypeManager.double_type)
- Expr = new DoubleConstant ((double) ConstantValue);
- else if (type == TypeManager.string_type)
- Expr = new StringConstant ((string) ConstantValue);
- else if (type == TypeManager.short_type)
- Expr = new ShortConstant ((short) ConstantValue);
- else if (type == TypeManager.ushort_type)
- Expr = new UShortConstant ((ushort) ConstantValue);
- else if (type == TypeManager.sbyte_type)
- Expr = new SByteConstant ((sbyte) ConstantValue);
- else if (type == TypeManager.byte_type)
- Expr = new ByteConstant ((byte) ConstantValue);
- else if (type == TypeManager.char_type)
- Expr = new CharConstant ((char) ConstantValue);
- else if (type == TypeManager.bool_type)
- Expr = new BoolConstant ((bool) ConstantValue);
+ Expr = ce;
}
+ ConstantValue = ce.GetValue ();
if (type.IsEnum){
//
expr.Emit (null);
}
+ if (expr_type == TypeManager.void_type)
+ return null;
+
//
// notice that it is possible to write "ValueType v = 1", the ValueType here
// is an abstract class, and not really a value type, so we apply the same rules.
if (ImplicitReferenceConversionExists (expr, target_type))
return true;
-
+
+ //
+ // Implicit Constant Expression Conversions
+ //
if (expr is IntConstant){
int value = ((IntConstant) expr).Value;
//
if (expr_type == TypeManager.object_type && target_type.IsValueType){
if (expr is NullLiteral){
- Report.Error (37, "Cannot convert null to value type `" +
- TypeManager.CSharpName (expr_type) + "'");
+ Report.Error (37, loc, "Cannot convert null to value type `" +
+ TypeManager.CSharpName (target_type) + "'");
return null;
}
return new UnboxCast (expr, target_type);
if ($1 != null){
DictionaryEntry de = (DictionaryEntry) $1;
- $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+ $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
}
}
;
;
local_constant_declaration
- : CONST local_variable_type constant_declarator
+ : CONST local_variable_type constant_declarators
{
if ($2 != null)
$$ = new DictionaryEntry ($2, $3);
return implicit_block;
}
-Block declare_local_constant (Expression type, VariableDeclaration decl)
+Block declare_local_constants (Expression type, ArrayList declarators)
{
Block implicit_block;
else
implicit_block = current_block;
- if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
- current_local_parameters, decl.Location))){
+ foreach (VariableDeclaration decl in declarators){
+ implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+ current_local_parameters, decl.Location);
}
return implicit_block;
return;\r
}\r
\r
- foreach (char c in arg){\r
- if (!Char.IsLetter (c) && (c != '_')){\r
- Report.Error (1001, Location, "Identifier expected");\r
+ if (!is_identifier_start_character (arg [0]))\r
+ Report.Error (1001, Location, "Identifier expected: " + arg);\r
+ \r
+ foreach (char c in arg.Substring (1)){\r
+ if (!is_identifier_part_character (c)){\r
+ Report.Error (1001, Location, "Identifier expected: " + arg);\r
return;\r
}\r
}\r
} catch {
Report.Error (
1900,
- "--wlevel requires an value from 0 to 4");
+ "--wlevel requires a value from 0 to 4");
Environment.Exit (1);
}
if (level < 0 || level > 4){
if ((i + 1) >= args.Length){
Report.Error (
1900,
- "--wlevel requires an value from 0 to 4");
+ "--wlevel requires a value from 0 to 4");
Environment.Exit (1);
}
// Assembly and FamORAssem succeed if we're in the same assembly.
if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
- if (mi.DeclaringType.Assembly != invocation_type.Assembly)
- continue;
- else
+ if (mi.DeclaringType.Assembly == invocation_type.Assembly)
return mi;
}
continue;
// Family and FamANDAssem require that we derive.
- if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem)){
+ if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
continue;
else {
if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)){
instance_expr.Emit (ec);
ec.ig.Emit (OpCodes.Ldlen);
+ ec.ig.Emit (OpCodes.Conv_I4);
return;
}
}
// For now: only localvariables when not remapped
//
- if (method == null && (expr is FieldExpr && ((FieldExpr) expr).FieldInfo.IsStatic)){
+ if (method == null &&
+ ((expr is LocalVariableReference) ||(expr is FieldExpr && ((FieldExpr) expr).FieldInfo.IsStatic))){
if (empty_expr == null)
empty_expr = new EmptyExpression ();
/// </summary>
public class New : ExpressionStatement, IMemoryLocation {
public readonly ArrayList Arguments;
- public readonly Expression RequestedType;
+
+ //
+ // During bootstrap, it contains the RequestedType,
+ // but if `type' is not null, it *might* contain a NewDelegate
+ // (because of field multi-initialization)
+ //
+ public Expression RequestedType;
MethodBase method = null;
//
// This leads to bugs (#37014)
//
- if (type != null)
+ if (type != null){
+ if (RequestedType is NewDelegate)
+ return RequestedType;
return this;
+ }
type = ec.DeclSpace.ResolveType (RequestedType, false, loc);
bool IsDelegate = TypeManager.IsDelegateType (type);
- if (IsDelegate)
- return (new NewDelegate (type, Arguments, loc)).Resolve (ec);
+ if (IsDelegate){
+ RequestedType = (new NewDelegate (type, Arguments, loc)).Resolve (ec);
+ if (RequestedType != null)
+ if (!(RequestedType is NewDelegate))
+ throw new Exception ("NewDelegate.Resolve returned a non NewDelegate: " + RequestedType.GetType ());
+ return RequestedType;
+ }
if (type.IsInterface || type.IsAbstract){
Error (144, "It is not possible to create instances of interfaces or abstract classes");
//
}
- static void Error_DuplicateParameterName (string name)
+ void Error_DuplicateParameterName (string name)
{
Report.Error (
- 100, "The parameter name `" + name + "' is a duplicate");
+ 100, loc, "The parameter name `" + name + "' is a duplicate");
}
public bool VerifyArgs ()
Report.Error (157, loc, "Control can not leave the body of the finally block");
return false;
}
-
+
if (ec.ReturnType == null){
if (Expr != null){
Report.Error (127, loc, "Return with a value not allowed here");
if (e == null)
continue;
- if (!(e is Constant)){
+ Constant ce = e as Constant;
+ if (ce == null){
Report.Error (133, vi.Location,
"The expression being assigned to `" +
name + "' must be constant (" + e + ")");
continue;
}
+ if (e.Type != variable_type){
+ e = Const.ChangeType (vi.Location, ce, variable_type);
+ if (e == null)
+ continue;
+ }
+
constants.Remove (name);
constants.Add (name, e);
}
if (rgKeys.Length > 0)
typeKeys = rgKeys [0].GetType (); // used for conversions
+ Type compare_type;
+
+ if (TypeManager.IsEnumType (SwitchType))
+ compare_type = TypeManager.EnumToUnderlying (SwitchType);
+ else
+ compare_type = SwitchType;
+
for (int iBlock = rgKeyBlocks.Count - 1; iBlock >= 0; --iBlock)
{
KeyBlock kb = ((KeyBlock) rgKeyBlocks [iBlock]);
{
// TODO: if all the keys in the block are the same and there are
// no gaps/defaults then just use a range-check.
- if (SwitchType == TypeManager.int64_type ||
- SwitchType == TypeManager.uint64_type)
+ if (compare_type == TypeManager.int64_type ||
+ compare_type == TypeManager.uint64_type)
{
// TODO: optimize constant/I4 cases
EmitObjectInteger (ig, System.Convert.ChangeType (kb.nFirst, typeKeys));
ig.Emit (OpCodes.Blt, lblDefault);
ig.Emit (OpCodes.Ldloc, val);
- EmitObjectInteger (ig, System.Convert.ChangeType (kb.nFirst, typeKeys));
+ EmitObjectInteger (ig, System.Convert.ChangeType (kb.nLast, typeKeys));
ig.Emit (OpCodes.Bgt, lblDefault);
// normalize range
// In .NET pointers turn out to be private, even if their
// element type is not
//
-
if (t.IsPointer){
t = t.GetElementType ();
continue;
} else
t = null;
- } else
+ } else {
return t;
+ }
} while (t != null);
}
return false;
}
+ static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
+
// This is a custom version of Convert.ChangeType() which works
// with the TypeBuilder defined types when compiling corlib.
public static object ChangeType (object value, Type conversionType, out bool error)
{
- if (!(value is IConvertible)){
+ IConvertible convert_value = value as IConvertible;
+
+ if (convert_value == null){
error = true;
return null;
}
- IConvertible convertValue = (IConvertible) value;
- CultureInfo ci = CultureInfo.CurrentCulture;
- NumberFormatInfo provider = ci.NumberFormat;
-
//
// We must use Type.Equals() here since `conversionType' is
// the TypeBuilder created version of a system type and not
error = false;
try {
if (conversionType.Equals (typeof (Boolean)))
- return (object)(convertValue.ToBoolean (provider));
+ return (object)(convert_value.ToBoolean (nf_provider));
else if (conversionType.Equals (typeof (Byte)))
- return (object)(convertValue.ToByte (provider));
+ return (object)(convert_value.ToByte (nf_provider));
else if (conversionType.Equals (typeof (Char)))
- return (object)(convertValue.ToChar (provider));
+ return (object)(convert_value.ToChar (nf_provider));
else if (conversionType.Equals (typeof (DateTime)))
- return (object)(convertValue.ToDateTime (provider));
+ return (object)(convert_value.ToDateTime (nf_provider));
else if (conversionType.Equals (typeof (Decimal)))
- return (object)(convertValue.ToDecimal (provider));
+ return (object)(convert_value.ToDecimal (nf_provider));
else if (conversionType.Equals (typeof (Double)))
- return (object)(convertValue.ToDouble (provider));
+ return (object)(convert_value.ToDouble (nf_provider));
else if (conversionType.Equals (typeof (Int16)))
- return (object)(convertValue.ToInt16 (provider));
+ return (object)(convert_value.ToInt16 (nf_provider));
else if (conversionType.Equals (typeof (Int32)))
- return (object)(convertValue.ToInt32 (provider));
+ return (object)(convert_value.ToInt32 (nf_provider));
else if (conversionType.Equals (typeof (Int64)))
- return (object)(convertValue.ToInt64 (provider));
+ return (object)(convert_value.ToInt64 (nf_provider));
else if (conversionType.Equals (typeof (SByte)))
- return (object)(convertValue.ToSByte (provider));
+ return (object)(convert_value.ToSByte (nf_provider));
else if (conversionType.Equals (typeof (Single)))
- return (object)(convertValue.ToSingle (provider));
+ return (object)(convert_value.ToSingle (nf_provider));
else if (conversionType.Equals (typeof (String)))
- return (object)(convertValue.ToString (provider));
+ return (object)(convert_value.ToString (nf_provider));
else if (conversionType.Equals (typeof (UInt16)))
- return (object)(convertValue.ToUInt16 (provider));
+ return (object)(convert_value.ToUInt16 (nf_provider));
else if (conversionType.Equals (typeof (UInt32)))
- return (object)(convertValue.ToUInt32 (provider));
+ return (object)(convert_value.ToUInt32 (nf_provider));
else if (conversionType.Equals (typeof (UInt64)))
- return (object)(convertValue.ToUInt64 (provider));
+ return (object)(convert_value.ToUInt64 (nf_provider));
else if (conversionType.Equals (typeof (Object)))
return (object)(value);
else
return TypeManager.int64_type;
case TypeCode.UInt64:
return TypeManager.uint64_type;
+ case TypeCode.Single:
+ return TypeManager.float_type;
+ case TypeCode.Double:
+ return TypeManager.double_type;
case TypeCode.String:
return TypeManager.string_type;
default: