2003-11-06 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / gmcs / expression.cs
index 2f8054153e5749baefbf6b4cb37e41cc3743a24b..9c8a5758cbeb6966b69fa2dbeb5b50826894d72a 100755 (executable)
@@ -3115,9 +3115,9 @@ namespace Mono.CSharp {
                                else
                                        ig.Emit (OpCodes.Clt);
                                
-                               ig.Emit (OpCodes.Ldc_I4_1);
+                               ig.Emit (OpCodes.Ldc_I4_0);
                                
-                               opcode = OpCodes.Sub;
+                               opcode = OpCodes.Ceq;
                                break;
 
                        case Operator.BitwiseOr:
@@ -4819,7 +4819,7 @@ namespace Mono.CSharp {
                                is_base = true;
 
                        Expression old = expr;
-                       
+
                        expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
                        if (expr == null)
                                return null;
@@ -4915,15 +4915,15 @@ namespace Mono.CSharp {
                                ig.Emit (OpCodes.Ldloc, array);
                                IntConstant.EmitInt (ig, j - idx);
 
-                               bool is_stobj;
-                               OpCode op = ArrayAccess.GetStoreOpcode (t, out is_stobj);
+                               bool is_stobj, has_type_arg;
+                               OpCode op = ArrayAccess.GetStoreOpcode (t, out is_stobj, out has_type_arg);
                                if (is_stobj)
                                        ig.Emit (OpCodes.Ldelema, t);
 
                                a.Emit (ec);
 
-                               if (is_stobj)
-                                       ig.Emit (OpCodes.Stobj, t);
+                               if (has_type_arg)
+                                       ig.Emit (op, t);
                                else
                                        ig.Emit (op);
                        }
@@ -5047,7 +5047,7 @@ namespace Mono.CSharp {
                                return;
                        
                        if (!is_static){
-                               if (decl_type.IsValueType)
+                               if (TypeManager.IsValueType (decl_type))
                                        struct_call = true;
                                //
                                // If this is ourselves, push "this"
@@ -5058,14 +5058,15 @@ namespace Mono.CSharp {
                                        //
                                        // Push the instance expression
                                        //
-                                       if (instance_expr.Type.IsValueType){
+                                       if (TypeManager.IsValueType (instance_expr.Type)){
                                                //
                                                // Special case: calls to a function declared in a 
                                                // reference-type with a value-type argument need
                                                // to have their value boxed.  
 
-                                               struct_call = true;
-                                               if (decl_type.IsValueType){
+                                               if (!instance_expr.Type.IsGenericParameter)
+                                                       struct_call = true;
+                                               if (TypeManager.IsValueType (decl_type)){
                                                        //
                                                        // If the expression implements IMemoryLocation, then
                                                        // we can optimize and use AddressOf on the
@@ -6072,7 +6073,7 @@ namespace Mono.CSharp {
                        ig.Emit (OpCodes.Call,
                                 TypeManager.void_initializearray_array_fieldhandle);
                }
-               
+
                //
                // Emits pieces of the array that can not be computed at compile
                // time (variables and string locations).
@@ -6138,9 +6139,9 @@ namespace Mono.CSharp {
                                                // If we are dealing with a struct, get the
                                                // address of it, so we can store it.
                                                //
-                                               if ((dims == 1) &&
+                                               if ((dims == 1) && 
                                                    etype.IsSubclassOf (TypeManager.value_type) &&
-                                                   (!TypeManager.IsBuiltinType (etype) ||
+                                                   (!TypeManager.IsBuiltinOrEnum (etype) ||
                                                     etype == TypeManager.decimal_type)) {
                                                        if (e is New){
                                                                New n = (New) e;
@@ -6155,7 +6156,10 @@ namespace Mono.CSharp {
                                                        ig.Emit (OpCodes.Ldelema, etype);
                                                }
 
+                                               ig.Emit (OpCodes.Nop);
                                                e.Emit (ec);
+                                               ig.Emit (OpCodes.Nop);
+                                               ig.Emit (OpCodes.Nop);
 
                                                 if (dims == 1)
                                                         ArrayAccess.EmitStoreOpcode (ig, array_element_type);
@@ -6672,7 +6676,8 @@ namespace Mono.CSharp {
                                // a FieldExpr
                                //
 
-                               if (ee.EventInfo.DeclaringType == ec.ContainerType) {
+                               if (ee.EventInfo.DeclaringType == ec.ContainerType ||
+                                   TypeManager.IsNestedChildOf(ec.ContainerType, ee.EventInfo.DeclaringType)) {
                                        MemberInfo mi = GetFieldFromEvent (ee);
 
                                        if (mi == null) {
@@ -6759,7 +6764,8 @@ namespace Mono.CSharp {
                        return null;
                }
                
-               public Expression DoResolve (EmitContext ec, Expression right_side, ResolveFlags flags)
+               public virtual Expression DoResolve (EmitContext ec, Expression right_side,
+                                                    ResolveFlags flags)
                {
                        if (type != null)
                                throw new Exception ();
@@ -7237,7 +7243,9 @@ namespace Mono.CSharp {
                        else if (type.IsValueType){
                                ig.Emit (OpCodes.Ldelema, type);
                                ig.Emit (OpCodes.Ldobj, type);
-                       } else 
+                       } else if (type.IsGenericParameter)
+                               ig.Emit (OpCodes.Ldelem_Any, type);
+                       else
                                ig.Emit (OpCodes.Ldelem_Ref);
                }
 
@@ -7247,10 +7255,10 @@ namespace Mono.CSharp {
                /// </summary>
                static public void EmitStoreOpcode (ILGenerator ig, Type t)
                {
-                       bool is_stobj;
-                       OpCode op = GetStoreOpcode (t, out is_stobj);
-                       if (is_stobj)
-                               ig.Emit (OpCodes.Stobj, t);
+                       bool is_stobj, has_type_arg;
+                       OpCode op = GetStoreOpcode (t, out is_stobj, out has_type_arg);
+                       if (has_type_arg)
+                               ig.Emit (op, t);
                        else
                                ig.Emit (op);
                }
@@ -7259,10 +7267,10 @@ namespace Mono.CSharp {
                ///    Returns the right opcode to store an object of Type `t'
                ///    from an array of T.  
                /// </summary>
-               static public OpCode GetStoreOpcode (Type t, out bool is_stobj)
+               static public OpCode GetStoreOpcode (Type t, out bool is_stobj, out bool has_type_arg)
                {
                        //Console.WriteLine (new System.Diagnostics.StackTrace ());
-                       is_stobj = false;
+                       has_type_arg = false; is_stobj = false;
                        t = TypeManager.TypeToCoreType (t);
                        if (TypeManager.IsEnumType (t) && t != TypeManager.enum_type)
                                t = TypeManager.EnumToUnderlying (t);
@@ -7281,11 +7289,16 @@ namespace Mono.CSharp {
                        else if (t == TypeManager.double_type)
                                return OpCodes.Stelem_R8;
                        else if (t == TypeManager.intptr_type) {
-                                is_stobj = true;
+                                has_type_arg = true;
+                               is_stobj = true;
                                 return OpCodes.Stobj;
                        } else if (t.IsValueType) {
+                               has_type_arg = true;
                                is_stobj = true;
                                return OpCodes.Stobj;
+                       } else if (t.IsGenericParameter) {
+                               has_type_arg = true;
+                               return OpCodes.Stelem_Any;
                        } else
                                return OpCodes.Stelem_Ref;
                }
@@ -7982,6 +7995,20 @@ namespace Mono.CSharp {
                        if (ltype == null)
                                return null;
 
+                       if (ltype.IsGenericParameter) {
+                               int rank = dim.Length-2;
+                               if ((rank < 0) || (dim [0] != '[') || (dim [rank+1] != ']'))
+                                       return null;
+                               for (int i = 0; i < rank; i++)
+                                       if (dim [i+1] != ',')
+                                               return null;
+
+                               type = Array.CreateInstance (ltype, rank).GetType ();
+
+                               eclass = ExprClass.Type;
+                               return this;
+                       }
+
                        //
                        // ltype.Fullname is already fully qualified, so we can skip
                        // a lot of probes, and go directly to TypeManager.LookupType