616a29600a1eaa2d5d4073b23660b458ce89d6ce
[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)))
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                                         block.Emit (ec);
1634                                 }
1635                         }
1636
1637                         if (source != null)
1638                                 source.CloseMethod ();
1639
1640                         if (declarative_security != null) {
1641                                 foreach (var de in declarative_security) {
1642 #if STATIC
1643                                         ConstructorBuilder.__AddDeclarativeSecurity (de);
1644 #else
1645                                         ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value);
1646 #endif
1647                                 }
1648                         }
1649
1650                         block = null;
1651                 }
1652
1653                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
1654                 {
1655                         // Is never override
1656                         bestCandidate = null;
1657                         return null;
1658                 }
1659
1660                 public override string GetSignatureForDocumentation ()
1661                 {
1662                         return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
1663                 }
1664
1665                 public override string GetSignatureForError()
1666                 {
1667                         return base.GetSignatureForError () + parameters.GetSignatureForError ();
1668                 }
1669
1670                 public override string[] ValidAttributeTargets {
1671                         get {
1672                                 return attribute_targets;
1673                         }
1674                 }
1675
1676                 protected override bool VerifyClsCompliance ()
1677                 {
1678                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
1679                                 return false;
1680                         }
1681
1682                         if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
1683                                 foreach (TypeSpec param in parameters.Types) {
1684                                         if (param.IsArray) {
1685                                                 return true;
1686                                         }
1687                                 }
1688                         }
1689
1690                         has_compliant_args = true;
1691                         return true;
1692                 }
1693
1694                 #region IMethodData Members
1695
1696                 public MemberName MethodName {
1697                         get {
1698                                 return MemberName;
1699                         }
1700                 }
1701
1702                 public TypeSpec ReturnType {
1703                         get {
1704                                 return MemberType;
1705                         }
1706                 }
1707
1708                 public EmitContext CreateEmitContext (ILGenerator ig)
1709                 {
1710                         throw new NotImplementedException ();
1711                 }
1712
1713                 public bool IsExcluded()
1714                 {
1715                         return false;
1716                 }
1717
1718                 GenericMethod IMethodData.GenericMethod {
1719                         get {
1720                                 return null;
1721                         }
1722                 }
1723
1724                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
1725                 { }
1726
1727                 #endregion
1728         }
1729
1730         /// <summary>
1731         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
1732         /// </summary>
1733         public interface IMethodData : IMemberContext
1734         {
1735                 CallingConventions CallingConventions { get; }
1736                 Location Location { get; }
1737                 MemberName MethodName { get; }
1738                 TypeSpec ReturnType { get; }
1739                 GenericMethod GenericMethod { get; }
1740                 ParametersCompiled ParameterInfo { get; }
1741                 MethodSpec Spec { get; }
1742                 bool IsAccessor { get; }
1743
1744                 Attributes OptAttributes { get; }
1745                 ToplevelBlock Block { get; set; }
1746
1747                 EmitContext CreateEmitContext (ILGenerator ig);
1748                 void EmitExtraSymbolInfo (SourceMethod source);
1749         }
1750
1751         //
1752         // Encapsulates most of the Method's state
1753         //
1754         public class MethodData
1755         {
1756 #if !STATIC
1757                 static FieldInfo methodbuilder_attrs_field;
1758 #endif
1759
1760                 public readonly IMethodData method;
1761
1762                 public readonly GenericMethod GenericMethod;
1763
1764                 //
1765                 // Are we implementing an interface ?
1766                 //
1767                 public MethodSpec implementing;
1768
1769                 //
1770                 // Protected data.
1771                 //
1772                 protected InterfaceMemberBase member;
1773                 protected Modifiers modifiers;
1774                 protected MethodAttributes flags;
1775                 protected TypeSpec declaring_type;
1776                 protected MethodSpec parent_method;
1777
1778                 MethodBuilder builder;
1779                 public MethodBuilder MethodBuilder {
1780                         get {
1781                                 return builder;
1782                         }
1783                 }
1784
1785                 public TypeSpec DeclaringType {
1786                         get {
1787                                 return declaring_type;
1788                         }
1789                 }
1790
1791                 public MethodData (InterfaceMemberBase member,
1792                                    Modifiers modifiers, MethodAttributes flags, IMethodData method)
1793                 {
1794                         this.member = member;
1795                         this.modifiers = modifiers;
1796                         this.flags = flags;
1797
1798                         this.method = method;
1799                 }
1800
1801                 public MethodData (InterfaceMemberBase member,
1802                                    Modifiers modifiers, MethodAttributes flags, 
1803                                    IMethodData method, MethodBuilder builder,
1804                                    GenericMethod generic, MethodSpec parent_method)
1805                         : this (member, modifiers, flags, method)
1806                 {
1807                         this.builder = builder;
1808                         this.GenericMethod = generic;
1809                         this.parent_method = parent_method;
1810                 }
1811
1812                 public bool Define (TypeContainer container, string method_full_name)
1813                 {
1814                         PendingImplementation pending = container.PendingImplementations;
1815                         MethodSpec ambig_iface_method;
1816                         bool optional = false;
1817
1818                         if (pending != null) {
1819                                 implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method, ref optional);
1820
1821                                 if (member.InterfaceType != null) {
1822                                         if (implementing == null) {
1823                                                 if (member is PropertyBase) {
1824                                                         container.Compiler.Report.Error (550, method.Location,
1825                                                                 "`{0}' is an accessor not found in interface member `{1}{2}'",
1826                                                                           method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
1827                                                                           member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
1828
1829                                                 } else {
1830                                                         container.Compiler.Report.Error (539, method.Location,
1831                                                                           "`{0}.{1}' in explicit interface declaration is not a member of interface",
1832                                                                           TypeManager.CSharpName (member.InterfaceType), member.ShortName);
1833                                                 }
1834                                                 return false;
1835                                         }
1836                                         if (implementing.IsAccessor && !method.IsAccessor) {
1837                                                 container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1838                                                 container.Compiler.Report.Error (683, method.Location,
1839                                                         "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
1840                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1841                                                 return false;
1842                                         }
1843                                 } else {
1844                                         if (implementing != null) {
1845                                                 if (!method.IsAccessor) {
1846                                                         if (implementing.IsAccessor) {
1847                                                                 container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1848                                                                 container.Compiler.Report.Error (470, method.Location,
1849                                                                         "Method `{0}' cannot implement interface accessor `{1}'",
1850                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1851                                                         }
1852                                                 } else if (implementing.DeclaringType.IsInterface) {
1853                                                         if (!implementing.IsAccessor) {
1854                                                                 container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1855                                                                 container.Compiler.Report.Error (686, method.Location,
1856                                                                         "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
1857                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
1858                                                         } else {
1859                                                                 PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
1860                                                                 if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
1861                                                                         container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1862                                                                         container.Compiler.Report.Error (277, method.Location,
1863                                                                                 "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                                 if (member.IsExplicitImpl) {
1880                                         if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
1881                                                 container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1882                                                 container.Compiler.Report.Error (466, method.Location,
1883                                                         "`{0}': the explicit interface implementation cannot introduce the params modifier",
1884                                                         method.GetSignatureForError ());
1885                                         }
1886
1887                                         if (ambig_iface_method != null) {
1888                                                 container.Compiler.Report.SymbolRelatedToPreviousError (ambig_iface_method);
1889                                                 container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
1890                                                 container.Compiler.Report.Warning (473, 2, method.Location,
1891                                                         "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
1892                                                         method.GetSignatureForError ());
1893                                         }
1894                                 } else {
1895                                         //
1896                                         // Setting implementin to null inside this block will trigger a more
1897                                         // verbose error reporting for missing interface implementations
1898                                         //
1899                                         if (implementing.DeclaringType.IsInterface) {
1900                                                 //
1901                                                 // If this is an interface method implementation,
1902                                                 // check for public accessibility
1903                                                 //
1904                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
1905                                                         implementing = null;
1906                                                 } else if (optional && (container.Interfaces == null || Array.IndexOf (container.Interfaces, implementing.DeclaringType) < 0)) {
1907                                                         //
1908                                                         // We are not implementing interface when base class already implemented it
1909                                                         //
1910                                                         implementing = null;
1911                                                 }
1912                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) {
1913                                                 // We may never be private.
1914                                                 implementing = null;
1915
1916                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0) {
1917                                                 //
1918                                                 // We may be protected if we're overriding something.
1919                                                 //
1920                                                 implementing = null;
1921                                         }
1922                                 }
1923                                         
1924                                 //
1925                                 // Static is not allowed
1926                                 //
1927                                 if ((modifiers & Modifiers.STATIC) != 0){
1928                                         implementing = null;
1929                                 }
1930                         }
1931                         
1932                         //
1933                         // If implementing is still valid, set flags
1934                         //
1935                         if (implementing != null){
1936                                 //
1937                                 // When implementing interface methods, set NewSlot
1938                                 // unless, we are overwriting a method.
1939                                 //
1940                                 if ((modifiers & Modifiers.OVERRIDE) == 0 && implementing.DeclaringType.IsInterface) {
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                                 pending.ImplementMethod (method.MethodName,
1954                                         member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method, ref optional);
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
2037                                         block.Emit (ec);
2038                                 }
2039                         }
2040
2041                         if (source != null) {
2042                                 method.EmitExtraSymbolInfo (source);
2043                                 source.CloseMethod ();
2044                         }
2045                 }
2046         }
2047
2048         public class Destructor : MethodOrOperator
2049         {
2050                 const Modifiers AllowedModifiers =
2051                         Modifiers.UNSAFE |
2052                         Modifiers.EXTERN;
2053
2054                 static readonly string[] attribute_targets = new string [] { "method" };
2055
2056                 public static readonly string MetadataName = "Finalize";
2057
2058                 public Destructor (DeclSpace parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
2059                         : base (parent, null, null, mod, AllowedModifiers,
2060                                 new MemberName (MetadataName, l), attrs, parameters)
2061                 {
2062                         ModFlags &= ~Modifiers.PRIVATE;
2063                         ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2064                 }
2065
2066                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2067                 {
2068                         if (a.Type == pa.Conditional) {
2069                                 Error_ConditionalAttributeIsNotValid ();
2070                                 return;
2071                         }
2072
2073                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2074                 }
2075
2076                 protected override bool CheckBase ()
2077                 {
2078                         // Don't check base, destructors have special syntax
2079                         return true;
2080                 }
2081
2082                 public override void Emit()
2083                 {
2084                         var base_type = Parent.PartialContainer.BaseType;
2085                         if (base_type != null && Block != null) {
2086                                 var base_dtor = MemberCache.FindMember (base_type,
2087                                         new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
2088
2089                                 if (base_dtor == null)
2090                                         throw new NotImplementedException ();
2091
2092                                 MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
2093                                 method_expr.InstanceExpression = new BaseThis (base_type, Location);
2094
2095                                 var try_block = new ExplicitBlock (block, block.StartLocation, block.EndLocation);
2096                                 var finaly_block = new ExplicitBlock (block, Location, Location);
2097
2098                                 //
2099                                 // 0-size arguments to avoid CS0250 error
2100                                 // TODO: Should use AddScopeStatement or something else which emits correct
2101                                 // debugger scope
2102                                 //
2103                                 finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0))));
2104
2105                                 var tf = new TryFinally (try_block, finaly_block, Location);
2106                                 block.WrapIntoDestructor (tf, try_block);
2107                         }
2108
2109                         base.Emit ();
2110                 }
2111
2112                 public override string GetSignatureForError ()
2113                 {
2114                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
2115                 }
2116
2117                 protected override bool ResolveMemberType ()
2118                 {
2119                         member_type = Compiler.BuiltinTypes.Void;
2120                         return true;
2121                 }
2122
2123                 public override string[] ValidAttributeTargets {
2124                         get {
2125                                 return attribute_targets;
2126                         }
2127                 }
2128         }
2129
2130         // Ooouh Martin, templates are missing here.
2131         // When it will be possible move here a lot of child code and template method type.
2132         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
2133                 protected MethodData method_data;
2134                 protected ToplevelBlock block;
2135                 protected SecurityType declarative_security;
2136
2137                 protected readonly string prefix;
2138
2139                 ReturnParameter return_attributes;
2140
2141                 public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
2142                         : base (member.Parent, SetupName (prefix, member, loc), attrs)
2143                 {
2144                         this.prefix = prefix;
2145                 }
2146
2147                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
2148                 {
2149                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
2150                 }
2151
2152                 public void UpdateName (InterfaceMemberBase member)
2153                 {
2154                         SetMemberName (SetupName (prefix, member, Location));
2155                 }
2156
2157                 #region IMethodData Members
2158
2159                 public ToplevelBlock Block {
2160                         get {
2161                                 return block;
2162                         }
2163
2164                         set {
2165                                 block = value;
2166                         }
2167                 }
2168
2169                 public CallingConventions CallingConventions {
2170                         get {
2171                                 return CallingConventions.Standard;
2172                         }
2173                 }
2174
2175                 public EmitContext CreateEmitContext (ILGenerator ig)
2176                 {
2177                         return new EmitContext (this, ig, ReturnType);
2178                 }
2179
2180                 public bool IsAccessor {
2181                         get {
2182                                 return true;
2183                         }
2184                 }
2185
2186                 public bool IsExcluded ()
2187                 {
2188                         return false;
2189                 }
2190
2191                 GenericMethod IMethodData.GenericMethod {
2192                         get {
2193                                 return null;
2194                         }
2195                 }
2196
2197                 public MemberName MethodName {
2198                         get {
2199                                 return MemberName;
2200                         }
2201                 }
2202
2203                 public TypeSpec[] ParameterTypes { 
2204                         get {
2205                                 return ParameterInfo.Types;
2206                         }
2207                 }
2208
2209                 public abstract ParametersCompiled ParameterInfo { get ; }
2210                 public abstract TypeSpec ReturnType { get; }
2211
2212                 #endregion
2213
2214                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2215                 {
2216                         if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
2217                                 Report.Error (1667, a.Location,
2218                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
2219                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
2220                                 return;
2221                         }
2222
2223                         if (a.IsValidSecurityAttribute ()) {
2224                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2225                                 return;
2226                         }
2227
2228                         if (a.Target == AttributeTargets.Method) {
2229                                 method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
2230                                 return;
2231                         }
2232
2233                         if (a.Target == AttributeTargets.ReturnValue) {
2234                                 if (return_attributes == null)
2235                                         return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2236
2237                                 return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
2238                                 return;
2239                         }
2240
2241                         ApplyToExtraTarget (a, ctor, cdata, pa);
2242                 }
2243
2244                 protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2245                 {
2246                         throw new NotSupportedException ("You forgot to define special attribute target handling");
2247                 }
2248
2249                 // It is not supported for the accessors
2250                 public sealed override bool Define()
2251                 {
2252                         throw new NotSupportedException ();
2253                 }
2254
2255                 public virtual void Emit (DeclSpace parent)
2256                 {
2257                         method_data.Emit (parent);
2258
2259                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2260                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
2261                         if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
2262                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
2263
2264                         if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2265                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2266                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
2267                         } else if (ReturnType.HasDynamicElement) {
2268                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2269                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
2270                         }
2271
2272                         if (OptAttributes != null)
2273                                 OptAttributes.Emit ();
2274
2275                         if (declarative_security != null) {
2276                                 foreach (var de in declarative_security) {
2277 #if STATIC
2278                                         method_data.MethodBuilder.__AddDeclarativeSecurity (de);
2279 #else
2280                                         method_data.MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2281 #endif
2282                                 }
2283                         }
2284
2285                         block = null;
2286                 }
2287
2288                 public override bool EnableOverloadChecks (MemberCore overload)
2289                 {
2290                         if (overload is MethodCore) {
2291                                 caching_flags |= Flags.MethodOverloadsExist;
2292                                 return true;
2293                         }
2294
2295                         // This can only happen with indexers and it will
2296                         // be catched as indexer difference
2297                         if (overload is AbstractPropertyEventMethod)
2298                                 return true;
2299
2300                         return false;
2301                 }
2302
2303                 public override string GetSignatureForDocumentation ()
2304                 {
2305                         // should not be called
2306                         throw new NotSupportedException ();
2307                 }
2308
2309                 public override bool IsClsComplianceRequired()
2310                 {
2311                         return false;
2312                 }
2313
2314                 public MethodSpec Spec { get; protected set; }
2315
2316                 //
2317                 //   Represents header string for documentation comment.
2318                 //
2319                 public override string DocCommentHeader {
2320                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
2321                 }
2322
2323                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
2324                 { }
2325         }
2326
2327         public class Operator : MethodOrOperator {
2328
2329                 const Modifiers AllowedModifiers =
2330                         Modifiers.PUBLIC |
2331                         Modifiers.UNSAFE |
2332                         Modifiers.EXTERN |
2333                         Modifiers.STATIC;
2334
2335                 public enum OpType : byte {
2336
2337                         // Unary operators
2338                         LogicalNot,
2339                         OnesComplement,
2340                         Increment,
2341                         Decrement,
2342                         True,
2343                         False,
2344
2345                         // Unary and Binary operators
2346                         Addition,
2347                         Subtraction,
2348
2349                         UnaryPlus,
2350                         UnaryNegation,
2351                         
2352                         // Binary operators
2353                         Multiply,
2354                         Division,
2355                         Modulus,
2356                         BitwiseAnd,
2357                         BitwiseOr,
2358                         ExclusiveOr,
2359                         LeftShift,
2360                         RightShift,
2361                         Equality,
2362                         Inequality,
2363                         GreaterThan,
2364                         LessThan,
2365                         GreaterThanOrEqual,
2366                         LessThanOrEqual,
2367
2368                         // Implicit and Explicit
2369                         Implicit,
2370                         Explicit,
2371
2372                         // Just because of enum
2373                         TOP
2374                 };
2375
2376                 public readonly OpType OperatorType;
2377
2378                 static readonly string [] [] names;
2379
2380                 static Operator ()
2381                 {
2382                         names = new string[(int)OpType.TOP][];
2383                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
2384                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
2385                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
2386                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
2387                         names [(int) OpType.True] = new string [] { "true", "op_True" };
2388                         names [(int) OpType.False] = new string [] { "false", "op_False" };
2389                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
2390                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
2391                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
2392                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
2393                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
2394                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
2395                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
2396                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
2397                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
2398                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
2399                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
2400                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
2401                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
2402                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
2403                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
2404                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
2405                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
2406                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
2407                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
2408                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
2409                 }
2410                 
2411                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
2412                                  Modifiers mod_flags, ParametersCompiled parameters,
2413                                  ToplevelBlock block, Attributes attrs, Location loc)
2414                         : base (parent, null, ret_type, mod_flags, AllowedModifiers,
2415                                 new MemberName (GetMetadataName (type), loc), attrs, parameters)
2416                 {
2417                         OperatorType = type;
2418                         Block = block;
2419                 }
2420
2421                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2422                 {
2423                         if (a.Type == pa.Conditional) {
2424                                 Error_ConditionalAttributeIsNotValid ();
2425                                 return;
2426                         }
2427
2428                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2429                 }
2430                 
2431                 public override bool Define ()
2432                 {
2433                         const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
2434                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
2435                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
2436                         }
2437
2438                         if (!base.Define ())
2439                                 return false;
2440
2441                         if (block != null && block.IsIterator) {
2442                                 //
2443                                 // Current method is turned into automatically generated
2444                                 // wrapper which creates an instance of iterator
2445                                 //
2446                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
2447                                 ModFlags |= Modifiers.DEBUGGER_HIDDEN;
2448                         }
2449
2450                         // imlicit and explicit operator of same types are not allowed
2451                         if (OperatorType == OpType.Explicit)
2452                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
2453                         else if (OperatorType == OpType.Implicit)
2454                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
2455
2456                         TypeSpec declaring_type = Parent.CurrentType;
2457                         TypeSpec return_type = MemberType;
2458                         TypeSpec first_arg_type = ParameterTypes [0];
2459                         
2460                         TypeSpec first_arg_type_unwrap = first_arg_type;
2461                         if (first_arg_type.IsNullableType)
2462                                 first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
2463                         
2464                         TypeSpec return_type_unwrap = return_type;
2465                         if (return_type.IsNullableType)
2466                                 return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);
2467
2468                         //
2469                         // Rules for conversion operators
2470                         //
2471                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2472                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
2473                                         Report.Error (555, Location,
2474                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
2475                                         return false;
2476                                 }
2477
2478                                 TypeSpec conv_type;
2479                                 if (declaring_type == return_type || declaring_type == return_type_unwrap) {
2480                                         conv_type = first_arg_type;
2481                                 } else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
2482                                         conv_type = return_type;
2483                                 } else {
2484                                         Report.Error (556, Location,
2485                                                 "User-defined conversion must convert to or from the enclosing type");
2486                                         return false;
2487                                 }
2488
2489                                 if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2490                                         Report.Error (1964, Location,
2491                                                 "User-defined conversion `{0}' cannot convert to or from the dynamic type",
2492                                                 GetSignatureForError ());
2493
2494                                         return false;
2495                                 }
2496
2497                                 if (conv_type.IsInterface) {
2498                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
2499                                                 GetSignatureForError ());
2500                                         return false;
2501                                 }
2502
2503                                 if (conv_type.IsClass) {
2504                                         if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
2505                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
2506                                                         GetSignatureForError ());
2507                                                 return false;
2508                                         }
2509
2510                                         if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
2511                                                 Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
2512                                                         GetSignatureForError ());
2513                                                 return false;
2514                                         }
2515                                 }
2516                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
2517                                 if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
2518                                         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");
2519                                         return false;
2520                                 }
2521                         } else if (parameters.Count == 1) {
2522                                 // Checks for Unary operators
2523
2524                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
2525                                         if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
2526                                                 Report.Error (448, Location,
2527                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
2528                                                 return false;
2529                                         }
2530                                         if (first_arg_type != declaring_type) {
2531                                                 Report.Error (
2532                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
2533                                                 return false;
2534                                         }
2535                                 }
2536
2537                                 if (first_arg_type_unwrap != declaring_type) {
2538                                         Report.Error (562, Location,
2539                                                 "The parameter type of a unary operator must be the containing type");
2540                                         return false;
2541                                 }
2542
2543                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
2544                                         if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
2545                                                 Report.Error (
2546                                                         215, Location,
2547                                                         "The return type of operator True or False " +
2548                                                         "must be bool");
2549                                                 return false;
2550                                         }
2551                                 }
2552
2553                         } else if (first_arg_type_unwrap != declaring_type) {
2554                                 // Checks for Binary operators
2555
2556                                 var second_arg_type = ParameterTypes[1];
2557                                 if (second_arg_type.IsNullableType)
2558                                         second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);
2559
2560                                 if (second_arg_type != declaring_type) {
2561                                         Report.Error (563, Location,
2562                                                 "One of the parameters of a binary operator must be the containing type");
2563                                         return false;
2564                                 }
2565                         }
2566
2567                         return true;
2568                 }
2569
2570                 protected override bool ResolveMemberType ()
2571                 {
2572                         if (!base.ResolveMemberType ())
2573                                 return false;
2574
2575                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2576                         return true;
2577                 }
2578
2579                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
2580                 {
2581                         // Operator cannot be override
2582                         bestCandidate = null;
2583                         return null;
2584                 }
2585
2586                 public static string GetName (OpType ot)
2587                 {
2588                         return names [(int) ot] [0];
2589                 }
2590
2591                 public static string GetName (string metadata_name)
2592                 {
2593                         for (int i = 0; i < names.Length; ++i) {
2594                                 if (names [i] [1] == metadata_name)
2595                                         return names [i] [0];
2596                         }
2597                         return null;
2598                 }
2599
2600                 public static string GetMetadataName (OpType ot)
2601                 {
2602                         return names [(int) ot] [1];
2603                 }
2604
2605                 public static string GetMetadataName (string name)
2606                 {
2607                         for (int i = 0; i < names.Length; ++i) {
2608                                 if (names [i] [0] == name)
2609                                         return names [i] [1];
2610                         }
2611                         return null;
2612                 }
2613
2614                 public static OpType? GetType (string metadata_name)
2615                 {
2616                         for (int i = 0; i < names.Length; ++i) {
2617                                 if (names[i][1] == metadata_name)
2618                                         return (OpType) i;
2619                         }
2620
2621                         return null;
2622                 }
2623
2624                 public OpType GetMatchingOperator ()
2625                 {
2626                         switch (OperatorType) {
2627                         case OpType.Equality:
2628                                 return OpType.Inequality;
2629                         case OpType.Inequality:
2630                                 return OpType.Equality;
2631                         case OpType.True:
2632                                 return OpType.False;
2633                         case OpType.False:
2634                                 return OpType.True;
2635                         case OpType.GreaterThan:
2636                                 return OpType.LessThan;
2637                         case OpType.LessThan:
2638                                 return OpType.GreaterThan;
2639                         case OpType.GreaterThanOrEqual:
2640                                 return OpType.LessThanOrEqual;
2641                         case OpType.LessThanOrEqual:
2642                                 return OpType.GreaterThanOrEqual;
2643                         default:
2644                                 return OpType.TOP;
2645                         }
2646                 }
2647
2648                 public override string GetSignatureForDocumentation ()
2649                 {
2650                         string s = base.GetSignatureForDocumentation ();
2651                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2652                                 s = s + "~" + ReturnType.GetSignatureForDocumentation ();
2653                         }
2654
2655                         return s;
2656                 }
2657
2658                 public override string GetSignatureForError ()
2659                 {
2660                         StringBuilder sb = new StringBuilder ();
2661                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2662                                 sb.AppendFormat ("{0}.{1} operator {2}",
2663                                         Parent.GetSignatureForError (), GetName (OperatorType),
2664                                         member_type == null ? type_expr.GetSignatureForError () : member_type.GetSignatureForError ());
2665                         }
2666                         else {
2667                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
2668                         }
2669
2670                         sb.Append (parameters.GetSignatureForError ());
2671                         return sb.ToString ();
2672                 }
2673         }
2674 }
2675