Avoid creating a temporary variable when target await expression is does not include...
[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 (this, 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 bool ContainsEmitWithAwait ()
1315                 {
1316                         throw new NotSupportedException ();
1317                 }
1318
1319                 public override Expression CreateExpressionTree (ResolveContext ec)
1320                 {
1321                         throw new NotSupportedException ("ET");
1322                 }
1323
1324                 protected override Expression DoResolve (ResolveContext ec)
1325                 {
1326                         eclass = ExprClass.Value;
1327
1328                         // FIXME: Hack
1329                         var caller_builder = (Constructor) ec.MemberContext;
1330
1331                         //
1332                         // Spec mandates that constructor initializer will not have `this' access
1333                         //
1334                         using (ec.Set (ResolveContext.Options.BaseInitializer)) {
1335                                 if (argument_list != null) {
1336                                         bool dynamic;
1337                                         argument_list.Resolve (ec, out dynamic);
1338
1339                                         if (dynamic) {
1340                                                 ec.Report.Error (1975, loc,
1341                                                         "The constructor call cannot be dynamically dispatched within constructor initializer");
1342
1343                                                 return null;
1344                                         }
1345                                 }
1346
1347                                 type = ec.CurrentType;
1348                                 if (this is ConstructorBaseInitializer) {
1349                                         if (ec.CurrentType.BaseType == null)
1350                                                 return this;
1351
1352                                         type = ec.CurrentType.BaseType;
1353                                         if (ec.CurrentType.IsStruct) {
1354                                                 ec.Report.Error (522, loc,
1355                                                         "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
1356                                                 return this;
1357                                         }
1358                                 } else {
1359                                         //
1360                                         // It is legal to have "this" initializers that take no arguments
1361                                         // in structs, they are just no-ops.
1362                                         //
1363                                         // struct D { public D (int a) : this () {}
1364                                         //
1365                                         if (ec.CurrentType.IsStruct && argument_list == null)
1366                                                 return this;
1367                                 }
1368
1369                                 base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
1370                         }
1371         
1372                         // TODO MemberCache: Does it work for inflated types ?
1373                         if (base_ctor == caller_builder.Spec){
1374                                 ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
1375                                         caller_builder.GetSignatureForError ());
1376                         }
1377                                                 
1378                         return this;
1379                 }
1380
1381                 public override void Emit (EmitContext ec)
1382                 {
1383                         // It can be null for static initializers
1384                         if (base_ctor == null)
1385                                 return;
1386                         
1387                         ec.Mark (loc);
1388
1389                         var call = new CallEmitter ();
1390                         call.InstanceExpression = new CompilerGeneratedThis (type, loc); 
1391                         call.EmitPredefined (ec, base_ctor, argument_list);
1392                 }
1393
1394                 public override void EmitStatement (EmitContext ec)
1395                 {
1396                         Emit (ec);
1397                 }
1398         }
1399
1400         public class ConstructorBaseInitializer : ConstructorInitializer {
1401                 public ConstructorBaseInitializer (Arguments argument_list, Location l) :
1402                         base (argument_list, l)
1403                 {
1404                 }
1405         }
1406
1407         class GeneratedBaseInitializer: ConstructorBaseInitializer {
1408                 public GeneratedBaseInitializer (Location loc):
1409                         base (null, loc)
1410                 {
1411                 }
1412         }
1413
1414         public class ConstructorThisInitializer : ConstructorInitializer {
1415                 public ConstructorThisInitializer (Arguments argument_list, Location l) :
1416                         base (argument_list, l)
1417                 {
1418                 }
1419         }
1420         
1421         public class Constructor : MethodCore, IMethodData {
1422                 public ConstructorBuilder ConstructorBuilder;
1423                 public ConstructorInitializer Initializer;
1424                 SecurityType declarative_security;
1425                 bool has_compliant_args;
1426
1427                 // <summary>
1428                 //   Modifiers allowed for a constructor.
1429                 // </summary>
1430                 public const Modifiers AllowedModifiers =
1431                         Modifiers.PUBLIC |
1432                         Modifiers.PROTECTED |
1433                         Modifiers.INTERNAL |
1434                         Modifiers.STATIC |
1435                         Modifiers.UNSAFE |
1436                         Modifiers.EXTERN |              
1437                         Modifiers.PRIVATE;
1438
1439                 static readonly string[] attribute_targets = new string [] { "method" };
1440
1441                 public static readonly string ConstructorName = ".ctor";
1442                 public static readonly string TypeConstructorName = ".cctor";
1443
1444                 //
1445                 // The spec claims that static is not permitted, but
1446                 // my very own code has static constructors.
1447                 //
1448                 public Constructor (DeclSpace parent, string name, Modifiers mod, Attributes attrs, ParametersCompiled args,
1449                                     ConstructorInitializer init, Location loc)
1450                         : base (parent, null, null, mod, AllowedModifiers,
1451                                 new MemberName (name, loc), attrs, args)
1452                 {
1453                         Initializer = init;
1454                 }
1455
1456                 public bool HasCompliantArgs {
1457                         get { return has_compliant_args; }
1458                 }
1459
1460                 public override AttributeTargets AttributeTargets {
1461                         get {
1462                                 return AttributeTargets.Constructor;
1463                         }
1464                 }
1465
1466                 bool IMethodData.IsAccessor {
1467                         get {
1468                                 return false;
1469                         }
1470                 }
1471
1472                 //
1473                 // Returns true if this is a default constructor
1474                 //
1475                 public bool IsDefault ()
1476                 {
1477                         if ((ModFlags & Modifiers.STATIC) != 0)
1478                                 return parameters.IsEmpty;
1479
1480                         return parameters.IsEmpty &&
1481                                         (Initializer is ConstructorBaseInitializer) &&
1482                                         (Initializer.Arguments == null);
1483                 }
1484
1485                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
1486                 {
1487                         if (a.IsValidSecurityAttribute ()) {
1488                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
1489                                 return;
1490                         }
1491
1492                         if (a.Type == pa.MethodImpl) {
1493                                 is_external_implementation = a.IsInternalCall ();
1494                         }
1495
1496                         ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
1497                 }
1498
1499                 protected override bool CheckBase ()
1500                 {
1501                         if ((ModFlags & Modifiers.STATIC) != 0) {
1502                                 if (!parameters.IsEmpty) {
1503                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
1504                                                 GetSignatureForError ());
1505                                         return false;
1506                                 }
1507
1508                                 // the rest can be ignored
1509                                 return true;
1510                         }
1511
1512                         // Check whether arguments were correct.
1513                         if (!DefineParameters (parameters))
1514                                 return false;
1515
1516                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
1517                                 Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
1518
1519                         if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
1520                                 Report.Error (568, Location, 
1521                                         "Structs cannot contain explicit parameterless constructors");
1522                                 return false;
1523                         }
1524
1525                         CheckProtectedModifier ();
1526                         
1527                         return true;
1528                 }
1529                 
1530                 //
1531                 // Creates the ConstructorBuilder
1532                 //
1533                 public override bool Define ()
1534                 {
1535                         if (ConstructorBuilder != null)
1536                                 return true;
1537
1538                         var ca = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
1539                         
1540                         if ((ModFlags & Modifiers.STATIC) != 0) {
1541                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
1542                         } else {
1543                                 ca |= ModifiersExtensions.MethodAttr (ModFlags);
1544                         }
1545
1546                         if (!CheckAbstractAndExtern (block != null))
1547                                 return false;
1548                         
1549                         // Check if arguments were correct.
1550                         if (!CheckBase ())
1551                                 return false;
1552
1553                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
1554                                 ca, CallingConventions,
1555                                 parameters.GetMetaInfo ());
1556
1557                         spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
1558                         
1559                         Parent.MemberCache.AddMember (spec);
1560                         
1561                         // It's here only to report an error
1562                         if (block != null && block.IsIterator) {
1563                                 member_type = Compiler.BuiltinTypes.Void;
1564                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1565                         }
1566
1567                         return true;
1568                 }
1569
1570                 //
1571                 // Emits the code
1572                 //
1573                 public override void Emit ()
1574                 {
1575                         if (Parent.PartialContainer.IsComImport) {
1576                                 if (!IsDefault ()) {
1577                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
1578                                                 Parent.GetSignatureForError ());
1579                                 }
1580
1581                                 // Set as internal implementation and reset block data
1582                                 // to ensure no IL is generated
1583                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
1584                                 block = null;
1585                         }
1586
1587                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
1588                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder);
1589
1590                         if (OptAttributes != null)
1591                                 OptAttributes.Emit ();
1592
1593                         base.Emit ();
1594                         parameters.ApplyAttributes (this, ConstructorBuilder);
1595
1596                         //
1597                         // If we use a "this (...)" constructor initializer, then
1598                         // do not emit field initializers, they are initialized in the other constructor
1599                         //
1600                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
1601                                 !(Initializer is ConstructorThisInitializer);
1602
1603                         BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
1604                         bc.Set (ResolveContext.Options.ConstructorScope);
1605
1606                         if (emit_field_initializers)
1607                                 Parent.PartialContainer.ResolveFieldInitializers (bc);
1608
1609                         if (block != null) {
1610                                 // If this is a non-static `struct' constructor and doesn't have any
1611                                 // initializer, it must initialize all of the struct's fields.
1612                                 if ((Parent.PartialContainer.Kind == MemberKind.Struct) &&
1613                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
1614                                         block.AddThisVariable (bc, Parent, Location);
1615
1616                                 if (block != null && (ModFlags & Modifiers.STATIC) == 0){
1617                                         if (Parent.PartialContainer.Kind == MemberKind.Class && Initializer == null)
1618                                                 Initializer = new GeneratedBaseInitializer (Location);
1619
1620                                         if (Initializer != null) {
1621                                                 block.AddScopeStatement (new StatementExpression (Initializer));
1622                                         }
1623                                 }
1624                         }
1625
1626                         SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
1627
1628                         if (block != null) {
1629                                 if (block.Resolve (null, bc, this)) {
1630                                         EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType);
1631                                         ec.With (EmitContext.Options.ConstructorScope, true);
1632
1633                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
1634                                                 ec.ReturnLabel = bc.ReturnLabel;
1635                                                 ec.HasReturnLabel = true;
1636                                         }
1637
1638                                         block.Emit (ec);
1639                                 }
1640                         }
1641
1642                         if (source != null)
1643                                 source.CloseMethod ();
1644
1645                         if (declarative_security != null) {
1646                                 foreach (var de in declarative_security) {
1647 #if STATIC
1648                                         ConstructorBuilder.__AddDeclarativeSecurity (de);
1649 #else
1650                                         ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value);
1651 #endif
1652                                 }
1653                         }
1654
1655                         block = null;
1656                 }
1657
1658                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
1659                 {
1660                         // Is never override
1661                         bestCandidate = null;
1662                         return null;
1663                 }
1664
1665                 public override string GetSignatureForDocumentation ()
1666                 {
1667                         return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
1668                 }
1669
1670                 public override string GetSignatureForError()
1671                 {
1672                         return base.GetSignatureForError () + parameters.GetSignatureForError ();
1673                 }
1674
1675                 public override string[] ValidAttributeTargets {
1676                         get {
1677                                 return attribute_targets;
1678                         }
1679                 }
1680
1681                 protected override bool VerifyClsCompliance ()
1682                 {
1683                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
1684                                 return false;
1685                         }
1686
1687                         if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
1688                                 foreach (TypeSpec param in parameters.Types) {
1689                                         if (param.IsArray) {
1690                                                 return true;
1691                                         }
1692                                 }
1693                         }
1694
1695                         has_compliant_args = true;
1696                         return true;
1697                 }
1698
1699                 #region IMethodData Members
1700
1701                 public MemberName MethodName {
1702                         get {
1703                                 return MemberName;
1704                         }
1705                 }
1706
1707                 public TypeSpec ReturnType {
1708                         get {
1709                                 return MemberType;
1710                         }
1711                 }
1712
1713                 public EmitContext CreateEmitContext (ILGenerator ig)
1714                 {
1715                         throw new NotImplementedException ();
1716                 }
1717
1718                 public bool IsExcluded()
1719                 {
1720                         return false;
1721                 }
1722
1723                 GenericMethod IMethodData.GenericMethod {
1724                         get {
1725                                 return null;
1726                         }
1727                 }
1728
1729                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
1730                 { }
1731
1732                 #endregion
1733         }
1734
1735         /// <summary>
1736         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
1737         /// </summary>
1738         public interface IMethodData : IMemberContext
1739         {
1740                 CallingConventions CallingConventions { get; }
1741                 Location Location { get; }
1742                 MemberName MethodName { get; }
1743                 TypeSpec ReturnType { get; }
1744                 GenericMethod GenericMethod { get; }
1745                 ParametersCompiled ParameterInfo { get; }
1746                 MethodSpec Spec { get; }
1747                 bool IsAccessor { get; }
1748
1749                 Attributes OptAttributes { get; }
1750                 ToplevelBlock Block { get; set; }
1751
1752                 EmitContext CreateEmitContext (ILGenerator ig);
1753                 void EmitExtraSymbolInfo (SourceMethod source);
1754         }
1755
1756         //
1757         // Encapsulates most of the Method's state
1758         //
1759         public class MethodData
1760         {
1761 #if !STATIC
1762                 static FieldInfo methodbuilder_attrs_field;
1763 #endif
1764
1765                 public readonly IMethodData method;
1766
1767                 public readonly GenericMethod GenericMethod;
1768
1769                 //
1770                 // Are we implementing an interface ?
1771                 //
1772                 public MethodSpec implementing;
1773
1774                 //
1775                 // Protected data.
1776                 //
1777                 protected InterfaceMemberBase member;
1778                 protected Modifiers modifiers;
1779                 protected MethodAttributes flags;
1780                 protected TypeSpec declaring_type;
1781                 protected MethodSpec parent_method;
1782
1783                 MethodBuilder builder;
1784                 public MethodBuilder MethodBuilder {
1785                         get {
1786                                 return builder;
1787                         }
1788                 }
1789
1790                 public TypeSpec DeclaringType {
1791                         get {
1792                                 return declaring_type;
1793                         }
1794                 }
1795
1796                 public MethodData (InterfaceMemberBase member,
1797                                    Modifiers modifiers, MethodAttributes flags, IMethodData method)
1798                 {
1799                         this.member = member;
1800                         this.modifiers = modifiers;
1801                         this.flags = flags;
1802
1803                         this.method = method;
1804                 }
1805
1806                 public MethodData (InterfaceMemberBase member,
1807                                    Modifiers modifiers, MethodAttributes flags, 
1808                                    IMethodData method, MethodBuilder builder,
1809                                    GenericMethod generic, MethodSpec parent_method)
1810                         : this (member, modifiers, flags, method)
1811                 {
1812                         this.builder = builder;
1813                         this.GenericMethod = generic;
1814                         this.parent_method = parent_method;
1815                 }
1816
1817                 public bool Define (DeclSpace parent, string method_full_name, Report Report)
1818                 {
1819                         TypeContainer container = parent.PartialContainer;
1820
1821                         PendingImplementation pending = container.PendingImplementations;
1822                         MethodSpec ambig_iface_method;
1823                         if (pending != null) {
1824                                 implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method);
1825
1826                                 if (member.InterfaceType != null) {
1827                                         if (implementing == null) {
1828                                                 if (member is PropertyBase) {
1829                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
1830                                                                           method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
1831                                                                           member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
1832
1833                                                 } else {
1834                                                         Report.Error (539, method.Location,
1835                                                                           "`{0}.{1}' in explicit interface declaration is not a member of interface",
1836                                                                           TypeManager.CSharpName (member.InterfaceType), member.ShortName);
1837                                                 }
1838                                                 return false;
1839                                         }
1840                                         if (implementing.IsAccessor && !method.IsAccessor) {
1841                                                 Report.SymbolRelatedToPreviousError (implementing);
1842                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
1843                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1844                                                 return false;
1845                                         }
1846                                 } else {
1847                                         if (implementing != null) {
1848                                                 if (!method.IsAccessor) {
1849                                                         if (implementing.IsAccessor) {
1850                                                                 Report.SymbolRelatedToPreviousError (implementing);
1851                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'",
1852                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1853                                                         }
1854                                                 } else if (implementing.DeclaringType.IsInterface) {
1855                                                         if (!implementing.IsAccessor) {
1856                                                                 Report.SymbolRelatedToPreviousError (implementing);
1857                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
1858                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
1859                                                         } else {
1860                                                                 PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
1861                                                                 if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
1862                                                                         Report.SymbolRelatedToPreviousError (implementing);
1863                                                                         Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
1864                                                                                 method.GetSignatureForError (), implementing.GetSignatureForError ());
1865                                                                 }
1866                                                         }
1867                                                 }
1868                                         }
1869                                 }
1870                         } else {
1871                                 ambig_iface_method = null;
1872                         }
1873
1874                         //
1875                         // For implicit implementations, make sure we are public, for
1876                         // explicit implementations, make sure we are private.
1877                         //
1878                         if (implementing != null){
1879                                 //
1880                                 // Setting null inside this block will trigger a more
1881                                 // verbose error reporting for missing interface implementations
1882                                 //
1883                                 // The "candidate" function has been flagged already
1884                                 // but it wont get cleared
1885                                 //
1886                                 if (member.IsExplicitImpl){
1887                                         if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
1888                                                 Report.SymbolRelatedToPreviousError (implementing);
1889                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
1890                                                         method.GetSignatureForError ());
1891                                         }
1892
1893                                         if (ambig_iface_method != null) {
1894                                                 Report.SymbolRelatedToPreviousError (ambig_iface_method);
1895                                                 Report.SymbolRelatedToPreviousError (implementing);
1896                                                 Report.Warning (473, 2, method.Location,
1897                                                         "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
1898                                                         method.GetSignatureForError ());
1899                                         }
1900
1901                                 } else {
1902                                         if (implementing.DeclaringType.IsInterface) {
1903                                                 //
1904                                                 // If this is an interface method implementation,
1905                                                 // check for public accessibility
1906                                                 //
1907                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
1908                                                 {
1909                                                         implementing = null;
1910                                                 }
1911                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
1912                                                 // We may never be private.
1913                                                 implementing = null;
1914
1915                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
1916                                                 //
1917                                                 // We may be protected if we're overriding something.
1918                                                 //
1919                                                 implementing = null;
1920                                         }
1921                                 }
1922                                         
1923                                 //
1924                                 // Static is not allowed
1925                                 //
1926                                 if ((modifiers & Modifiers.STATIC) != 0){
1927                                         implementing = null;
1928                                 }
1929                         }
1930                         
1931                         //
1932                         // If implementing is still valid, set flags
1933                         //
1934                         if (implementing != null){
1935                                 //
1936                                 // When implementing interface methods, set NewSlot
1937                                 // unless, we are overwriting a method.
1938                                 //
1939                                 if (implementing.DeclaringType.IsInterface){
1940                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
1941                                                 flags |= MethodAttributes.NewSlot;
1942                                 }
1943
1944                                 flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig;
1945
1946                                 // Set Final unless we're virtual, abstract or already overriding a method.
1947                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
1948                                         flags |= MethodAttributes.Final;
1949
1950                                 //
1951                                 // clear the pending implementation flag (requires explicit methods to be defined first)
1952                                 //
1953                                 parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName,
1954                                         member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method);
1955
1956                                 //
1957                                 // Update indexer accessor name to match implementing abstract accessor
1958                                 //
1959                                 if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor)
1960                                         method_full_name = implementing.MemberDefinition.Name;
1961                         }
1962
1963                         DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
1964
1965                         if (builder == null)
1966                                 return false;
1967
1968 //                      if (container.CurrentType != null)
1969 //                              declaring_type = container.CurrentType;
1970 //                      else
1971                                 declaring_type = container.Definition;
1972
1973                         if (implementing != null && member.IsExplicitImpl) {
1974                                 container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
1975                         }
1976
1977                         return true;
1978                 }
1979
1980
1981                 /// <summary>
1982                 /// Create the MethodBuilder for the method 
1983                 /// </summary>
1984                 void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param)
1985                 {
1986                         var return_type = method.ReturnType.GetMetaInfo ();
1987                         var p_types = param.GetMetaInfo ();
1988
1989                         if (builder == null) {
1990                                 builder = container.TypeBuilder.DefineMethod (
1991                                         method_name, flags, method.CallingConventions,
1992                                         return_type, p_types);
1993                                 return;
1994                         }
1995
1996                         //
1997                         // Generic method has been already defined to resolve method parameters
1998                         // correctly when they use type parameters
1999                         //
2000                         builder.SetParameters (p_types);
2001                         builder.SetReturnType (return_type);
2002                         if (builder.Attributes != flags) {
2003 #if STATIC
2004                                 builder.__SetAttributes (flags);
2005 #else
2006                                 try {
2007                                         if (methodbuilder_attrs_field == null)
2008                                                 methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
2009                                         methodbuilder_attrs_field.SetValue (builder, flags);
2010                                 } catch {
2011                                         container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
2012                                 }
2013 #endif
2014                         }
2015                 }
2016
2017                 //
2018                 // Emits the code
2019                 // 
2020                 public void Emit (DeclSpace parent)
2021                 {
2022                         if (GenericMethod != null)
2023                                 GenericMethod.EmitAttributes ();
2024
2025                         var mc = (IMemberContext) method;
2026
2027                         method.ParameterInfo.ApplyAttributes (mc, MethodBuilder);
2028
2029                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
2030
2031                         ToplevelBlock block = method.Block;
2032                         if (block != null) {
2033                                 BlockContext bc = new BlockContext (mc, block, method.ReturnType);
2034                                 if (block.Resolve (null, bc, method)) {
2035                                         EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator ());
2036                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
2037                                                 ec.ReturnLabel = bc.ReturnLabel;
2038                                                 ec.HasReturnLabel = true;
2039                                         }
2040
2041                                         block.Emit (ec);
2042                                 }
2043                         }
2044
2045                         if (source != null) {
2046                                 method.EmitExtraSymbolInfo (source);
2047                                 source.CloseMethod ();
2048                         }
2049                 }
2050         }
2051
2052         public class Destructor : MethodOrOperator
2053         {
2054                 const Modifiers AllowedModifiers =
2055                         Modifiers.UNSAFE |
2056                         Modifiers.EXTERN;
2057
2058                 static readonly string[] attribute_targets = new string [] { "method" };
2059
2060                 public static readonly string MetadataName = "Finalize";
2061
2062                 public Destructor (DeclSpace parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
2063                         : base (parent, null, null, mod, AllowedModifiers,
2064                                 new MemberName (MetadataName, l), attrs, parameters)
2065                 {
2066                         ModFlags &= ~Modifiers.PRIVATE;
2067                         ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2068                 }
2069
2070                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2071                 {
2072                         if (a.Type == pa.Conditional) {
2073                                 Error_ConditionalAttributeIsNotValid ();
2074                                 return;
2075                         }
2076
2077                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2078                 }
2079
2080                 protected override bool CheckBase ()
2081                 {
2082                         // Don't check base, destructors have special syntax
2083                         return true;
2084                 }
2085
2086                 public override void Emit()
2087                 {
2088                         var base_type = Parent.PartialContainer.BaseType;
2089                         if (base_type != null && Block != null) {
2090                                 var base_dtor = MemberCache.FindMember (base_type,
2091                                         new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
2092
2093                                 if (base_dtor == null)
2094                                         throw new NotImplementedException ();
2095
2096                                 MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
2097                                 method_expr.InstanceExpression = new BaseThis (base_type, Location);
2098
2099                                 var try_block = new ExplicitBlock (block, block.StartLocation, block.EndLocation);
2100                                 var finaly_block = new ExplicitBlock (block, Location, Location);
2101
2102                                 //
2103                                 // 0-size arguments to avoid CS0250 error
2104                                 // TODO: Should use AddScopeStatement or something else which emits correct
2105                                 // debugger scope
2106                                 //
2107                                 finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0))));
2108
2109                                 var tf = new TryFinally (try_block, finaly_block, Location);
2110                                 block.WrapIntoDestructor (tf, try_block);
2111                         }
2112
2113                         base.Emit ();
2114                 }
2115
2116                 public override string GetSignatureForError ()
2117                 {
2118                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
2119                 }
2120
2121                 protected override bool ResolveMemberType ()
2122                 {
2123                         member_type = Compiler.BuiltinTypes.Void;
2124                         return true;
2125                 }
2126
2127                 public override string[] ValidAttributeTargets {
2128                         get {
2129                                 return attribute_targets;
2130                         }
2131                 }
2132         }
2133
2134         // Ooouh Martin, templates are missing here.
2135         // When it will be possible move here a lot of child code and template method type.
2136         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
2137                 protected MethodData method_data;
2138                 protected ToplevelBlock block;
2139                 protected SecurityType declarative_security;
2140
2141                 protected readonly string prefix;
2142
2143                 ReturnParameter return_attributes;
2144
2145                 public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
2146                         : base (member.Parent, SetupName (prefix, member, loc), attrs)
2147                 {
2148                         this.prefix = prefix;
2149                 }
2150
2151                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
2152                 {
2153                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
2154                 }
2155
2156                 public void UpdateName (InterfaceMemberBase member)
2157                 {
2158                         SetMemberName (SetupName (prefix, member, Location));
2159                 }
2160
2161                 #region IMethodData Members
2162
2163                 public ToplevelBlock Block {
2164                         get {
2165                                 return block;
2166                         }
2167
2168                         set {
2169                                 block = value;
2170                         }
2171                 }
2172
2173                 public CallingConventions CallingConventions {
2174                         get {
2175                                 return CallingConventions.Standard;
2176                         }
2177                 }
2178
2179                 public EmitContext CreateEmitContext (ILGenerator ig)
2180                 {
2181                         return new EmitContext (this, ig, ReturnType);
2182                 }
2183
2184                 public bool IsAccessor {
2185                         get {
2186                                 return true;
2187                         }
2188                 }
2189
2190                 public bool IsExcluded ()
2191                 {
2192                         return false;
2193                 }
2194
2195                 GenericMethod IMethodData.GenericMethod {
2196                         get {
2197                                 return null;
2198                         }
2199                 }
2200
2201                 public MemberName MethodName {
2202                         get {
2203                                 return MemberName;
2204                         }
2205                 }
2206
2207                 public TypeSpec[] ParameterTypes { 
2208                         get {
2209                                 return ParameterInfo.Types;
2210                         }
2211                 }
2212
2213                 public abstract ParametersCompiled ParameterInfo { get ; }
2214                 public abstract TypeSpec ReturnType { get; }
2215
2216                 #endregion
2217
2218                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2219                 {
2220                         if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
2221                                 Report.Error (1667, a.Location,
2222                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
2223                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
2224                                 return;
2225                         }
2226
2227                         if (a.IsValidSecurityAttribute ()) {
2228                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2229                                 return;
2230                         }
2231
2232                         if (a.Target == AttributeTargets.Method) {
2233                                 method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
2234                                 return;
2235                         }
2236
2237                         if (a.Target == AttributeTargets.ReturnValue) {
2238                                 if (return_attributes == null)
2239                                         return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2240
2241                                 return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
2242                                 return;
2243                         }
2244
2245                         ApplyToExtraTarget (a, ctor, cdata, pa);
2246                 }
2247
2248                 protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2249                 {
2250                         throw new NotSupportedException ("You forgot to define special attribute target handling");
2251                 }
2252
2253                 // It is not supported for the accessors
2254                 public sealed override bool Define()
2255                 {
2256                         throw new NotSupportedException ();
2257                 }
2258
2259                 public virtual void Emit (DeclSpace parent)
2260                 {
2261                         method_data.Emit (parent);
2262
2263                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2264                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
2265                         if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
2266                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
2267
2268                         if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2269                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2270                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
2271                         } else if (ReturnType.HasDynamicElement) {
2272                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2273                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
2274                         }
2275
2276                         if (OptAttributes != null)
2277                                 OptAttributes.Emit ();
2278
2279                         if (declarative_security != null) {
2280                                 foreach (var de in declarative_security) {
2281 #if STATIC
2282                                         method_data.MethodBuilder.__AddDeclarativeSecurity (de);
2283 #else
2284                                         method_data.MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2285 #endif
2286                                 }
2287                         }
2288
2289                         block = null;
2290                 }
2291
2292                 public override bool EnableOverloadChecks (MemberCore overload)
2293                 {
2294                         if (overload is MethodCore) {
2295                                 caching_flags |= Flags.MethodOverloadsExist;
2296                                 return true;
2297                         }
2298
2299                         // This can only happen with indexers and it will
2300                         // be catched as indexer difference
2301                         if (overload is AbstractPropertyEventMethod)
2302                                 return true;
2303
2304                         return false;
2305                 }
2306
2307                 public override string GetSignatureForDocumentation ()
2308                 {
2309                         // should not be called
2310                         throw new NotSupportedException ();
2311                 }
2312
2313                 public override bool IsClsComplianceRequired()
2314                 {
2315                         return false;
2316                 }
2317
2318                 public MethodSpec Spec { get; protected set; }
2319
2320                 //
2321                 //   Represents header string for documentation comment.
2322                 //
2323                 public override string DocCommentHeader {
2324                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
2325                 }
2326
2327                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
2328                 { }
2329         }
2330
2331         public class Operator : MethodOrOperator {
2332
2333                 const Modifiers AllowedModifiers =
2334                         Modifiers.PUBLIC |
2335                         Modifiers.UNSAFE |
2336                         Modifiers.EXTERN |
2337                         Modifiers.STATIC;
2338
2339                 public enum OpType : byte {
2340
2341                         // Unary operators
2342                         LogicalNot,
2343                         OnesComplement,
2344                         Increment,
2345                         Decrement,
2346                         True,
2347                         False,
2348
2349                         // Unary and Binary operators
2350                         Addition,
2351                         Subtraction,
2352
2353                         UnaryPlus,
2354                         UnaryNegation,
2355                         
2356                         // Binary operators
2357                         Multiply,
2358                         Division,
2359                         Modulus,
2360                         BitwiseAnd,
2361                         BitwiseOr,
2362                         ExclusiveOr,
2363                         LeftShift,
2364                         RightShift,
2365                         Equality,
2366                         Inequality,
2367                         GreaterThan,
2368                         LessThan,
2369                         GreaterThanOrEqual,
2370                         LessThanOrEqual,
2371
2372                         // Implicit and Explicit
2373                         Implicit,
2374                         Explicit,
2375
2376                         // Just because of enum
2377                         TOP
2378                 };
2379
2380                 public readonly OpType OperatorType;
2381
2382                 static readonly string [] [] names;
2383
2384                 static Operator ()
2385                 {
2386                         names = new string[(int)OpType.TOP][];
2387                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
2388                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
2389                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
2390                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
2391                         names [(int) OpType.True] = new string [] { "true", "op_True" };
2392                         names [(int) OpType.False] = new string [] { "false", "op_False" };
2393                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
2394                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
2395                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
2396                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
2397                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
2398                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
2399                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
2400                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
2401                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
2402                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
2403                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
2404                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
2405                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
2406                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
2407                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
2408                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
2409                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
2410                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
2411                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
2412                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
2413                 }
2414                 
2415                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
2416                                  Modifiers mod_flags, ParametersCompiled parameters,
2417                                  ToplevelBlock block, Attributes attrs, Location loc)
2418                         : base (parent, null, ret_type, mod_flags, AllowedModifiers,
2419                                 new MemberName (GetMetadataName (type), loc), attrs, parameters)
2420                 {
2421                         OperatorType = type;
2422                         Block = block;
2423                 }
2424
2425                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2426                 {
2427                         if (a.Type == pa.Conditional) {
2428                                 Error_ConditionalAttributeIsNotValid ();
2429                                 return;
2430                         }
2431
2432                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2433                 }
2434                 
2435                 public override bool Define ()
2436                 {
2437                         const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
2438                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
2439                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
2440                         }
2441
2442                         if (!base.Define ())
2443                                 return false;
2444
2445                         if (block != null && block.IsIterator) {
2446                                 //
2447                                 // Current method is turned into automatically generated
2448                                 // wrapper which creates an instance of iterator
2449                                 //
2450                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
2451                                 ModFlags |= Modifiers.DEBUGGER_HIDDEN;
2452                         }
2453
2454                         // imlicit and explicit operator of same types are not allowed
2455                         if (OperatorType == OpType.Explicit)
2456                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
2457                         else if (OperatorType == OpType.Implicit)
2458                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
2459
2460                         TypeSpec declaring_type = Parent.CurrentType;
2461                         TypeSpec return_type = MemberType;
2462                         TypeSpec first_arg_type = ParameterTypes [0];
2463                         
2464                         TypeSpec first_arg_type_unwrap = first_arg_type;
2465                         if (first_arg_type.IsNullableType)
2466                                 first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
2467                         
2468                         TypeSpec return_type_unwrap = return_type;
2469                         if (return_type.IsNullableType)
2470                                 return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);
2471
2472                         //
2473                         // Rules for conversion operators
2474                         //
2475                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2476                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
2477                                         Report.Error (555, Location,
2478                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
2479                                         return false;
2480                                 }
2481
2482                                 TypeSpec conv_type;
2483                                 if (declaring_type == return_type || declaring_type == return_type_unwrap) {
2484                                         conv_type = first_arg_type;
2485                                 } else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
2486                                         conv_type = return_type;
2487                                 } else {
2488                                         Report.Error (556, Location,
2489                                                 "User-defined conversion must convert to or from the enclosing type");
2490                                         return false;
2491                                 }
2492
2493                                 if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2494                                         Report.Error (1964, Location,
2495                                                 "User-defined conversion `{0}' cannot convert to or from the dynamic type",
2496                                                 GetSignatureForError ());
2497
2498                                         return false;
2499                                 }
2500
2501                                 if (conv_type.IsInterface) {
2502                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
2503                                                 GetSignatureForError ());
2504                                         return false;
2505                                 }
2506
2507                                 if (conv_type.IsClass) {
2508                                         if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
2509                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
2510                                                         GetSignatureForError ());
2511                                                 return false;
2512                                         }
2513
2514                                         if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
2515                                                 Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
2516                                                         GetSignatureForError ());
2517                                                 return false;
2518                                         }
2519                                 }
2520                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
2521                                 if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
2522                                         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");
2523                                         return false;
2524                                 }
2525                         } else if (parameters.Count == 1) {
2526                                 // Checks for Unary operators
2527
2528                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
2529                                         if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
2530                                                 Report.Error (448, Location,
2531                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
2532                                                 return false;
2533                                         }
2534                                         if (first_arg_type != declaring_type) {
2535                                                 Report.Error (
2536                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
2537                                                 return false;
2538                                         }
2539                                 }
2540
2541                                 if (first_arg_type_unwrap != declaring_type) {
2542                                         Report.Error (562, Location,
2543                                                 "The parameter type of a unary operator must be the containing type");
2544                                         return false;
2545                                 }
2546
2547                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
2548                                         if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
2549                                                 Report.Error (
2550                                                         215, Location,
2551                                                         "The return type of operator True or False " +
2552                                                         "must be bool");
2553                                                 return false;
2554                                         }
2555                                 }
2556
2557                         } else if (first_arg_type_unwrap != declaring_type) {
2558                                 // Checks for Binary operators
2559
2560                                 var second_arg_type = ParameterTypes[1];
2561                                 if (second_arg_type.IsNullableType)
2562                                         second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);
2563
2564                                 if (second_arg_type != declaring_type) {
2565                                         Report.Error (563, Location,
2566                                                 "One of the parameters of a binary operator must be the containing type");
2567                                         return false;
2568                                 }
2569                         }
2570
2571                         return true;
2572                 }
2573
2574                 protected override bool ResolveMemberType ()
2575                 {
2576                         if (!base.ResolveMemberType ())
2577                                 return false;
2578
2579                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2580                         return true;
2581                 }
2582
2583                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
2584                 {
2585                         // Operator cannot be override
2586                         bestCandidate = null;
2587                         return null;
2588                 }
2589
2590                 public static string GetName (OpType ot)
2591                 {
2592                         return names [(int) ot] [0];
2593                 }
2594
2595                 public static string GetName (string metadata_name)
2596                 {
2597                         for (int i = 0; i < names.Length; ++i) {
2598                                 if (names [i] [1] == metadata_name)
2599                                         return names [i] [0];
2600                         }
2601                         return null;
2602                 }
2603
2604                 public static string GetMetadataName (OpType ot)
2605                 {
2606                         return names [(int) ot] [1];
2607                 }
2608
2609                 public static string GetMetadataName (string name)
2610                 {
2611                         for (int i = 0; i < names.Length; ++i) {
2612                                 if (names [i] [0] == name)
2613                                         return names [i] [1];
2614                         }
2615                         return null;
2616                 }
2617
2618                 public static OpType? GetType (string metadata_name)
2619                 {
2620                         for (int i = 0; i < names.Length; ++i) {
2621                                 if (names[i][1] == metadata_name)
2622                                         return (OpType) i;
2623                         }
2624
2625                         return null;
2626                 }
2627
2628                 public OpType GetMatchingOperator ()
2629                 {
2630                         switch (OperatorType) {
2631                         case OpType.Equality:
2632                                 return OpType.Inequality;
2633                         case OpType.Inequality:
2634                                 return OpType.Equality;
2635                         case OpType.True:
2636                                 return OpType.False;
2637                         case OpType.False:
2638                                 return OpType.True;
2639                         case OpType.GreaterThan:
2640                                 return OpType.LessThan;
2641                         case OpType.LessThan:
2642                                 return OpType.GreaterThan;
2643                         case OpType.GreaterThanOrEqual:
2644                                 return OpType.LessThanOrEqual;
2645                         case OpType.LessThanOrEqual:
2646                                 return OpType.GreaterThanOrEqual;
2647                         default:
2648                                 return OpType.TOP;
2649                         }
2650                 }
2651
2652                 public override string GetSignatureForDocumentation ()
2653                 {
2654                         string s = base.GetSignatureForDocumentation ();
2655                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2656                                 s = s + "~" + ReturnType.GetSignatureForDocumentation ();
2657                         }
2658
2659                         return s;
2660                 }
2661
2662                 public override string GetSignatureForError ()
2663                 {
2664                         StringBuilder sb = new StringBuilder ();
2665                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2666                                 sb.AppendFormat ("{0}.{1} operator {2}",
2667                                         Parent.GetSignatureForError (), GetName (OperatorType),
2668                                         member_type == null ? type_expr.GetSignatureForError () : member_type.GetSignatureForError ());
2669                         }
2670                         else {
2671                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
2672                         }
2673
2674                         sb.Append (parameters.GetSignatureForError ());
2675                         return sb.ToString ();
2676                 }
2677         }
2678 }
2679