2004-01-04 David Sheldon <dave-mono@earth.li>
[mono.git] / mcs / gmcs / expression.cs
index 6f687c6cda31801df8f7a0cfec201a14675adbe1..65e8124d79590c72bf2eab9a38fb44198112a12f 100755 (executable)
@@ -254,16 +254,16 @@ namespace Mono.CSharp {
 
                                        result = null;
                                        if (Convert.ImplicitConversionExists (ec, e, TypeManager.int32_type)){
-                                               result = new Cast (new TypeExpr (TypeManager.int32_type, loc), e, loc);
+                                               result = new Cast (new TypeExpression (TypeManager.int32_type, loc), e, loc);
                                                result = result.Resolve (ec);
                                        } else if (Convert.ImplicitConversionExists (ec, e, TypeManager.uint32_type)){
-                                               result = new Cast (new TypeExpr (TypeManager.uint32_type, loc), e, loc);
+                                               result = new Cast (new TypeExpression (TypeManager.uint32_type, loc), e, loc);
                                                result = result.Resolve (ec);
                                        } else if (Convert.ImplicitConversionExists (ec, e, TypeManager.int64_type)){
-                                               result = new Cast (new TypeExpr (TypeManager.int64_type, loc), e, loc);
+                                               result = new Cast (new TypeExpression (TypeManager.int64_type, loc), e, loc);
                                                result = result.Resolve (ec);
                                        } else if (Convert.ImplicitConversionExists (ec, e, TypeManager.uint64_type)){
-                                               result = new Cast (new TypeExpr (TypeManager.uint64_type, loc), e, loc);
+                                               result = new Cast (new TypeExpression (TypeManager.uint64_type, loc), e, loc);
                                                result = result.Resolve (ec);
                                        }
 
@@ -975,7 +975,8 @@ namespace Mono.CSharp {
                                // 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 ();
                                        
@@ -1241,7 +1242,7 @@ namespace Mono.CSharp {
 
                        if (TypeManager.IsValueType (probe_type)){
                                Report.Error (77, loc, "The as operator should be used with a reference type only (" +
-                                             TypeManager.CSharpName (probe_type) + " is a value type");
+                                             TypeManager.CSharpName (probe_type) + " is a value type)");
                                return null;
                        
                        }
@@ -4766,11 +4767,6 @@ namespace Mono.CSharp {
                                        conv = Convert.ImplicitConversion (ec, a_expr, parameter_type, loc);
 
                                        if (conv == null) {
-                                                Console.WriteLine ("GAA: {0} {1} {2}",
-                                                                   pd.ParameterType (j),
-                                                                   pd.ParameterType (j).Assembly == CodeGen.AssemblyBuilder,
-                                                                   method.DeclaringType.Assembly == CodeGen.AssemblyBuilder);
-
                                                if (!Location.IsNull (loc)) 
                                                        Error_InvalidArguments (
                                                                loc, j, method, delegate_type,
@@ -4819,7 +4815,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 +4911,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 +5043,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 +5054,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
@@ -5150,7 +5147,7 @@ namespace Mono.CSharp {
                        //
                        type = ec.DeclSpace.ResolveType (expr, true, loc);
                        if (type != null) {
-                               Cast cast = new Cast (new TypeExpr (type, loc), argument, loc);
+                               Cast cast = new Cast (new TypeExpression (type, loc), argument, loc);
                                return cast.Resolve (ec);
                        }
 
@@ -5166,7 +5163,7 @@ namespace Mono.CSharp {
                        // Ok, so it's a Cast.
                        //
                        if (expr.eclass == ExprClass.Type) {
-                               Cast cast = new Cast (new TypeExpr (expr.Type, loc), argument, loc);
+                               Cast cast = new Cast (new TypeExpression (expr.Type, loc), argument, loc);
                                return cast.Resolve (ec);
                        }
 
@@ -5252,7 +5249,13 @@ namespace Mono.CSharp {
        /// </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;
 
@@ -5318,8 +5321,11 @@ namespace Mono.CSharp {
                        //
                        // 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);
                        
@@ -5328,8 +5334,13 @@ namespace Mono.CSharp {
                        
                        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");
@@ -6513,7 +6524,8 @@ namespace Mono.CSharp {
                                ((TypeParameterExpr)QueriedType).Error_CannotUseAsUnmanagedType (loc);
                                return null;
                        }
-                       
+
+                       type_queried = QueriedType.Type;
                        if (!TypeManager.IsUnmanagedType (type_queried)){
                                Report.Error (208, loc, "Cannot take the size of an unmanaged type (" + TypeManager.CSharpName (type_queried) + ")");
                                return null;
@@ -6763,7 +6775,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 ();
@@ -6883,7 +6896,7 @@ namespace Mono.CSharp {
                                        string full_name = String.Concat (((SimpleName) full_expr.Expr).Name, ".", fname);
                                        Type fully_qualified = ec.DeclSpace.FindType (loc, full_name);
                                        if (fully_qualified != null)
-                                               return new TypeExpr (fully_qualified, loc);
+                                               return new TypeExpression (fully_qualified, loc);
                                }
 
                                full_expr = full_expr.Expr as MemberAccess;
@@ -7241,7 +7254,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);
                }
 
@@ -7251,10 +7266,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);
                }
@@ -7263,10 +7278,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);
@@ -7285,11 +7300,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;
                }
@@ -7555,9 +7575,10 @@ namespace Mono.CSharp {
                        if (!lookup_type.IsInterface)
                                return ix;
 
-                       Type [] ifaces = TypeManager.GetInterfaces (lookup_type);
+                       TypeExpr [] ifaces = TypeManager.GetInterfaces (lookup_type);
                        if (ifaces != null) {
-                               foreach (Type itype in ifaces) {
+                               foreach (TypeExpr iface in ifaces) {
+                                       Type itype = iface.Type;
                                        MemberInfo [] mi = GetIndexersForTypeOrInterface (caller_type, itype);
                                        if (mi != null){
                                                if (ix == null)
@@ -7833,7 +7854,7 @@ namespace Mono.CSharp {
                        Expression left;
                        
                        if (ec.IsStatic)
-                               left = new TypeExpr (base_type, loc);
+                               left = new TypeExpression (base_type, loc);
                        else
                                left = ec.GetThis (loc);
                        
@@ -7969,7 +7990,7 @@ namespace Mono.CSharp {
        //   the type specification, we just use this to construct the type
        //   one bit at a time.
        // </summary>
-       public class ComposedCast : Expression {
+       public class ComposedCast : TypeExpr {
                Expression left;
                string dim;
                
@@ -7980,22 +8001,35 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
-               public override Expression ResolveAsTypeStep (EmitContext ec)
+               public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
                {
                        Type ltype = ec.DeclSpace.ResolveType (left, false, loc);
                        if (ltype == null)
                                return null;
 
-                       if (ltype.IsUnboundGenericParameter) {
-                               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;
+                       int pos = 0;
+                       while ((pos < dim.Length) && (dim [pos] == '[')) {
+                               pos++;
+                               if (dim [pos] == ']') {
+                                       ltype = ltype.MakeArrayType ();
+                                       pos++;
 
-                               type = Array.CreateInstance (ltype, rank).GetType ();
+                                       if (pos < dim.Length)
+                                               continue;
 
+                                       type = ltype;
+                                       eclass = ExprClass.Type;
+                                       return this;
+                               }
+
+                               int rank = 0;
+                               while (dim [pos++] == ',')
+                                       rank++;
+
+                               if ((dim [pos] != ']') || (pos != dim.Length-1))
+                                       return null;
+                                               
+                               type = ltype.MakeArrayType (rank + 1);
                                eclass = ExprClass.Type;
                                return this;
                        }
@@ -8035,19 +8069,10 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override Expression DoResolve (EmitContext ec)
-               {
-                       return ResolveAsTypeStep (ec);
-               }
-
-               public override void Emit (EmitContext ec)
-               {
-                       throw new Exception ("This should never be called");
-               }
-
-               public override string ToString ()
-               {
-                       return left + dim;
+               public override string Name {
+                       get {
+                               return left + dim;
+                       }
                }
        }