merge -r 58060:58217
[mono.git] / mcs / gmcs / expression.cs
index 9b2923e18b059b027421a43ecfec54cf77af6c9f..3985cd5818cf8a0f8661dba3622bf71368784743 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
+//   Marek Safar (marek.safar@seznam.cz)
 //
 // (C) 2001, 2002, 2003 Ximian, Inc.
 // (C) 2003, 2004 Novell, Inc.
@@ -94,7 +95,6 @@ namespace Mono.CSharp {
                public ParenthesizedExpression (Expression expr)
                {
                        this.Expr = expr;
-                       this.loc = expr.Location;
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -1267,7 +1267,7 @@ namespace Mono.CSharp {
                                if (error){
                                        Report.Error (413, loc,
                                                      "The as operator requires that the `{0}' type parameter be constrained by a class",
-                                                     probe_type_expr);
+                                                     probe_type_expr.GetSignatureForError ());
                                        return null;
                                }
                        }
@@ -2447,6 +2447,11 @@ namespace Mono.CSharp {
                                if (rc is EnumConstant &&
                                    lc != null && lc.IsZeroInteger)
                                        return rc;
+                       } else if (oper == Operator.LogicalAnd) {
+                               if (rc != null && rc.IsDefaultValue && rc.Type == TypeManager.bool_type)
+                                       return rc;
+                               if (lc != null && lc.IsDefaultValue && lc.Type == TypeManager.bool_type)
+                                       return lc;
                        }
 
                        if (rc != null && lc != null){
@@ -3863,7 +3868,7 @@ namespace Mono.CSharp {
                        if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
                                if (leave_copy)
                                        throw new InternalErrorException ();
-
+                               
                                ec.EmitParameter (name);
                                return;
                        }
@@ -3960,6 +3965,10 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override string ToString ()
+               {
+                       return "ParameterReference[" + name + "]";
+               }
        }
        
        /// <summary>
@@ -4366,7 +4375,7 @@ namespace Mono.CSharp {
                         return !candidate_params && best_params;
                }
 
-               static bool IsOverride (MethodBase cand_method, MethodBase base_method)
+               internal static bool IsOverride (MethodBase cand_method, MethodBase base_method)
                {
                        if (!IsAncestralType (base_method.DeclaringType, cand_method.DeclaringType))
                                return false;
@@ -4934,7 +4943,7 @@ namespace Mono.CSharp {
                public static void Error_WrongNumArguments (Location loc, String name, int arg_count)
                {
                        Report.Error (1501, loc, "No overload for method `{0}' takes `{1}' arguments",
-                               name, arg_count);
+                               name, arg_count.ToString ());
                }
 
                 static void Error_InvokeOnDelegate (Location loc)
@@ -4955,16 +4964,17 @@ namespace Mono.CSharp {
 
                        Parameter.Modifier mod = expected_par.ParameterModifier (idx);
 
+                       string index = (idx + 1).ToString ();
                        if (mod != Parameter.Modifier.ARGLIST && mod != a.Modifier) {
                                if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) == 0)
                                        Report.Error (1615, loc, "Argument `{0}' should not be passed with the `{1}' keyword",
-                                               idx + 1, Parameter.GetModifierSignature (a.Modifier));
+                                               index, Parameter.GetModifierSignature (a.Modifier));
                                else
                                        Report.Error (1620, loc, "Argument `{0}' must be passed with the `{1}' keyword",
-                                               idx + 1, Parameter.GetModifierSignature (mod));
+                                               index, Parameter.GetModifierSignature (mod));
                        } else {
                                Report.Error (1503, loc, "Argument {0}: Cannot convert from `{1}' to `{2}'",
-                                       idx + 1, Argument.FullDesc (a), expected_par.ParameterDesc (idx));
+                                       index, Argument.FullDesc (a), expected_par.ParameterDesc (idx));
                        }
                }
                
