diff options
-rw-r--r-- | mcs/mcs/ChangeLog | 6 | ||||
-rw-r--r-- | mcs/mcs/const.cs | 8 | ||||
-rw-r--r-- | mcs/mcs/cs-parser.jay | 7 | ||||
-rw-r--r-- | mcs/mcs/ecore.cs | 57 | ||||
-rw-r--r-- | mcs/mcs/expression.cs | 30 | ||||
-rw-r--r-- | mcs/mcs/statement.cs | 2 |
6 files changed, 89 insertions, 21 deletions
diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog index 7d1a66ac068..286c45c174a 100644 --- a/mcs/mcs/ChangeLog +++ b/mcs/mcs/ChangeLog @@ -1,3 +1,9 @@ +2008-09-18 Marek Safar <marek.safar@gmail.com> + + * const.cs, expression.cs, statement.cs, ecore.cs, cs-parser.jay: + Fixed expression tree representation of empty new expression and + new initializer expression. + 2008-09-18 Miguel de Icaza <miguel@novell.com> * eval.cs: Remove warning, keep reference to driver around. diff --git a/mcs/mcs/const.cs b/mcs/mcs/const.cs index 0c468b53525..0a87387689f 100644 --- a/mcs/mcs/const.cs +++ b/mcs/mcs/const.cs @@ -183,10 +183,10 @@ namespace Mono.CSharp { mc.GetSignatureForError ()); } - public static void Error_ConstantCanBeInitializedWithNullOnly (Location loc, string name) + public static void Error_ConstantCanBeInitializedWithNullOnly (Type type, Location loc, string name) { - Report.Error (134, loc, "`{0}': the constant of reference type other than string can only be initialized with null", - name); + Report.Error (134, loc, "A constant `{0}' of reference type `{1}' can only be initialized with null", + name, TypeManager.CSharpName (type)); } public static void Error_InvalidConstantType (Type t, Location loc) @@ -231,7 +231,7 @@ namespace Mono.CSharp { Constant c = value.ConvertImplicitly (MemberType); if (c == null) { if (TypeManager.IsReferenceType (MemberType)) - Error_ConstantCanBeInitializedWithNullOnly (Location, GetSignatureForError ()); + Error_ConstantCanBeInitializedWithNullOnly (MemberType, Location, GetSignatureForError ()); else value.Error_ValueCannotBeConverted (ec, Location, MemberType, false); } diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index eeaabe5a99d..14954d29c46 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -1015,7 +1015,7 @@ constant_declarator { ++lexer.parsing_block; } - constant_expression + constant_initializer { --lexer.parsing_block; $$ = new VariableDeclaration ((LocatedToken) $1, $4); @@ -1027,6 +1027,11 @@ constant_declarator $$ = null; } ; + +constant_initializer + : constant_expression + | array_initializer + ; field_declaration : opt_attributes diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 26628f3cdfe..ee1297b2f73 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -522,7 +522,11 @@ namespace Mono.CSharp { if (c != null) return c; - Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ()); + if (type != null && TypeManager.IsReferenceType (type)) + Const.Error_ConstantCanBeInitializedWithNullOnly (type, loc, mc.GetSignatureForError ()); + else + Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ()); + return null; } @@ -2205,7 +2209,7 @@ namespace Mono.CSharp { // Even if resolved result is a constant original expression was not // and attribute accepts constants only // - Attribute.Error_AttributeArgumentNotValid (loc); + Attribute.Error_AttributeArgumentNotValid (orig_expr.Location); value = null; return false; } @@ -2219,6 +2223,46 @@ namespace Mono.CSharp { } } + sealed class ReducedExpressionStatement : ExpressionStatement + { + readonly Expression orig_expr; + readonly ExpressionStatement stm; + + public ReducedExpressionStatement (ExpressionStatement stm, Expression orig) + { + this.orig_expr = orig; + this.stm = stm; + this.loc = orig.Location; + } + + public override Expression CreateExpressionTree (EmitContext ec) + { + return orig_expr.CreateExpressionTree (ec); + } + + public override Expression DoResolve (EmitContext ec) + { + eclass = stm.eclass; + type = stm.Type; + return this; + } + + public override void Emit (EmitContext ec) + { + stm.Emit (ec); + } + + public override void EmitStatement (EmitContext ec) + { + stm.EmitStatement (ec); + } + + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + stm.MutateHoistedGenericType (storey); + } + } + readonly Expression expr, orig_expr; private ReducedExpression (Expression expr, Expression orig_expr) @@ -2233,12 +2277,21 @@ namespace Mono.CSharp { return new ReducedConstantExpression (expr, original_expr); } + public static ExpressionStatement Create (ExpressionStatement s, Expression orig) + { + return new ReducedExpressionStatement (s, orig); + } + public static Expression Create (Expression expr, Expression original_expr) { Constant c = expr as Constant; if (c != null) return Create (c, original_expr); + ExpressionStatement s = expr as ExpressionStatement; + if (s != null) + return Create (s, original_expr); + return new ReducedExpression (expr, original_expr); } diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 8d003c99eaa..377888e5e63 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -5409,9 +5409,9 @@ namespace Mono.CSharp { } if (Arguments == null) { - Expression c = Constantify (type); + Constant c = Constantify (type); if (c != null) - return c; + return ReducedExpression.Create (c, this); } if (TypeManager.IsDelegateType (type)) { @@ -9406,7 +9406,7 @@ namespace Mono.CSharp { if (eclass != ExprClass.Invalid) return this; - bool is_elements_initialization = false; + bool is_collection_initialization = false; ArrayList element_names = null; for (int i = 0; i < initializers.Count; ++i) { Expression initializer = (Expression) initializers [i]; @@ -9414,7 +9414,6 @@ namespace Mono.CSharp { if (i == 0) { if (element_initializer != null) { - is_elements_initialization = true; element_names = new ArrayList (initializers.Count); element_names.Add (element_initializer.Name); } else { @@ -9427,15 +9426,16 @@ namespace Mono.CSharp { TypeManager.CSharpName (TypeManager.ienumerable_type)); return null; } + is_collection_initialization = true; } } else { - if (is_elements_initialization == (element_initializer == null)) { + if (is_collection_initialization != (element_initializer == null)) { Report.Error (747, initializer.Location, "Inconsistent `{0}' member declaration", - is_elements_initialization ? "object initializer" : "collection initializer"); + is_collection_initialization ? "collection initializer" : "object initializer"); continue; } - - if (is_elements_initialization) { + + if (!is_collection_initialization) { if (element_names.Contains (element_initializer.Name)) { Report.Error (1912, element_initializer.Location, "An object initializer includes more than one member `{0}' initialization", @@ -9453,7 +9453,7 @@ namespace Mono.CSharp { initializers [i] = e; } - type = is_elements_initialization ? typeof (ElementInitializer) : typeof (CollectionOrObjectInitializers); + type = is_collection_initialization ? typeof (CollectionOrObjectInitializers) : typeof (ElementInitializer); eclass = ExprClass.Variable; return this; } @@ -9549,7 +9549,8 @@ namespace Mono.CSharp { { ArrayList args = new ArrayList (2); args.Add (new Argument (base.CreateExpressionTree (ec))); - args.Add (new Argument (initializers.CreateExpressionTree (ec))); + if (!initializers.IsEmpty) + args.Add (new Argument (initializers.CreateExpressionTree (ec))); return CreateExpressionFactoryCall ( initializers.IsCollectionInitializer ? "ListInit" : "MemberInit", @@ -9566,8 +9567,10 @@ namespace Mono.CSharp { return null; // Empty initializer can be optimized to simple new - if (initializers.IsEmpty) - return e; + if (initializers.IsEmpty) { + initializers.Resolve (ec); + return ReducedExpression.Create (e, this).Resolve (ec); + } Expression previous = ec.CurrentInitializerVariable; ec.CurrentInitializerVariable = new InitializerTargetExpression (this); @@ -9674,7 +9677,8 @@ namespace Mono.CSharp { type.DefineMembers (); type.Define (); type.EmitType (); - type.CloseType (); + if (Report.Errors == 0) + type.CloseType (); RootContext.ToplevelTypes.AddAnonymousType (type); return type; diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 1f42cbdabd0..a88b63b6c3e 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -2074,7 +2074,7 @@ namespace Mono.CSharp { e = ce.ConvertImplicitly (variable_type); if (e == null) { if (TypeManager.IsReferenceType (variable_type)) - Const.Error_ConstantCanBeInitializedWithNullOnly (vi.Location, vi.Name); + Const.Error_ConstantCanBeInitializedWithNullOnly (variable_type, vi.Location, vi.Name); else ce.Error_ValueCannotBeConverted (ec, vi.Location, variable_type, false); continue; |