Merge pull request #109 from rnagy/master
[mono.git] / mcs / mcs / method.cs
1 //
2 // method.cs: Method based declarations
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@gmail.com)
7 //
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 //
10 // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2004-2008 Novell, Inc
12 //
13
14 using System;
15 using System.Collections.Generic;
16 using System.Security;
17 using System.Security.Permissions;
18 using System.Text;
19 using System.Linq;
20
21 #if NET_2_1
22 using XmlElement = System.Object;
23 #else
24 using System.Xml;
25 #endif
26
27 #if STATIC
28 using MetaType = IKVM.Reflection.Type;
29 using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
30 using IKVM.Reflection;
31 using IKVM.Reflection.Emit;
32 #else
33 using MetaType = System.Type;
34 using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
35 using System.Reflection;
36 using System.Reflection.Emit;
37 #endif
38
39 using Mono.CompilerServices.SymbolWriter;
40
41 namespace Mono.CSharp {
42
43         public abstract class MethodCore : InterfaceMemberBase, IParametersMember
44         {
45                 protected ParametersCompiled parameters;
46                 protected ToplevelBlock block;
47                 protected MethodSpec spec;
48
49                 public MethodCore (DeclSpace parent, GenericMethod generic,
50                         FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
51                         MemberName name, Attributes attrs, ParametersCompiled parameters)
52                         : base (parent, generic, type, mod, allowed_mod, name, attrs)
53                 {
54                         this.parameters = parameters;
55                 }
56
57                 public override Variance ExpectedMemberTypeVariance {
58                         get {
59                                 return Variance.Covariant;
60                         }
61                 }
62
63                 //
64                 //  Returns the System.Type array for the parameters of this method
65                 //
66                 public TypeSpec [] ParameterTypes {
67                         get {
68                                 return parameters.Types;
69                         }
70                 }
71
72                 public ParametersCompiled ParameterInfo {
73                         get {
74                                 return parameters;
75                         }
76                 }
77
78                 AParametersCollection IParametersMember.Parameters {
79                         get { return parameters; }
80                 }
81                 
82                 public ToplevelBlock Block {
83                         get {
84                                 return block;
85                         }
86
87                         set {
88                                 block = value;
89                         }
90                 }
91
92                 public CallingConventions CallingConventions {
93                         get {
94                                 CallingConventions cc = parameters.CallingConvention;
95                                 if (!IsInterface)
96                                         if ((ModFlags & Modifiers.STATIC) == 0)
97                                                 cc |= CallingConventions.HasThis;
98
99                                 // FIXME: How is `ExplicitThis' used in C#?
100                         
101                                 return cc;
102                         }
103                 }
104
105                 protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
106                 {
107                         bool res = base.CheckOverrideAgainstBase (base_member);
108
109                         //
110                         // Check that the permissions are not being changed
111                         //
112                         if (!CheckAccessModifiers (this, base_member)) {
113                                 Error_CannotChangeAccessModifiers (this, base_member);
114                                 res = false;
115                         }
116
117                         return res;
118                 }
119
120                 protected override bool CheckBase ()
121                 {
122                         // Check whether arguments were correct.
123                         if (!DefineParameters (parameters))
124                                 return false;
125
126                         return base.CheckBase ();
127                 }
128
129                 //
130                 //   Represents header string for documentation comment.
131                 //
132                 public override string DocCommentHeader 
133                 {
134                         get { return "M:"; }
135                 }
136
137                 public override void Emit ()
138                 {
139                         if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
140                                 parameters.CheckConstraints (this);
141                         }
142
143                         base.Emit ();
144                 }
145
146                 public override bool EnableOverloadChecks (MemberCore overload)
147                 {
148                         if (overload is MethodCore) {
149                                 caching_flags |= Flags.MethodOverloadsExist;
150                                 return true;
151                         }
152
153                         if (overload is AbstractPropertyEventMethod)
154                                 return true;
155
156                         return base.EnableOverloadChecks (overload);
157                 }
158
159                 public override string GetSignatureForDocumentation ()
160                 {
161                         string s = base.GetSignatureForDocumentation ();
162                         if (MemberName.Arity > 0)
163                                 s += "``" + MemberName.Arity.ToString ();
164
165                         return s + parameters.GetSignatureForDocumentation ();
166                 }
167
168                 public MethodSpec Spec {
169                         get { return spec; }
170                 }
171
172                 protected override bool VerifyClsCompliance ()
173                 {
174                         if (!base.VerifyClsCompliance ())
175                                 return false;
176
177                         if (parameters.HasArglist) {
178                                 Report.Warning (3000, 1, Location, "Methods with variable arguments are not CLS-compliant");
179                         }
180
181                         if (member_type != null && !member_type.IsCLSCompliant ()) {
182                                 Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
183                                         GetSignatureForError ());
184                         }
185
186                         parameters.VerifyClsCompliance (this);
187                         return true;
188                 }
189         }
190
191         public interface IGenericMethodDefinition : IMemberDefinition
192         {
193                 TypeParameterSpec[] TypeParameters { get; }
194                 int TypeParametersCount { get; }
195
196 //              MethodInfo MakeGenericMethod (TypeSpec[] targs);
197         }
198
199         public sealed class MethodSpec : MemberSpec, IParametersMember
200         {
201                 MethodBase metaInfo, inflatedMetaInfo;
202                 AParametersCollection parameters;
203                 TypeSpec returnType;
204
205                 TypeSpec[] targs;
206                 TypeParameterSpec[] constraints;
207
208                 public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
209                         MethodBase info, AParametersCollection parameters, Modifiers modifiers)
210                         : base (kind, declaringType, details, modifiers)
211                 {
212                         this.metaInfo = info;
213                         this.parameters = parameters;
214                         this.returnType = returnType;
215                 }
216
217                 #region Properties
218
219                 public override int Arity {
220                         get {
221                                 return IsGeneric ? GenericDefinition.TypeParametersCount : 0;
222                         }
223                 }
224
225                 public TypeParameterSpec[] Constraints {
226                         get {
227                                 if (constraints == null && IsGeneric)
228                                         constraints = GenericDefinition.TypeParameters;
229
230                                 return constraints;
231                         }
232                 }
233
234                 public bool IsConstructor {
235                         get {
236                                 return Kind == MemberKind.Constructor;
237                         }
238                 }
239
240                 public IGenericMethodDefinition GenericDefinition {
241                         get {
242                                 return (IGenericMethodDefinition) definition;
243                         }
244                 }
245
246                 public bool IsExtensionMethod {
247                         get {
248                                 return IsStatic && parameters.HasExtensionMethodType;
249                         }
250                 }
251
252                 public bool IsSealed {
253                         get {
254                                 return (Modifiers & Modifiers.SEALED) != 0;
255                         }
256                 }
257
258                 // When is virtual or abstract
259                 public bool IsVirtual {
260                         get {
261                                 return (Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != 0;
262                         }
263                 }
264
265                 public bool IsReservedMethod {
266                         get {
267                                 return Kind == MemberKind.Operator || IsAccessor;
268                         }
269                 }
270
271                 TypeSpec IInterfaceMemberSpec.MemberType {
272                         get {
273                                 return returnType;
274                         }
275                 }
276
277                 public AParametersCollection Parameters {
278                         get { 
279                                 return parameters;
280                         }
281                 }
282
283                 public TypeSpec ReturnType {
284                         get {
285                                 return returnType;
286                         }
287                 }
288
289                 public TypeSpec[] TypeArguments {
290                         get {
291                                 return targs;
292                         }
293                 }
294
295                 #endregion
296
297                 public MethodSpec GetGenericMethodDefinition ()
298                 {
299                         if (!IsGeneric && !DeclaringType.IsGeneric)
300                                 return this;
301
302                         return MemberCache.GetMember (declaringType, this);
303                 }
304
305                 public MethodBase GetMetaInfo ()
306                 {
307                         //
308                         // inflatedMetaInfo is extra field needed for cases where we
309                         // inflate method but another nested type can later inflate
310                         // again (the cache would be build with inflated metaInfo) and
311                         // TypeBuilder can work with method definitions only
312                         //
313                         if (inflatedMetaInfo == null) {
314                                 if ((state & StateFlags.PendingMetaInflate) != 0) {
315                                         var dt_meta = DeclaringType.GetMetaInfo ();
316
317                                         if (DeclaringType.IsTypeBuilder) {
318                                                 if (IsConstructor)
319                                                         inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) metaInfo);
320                                                 else
321                                                         inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) metaInfo);
322                                         } else {
323 #if STATIC
324                                                 // it should not be reached
325                                                 throw new NotImplementedException ();
326 #else
327                                                 inflatedMetaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, dt_meta.TypeHandle);
328 #endif
329                                         }
330
331                                         state &= ~StateFlags.PendingMetaInflate;
332                                 } else {
333                                         inflatedMetaInfo = metaInfo;
334                                 }
335                         }
336
337                         if ((state & StateFlags.PendingMakeMethod) != 0) {
338                                 var sre_targs = new MetaType[targs.Length];
339                                 for (int i = 0; i < sre_targs.Length; ++i)
340                                         sre_targs[i] = targs[i].GetMetaInfo ();
341
342                                 inflatedMetaInfo = ((MethodInfo) inflatedMetaInfo).MakeGenericMethod (sre_targs);
343                                 state &= ~StateFlags.PendingMakeMethod;
344                         }
345
346                         return inflatedMetaInfo;
347                 }
348
349                 public override string GetSignatureForDocumentation ()
350                 {
351                         string name;
352                         switch (Kind) {
353                         case MemberKind.Constructor:
354                                 name = "#ctor";
355                                 break;
356                         case MemberKind.Method:
357                                 if (Arity > 0)
358                                         name = Name + "``" + Arity.ToString ();
359                                 else
360                                         name = Name;
361
362                                 break;
363                         default:
364                                 name = Name;
365                                 break;
366                         }
367
368                         name = DeclaringType.GetSignatureForDocumentation () + "." + name + parameters.GetSignatureForDocumentation ();
369                         if (Kind == MemberKind.Operator) {
370                                 var op = Operator.GetType (Name).Value;
371                                 if (op == Operator.OpType.Explicit || op == Operator.OpType.Implicit) {
372                                         name += "~" + ReturnType.GetSignatureForDocumentation ();
373                                 }
374                         }
375
376                         return name;
377                 }
378
379                 public override string GetSignatureForError ()
380                 {
381                         string name;
382                         if (IsConstructor) {
383                                 name = DeclaringType.GetSignatureForError () + "." + DeclaringType.Name;
384                         } else if (Kind == MemberKind.Operator) {
385                                 var op = Operator.GetType (Name).Value;
386                                 if (op == Operator.OpType.Implicit || op == Operator.OpType.Explicit) {
387                                         name = DeclaringType.GetSignatureForError () + "." + Operator.GetName (op) + " operator " + returnType.GetSignatureForError ();
388                                 } else {
389                                         name = DeclaringType.GetSignatureForError () + ".operator " + Operator.GetName (op);
390                                 }
391                         } else if (IsAccessor) {
392                                 int split = Name.IndexOf ('_');
393                                 name = Name.Substring (split + 1);
394                                 var postfix = Name.Substring (0, split);
395                                 if (split == 3) {
396                                         var pc = parameters.Count;
397                                         if (pc > 0 && postfix == "get") {
398                                                 name = "this" + parameters.GetSignatureForError ("[", "]", pc);
399                                         } else if (pc > 1 && postfix == "set") {
400                                                 name = "this" + parameters.GetSignatureForError ("[", "]", pc - 1);
401                                         }
402                                 }
403
404                                 return DeclaringType.GetSignatureForError () + "." + name + "." + postfix;
405                         } else {
406                                 name = base.GetSignatureForError ();
407                                 if (targs != null)
408                                         name += "<" + TypeManager.CSharpName (targs) + ">";
409                                 else if (IsGeneric)
410                                         name += "<" + TypeManager.CSharpName (GenericDefinition.TypeParameters) + ">";
411                         }
412
413                         return name + parameters.GetSignatureForError ();
414                 }
415
416                 public override MemberSpec InflateMember (TypeParameterInflator inflator)
417                 {
418                         var ms = (MethodSpec) base.InflateMember (inflator);
419                         ms.inflatedMetaInfo = null;
420                         ms.returnType = inflator.Inflate (returnType);
421                         ms.parameters = parameters.Inflate (inflator);
422                         if (IsGeneric)
423                                 ms.constraints = TypeParameterSpec.InflateConstraints (inflator, Constraints);
424
425                         return ms;
426                 }
427
428                 public MethodSpec MakeGenericMethod (IMemberContext context, params TypeSpec[] targs)
429                 {
430                         if (targs == null)
431                                 throw new ArgumentNullException ();
432 // TODO MemberCache
433 //                      if (generic_intances != null && generic_intances.TryGetValue (targs, out ginstance))
434 //                              return ginstance;
435
436                         //if (generic_intances == null)
437                         //    generic_intances = new Dictionary<TypeSpec[], Method> (TypeSpecArrayComparer.Default);
438
439                         var inflator = new TypeParameterInflator (context, DeclaringType, GenericDefinition.TypeParameters, targs);
440
441                         var inflated = (MethodSpec) MemberwiseClone ();
442                         inflated.declaringType = inflator.TypeInstance;
443                         inflated.returnType = inflator.Inflate (returnType);
444                         inflated.parameters = parameters.Inflate (inflator);
445                         inflated.targs = targs;
446                         inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
447                         inflated.state |= StateFlags.PendingMakeMethod;
448
449                         //                      if (inflated.parent == null)
450                         //                              inflated.parent = parent;
451
452                         //generic_intances.Add (targs, inflated);
453                         return inflated;
454                 }
455
456                 public MethodSpec Mutate (TypeParameterMutator mutator)
457                 {
458                         var targs = TypeArguments;
459                         if (targs != null)
460                                 targs = mutator.Mutate (targs);
461
462                         var decl = DeclaringType;
463                         if (DeclaringType.IsGenericOrParentIsGeneric) {
464                                 decl = mutator.Mutate (decl);
465                         }
466
467                         if (targs == TypeArguments && decl == DeclaringType)
468                                 return this;
469
470                         var ms = (MethodSpec) MemberwiseClone ();
471                         if (decl != DeclaringType) {
472                                 ms.inflatedMetaInfo = null;
473                                 ms.declaringType = decl;
474                                 ms.state |= StateFlags.PendingMetaInflate;
475                         }
476
477                         if (targs != null) {
478                                 ms.targs = targs;
479                                 ms.state |= StateFlags.PendingMakeMethod;
480                         }
481
482                         return ms;
483                 }
484
485                 public override List<TypeSpec> ResolveMissingDependencies ()
486                 {
487                         var missing = returnType.ResolveMissingDependencies ();
488                         foreach (var pt in parameters.Types) {
489                                 var m = pt.GetMissingDependencies ();
490                                 if (m == null)
491                                         continue;
492
493                                 if (missing == null)
494                                         missing = new List<TypeSpec> ();
495
496                                 missing.AddRange (m);
497                         }
498
499                         return missing;                 
500                 }
501
502                 public void SetMetaInfo (MethodInfo info)
503                 {
504                         if (this.metaInfo != null)
505                                 throw new InternalErrorException ("MetaInfo reset");
506
507                         this.metaInfo = info;
508                 }
509         }
510
511         public abstract class MethodOrOperator : MethodCore, IMethodData
512         {
513                 public MethodBuilder MethodBuilder;
514                 ReturnParameter return_attributes;
515                 SecurityType declarative_security;
516                 protected MethodData MethodData;
517
518                 static readonly string[] attribute_targets = new string [] { "method", "return" };
519
520                 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, FullNamedExpression type, Modifiers mod,
521                                 Modifiers allowed_mod, MemberName name,
522                                 Attributes attrs, ParametersCompiled parameters)
523                         : base (parent, generic, type, mod, allowed_mod, name,
524                                         attrs, parameters)
525                 {
526                 }
527
528                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
529                 {
530                         if (a.Target == AttributeTargets.ReturnValue) {
531                                 if (return_attributes == null)
532                                         return_attributes = new ReturnParameter (this, MethodBuilder, Location);
533
534                                 return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
535                                 return;
536                         }
537
538                         if (a.Type == pa.MethodImpl) {
539                                 is_external_implementation = a.IsInternalCall ();
540                         }
541
542                         if (a.Type == pa.DllImport) {
543                                 const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC;
544                                 if ((ModFlags & extern_static) != extern_static) {
545                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
546                                 }
547                                 is_external_implementation = true;
548                         }
549
550                         if (a.IsValidSecurityAttribute ()) {
551                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
552                                 return;
553                         }
554
555                         if (MethodBuilder != null)
556                                 MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
557                 }
558
559                 public override AttributeTargets AttributeTargets {
560                         get {
561                                 return AttributeTargets.Method; 
562                         }
563                 }
564
565                 protected override bool CheckForDuplications ()
566                 {
567                         return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
568                 }
569
570                 public virtual EmitContext CreateEmitContext (ILGenerator ig)
571                 {
572                         return new EmitContext (this, ig, MemberType);
573                 }
574
575                 public override bool Define ()
576                 {
577                         if (!base.Define ())
578                                 return false;
579
580                         if (!CheckBase ())
581                                 return false;
582
583                         MemberKind kind;
584                         if (this is Operator)
585                                 kind = MemberKind.Operator;
586                         else if (this is Destructor)
587                                 kind = MemberKind.Destructor;
588                         else
589                                 kind = MemberKind.Method;
590
591                         if (IsPartialDefinition) {
592                                 caching_flags &= ~Flags.Excluded_Undetected;
593                                 caching_flags |= Flags.Excluded;
594
595                                 // Add to member cache only when a partial method implementation has not been found yet
596                                 if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
597 //                                      MethodBase mb = new PartialMethodDefinitionInfo (this);
598
599                                         spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
600                                         if (MemberName.Arity > 0) {
601                                                 spec.IsGeneric = true;
602
603                                                 // TODO: Have to move DefineMethod after Define (ideally to Emit)
604                                                 throw new NotImplementedException ("Generic partial methods");
605                                         }
606
607                                         Parent.MemberCache.AddMember (spec);
608                                 }
609
610                                 return true;
611                         }
612
613                         MethodData = new MethodData (
614                                 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
615
616                         if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName), Report))
617                                 return false;
618                                         
619                         MethodBuilder = MethodData.MethodBuilder;
620
621                         spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
622                         if (MemberName.Arity > 0)
623                                 spec.IsGeneric = true;
624                         
625                         Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
626
627                         return true;
628                 }
629
630                 protected override void DoMemberTypeIndependentChecks ()
631                 {
632                         base.DoMemberTypeIndependentChecks ();
633
634                         CheckAbstractAndExtern (block != null);
635
636                         if ((ModFlags & Modifiers.PARTIAL) != 0) {
637                                 for (int i = 0; i < parameters.Count; ++i) {
638                                         IParameterData p = parameters.FixedParameters [i];
639                                         if (p.ModFlags == Parameter.Modifier.OUT) {
640                                                 Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
641                                                         GetSignatureForError ());
642                                         }
643
644                                         if (p.HasDefaultValue && IsPartialImplementation)
645                                                 ((Parameter) p).Warning_UselessOptionalParameter (Report);
646                                 }
647                         }
648                 }
649
650                 protected override void DoMemberTypeDependentChecks ()
651                 {
652                         base.DoMemberTypeDependentChecks ();
653
654                         if (MemberType.IsStatic) {
655                                 Error_StaticReturnType ();
656                         }
657                 }
658
659                 public override void Emit ()
660                 {
661                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
662                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder);
663                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
664                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder);
665
666                         if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
667                                 return_attributes = new ReturnParameter (this, MethodBuilder, Location);
668                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
669                         } else if (ReturnType.HasDynamicElement) {
670                                 return_attributes = new ReturnParameter (this, MethodBuilder, Location);
671                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
672                         }
673
674                         if (OptAttributes != null)
675                                 OptAttributes.Emit ();
676
677                         if (declarative_security != null) {
678                                 foreach (var de in declarative_security) {
679 #if STATIC
680                                         MethodBuilder.__AddDeclarativeSecurity (de);
681 #else
682                                         MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
683 #endif
684                                 }
685                         }
686
687                         if (type_expr != null)
688                                 ConstraintChecker.Check (this, member_type, type_expr.Location);
689
690                         base.Emit ();
691
692                         if (MethodData != null)
693                                 MethodData.Emit (Parent);
694
695                         Block = null;
696                         MethodData = null;
697                 }
698
699                 protected void Error_ConditionalAttributeIsNotValid ()
700                 {
701                         Report.Error (577, Location,
702                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
703                                 GetSignatureForError ());
704                 }
705
706                 public bool IsPartialDefinition {
707                         get {
708                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
709                         }
710                 }
711
712                 public bool IsPartialImplementation {
713                         get {
714                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
715                         }
716                 }
717
718                 public override string[] ValidAttributeTargets {
719                         get {
720                                 return attribute_targets;
721                         }
722                 }
723
724                 #region IMethodData Members
725
726                 bool IMethodData.IsAccessor {
727                         get {
728                                 return false;
729                         }
730                 }
731
732                 public TypeSpec ReturnType {
733                         get {
734                                 return MemberType;
735                         }
736                 }
737
738                 public MemberName MethodName {
739                         get {
740                                 return MemberName;
741                         }
742                 }
743
744                 /// <summary>
745                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
746                 /// </summary>
747                 public override string[] ConditionalConditions ()
748                 {
749                         if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
750                                 return null;
751
752                         if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.Excluded) != 0)
753                                 return new string [0];
754
755                         caching_flags &= ~Flags.Excluded_Undetected;
756                         string[] conditions;
757
758                         if (base_method == null) {
759                                 if (OptAttributes == null)
760                                         return null;
761
762                                 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
763                                 if (attrs == null)
764                                         return null;
765
766                                 conditions = new string[attrs.Length];
767                                 for (int i = 0; i < conditions.Length; ++i)
768                                         conditions[i] = attrs[i].GetConditionalAttributeValue ();
769                         } else {
770                                 conditions = base_method.MemberDefinition.ConditionalConditions();
771                         }
772
773                         if (conditions != null)
774                                 caching_flags |= Flags.Excluded;
775
776                         return conditions;
777                 }
778
779                 GenericMethod IMethodData.GenericMethod {
780                         get {
781                                 return GenericMethod;
782                         }
783                 }
784
785                 public virtual void EmitExtraSymbolInfo (SourceMethod source)
786                 { }
787
788                 #endregion
789
790         }
791
792         public class SourceMethod : IMethodDef
793         {
794                 MethodBase method;
795                 SourceMethodBuilder builder;
796
797                 protected SourceMethod (DeclSpace parent, MethodBase method, ICompileUnit file)
798                 {
799                         this.method = method;
800                         
801                         builder = SymbolWriter.OpenMethod (file, parent.NamespaceEntry.SymbolFileID, this);
802                 }
803
804                 public string Name {
805                         get { return method.Name; }
806                 }
807
808                 public int Token {
809                         get {
810                                 MethodToken token;
811                                 var mb = method as MethodBuilder;
812                                 if (mb != null)
813                                         token = mb.GetToken ();
814                                 else
815                                         token = ((ConstructorBuilder) method).GetToken ();
816 #if STATIC
817                                 if (token.IsPseudoToken)
818                                         return ((ModuleBuilder) method.Module).ResolvePseudoToken (token.Token);
819 #endif
820                                 return token.Token;
821                         }
822                 }
823
824                 public void CloseMethod ()
825                 {
826                         SymbolWriter.CloseMethod ();
827                 }
828
829                 public void SetRealMethodName (string name)
830                 {
831                         if (builder != null)
832                                 builder.SetRealMethodName (name);
833                 }
834
835                 public static SourceMethod Create (DeclSpace parent, MethodBase method, Block block)
836                 {
837                         if (!SymbolWriter.HasSymbolWriter)
838                                 return null;
839                         if (block == null)
840                                 return null;
841
842                         Location start_loc = block.StartLocation;
843                         if (start_loc.IsNull)
844                                 return null;
845
846                         ICompileUnit compile_unit = start_loc.CompilationUnit;
847                         if (compile_unit == null)
848                                 return null;
849
850                         return new SourceMethod (parent, method, compile_unit);
851                 }
852         }
853
854         public class Method : MethodOrOperator, IGenericMethodDefinition
855         {
856                 Method partialMethodImplementation;
857
858                 public Method (DeclSpace parent, GenericMethod generic,
859                                FullNamedExpression return_type, Modifiers mod,
860                                MemberName name, ParametersCompiled parameters, Attributes attrs)
861                         : base (parent, generic, return_type, mod,
862                                 parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface :
863                                 parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct | Modifiers.ASYNC :
864                                 AllowedModifiersClass | Modifiers.ASYNC,
865                                 name, attrs, parameters)
866                 {
867                 }
868
869                 protected Method (DeclSpace parent, FullNamedExpression return_type, Modifiers mod, Modifiers amod,
870                                         MemberName name, ParametersCompiled parameters, Attributes attrs)
871                         : base (parent, null, return_type, mod, amod, name, attrs, parameters)
872                 {
873                 }
874
875                 #region Properties
876
877                 public override TypeParameter[] CurrentTypeParameters {
878                         get {
879                                 if (GenericMethod != null)
880                                         return GenericMethod.CurrentTypeParameters;
881
882                                 return null;
883                         }
884                 }
885
886                 public TypeParameterSpec[] TypeParameters {
887                         get {
888                                 // TODO: Cache this
889                                 return CurrentTypeParameters.Select (l => l.Type).ToArray ();
890                         }
891                 }
892
893                 public int TypeParametersCount {
894                         get {
895                                 return CurrentTypeParameters == null ? 0 : CurrentTypeParameters.Length;
896                         }
897                 }
898
899 #endregion
900
901                 public override string GetSignatureForError()
902                 {
903                         return base.GetSignatureForError () + parameters.GetSignatureForError ();
904                 }
905
906                 void Error_DuplicateEntryPoint (Method b)
907                 {
908                         Report.Error (17, b.Location,
909                                 "Program `{0}' has more than one entry point defined: `{1}'",
910                                 b.Module.Builder.ScopeName, b.GetSignatureForError ());
911                 }
912
913                 bool IsEntryPoint ()
914                 {
915                         if (ReturnType.Kind != MemberKind.Void && ReturnType.BuiltinType != BuiltinTypeSpec.Type.Int)
916                                 return false;
917
918                         if (parameters.IsEmpty)
919                                 return true;
920
921                         if (parameters.Count > 1)
922                                 return false;
923
924                         var ac = parameters.Types [0] as ArrayContainer;
925                         return ac != null && ac.Rank == 1 && ac.Element.BuiltinType == BuiltinTypeSpec.Type.String &&
926                                         (parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
927                 }
928
929                 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
930                 {
931                         if (arity == 0) {
932                                 TypeParameter[] tp = CurrentTypeParameters;
933                                 if (tp != null) {
934                                         TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
935                                         if (t != null)
936                                                 return new TypeParameterExpr (t, loc);
937                                 }
938                         }
939
940                         return base.LookupNamespaceOrType (name, arity, mode, loc);
941                 }
942
943                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
944                 {
945                         if (a.Type == pa.Conditional) {
946                                 if (IsExplicitImpl) {
947                                         Error_ConditionalAttributeIsNotValid ();
948                                         return;
949                                 }
950
951                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
952                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
953                                         return;
954                                 }
955
956                                 if (ReturnType.Kind != MemberKind.Void) {
957                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
958                                         return;
959                                 }
960
961                                 if (IsInterface) {
962                                         Report.Error (582, Location, "Conditional not valid on interface members");
963                                         return;
964                                 }
965
966                                 if (MethodData.implementing != null) {
967                                         Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
968                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
969                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
970                                         return;
971                                 }
972
973                                 for (int i = 0; i < parameters.Count; ++i) {
974                                         if (parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
975                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
976                                                 return;
977                                         }
978                                 }
979                         }
980
981                         if (a.Type == pa.Extension) {
982                                 a.Error_MisusedExtensionAttribute ();
983                                 return;
984                         }
985
986                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
987                 }
988
989                 protected virtual void DefineTypeParameters ()
990                 {
991                         var tparams = CurrentTypeParameters;
992
993                         TypeParameterSpec[] base_tparams = null;
994                         TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
995                         TypeSpec[] base_targs = TypeSpec.EmptyTypes;
996                         if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
997                                 if (base_method != null) {
998                                         base_tparams = base_method.GenericDefinition.TypeParameters;
999                                 
1000                                         if (base_method.DeclaringType.IsGeneric) {
1001                                                 base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters;
1002
1003                                                 var base_type_parent = CurrentType;
1004                                                 while (base_type_parent.BaseType != base_method.DeclaringType) {
1005                                                         base_type_parent = base_type_parent.BaseType;
1006                                                 }
1007
1008                                                 base_targs = base_type_parent.BaseType.TypeArguments;
1009                                         }
1010
1011                                         if (base_method.IsGeneric) {
1012                                                 ObsoleteAttribute oa;
1013                                                 foreach (var base_tp in base_tparams) {
1014                                                         oa = base_tp.BaseType.GetAttributeObsolete ();
1015                                                         if (oa != null) {
1016                                                                 AttributeTester.Report_ObsoleteMessage (oa, base_tp.BaseType.GetSignatureForError (), Location, Report);
1017                                                         }
1018
1019                                                         if (base_tp.InterfacesDefined != null) {
1020                                                                 foreach (var iface in base_tp.InterfacesDefined) {
1021                                                                         oa = iface.GetAttributeObsolete ();
1022                                                                         if (oa != null) {
1023                                                                                 AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
1024                                                                         }
1025                                                                 }
1026                                                         }
1027                                                 }
1028
1029                                                 if (base_decl_tparams.Length != 0) {
1030                                                         base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
1031                                                         base_targs = base_targs.Concat (tparams.Select<TypeParameter, TypeSpec> (l => l.Type)).ToArray ();
1032                                                 } else {
1033                                                         base_decl_tparams = base_tparams;
1034                                                         base_targs = tparams.Select (l => l.Type).ToArray ();
1035                                                 }
1036                                         }
1037                                 } else if (MethodData.implementing != null) {
1038                                         base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
1039                                         if (MethodData.implementing.DeclaringType.IsGeneric) {
1040                                                 base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters;
1041                                                 foreach (var iface in Parent.CurrentType.Interfaces) {
1042                                                         if (iface == MethodData.implementing.DeclaringType) {
1043                                                                 base_targs = iface.TypeArguments;
1044                                                                 break;
1045                                                         }
1046                                                 }
1047                                         }
1048                                 }
1049                         }
1050
1051                         for (int i = 0; i < tparams.Length; ++i) {
1052                                 var tp = tparams[i];
1053
1054                                 if (!tp.ResolveConstraints (this))
1055                                         continue;
1056
1057                                 //
1058                                 // Copy base constraints for override/explicit methods
1059                                 //
1060                                 if (base_tparams != null) {
1061                                         var base_tparam = base_tparams[i];
1062                                         var local_tparam = tp.Type;
1063                                         local_tparam.SpecialConstraint = base_tparam.SpecialConstraint;
1064
1065                                         var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs);
1066                                         base_tparam.InflateConstraints (inflator, local_tparam);
1067
1068                                         //
1069                                         // Check all type argument constraints for possible collision
1070                                         // introduced by inflating inherited constraints in this context
1071                                         //
1072                                         // Conflict example:
1073                                         //
1074                                         // class A<T> { virtual void Foo<U> () where U : class, T {} }
1075                                         // class B : A<int> { override void Foo<U> {} }
1076                                         //
1077                                         var local_tparam_targs = local_tparam.TypeArguments;
1078                                         if (local_tparam_targs != null) {                                       
1079                                                 for (int ii = 0; ii < local_tparam_targs.Length; ++ii) {
1080                                                         var ta = local_tparam_targs [ii];
1081                                                         if (!ta.IsClass && !ta.IsStruct)
1082                                                                 continue;
1083
1084                                                         if (Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location)) {
1085                                                                 local_tparam.ChangeTypeArgumentToBaseType (ii);
1086                                                         }
1087                                                 }
1088                                         }
1089
1090                                         continue;
1091                                 }
1092                                 
1093                                 if (MethodData != null && MethodData.implementing != null) {
1094                                         var base_tp = MethodData.implementing.Constraints[i];
1095                                         if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
1096                                                 Report.SymbolRelatedToPreviousError (MethodData.implementing);
1097                                                 Report.Error (425, Location,
1098                                                         "The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
1099                                                         tp.GetSignatureForError (), GetSignatureForError (), base_tp.GetSignatureForError (), MethodData.implementing.GetSignatureForError ());
1100                                         }
1101                                 }
1102                         }
1103                 }
1104
1105                 //
1106                 // Creates the type
1107                 //
1108                 public override bool Define ()
1109                 {
1110                         if (!base.Define ())
1111                                 return false;
1112
1113                         if (member_type.Kind == MemberKind.Void && parameters.IsEmpty && MemberName.Arity == 0 && MemberName.Name == Destructor.MetadataName) {
1114                                 Report.Warning (465, 1, Location,
1115                                         "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
1116                         }
1117
1118                         if (partialMethodImplementation != null && IsPartialDefinition)
1119                                 MethodBuilder = partialMethodImplementation.MethodBuilder;
1120
1121                         if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) {
1122                                 Error1599 (Location, ReturnType, Report);
1123                                 return false;
1124                         }
1125
1126                         if (CurrentTypeParameters == null) {
1127                                 if (base_method != null) {
1128                                         if (parameters.Count == 1 && ParameterTypes[0].BuiltinType == BuiltinTypeSpec.Type.Object && Name == "Equals")
1129                                                 Parent.PartialContainer.Mark_HasEquals ();
1130                                         else if (parameters.IsEmpty && Name == "GetHashCode")
1131                                                 Parent.PartialContainer.Mark_HasGetHashCode ();
1132                                 }
1133                                         
1134                         } else {
1135                                 DefineTypeParameters ();
1136                         }
1137
1138                         if (block != null) {
1139                                 if (block.IsIterator) {
1140                                         //
1141                                         // Current method is turned into automatically generated
1142                                         // wrapper which creates an instance of iterator
1143                                         //
1144                                         Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1145                                         ModFlags |= Modifiers.DEBUGGER_HIDDEN;
1146                                 }
1147
1148                                 if ((ModFlags & Modifiers.ASYNC) != 0) {
1149                                         AsyncInitializer.Create (block, parameters, Parent.PartialContainer, ReturnType, Location);
1150                                 }
1151                         }
1152
1153                         if ((ModFlags & Modifiers.STATIC) == 0)
1154                                 return true;
1155
1156                         if (parameters.HasExtensionMethodType) {
1157                                 if (Parent.PartialContainer.IsStatic && !Parent.IsGeneric) {
1158                                         if (!Parent.IsTopLevel)
1159                                                 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
1160                                                         GetSignatureForError ());
1161
1162                                         PredefinedAttribute pa = Module.PredefinedAttributes.Extension;
1163                                         if (!pa.IsDefined) {
1164                                                 Report.Error (1110, Location,
1165                                                         "`{0}': Extension methods cannot be declared without a reference to System.Core.dll assembly. Add the assembly reference or remove `this' modifer from the first parameter",
1166                                                         GetSignatureForError ());
1167                                         }
1168
1169                                         ModFlags |= Modifiers.METHOD_EXTENSION;
1170                                         Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
1171                                         Spec.DeclaringType.SetExtensionMethodContainer ();
1172                                         Parent.Module.HasExtensionMethod = true;
1173                                 } else {
1174                                         Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
1175                                                 GetSignatureForError ());
1176                                 }
1177                         }
1178
1179                         //
1180                         // This is used to track the Entry Point,
1181                         //
1182                         var settings = Compiler.Settings;
1183                         if (settings.NeedsEntryPoint && Name == "Main" && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
1184                                 if (IsEntryPoint ()) {
1185                                         if (Parent.DeclaringAssembly.EntryPoint == null) {
1186                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
1187                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
1188                                                                 GetSignatureForError ());
1189                                                 } else {
1190                                                         SetIsUsed ();
1191                                                         Parent.DeclaringAssembly.EntryPoint = this;
1192                                                 }
1193                                         } else {
1194                                                 Error_DuplicateEntryPoint (Parent.DeclaringAssembly.EntryPoint);
1195                                                 Error_DuplicateEntryPoint (this);
1196                                         }
1197                                 } else {
1198                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
1199                                                 GetSignatureForError ());
1200                                 }
1201                         }
1202
1203                         return true;
1204                 }
1205
1206                 //
1207                 // Emits the code
1208                 // 
1209                 public override void Emit ()
1210                 {
1211                         try {
1212                                 if (IsPartialDefinition) {
1213                                         //
1214                                         // Use partial method implementation builder for partial method declaration attributes
1215                                         //
1216                                         if (partialMethodImplementation != null) {
1217                                                 MethodBuilder = partialMethodImplementation.MethodBuilder;
1218                                         }
1219
1220                                         return;
1221                                 }
1222                                 
1223                                 if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) {
1224                                         Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
1225                                                 GetSignatureForError ());
1226                                 }
1227
1228                                 if (CurrentTypeParameters != null) {
1229                                         for (int i = 0; i < CurrentTypeParameters.Length; ++i) {
1230                                                 var tp = CurrentTypeParameters [i];
1231                                                 tp.CheckGenericConstraints (false);
1232                                                 tp.Emit ();
1233                                         }
1234                                 }
1235
1236                                 base.Emit ();
1237                                 
1238                                 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
1239                                         Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
1240                         } catch {
1241                                 Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
1242                                                    Location, MethodBuilder);
1243                                 throw;
1244                         }
1245                 }
1246
1247                 public override bool EnableOverloadChecks (MemberCore overload)
1248                 {
1249                         // TODO: It can be deleted when members will be defined in correct order
1250                         if (overload is Operator)
1251                                 return overload.EnableOverloadChecks (this);
1252
1253                         if (overload is Indexer)
1254                                 return false;
1255
1256                         return base.EnableOverloadChecks (overload);
1257                 }
1258
1259                 public static void Error1599 (Location loc, TypeSpec t, Report Report)
1260                 {
1261                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
1262                 }
1263
1264                 protected override bool ResolveMemberType ()
1265                 {
1266                         if (GenericMethod != null) {
1267                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
1268                                 if (!GenericMethod.Define (this))
1269                                         return false;
1270                         }
1271
1272                         return base.ResolveMemberType ();
1273                 }
1274
1275                 public void SetPartialDefinition (Method methodDefinition)
1276                 {
1277                         caching_flags |= Flags.PartialDefinitionExists;
1278                         methodDefinition.partialMethodImplementation = this;
1279
1280                         // Ensure we are always using method declaration parameters
1281                         for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
1282                                 parameters [i].Name = methodDefinition.parameters [i].Name;
1283                                 parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
1284                         }
1285
1286                         if (methodDefinition.attributes == null)
1287                                 return;
1288
1289                         if (attributes == null) {
1290                                 attributes = methodDefinition.attributes;
1291                         } else {
1292                                 attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
1293                         }
1294                 }
1295         }
1296
1297         public abstract class ConstructorInitializer : ExpressionStatement
1298         {
1299                 Arguments argument_list;
1300                 MethodSpec base_ctor;
1301
1302                 public ConstructorInitializer (Arguments argument_list, Location loc)
1303                 {
1304                         this.argument_list = argument_list;
1305                         this.loc = loc;
1306                 }
1307
1308                 public Arguments Arguments {
1309                         get {
1310                                 return argument_list;
1311                         }
1312                 }
1313
1314                 public override Expression CreateExpressionTree (ResolveContext ec)
1315                 {
1316                         throw new NotSupportedException ("ET");
1317                 }
1318
1319                 protected override Expression DoResolve (ResolveContext ec)
1320                 {
1321                         eclass = ExprClass.Value;
1322
1323                         // FIXME: Hack
1324                         var caller_builder = (Constructor) ec.MemberContext;
1325
1326                         //
1327                         // Spec mandates that constructor initializer will not have `this' access
1328                         //
1329                         using (ec.Set (ResolveContext.Options.BaseInitializer)) {
1330                                 if (argument_list != null) {
1331                                         bool dynamic;
1332                                         argument_list.Resolve (ec, out dynamic);
1333
1334                                         if (dynamic) {
1335                                                 ec.Report.Error (1975, loc,
1336                                                         "The constructor call cannot be dynamically dispatched within constructor initializer");
1337
1338                                                 return null;
1339                                         }
1340                                 }
1341
1342                                 type = ec.CurrentType;
1343                                 if (this is ConstructorBaseInitializer) {
1344                                         if (ec.CurrentType.BaseType == null)
1345                                                 return this;
1346
1347                                         type = ec.CurrentType.BaseType;
1348                                         if (ec.CurrentType.IsStruct) {
1349                                                 ec.Report.Error (522, loc,
1350                                                         "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
1351                                                 return this;
1352                                         }
1353                                 } else {
1354                                         //
1355                                         // It is legal to have "this" initializers that take no arguments
1356                                         // in structs, they are just no-ops.
1357                                         //
1358                                         // struct D { public D (int a) : this () {}
1359                                         //
1360                                         if (ec.CurrentType.IsStruct && argument_list == null)
1361                                                 return this;
1362                                 }
1363
1364                                 base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
1365                         }
1366         
1367                         // TODO MemberCache: Does it work for inflated types ?
1368                         if (base_ctor == caller_builder.Spec){
1369                                 ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
1370                                         caller_builder.GetSignatureForError ());
1371                         }
1372                                                 
1373                         return this;
1374                 }
1375
1376                 public override void Emit (EmitContext ec)
1377                 {
1378                         // It can be null for static initializers
1379                         if (base_ctor == null)
1380                                 return;
1381                         
1382                         ec.Mark (loc);
1383
1384                         Invocation.EmitCall (ec, new CompilerGeneratedThis (type, loc), base_ctor, argument_list, loc);
1385                 }
1386
1387                 public override void EmitStatement (EmitContext ec)
1388                 {
1389                         Emit (ec);
1390                 }
1391         }
1392
1393         public class ConstructorBaseInitializer : ConstructorInitializer {
1394                 public ConstructorBaseInitializer (Arguments argument_list, Location l) :
1395                         base (argument_list, l)
1396                 {
1397                 }
1398         }
1399
1400         class GeneratedBaseInitializer: ConstructorBaseInitializer {
1401                 public GeneratedBaseInitializer (Location loc):
1402                         base (null, loc)
1403                 {
1404                 }
1405         }
1406
1407         public class ConstructorThisInitializer : ConstructorInitializer {
1408                 public ConstructorThisInitializer (Arguments argument_list, Location l) :
1409                         base (argument_list, l)
1410                 {
1411                 }
1412         }
1413         
1414         public class Constructor : MethodCore, IMethodData {
1415                 public ConstructorBuilder ConstructorBuilder;
1416                 public ConstructorInitializer Initializer;
1417                 SecurityType declarative_security;
1418                 bool has_compliant_args;
1419
1420                 // <summary>
1421                 //   Modifiers allowed for a constructor.
1422                 // </summary>
1423                 public const Modifiers AllowedModifiers =
1424                         Modifiers.PUBLIC |
1425                         Modifiers.PROTECTED |
1426                         Modifiers.INTERNAL |
1427                         Modifiers.STATIC |
1428                         Modifiers.UNSAFE |
1429                         Modifiers.EXTERN |              
1430                         Modifiers.PRIVATE;
1431
1432                 static readonly string[] attribute_targets = new string [] { "method" };
1433
1434                 public static readonly string ConstructorName = ".ctor";
1435                 public static readonly string TypeConstructorName = ".cctor";
1436
1437                 //
1438                 // The spec claims that static is not permitted, but
1439                 // my very own code has static constructors.
1440                 //
1441                 public Constructor (DeclSpace parent, string name, Modifiers mod, Attributes attrs, ParametersCompiled args,
1442                                     ConstructorInitializer init, Location loc)
1443                         : base (parent, null, null, mod, AllowedModifiers,
1444                                 new MemberName (name, loc), attrs, args)
1445                 {
1446                         Initializer = init;
1447                 }
1448
1449                 public bool HasCompliantArgs {
1450                         get { return has_compliant_args; }
1451                 }
1452
1453                 public override AttributeTargets AttributeTargets {
1454                         get {
1455                                 return AttributeTargets.Constructor;
1456                         }
1457                 }
1458
1459                 bool IMethodData.IsAccessor {
1460                         get {
1461                                 return false;
1462                         }
1463                 }
1464
1465                 //
1466                 // Returns true if this is a default constructor
1467                 //
1468                 public bool IsDefault ()
1469                 {
1470                         if ((ModFlags & Modifiers.STATIC) != 0)
1471                                 return parameters.IsEmpty;
1472
1473                         return parameters.IsEmpty &&
1474                                         (Initializer is ConstructorBaseInitializer) &&
1475                                         (Initializer.Arguments == null);
1476                 }
1477
1478                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
1479                 {
1480                         if (a.IsValidSecurityAttribute ()) {
1481                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
1482                                 return;
1483                         }
1484
1485                         if (a.Type == pa.MethodImpl) {
1486                                 is_external_implementation = a.IsInternalCall ();
1487                         }
1488
1489                         ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
1490                 }
1491
1492                 protected override bool CheckBase ()
1493                 {
1494                         if ((ModFlags & Modifiers.STATIC) != 0) {
1495                                 if (!parameters.IsEmpty) {
1496                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
1497                                                 GetSignatureForError ());
1498                                         return false;
1499                                 }
1500
1501                                 // the rest can be ignored
1502                                 return true;
1503                         }
1504
1505                         // Check whether arguments were correct.
1506                         if (!DefineParameters (parameters))
1507                                 return false;
1508
1509                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
1510                                 Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
1511
1512                         if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
1513                                 Report.Error (568, Location, 
1514                                         "Structs cannot contain explicit parameterless constructors");
1515                                 return false;
1516                         }
1517
1518                         CheckProtectedModifier ();
1519                         
1520                         return true;
1521                 }
1522                 
1523                 //
1524                 // Creates the ConstructorBuilder
1525                 //
1526                 public override bool Define ()
1527                 {
1528                         if (ConstructorBuilder != null)
1529                                 return true;
1530
1531                         var ca = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
1532                         
1533                         if ((ModFlags & Modifiers.STATIC) != 0) {
1534                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
1535                         } else {
1536                                 ca |= ModifiersExtensions.MethodAttr (ModFlags);
1537                         }
1538
1539                         if (!CheckAbstractAndExtern (block != null))
1540                                 return false;
1541                         
1542                         // Check if arguments were correct.
1543                         if (!CheckBase ())
1544                                 return false;
1545
1546                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
1547                                 ca, CallingConventions,
1548                                 parameters.GetMetaInfo ());
1549
1550                         spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
1551                         
1552                         Parent.MemberCache.AddMember (spec);
1553                         
1554                         // It's here only to report an error
1555                         if (block != null && block.IsIterator) {
1556                                 member_type = Compiler.BuiltinTypes.Void;
1557                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1558                         }
1559
1560                         return true;
1561                 }
1562
1563                 //
1564                 // Emits the code
1565                 //
1566                 public override void Emit ()
1567                 {
1568                         if (Parent.PartialContainer.IsComImport) {
1569                                 if (!IsDefault ()) {
1570                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
1571                                                 Parent.GetSignatureForError ());
1572                                 }
1573
1574                                 // Set as internal implementation and reset block data
1575                                 // to ensure no IL is generated
1576                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
1577                                 block = null;
1578                         }
1579
1580                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
1581                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder);
1582
1583                         if (OptAttributes != null)
1584                                 OptAttributes.Emit ();
1585
1586                         base.Emit ();
1587                         parameters.ApplyAttributes (this, ConstructorBuilder);
1588
1589                         //
1590                         // If we use a "this (...)" constructor initializer, then
1591                         // do not emit field initializers, they are initialized in the other constructor
1592                         //
1593                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
1594                                 !(Initializer is ConstructorThisInitializer);
1595
1596                         BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
1597                         bc.Set (ResolveContext.Options.ConstructorScope);
1598
1599                         if (emit_field_initializers)
1600                                 Parent.PartialContainer.ResolveFieldInitializers (bc);
1601
1602                         if (block != null) {
1603                                 // If this is a non-static `struct' constructor and doesn't have any
1604                                 // initializer, it must initialize all of the struct's fields.
1605                                 if ((Parent.PartialContainer.Kind == MemberKind.Struct) &&
1606                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
1607                                         block.AddThisVariable (bc, Parent, Location);
1608
1609                                 if (block != null && (ModFlags & Modifiers.STATIC) == 0){
1610                                         if (Parent.PartialContainer.Kind == MemberKind.Class && Initializer == null)
1611                                                 Initializer = new GeneratedBaseInitializer (Location);
1612
1613                                         if (Initializer != null) {
1614                                                 block.AddScopeStatement (new StatementExpression (Initializer));
1615                                         }
1616                                 }
1617                         }
1618
1619                         SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
1620
1621                         if (block != null) {
1622                                 if (block.Resolve (null, bc, this)) {
1623                                         EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType);
1624                                         ec.With (EmitContext.Options.ConstructorScope, true);
1625
1626                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
1627                                                 ec.ReturnLabel = bc.ReturnLabel;
1628                                                 ec.HasReturnLabel = true;
1629                                         }
1630
1631                                         block.Emit (ec);
1632                                 }
1633                         }
1634
1635                         if (source != null)
1636                                 source.CloseMethod ();
1637
1638                         if (declarative_security != null) {
1639                                 foreach (var de in declarative_security) {
1640 #if STATIC
1641                                         ConstructorBuilder.__AddDeclarativeSecurity (de);
1642 #else
1643                                         ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value);
1644 #endif
1645                                 }
1646                         }
1647
1648                         block = null;
1649                 }
1650
1651                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
1652                 {
1653                         // Is never override
1654                         bestCandidate = null;
1655                         return null;
1656                 }
1657
1658                 public override string GetSignatureForDocumentation ()
1659                 {
1660                         return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
1661                 }
1662
1663                 public override string GetSignatureForError()
1664                 {
1665                         return base.GetSignatureForError () + parameters.GetSignatureForError ();
1666                 }
1667
1668                 public override string[] ValidAttributeTargets {
1669                         get {
1670                                 return attribute_targets;
1671                         }
1672                 }
1673
1674                 protected override bool VerifyClsCompliance ()
1675                 {
1676                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
1677                                 return false;
1678                         }
1679
1680                         if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
1681                                 foreach (TypeSpec param in parameters.Types) {
1682                                         if (param.IsArray) {
1683                                                 return true;
1684                                         }
1685                                 }
1686                         }
1687
1688                         has_compliant_args = true;
1689                         return true;
1690                 }
1691
1692                 #region IMethodData Members
1693
1694                 public MemberName MethodName {
1695                         get {
1696                                 return MemberName;
1697                         }
1698                 }
1699
1700                 public TypeSpec ReturnType {
1701                         get {
1702                                 return MemberType;
1703                         }
1704                 }
1705
1706                 public EmitContext CreateEmitContext (ILGenerator ig)
1707                 {
1708                         throw new NotImplementedException ();
1709                 }
1710
1711                 public bool IsExcluded()
1712                 {
1713                         return false;
1714                 }
1715
1716                 GenericMethod IMethodData.GenericMethod {
1717                         get {
1718                                 return null;
1719                         }
1720                 }
1721
1722                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
1723                 { }
1724
1725                 #endregion
1726         }
1727
1728         /// <summary>
1729         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
1730         /// </summary>
1731         public interface IMethodData : IMemberContext
1732         {
1733                 CallingConventions CallingConventions { get; }
1734                 Location Location { get; }
1735                 MemberName MethodName { get; }
1736                 TypeSpec ReturnType { get; }
1737                 GenericMethod GenericMethod { get; }
1738                 ParametersCompiled ParameterInfo { get; }
1739                 MethodSpec Spec { get; }
1740                 bool IsAccessor { get; }
1741
1742                 Attributes OptAttributes { get; }
1743                 ToplevelBlock Block { get; set; }
1744
1745                 EmitContext CreateEmitContext (ILGenerator ig);
1746                 void EmitExtraSymbolInfo (SourceMethod source);
1747         }
1748
1749         //
1750         // Encapsulates most of the Method's state
1751         //
1752         public class MethodData
1753         {
1754 #if !STATIC
1755                 static FieldInfo methodbuilder_attrs_field;
1756 #endif
1757
1758                 public readonly IMethodData method;
1759
1760                 public readonly GenericMethod GenericMethod;
1761
1762                 //
1763                 // Are we implementing an interface ?
1764                 //
1765                 public MethodSpec implementing;
1766
1767                 //
1768                 // Protected data.
1769                 //
1770                 protected InterfaceMemberBase member;
1771                 protected Modifiers modifiers;
1772                 protected MethodAttributes flags;
1773                 protected TypeSpec declaring_type;
1774                 protected MethodSpec parent_method;
1775
1776                 MethodBuilder builder;
1777                 public MethodBuilder MethodBuilder {
1778                         get {
1779                                 return builder;
1780                         }
1781                 }
1782
1783                 public TypeSpec DeclaringType {
1784                         get {
1785                                 return declaring_type;
1786                         }
1787                 }
1788
1789                 public MethodData (InterfaceMemberBase member,
1790                                    Modifiers modifiers, MethodAttributes flags, IMethodData method)
1791                 {
1792                         this.member = member;
1793                         this.modifiers = modifiers;
1794                         this.flags = flags;
1795
1796                         this.method = method;
1797                 }
1798
1799                 public MethodData (InterfaceMemberBase member,
1800                                    Modifiers modifiers, MethodAttributes flags, 
1801                                    IMethodData method, MethodBuilder builder,
1802                                    GenericMethod generic, MethodSpec parent_method)
1803                         : this (member, modifiers, flags, method)
1804                 {
1805                         this.builder = builder;
1806                         this.GenericMethod = generic;
1807                         this.parent_method = parent_method;
1808                 }
1809
1810                 public bool Define (DeclSpace parent, string method_full_name, Report Report)
1811                 {
1812                         TypeContainer container = parent.PartialContainer;
1813
1814                         PendingImplementation pending = container.PendingImplementations;
1815                         MethodSpec ambig_iface_method;
1816                         if (pending != null) {
1817                                 implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method);
1818
1819                                 if (member.InterfaceType != null) {
1820                                         if (implementing == null) {
1821                                                 if (member is PropertyBase) {
1822                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
1823                                                                           method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
1824                                                                           member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
1825
1826                                                 } else {
1827                                                         Report.Error (539, method.Location,
1828                                                                           "`{0}.{1}' in explicit interface declaration is not a member of interface",
1829                                                                           TypeManager.CSharpName (member.InterfaceType), member.ShortName);
1830                                                 }
1831                                                 return false;
1832                                         }
1833                                         if (implementing.IsAccessor && !method.IsAccessor) {
1834                                                 Report.SymbolRelatedToPreviousError (implementing);
1835                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
1836                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1837                                                 return false;
1838                                         }
1839                                 } else {
1840                                         if (implementing != null) {
1841                                                 if (!method.IsAccessor) {
1842                                                         if (implementing.IsAccessor) {
1843                                                                 Report.SymbolRelatedToPreviousError (implementing);
1844                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'",
1845                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1846                                                         }
1847                                                 } else if (implementing.DeclaringType.IsInterface) {
1848                                                         if (!implementing.IsAccessor) {
1849                                                                 Report.SymbolRelatedToPreviousError (implementing);
1850                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
1851                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
1852                                                         } else {
1853                                                                 PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
1854                                                                 if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
1855                                                                         Report.SymbolRelatedToPreviousError (implementing);
1856                                                                         Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
1857                                                                                 method.GetSignatureForError (), implementing.GetSignatureForError ());
1858                                                                 }
1859                                                         }
1860                                                 }
1861                                         }
1862                                 }
1863                         } else {
1864                                 ambig_iface_method = null;
1865                         }
1866
1867                         //
1868                         // For implicit implementations, make sure we are public, for
1869                         // explicit implementations, make sure we are private.
1870                         //
1871                         if (implementing != null){
1872                                 //
1873                                 // Setting null inside this block will trigger a more
1874                                 // verbose error reporting for missing interface implementations
1875                                 //
1876                                 // The "candidate" function has been flagged already
1877                                 // but it wont get cleared
1878                                 //
1879                                 if (member.IsExplicitImpl){
1880                                         if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
1881                                                 Report.SymbolRelatedToPreviousError (implementing);
1882                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
1883                                                         method.GetSignatureForError ());
1884                                         }
1885
1886                                         if (ambig_iface_method != null) {
1887                                                 Report.SymbolRelatedToPreviousError (ambig_iface_method);
1888                                                 Report.SymbolRelatedToPreviousError (implementing);
1889                                                 Report.Warning (473, 2, method.Location,
1890                                                         "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
1891                                                         method.GetSignatureForError ());
1892                                         }
1893
1894                                 } else {
1895                                         if (implementing.DeclaringType.IsInterface) {
1896                                                 //
1897                                                 // If this is an interface method implementation,
1898                                                 // check for public accessibility
1899                                                 //
1900                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
1901                                                 {
1902                                                         implementing = null;
1903                                                 }
1904                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
1905                                                 // We may never be private.
1906                                                 implementing = null;
1907
1908                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
1909                                                 //
1910                                                 // We may be protected if we're overriding something.
1911                                                 //
1912                                                 implementing = null;
1913                                         }
1914                                 }
1915                                         
1916                                 //
1917                                 // Static is not allowed
1918                                 //
1919                                 if ((modifiers & Modifiers.STATIC) != 0){
1920                                         implementing = null;
1921                                 }
1922                         }
1923                         
1924                         //
1925                         // If implementing is still valid, set flags
1926                         //
1927                         if (implementing != null){
1928                                 //
1929                                 // When implementing interface methods, set NewSlot
1930                                 // unless, we are overwriting a method.
1931                                 //
1932                                 if (implementing.DeclaringType.IsInterface){
1933                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
1934                                                 flags |= MethodAttributes.NewSlot;
1935                                 }
1936
1937                                 flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig;
1938
1939                                 // Set Final unless we're virtual, abstract or already overriding a method.
1940                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
1941                                         flags |= MethodAttributes.Final;
1942
1943                                 //
1944                                 // clear the pending implementation flag (requires explicit methods to be defined first)
1945                                 //
1946                                 parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName,
1947                                         member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method);
1948
1949                                 //
1950                                 // Update indexer accessor name to match implementing abstract accessor
1951                                 //
1952                                 if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor)
1953                                         method_full_name = implementing.MemberDefinition.Name;
1954                         }
1955
1956                         DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
1957
1958                         if (builder == null)
1959                                 return false;
1960
1961 //                      if (container.CurrentType != null)
1962 //                              declaring_type = container.CurrentType;
1963 //                      else
1964                                 declaring_type = container.Definition;
1965
1966                         if (implementing != null && member.IsExplicitImpl) {
1967                                 container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
1968                         }
1969
1970                         return true;
1971                 }
1972
1973
1974                 /// <summary>
1975                 /// Create the MethodBuilder for the method 
1976                 /// </summary>
1977                 void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param)
1978                 {
1979                         var return_type = method.ReturnType.GetMetaInfo ();
1980                         var p_types = param.GetMetaInfo ();
1981
1982                         if (builder == null) {
1983                                 builder = container.TypeBuilder.DefineMethod (
1984                                         method_name, flags, method.CallingConventions,
1985                                         return_type, p_types);
1986                                 return;
1987                         }
1988
1989                         //
1990                         // Generic method has been already defined to resolve method parameters
1991                         // correctly when they use type parameters
1992                         //
1993                         builder.SetParameters (p_types);
1994                         builder.SetReturnType (return_type);
1995                         if (builder.Attributes != flags) {
1996 #if STATIC
1997                                 builder.__SetAttributes (flags);
1998 #else
1999                                 try {
2000                                         if (methodbuilder_attrs_field == null)
2001                                                 methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
2002                                         methodbuilder_attrs_field.SetValue (builder, flags);
2003                                 } catch {
2004                                         container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
2005                                 }
2006 #endif
2007                         }
2008                 }
2009
2010                 //
2011                 // Emits the code
2012                 // 
2013                 public void Emit (DeclSpace parent)
2014                 {
2015                         if (GenericMethod != null)
2016                                 GenericMethod.EmitAttributes ();
2017
2018                         var mc = (IMemberContext) method;
2019
2020                         method.ParameterInfo.ApplyAttributes (mc, MethodBuilder);
2021
2022                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
2023
2024                         ToplevelBlock block = method.Block;
2025                         if (block != null) {
2026                                 BlockContext bc = new BlockContext (mc, block, method.ReturnType);
2027                                 if (block.Resolve (null, bc, method)) {
2028                                         EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator ());
2029                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
2030                                                 ec.ReturnLabel = bc.ReturnLabel;
2031                                                 ec.HasReturnLabel = true;
2032                                         }
2033
2034                                         block.Emit (ec);
2035                                 }
2036                         }
2037
2038                         if (source != null) {
2039                                 method.EmitExtraSymbolInfo (source);
2040                                 source.CloseMethod ();
2041                         }
2042                 }
2043         }
2044
2045         public class Destructor : MethodOrOperator
2046         {
2047                 const Modifiers AllowedModifiers =
2048                         Modifiers.UNSAFE |
2049                         Modifiers.EXTERN;
2050
2051                 static readonly string[] attribute_targets = new string [] { "method" };
2052
2053                 public static readonly string MetadataName = "Finalize";
2054
2055                 public Destructor (DeclSpace parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
2056                         : base (parent, null, null, mod, AllowedModifiers,
2057                                 new MemberName (MetadataName, l), attrs, parameters)
2058                 {
2059                         ModFlags &= ~Modifiers.PRIVATE;
2060                         ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2061                 }
2062
2063                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2064                 {
2065                         if (a.Type == pa.Conditional) {
2066                                 Error_ConditionalAttributeIsNotValid ();
2067                                 return;
2068                         }
2069
2070                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2071                 }
2072
2073                 protected override bool CheckBase ()
2074                 {
2075                         // Don't check base, destructors have special syntax
2076                         return true;
2077                 }
2078
2079                 public override void Emit()
2080                 {
2081                         var base_type = Parent.PartialContainer.BaseType;
2082                         if (base_type != null && Block != null) {
2083                                 var base_dtor = MemberCache.FindMember (base_type,
2084                                         new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
2085
2086                                 if (base_dtor == null)
2087                                         throw new NotImplementedException ();
2088
2089                                 MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
2090                                 method_expr.InstanceExpression = new BaseThis (base_type, Location);
2091
2092                                 var try_block = new ExplicitBlock (block, block.StartLocation, block.EndLocation);
2093                                 var finaly_block = new ExplicitBlock (block, Location, Location);
2094
2095                                 //
2096                                 // 0-size arguments to avoid CS0250 error
2097                                 // TODO: Should use AddScopeStatement or something else which emits correct
2098                                 // debugger scope
2099                                 //
2100                                 finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0))));
2101
2102                                 var tf = new TryFinally (try_block, finaly_block, Location);
2103                                 block.WrapIntoDestructor (tf, try_block);
2104                         }
2105
2106                         base.Emit ();
2107                 }
2108
2109                 public override string GetSignatureForError ()
2110                 {
2111                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
2112                 }
2113
2114                 protected override bool ResolveMemberType ()
2115                 {
2116                         member_type = Compiler.BuiltinTypes.Void;
2117                         return true;
2118                 }
2119
2120                 public override string[] ValidAttributeTargets {
2121                         get {
2122                                 return attribute_targets;
2123                         }
2124                 }
2125         }
2126
2127         // Ooouh Martin, templates are missing here.
2128         // When it will be possible move here a lot of child code and template method type.
2129         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
2130                 protected MethodData method_data;
2131                 protected ToplevelBlock block;
2132                 protected SecurityType declarative_security;
2133
2134                 protected readonly string prefix;
2135
2136                 ReturnParameter return_attributes;
2137
2138                 public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
2139                         : base (member.Parent, SetupName (prefix, member, loc), attrs)
2140                 {
2141                         this.prefix = prefix;
2142                 }
2143
2144                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
2145                 {
2146                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
2147                 }
2148
2149                 public void UpdateName (InterfaceMemberBase member)
2150                 {
2151                         SetMemberName (SetupName (prefix, member, Location));
2152                 }
2153
2154                 #region IMethodData Members
2155
2156                 public ToplevelBlock Block {
2157                         get {
2158                                 return block;
2159                         }
2160
2161                         set {
2162                                 block = value;
2163                         }
2164                 }
2165
2166                 public CallingConventions CallingConventions {
2167                         get {
2168                                 return CallingConventions.Standard;
2169                         }
2170                 }
2171
2172                 public EmitContext CreateEmitContext (ILGenerator ig)
2173                 {
2174                         return new EmitContext (this, ig, ReturnType);
2175                 }
2176
2177                 public bool IsAccessor {
2178                         get {
2179                                 return true;
2180                         }
2181                 }
2182
2183                 public bool IsExcluded ()
2184                 {
2185                         return false;
2186                 }
2187
2188                 GenericMethod IMethodData.GenericMethod {
2189                         get {
2190                                 return null;
2191                         }
2192                 }
2193
2194                 public MemberName MethodName {
2195                         get {
2196                                 return MemberName;
2197                         }
2198                 }
2199
2200                 public TypeSpec[] ParameterTypes { 
2201                         get {
2202                                 return ParameterInfo.Types;
2203                         }
2204                 }
2205
2206                 public abstract ParametersCompiled ParameterInfo { get ; }
2207                 public abstract TypeSpec ReturnType { get; }
2208
2209                 #endregion
2210
2211                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2212                 {
2213                         if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
2214                                 Report.Error (1667, a.Location,
2215                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
2216                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
2217                                 return;
2218                         }
2219
2220                         if (a.IsValidSecurityAttribute ()) {
2221                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2222                                 return;
2223                         }
2224
2225                         if (a.Target == AttributeTargets.Method) {
2226                                 method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
2227                                 return;
2228                         }
2229
2230                         if (a.Target == AttributeTargets.ReturnValue) {
2231                                 if (return_attributes == null)
2232                                         return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2233
2234                                 return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
2235                                 return;
2236                         }
2237
2238                         ApplyToExtraTarget (a, ctor, cdata, pa);
2239                 }
2240
2241                 protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2242                 {
2243                         throw new NotSupportedException ("You forgot to define special attribute target handling");
2244                 }
2245
2246                 // It is not supported for the accessors
2247                 public sealed override bool Define()
2248                 {
2249                         throw new NotSupportedException ();
2250                 }
2251
2252                 public virtual void Emit (DeclSpace parent)
2253                 {
2254                         method_data.Emit (parent);
2255
2256                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2257                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
2258                         if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
2259                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
2260
2261                         if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2262                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2263                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
2264                         } else if (ReturnType.HasDynamicElement) {
2265                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2266                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
2267                         }
2268
2269                         if (OptAttributes != null)
2270                                 OptAttributes.Emit ();
2271
2272                         if (declarative_security != null) {
2273                                 foreach (var de in declarative_security) {
2274 #if STATIC
2275                                         method_data.MethodBuilder.__AddDeclarativeSecurity (de);
2276 #else
2277                                         method_data.MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2278 #endif
2279                                 }
2280                         }
2281
2282                         block = null;
2283                 }
2284
2285                 public override bool EnableOverloadChecks (MemberCore overload)
2286                 {
2287                         if (overload is MethodCore) {
2288                                 caching_flags |= Flags.MethodOverloadsExist;
2289                                 return true;
2290                         }
2291
2292                         // This can only happen with indexers and it will
2293                         // be catched as indexer difference
2294                         if (overload is AbstractPropertyEventMethod)
2295                                 return true;
2296
2297                         return false;
2298                 }
2299
2300                 public override string GetSignatureForDocumentation ()
2301                 {
2302                         // should not be called
2303                         throw new NotSupportedException ();
2304                 }
2305
2306                 public override bool IsClsComplianceRequired()
2307                 {
2308                         return false;
2309                 }
2310
2311                 public MethodSpec Spec { get; protected set; }
2312
2313                 //
2314                 //   Represents header string for documentation comment.
2315                 //
2316                 public override string DocCommentHeader {
2317                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
2318                 }
2319
2320                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
2321                 { }
2322         }
2323
2324         public class Operator : MethodOrOperator {
2325
2326                 const Modifiers AllowedModifiers =
2327                         Modifiers.PUBLIC |
2328                         Modifiers.UNSAFE |
2329                         Modifiers.EXTERN |
2330                         Modifiers.STATIC;
2331
2332                 public enum OpType : byte {
2333
2334                         // Unary operators
2335                         LogicalNot,
2336                         OnesComplement,
2337                         Increment,
2338                         Decrement,
2339                         True,
2340                         False,
2341
2342                         // Unary and Binary operators
2343                         Addition,
2344                         Subtraction,
2345
2346                         UnaryPlus,
2347                         UnaryNegation,
2348                         
2349                         // Binary operators
2350                         Multiply,
2351                         Division,
2352                         Modulus,
2353                         BitwiseAnd,
2354                         BitwiseOr,
2355                         ExclusiveOr,
2356                         LeftShift,
2357                         RightShift,
2358                         Equality,
2359                         Inequality,
2360                         GreaterThan,
2361                         LessThan,
2362                         GreaterThanOrEqual,
2363                         LessThanOrEqual,
2364
2365                         // Implicit and Explicit
2366                         Implicit,
2367                         Explicit,
2368
2369                         // Just because of enum
2370                         TOP
2371                 };
2372
2373                 public readonly OpType OperatorType;
2374
2375                 static readonly string [] [] names;
2376
2377                 static Operator ()
2378                 {
2379                         names = new string[(int)OpType.TOP][];
2380                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
2381                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
2382                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
2383                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
2384                         names [(int) OpType.True] = new string [] { "true", "op_True" };
2385                         names [(int) OpType.False] = new string [] { "false", "op_False" };
2386                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
2387                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
2388                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
2389                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
2390                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
2391                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
2392                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
2393                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
2394                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
2395                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
2396                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
2397                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
2398                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
2399                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
2400                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
2401                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
2402                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
2403                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
2404                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
2405                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
2406                 }
2407                 
2408                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
2409                                  Modifiers mod_flags, ParametersCompiled parameters,
2410                                  ToplevelBlock block, Attributes attrs, Location loc)
2411                         : base (parent, null, ret_type, mod_flags, AllowedModifiers,
2412                                 new MemberName (GetMetadataName (type), loc), attrs, parameters)
2413                 {
2414                         OperatorType = type;
2415                         Block = block;
2416                 }
2417
2418                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2419                 {
2420                         if (a.Type == pa.Conditional) {
2421                                 Error_ConditionalAttributeIsNotValid ();
2422                                 return;
2423                         }
2424
2425                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2426                 }
2427                 
2428                 public override bool Define ()
2429                 {
2430                         const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
2431                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
2432                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
2433                         }
2434
2435                         if (!base.Define ())
2436                                 return false;
2437
2438                         if (block != null && block.IsIterator) {
2439                                 //
2440                                 // Current method is turned into automatically generated
2441                                 // wrapper which creates an instance of iterator
2442                                 //
2443                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
2444                                 ModFlags |= Modifiers.DEBUGGER_HIDDEN;
2445                         }
2446
2447                         // imlicit and explicit operator of same types are not allowed
2448                         if (OperatorType == OpType.Explicit)
2449                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
2450                         else if (OperatorType == OpType.Implicit)
2451                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
2452
2453                         TypeSpec declaring_type = Parent.CurrentType;
2454                         TypeSpec return_type = MemberType;
2455                         TypeSpec first_arg_type = ParameterTypes [0];
2456                         
2457                         TypeSpec first_arg_type_unwrap = first_arg_type;
2458                         if (first_arg_type.IsNullableType)
2459                                 first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
2460                         
2461                         TypeSpec return_type_unwrap = return_type;
2462                         if (return_type.IsNullableType)
2463                                 return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);
2464
2465                         //
2466                         // Rules for conversion operators
2467                         //
2468                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2469                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
2470                                         Report.Error (555, Location,
2471                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
2472                                         return false;
2473                                 }
2474
2475                                 TypeSpec conv_type;
2476                                 if (declaring_type == return_type || declaring_type == return_type_unwrap) {
2477                                         conv_type = first_arg_type;
2478                                 } else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
2479                                         conv_type = return_type;
2480                                 } else {
2481                                         Report.Error (556, Location,
2482                                                 "User-defined conversion must convert to or from the enclosing type");
2483                                         return false;
2484                                 }
2485
2486                                 if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2487                                         Report.Error (1964, Location,
2488                                                 "User-defined conversion `{0}' cannot convert to or from the dynamic type",
2489                                                 GetSignatureForError ());
2490
2491                                         return false;
2492                                 }
2493
2494                                 if (conv_type.IsInterface) {
2495                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
2496                                                 GetSignatureForError ());
2497                                         return false;
2498                                 }
2499
2500                                 if (conv_type.IsClass) {
2501                                         if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
2502                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
2503                                                         GetSignatureForError ());
2504                                                 return false;
2505                                         }
2506
2507                                         if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
2508                                                 Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
2509                                                         GetSignatureForError ());
2510                                                 return false;
2511                                         }
2512                                 }
2513                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
2514                                 if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
2515                                         Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
2516                                         return false;
2517                                 }
2518                         } else if (parameters.Count == 1) {
2519                                 // Checks for Unary operators
2520
2521                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
2522                                         if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
2523                                                 Report.Error (448, Location,
2524                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
2525                                                 return false;
2526                                         }
2527                                         if (first_arg_type != declaring_type) {
2528                                                 Report.Error (
2529                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
2530                                                 return false;
2531                                         }
2532                                 }
2533
2534                                 if (first_arg_type_unwrap != declaring_type) {
2535                                         Report.Error (562, Location,
2536                                                 "The parameter type of a unary operator must be the containing type");
2537                                         return false;
2538                                 }
2539
2540                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
2541                                         if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
2542                                                 Report.Error (
2543                                                         215, Location,
2544                                                         "The return type of operator True or False " +
2545                                                         "must be bool");
2546                                                 return false;
2547                                         }
2548                                 }
2549
2550                         } else if (first_arg_type_unwrap != declaring_type) {
2551                                 // Checks for Binary operators
2552
2553                                 var second_arg_type = ParameterTypes[1];
2554                                 if (second_arg_type.IsNullableType)
2555                                         second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);
2556
2557                                 if (second_arg_type != declaring_type) {
2558                                         Report.Error (563, Location,
2559                                                 "One of the parameters of a binary operator must be the containing type");
2560                                         return false;
2561                                 }
2562                         }
2563
2564                         return true;
2565                 }
2566
2567                 protected override bool ResolveMemberType ()
2568                 {
2569                         if (!base.ResolveMemberType ())
2570                                 return false;
2571
2572                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2573                         return true;
2574                 }
2575
2576                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
2577                 {
2578                         // Operator cannot be override
2579                         bestCandidate = null;
2580                         return null;
2581                 }
2582
2583                 public static string GetName (OpType ot)
2584                 {
2585                         return names [(int) ot] [0];
2586                 }
2587
2588                 public static string GetName (string metadata_name)
2589                 {
2590                         for (int i = 0; i < names.Length; ++i) {
2591                                 if (names [i] [1] == metadata_name)
2592                                         return names [i] [0];
2593                         }
2594                         return null;
2595                 }
2596
2597                 public static string GetMetadataName (OpType ot)
2598                 {
2599                         return names [(int) ot] [1];
2600                 }
2601
2602                 public static string GetMetadataName (string name)
2603                 {
2604                         for (int i = 0; i < names.Length; ++i) {
2605                                 if (names [i] [0] == name)
2606                                         return names [i] [1];
2607                         }
2608                         return null;
2609                 }
2610
2611                 public static OpType? GetType (string metadata_name)
2612                 {
2613                         for (int i = 0; i < names.Length; ++i) {
2614                                 if (names[i][1] == metadata_name)
2615                                         return (OpType) i;
2616                         }
2617
2618                         return null;
2619                 }
2620
2621                 public OpType GetMatchingOperator ()
2622                 {
2623                         switch (OperatorType) {
2624                         case OpType.Equality:
2625                                 return OpType.Inequality;
2626                         case OpType.Inequality:
2627                                 return OpType.Equality;
2628                         case OpType.True:
2629                                 return OpType.False;
2630                         case OpType.False:
2631                                 return OpType.True;
2632                         case OpType.GreaterThan:
2633                                 return OpType.LessThan;
2634                         case OpType.LessThan:
2635                                 return OpType.GreaterThan;
2636                         case OpType.GreaterThanOrEqual:
2637                                 return OpType.LessThanOrEqual;
2638                         case OpType.LessThanOrEqual:
2639                                 return OpType.GreaterThanOrEqual;
2640                         default:
2641                                 return OpType.TOP;
2642                         }
2643                 }
2644
2645                 public override string GetSignatureForDocumentation ()
2646                 {
2647                         string s = base.GetSignatureForDocumentation ();
2648                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2649                                 s = s + "~" + ReturnType.GetSignatureForDocumentation ();
2650                         }
2651
2652                         return s;
2653                 }
2654
2655                 public override string GetSignatureForError ()
2656                 {
2657                         StringBuilder sb = new StringBuilder ();
2658                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2659                                 sb.AppendFormat ("{0}.{1} operator {2}",
2660                                         Parent.GetSignatureForError (), GetName (OperatorType),
2661                                         member_type == null ? type_expr.GetSignatureForError () : member_type.GetSignatureForError ());
2662                         }
2663                         else {
2664                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
2665                         }
2666
2667                         sb.Append (parameters.GetSignatureForError ());
2668                         return sb.ToString ();
2669                 }
2670         }
2671 }
2672