@@ -5730,6 +5740,29 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               //
+               // Checks whether the type is an interface that has the
+               // [ComImport, CoClass] attributes and must be treated
+               // specially
+               //
+               public Expression CheckComImport (EmitContext ec)
+               {
+                       if (!type.IsInterface)
+                               return null;
+
+                       //
+                       // Turn the call into:
+                       // (the-interface-stated) (new class-referenced-in-coclassattribute ())
+                       //
+                       Type real_class = AttributeTester.GetCoClassAttribute (type);
+                       if (real_class == null)
+                               return null;
+
+                       New proxy = new New (new TypeExpression (real_class, loc), Arguments, loc);
+                       Cast cast = new Cast (new TypeExpression (type, loc), proxy, loc);
+                       return cast.Resolve (ec);
+               }
+               
                public override Expression DoResolve (EmitContext ec)
                {
                        //
@@ -5798,6 +5831,10 @@ namespace Mono.CSharp {
                        }
 
                        if (type.IsInterface || type.IsAbstract){
+                               RequestedType = CheckComImport (ec);
+                               if (RequestedType != null)
+                                       return RequestedType;
+                               
                                Report.SymbolRelatedToPreviousError (type);
                                Report.Error (144, loc, "Cannot create an instance of the abstract class or interface `{0}'", TypeManager.CSharpName (type));
                                return null;
@@ -6063,16 +6100,21 @@ namespace Mono.CSharp {
                {
                        if (specified_dims) { 
                                Argument a = (Argument) arguments [idx];
-                               
+
                                if (!a.Resolve (ec, loc))
                                        return false;
-                               
-                               if (!(a.Expr is Constant)) {
-                                       Error (150, "A constant value is expected");
+
+                               Constant c = a.Expr as Constant;
+                               if (c != null) {
+                                       c = c.ToType (TypeManager.int32_type, a.Expr.Location);
+                               }
+
+                               if (c == null) {
+                                       Report.Error (150, a.Expr.Location, "A constant value is expected");
                                        return false;
                                }
-                               
-                               int value = (int) ((Constant) a.Expr).GetValue ();
+
+                               int value = (int) c.GetValue ();
                                
                                if (value != probe.Count) {
                                        Error_IncorrectArrayInitializer ();
@@ -7314,10 +7356,8 @@ namespace Mono.CSharp {
                {
                        FullNamedExpression new_expr = expr.ResolveAsTypeStep (ec, silent);
 
-                       if (new_expr == null) {
-                               Report.Error (234, "No such name or typespace {0}", expr);
+                       if (new_expr == null)
                                return null;
-                       }
 
                        string lookup_id = MemberName.MakeName (Identifier, args);
 
@@ -7618,11 +7658,10 @@ namespace Mono.CSharp {
                                                Report.Error (1708, loc, "Fixed size buffers can only be accessed through locals or fields");
                                                return null;
                                        }
-// TODO: not sure whether it is correct
-//                                     if (!ec.InFixedInitializer) {
-//                                             Error (1666, "You cannot use fixed sized buffers contained in unfixed expressions. Try using the fixed statement");
-//                                             return null;
-//                                     }
+                                       if (!ec.InFixedInitializer && ec.ContainerType.IsValueType) {
+                                               Error (1666, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
+                                               return null;
+                                       }
                                        return MakePointerAccess (ec, ff.ElementType);
                                }
                        }
@@ -7675,7 +7714,7 @@ namespace Mono.CSharp {
                        Type t = ea.Expr.Type;
                        if (t.GetArrayRank () != ea.Arguments.Count){
                                Report.Error (22, ea.Location, "Wrong number of indexes `{0}' inside [], expected `{1}'",
-                                         ea.Arguments.Count, t.GetArrayRank ());
+                                         ea.Arguments.Count.ToString (), t.GetArrayRank ().ToString ());
                                return null;
                        }
 
@@ -8076,6 +8115,21 @@ namespace Mono.CSharp {
                {
                        Indexers ix = empty;
 
+                       if (lookup_type.IsGenericParameter) {
+                               GenericConstraints gc = TypeManager.GetTypeParameterConstraints (lookup_type);
+                               if (gc == null)
+                                       return empty;
+
+                               if (gc.HasClassConstraint)
+                                       Append (ref ix, caller_type, GetIndexersForTypeOrInterface (caller_type, gc.ClassConstraint));
+
+                               Type[] ifaces = gc.InterfaceConstraints;
+                               foreach (Type itype in ifaces)
+                                       Append (ref ix, caller_type, GetIndexersForTypeOrInterface (caller_type, itype));
+
+                               return ix;
+                       }
+
                        Type copy = lookup_type;
                        while (copy != TypeManager.object_type && copy != null){
                                Append (ref ix, caller_type, GetIndexersForTypeOrInterface (caller_type, copy));