Merge branch 'master' into msbuilddll2
[mono.git] / mcs / mcs / delegate.cs
index 13a2a4c7bcf971abd38c1b322d7cf01d890b441c..21854b19ff051685338f18527b18627c8eef8c82 100644 (file)
@@ -181,7 +181,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this);
+                       VarianceDecl.CheckTypeVariance (ret_type, Variance.Covariant, this);
 
                        var resolved_rt = new TypeExpression (ret_type, Location);
                        InvokeBuilder = new Method (this, resolved_rt, MethodModifiers, new MemberName (InvokeMethodName), p, null);
@@ -191,13 +191,13 @@ namespace Mono.CSharp {
                        // Don't emit async method for compiler generated delegates (e.g. dynamic site containers)
                        //
                        if (!IsCompilerGenerated) {
-                               DefineAsyncMethods (Parameters.CallingConvention, resolved_rt);
+                               DefineAsyncMethods (resolved_rt);
                        }
 
                        return true;
                }
 
-               void DefineAsyncMethods (CallingConventions cc, TypeExpression returnType)
+               void DefineAsyncMethods (TypeExpression returnType)
                {
                        var iasync_result = Module.PredefinedTypes.IAsyncResult;
                        var async_callback = Module.PredefinedTypes.AsyncCallback;
@@ -454,7 +454,7 @@ namespace Mono.CSharp {
                        Arguments delegate_arguments = new Arguments (pd.Count);
                        for (int i = 0; i < pd.Count; ++i) {
                                Argument.AType atype_modifier;
-                               switch (pd.FixedParameters [i].ModFlags) {
+                               switch (pd.FixedParameters [i].ModFlags & Parameter.Modifier.RefOutMask) {
                                case Parameter.Modifier.REF:
                                        atype_modifier = Argument.AType.Ref;
                                        break;
@@ -532,7 +532,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       TypeSpec rt = delegate_method.ReturnType;
+                       TypeSpec rt = method_group.BestCandidateReturnType;
                        if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                                rt = ec.BuiltinTypes.Object;
 
@@ -541,7 +541,7 @@ namespace Mono.CSharp {
                                Error_ConversionFailed (ec, delegate_method, ret_expr);
                        }
 
-                       if (delegate_method.IsConditionallyExcluded (ec, loc)) {
+                       if (method_group.IsConditionallyExcluded) {
                                ec.Report.SymbolRelatedToPreviousError (delegate_method);
                                MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator;
                                if (m != null && m.IsPartialDefinition) {
@@ -663,7 +663,7 @@ namespace Mono.CSharp {
                //
                // Returns true when type is MVAR or has MVAR reference
                //
-               static bool ContainsMethodTypeParameter (TypeSpec type)
+               public static bool ContainsMethodTypeParameter (TypeSpec type)
                {
                        var tps = type as TypeParameterSpec;
                        if (tps != null)
@@ -681,12 +681,31 @@ namespace Mono.CSharp {
 
                        return false;
                }
+               
+               bool HasMvar ()
+               {
+                       if (ContainsMethodTypeParameter (type))
+                               return false;
+
+                       var best = method_group.BestCandidate;
+                       if (ContainsMethodTypeParameter (best.DeclaringType))
+                               return false;
+
+                       if (best.TypeArguments != null) {
+                               foreach (var ta in best.TypeArguments) {
+                                       if (ContainsMethodTypeParameter (ta))
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               }
 
                protected override Expression DoResolve (ResolveContext ec)
                {
                        var expr = base.DoResolve (ec);
                        if (expr == null)
-                               return null;
+                               return ErrorExpression.Instance;
 
                        if (ec.IsInProbingMode)
                                return expr;
@@ -700,10 +719,7 @@ namespace Mono.CSharp {
                        //
                        // Cannot easily cache types with MVAR
                        //
-                       if (ContainsMethodTypeParameter (type))
-                               return expr;
-
-                       if (ContainsMethodTypeParameter (method_group.BestCandidate.DeclaringType))
+                       if (!HasMvar ())
                                return expr;
 
                        //
@@ -828,6 +844,13 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Invoke", args);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       InstanceExpr.FlowAnalysis (fc);
+                       if (arguments != null)
+                               arguments.FlowAnalysis (fc);
+               }
+
                protected override Expression DoResolve (ResolveContext ec)
                {               
                        TypeSpec del_type = InstanceExpr.Type;
@@ -857,7 +880,7 @@ namespace Mono.CSharp {
                        //
                        var call = new CallEmitter ();
                        call.InstanceExpression = InstanceExpr;
-                       call.EmitPredefined (ec, method, arguments);
+                       call.EmitPredefined (ec, method, arguments, loc);
                }
 
                public override void EmitStatement (EmitContext ec)