**** Merged from MCS ****
[mono.git] / mcs / gmcs / assign.cs
index e8376406bda0c07fd8903b4a3e5a1405ef4a9459..3f1827e5cfa224567e6d603db54f77fcd5552e22 100755 (executable)
@@ -64,12 +64,12 @@ namespace Mono.CSharp {
                        type = t;
                        eclass = ExprClass.Value;
                        loc = Location.Null;
-                       builder = ec.GetTemporaryStorage (t);
+                       builder = ec.GetTemporaryLocal (t);
                }
 
                public void Release (EmitContext ec)
                {
-                       ec.FreeTemporaryStorage (builder);
+                       ec.FreeTemporaryLocal (builder, type);
                        builder = null;
                }
                
@@ -216,33 +216,6 @@ namespace Mono.CSharp {
                                type = target_type;
                        eclass = ExprClass.Value;
 
-                       //
-                       // If we are doing a property assignment, then
-                       // set the `value' field on the property, and Resolve
-                       // it.
-                       //
-                       if (target is PropertyExpr){
-                               PropertyExpr property_assign = (PropertyExpr) target;
-
-                               if (source_type != target_type){
-                                       source = Convert.ImplicitConversionRequired (ec, source, target_type, loc);
-                                       if (source == null)
-                                               return null;
-                               }
-
-                               //
-                               // FIXME: Maybe handle this in the LValueResolve
-                               //
-                               if (!property_assign.VerifyAssignable ())
-                                       return null;
-
-                               return this;
-                       }
-
-                       if (target is IndexerAccess) {
-                               return this;
-                       }
-
                        if (target is EventExpr) {
                                EventInfo ei = ((EventExpr) target).EventInfo;
 
@@ -262,21 +235,15 @@ namespace Mono.CSharp {
                                        // it will appear as a FieldExpr in that case.
                                        //
                                        
-                                       if (!(source is Binary)) {
+                                       if (!(source is BinaryDelegate)) {
                                                error70 (ei, loc);
                                                return null;
-                                       } else {
-                                               Binary tmp = ((Binary) source);
-                                               if (tmp.Oper != Binary.Operator.Addition &&
-                                                   tmp.Oper != Binary.Operator.Subtraction) {
-                                                       error70 (ei, loc);
-                                                       return null;
-                                               }
-                                       }
+                                       } 
                                }
                        }
                        
-                       if (source is New && target_type.IsValueType){
+                       if (source is New && target_type.IsValueType &&
+                           (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){
                                New n = (New) source;
 
                                if (n.SetValueTypeVariable (target))
@@ -285,7 +252,7 @@ namespace Mono.CSharp {
                                        return null;
                        }
 
-                       if (target.eclass != ExprClass.Variable && target.eclass != ExprClass.EventAccess){
+                       if (!(target is IAssignMethod) && (target.eclass != ExprClass.EventAccess)) {
                                Report.Error (131, loc,
                                              "Left hand of an assignment must be a variable, " +
                                              "a property or an indexer");
@@ -295,9 +262,10 @@ namespace Mono.CSharp {
                        if ((source.eclass == ExprClass.Type) && (source is TypeExpr)) {
                                source.Error_UnexpectedKind ("variable or value");
                                return null;
-                       } else if (source is MethodGroupExpr){
+                       } else if (!RootContext.V2 && (source is MethodGroupExpr)){
                                ((MethodGroupExpr) source).ReportUsageError ();
                                return null;
+
                        }
 
                        if (target_type == source_type)
@@ -313,7 +281,7 @@ namespace Mono.CSharp {
                                CompoundAssign a = (CompoundAssign) this;
                                
                                Binary b = source as Binary;
-                               if (b != null && b.IsBuiltinOperator){
+                               if (b != null){
                                        //
                                        // 1. if the source is explicitly convertible to the
                                        //    target_type
@@ -327,16 +295,24 @@ namespace Mono.CSharp {
                                
                                        //
                                        // 2. and the original right side is implicitly convertible to
-                                       // the type of target_type.
+                                       // the type of target
                                        //
                                        if (Convert.ImplicitStandardConversionExists (a.original_source, target_type))
                                                return this;
 
+                                       //
+                                       // In the spec 2.4 they added: or if type of the target is int
+                                       // and the operator is a shift operator...
+                                       //
+                                       if (source_type == TypeManager.int32_type &&
+                                           (b.Oper == Binary.Operator.LeftShift || b.Oper == Binary.Operator.RightShift))
+                                               return this;
+
                                        Convert.Error_CannotImplicitConversion (loc, a.original_source.Type, target_type);
                                        return null;
                                }
                        }
-                       
+
                        source = Convert.ImplicitConversionRequired (ec, source, target_type, loc);
                        if (source == null)
                                return null;
@@ -411,10 +387,8 @@ namespace Mono.CSharp {
                        // 
                        IAssignMethod am = (IAssignMethod) target;
                        
-                       if (this is CompoundAssign){
+                       if (this is CompoundAssign)
                                am.CacheTemporaries (ec);
-                               use_temporaries = true;
-                       }
 
                        if (!is_statement)
                                use_temporaries = true;