Add more checks for async modifier
[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                                         Parent.MemberCache.AddMember (spec);
601                                 }
602
603                                 return true;
604                         }
605
606                         MethodData = new MethodData (
607                                 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
608
609                         if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName), Report))
610                                 return false;
611                                         
612                         MethodBuilder = MethodData.MethodBuilder;
613
614                         spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
615                         if (MemberName.Arity > 0)
616                                 spec.IsGeneric = true;
617                         
618                         Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
619
620                         return true;
621                 }
622
623                 protected override void DoMemberTypeIndependentChecks ()
624                 {
625                         base.DoMemberTypeIndependentChecks ();
626
627                         CheckAbstractAndExtern (block != null);
628
629                         if ((ModFlags & Modifiers.PARTIAL) != 0) {
630                                 for (int i = 0; i < parameters.Count; ++i) {
631                                         IParameterData p = parameters.FixedParameters [i];
632                                         if (p.ModFlags == Parameter.Modifier.OUT) {
633                                                 Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
634                                                         GetSignatureForError ());
635                                         }
636
637                                         if (p.HasDefaultValue && IsPartialImplementation)
638                                                 ((Parameter) p).Warning_UselessOptionalParameter (Report);
639                                 }
640                         }
641                 }
642
643                 protected override void DoMemberTypeDependentChecks ()
644                 {
645                         base.DoMemberTypeDependentChecks ();
646
647                         if (MemberType.IsStatic) {
648                                 Error_StaticReturnType ();
649                         }
650                 }
651
652                 public override void Emit ()
653                 {
654                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
655                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder);
656                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
657                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder);
658
659                         if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
660                                 return_attributes = new ReturnParameter (this, MethodBuilder, Location);
661                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
662                         } else if (ReturnType.HasDynamicElement) {
663                                 return_attributes = new ReturnParameter (this, MethodBuilder, Location);
664                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
665                         }
666
667                         if (OptAttributes != null)
668                                 OptAttributes.Emit ();
669
670                         if (declarative_security != null) {
671                                 foreach (var de in declarative_security) {
672 #if STATIC
673                                         MethodBuilder.__AddDeclarativeSecurity (de);
674 #else
675                                         MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
676 #endif
677                                 }
678                         }
679
680                         if (type_expr != null)
681                                 ConstraintChecker.Check (this, member_type, type_expr.Location);
682
683                         base.Emit ();
684
685                         if (MethodData != null)
686                                 MethodData.Emit (Parent);
687
688                         Block = null;
689                         MethodData = null;
690                 }
691
692                 protected void Error_ConditionalAttributeIsNotValid ()
693                 {
694                         Report.Error (577, Location,
695                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
696                                 GetSignatureForError ());
697                 }
698
699                 public bool IsPartialDefinition {
700                         get {
701                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
702                         }
703                 }
704
705                 public bool IsPartialImplementation {
706                         get {
707                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
708                         }
709                 }
710
711                 public override string[] ValidAttributeTargets {
712                         get {
713                                 return attribute_targets;
714                         }
715                 }
716
717                 #region IMethodData Members
718
719                 bool IMethodData.IsAccessor {
720                         get {
721                                 return false;
722                         }
723                 }
724
725                 public TypeSpec ReturnType {
726                         get {
727                                 return MemberType;
728                         }
729                 }
730
731                 public MemberName MethodName {
732                         get {
733                                 return MemberName;
734                         }
735                 }
736
737                 /// <summary>
738                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
739                 /// </summary>
740                 public override string[] ConditionalConditions ()
741                 {
742                         if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
743                                 return null;
744
745                         if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.Excluded) != 0)
746                                 return new string [0];
747
748                         caching_flags &= ~Flags.Excluded_Undetected;
749                         string[] conditions;
750
751                         if (base_method == null) {
752                                 if (OptAttributes == null)
753                                         return null;
754
755                                 Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
756                                 if (attrs == null)
757                                         return null;
758
759                                 conditions = new string[attrs.Length];
760                                 for (int i = 0; i < conditions.Length; ++i)
761                                         conditions[i] = attrs[i].GetConditionalAttributeValue ();
762                         } else {
763                                 conditions = base_method.MemberDefinition.ConditionalConditions();
764                         }
765
766                         if (conditions != null)
767                                 caching_flags |= Flags.Excluded;
768
769                         return conditions;
770                 }
771
772                 GenericMethod IMethodData.GenericMethod {
773                         get {
774                                 return GenericMethod;
775                         }
776                 }
777
778                 public virtual void EmitExtraSymbolInfo (SourceMethod source)
779                 { }
780
781                 #endregion
782
783         }
784
785         public class SourceMethod : IMethodDef
786         {
787                 MethodBase method;
788                 SourceMethodBuilder builder;
789
790                 protected SourceMethod (DeclSpace parent, MethodBase method, ICompileUnit file)
791                 {
792                         this.method = method;
793                         
794                         builder = SymbolWriter.OpenMethod (file, parent.NamespaceEntry.SymbolFileID, this);
795                 }
796
797                 public string Name {
798                         get { return method.Name; }
799                 }
800
801                 public int Token {
802                         get {
803                                 MethodToken token;
804                                 var mb = method as MethodBuilder;
805                                 if (mb != null)
806                                         token = mb.GetToken ();
807                                 else
808                                         token = ((ConstructorBuilder) method).GetToken ();
809 #if STATIC
810                                 if (token.IsPseudoToken)
811                                         return ((ModuleBuilder) method.Module).ResolvePseudoToken (token.Token);
812 #endif
813                                 return token.Token;
814                         }
815                 }
816
817                 public void CloseMethod ()
818                 {
819                         SymbolWriter.CloseMethod ();
820                 }
821
822                 public void SetRealMethodName (string name)
823                 {
824                         if (builder != null)
825                                 builder.SetRealMethodName (name);
826                 }
827
828                 public static SourceMethod Create (DeclSpace parent, MethodBase method, Block block)
829                 {
830                         if (!SymbolWriter.HasSymbolWriter)
831                                 return null;
832                         if (block == null)
833                                 return null;
834
835                         Location start_loc = block.StartLocation;
836                         if (start_loc.IsNull)
837                                 return null;
838
839                         ICompileUnit compile_unit = start_loc.CompilationUnit;
840                         if (compile_unit == null)
841                                 return null;
842
843                         return new SourceMethod (parent, method, compile_unit);
844                 }
845         }
846
847         public class Method : MethodOrOperator, IGenericMethodDefinition
848         {
849                 Method partialMethodImplementation;
850
851                 public Method (DeclSpace parent, GenericMethod generic,
852                                FullNamedExpression return_type, Modifiers mod,
853                                MemberName name, ParametersCompiled parameters, Attributes attrs)
854                         : base (parent, generic, return_type, mod,
855                                 parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface :
856                                 parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct | Modifiers.ASYNC :
857                                 AllowedModifiersClass | Modifiers.ASYNC,
858                                 name, attrs, parameters)
859                 {
860                 }
861
862                 protected Method (DeclSpace parent, FullNamedExpression return_type, Modifiers mod, Modifiers amod,
863                                         MemberName name, ParametersCompiled parameters, Attributes attrs)
864                         : base (parent, null, return_type, mod, amod, name, attrs, parameters)
865                 {
866                 }
867
868                 #region Properties
869
870                 public override TypeParameter[] CurrentTypeParameters {
871                         get {
872                                 if (GenericMethod != null)
873                                         return GenericMethod.CurrentTypeParameters;
874
875                                 return null;
876                         }
877                 }
878
879                 public TypeParameterSpec[] TypeParameters {
880                         get {
881                                 // TODO: Cache this
882                                 return CurrentTypeParameters.Select (l => l.Type).ToArray ();
883                         }
884                 }
885
886                 public int TypeParametersCount {
887                         get {
888                                 return CurrentTypeParameters == null ? 0 : CurrentTypeParameters.Length;
889                         }
890                 }
891
892 #endregion
893
894                 public override string GetSignatureForError()
895                 {
896                         return base.GetSignatureForError () + parameters.GetSignatureForError ();
897                 }
898
899                 void Error_DuplicateEntryPoint (Method b)
900                 {
901                         Report.Error (17, b.Location,
902                                 "Program `{0}' has more than one entry point defined: `{1}'",
903                                 b.Module.Builder.ScopeName, b.GetSignatureForError ());
904                 }
905
906                 bool IsEntryPoint ()
907                 {
908                         if (ReturnType.Kind != MemberKind.Void && ReturnType.BuiltinType != BuiltinTypeSpec.Type.Int)
909                                 return false;
910
911                         if (parameters.IsEmpty)
912                                 return true;
913
914                         if (parameters.Count > 1)
915                                 return false;
916
917                         var ac = parameters.Types [0] as ArrayContainer;
918                         return ac != null && ac.Rank == 1 && ac.Element.BuiltinType == BuiltinTypeSpec.Type.String &&
919                                         (parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
920                 }
921
922                 public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
923                 {
924                         if (arity == 0) {
925                                 TypeParameter[] tp = CurrentTypeParameters;
926                                 if (tp != null) {
927                                         TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
928                                         if (t != null)
929                                                 return new TypeParameterExpr (t, loc);
930                                 }
931                         }
932
933                         return base.LookupNamespaceOrType (name, arity, mode, loc);
934                 }
935
936                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
937                 {
938                         if (a.Type == pa.Conditional) {
939                                 if (IsExplicitImpl) {
940                                         Error_ConditionalAttributeIsNotValid ();
941                                         return;
942                                 }
943
944                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
945                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
946                                         return;
947                                 }
948
949                                 if (ReturnType.Kind != MemberKind.Void) {
950                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
951                                         return;
952                                 }
953
954                                 if (IsInterface) {
955                                         Report.Error (582, Location, "Conditional not valid on interface members");
956                                         return;
957                                 }
958
959                                 if (MethodData.implementing != null) {
960                                         Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
961                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
962                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
963                                         return;
964                                 }
965
966                                 for (int i = 0; i < parameters.Count; ++i) {
967                                         if (parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
968                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
969                                                 return;
970                                         }
971                                 }
972                         }
973
974                         if (a.Type == pa.Extension) {
975                                 a.Error_MisusedExtensionAttribute ();
976                                 return;
977                         }
978
979                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
980                 }
981
982                 protected virtual void DefineTypeParameters ()
983                 {
984                         var tparams = CurrentTypeParameters;
985
986                         TypeParameterSpec[] base_tparams = null;
987                         TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
988                         TypeSpec[] base_targs = TypeSpec.EmptyTypes;
989                         if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
990                                 if (base_method != null) {
991                                         base_tparams = base_method.GenericDefinition.TypeParameters;
992                                 
993                                         if (base_method.DeclaringType.IsGeneric) {
994                                                 base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters;
995
996                                                 var base_type_parent = CurrentType;
997                                                 while (base_type_parent.BaseType != base_method.DeclaringType) {
998                                                         base_type_parent = base_type_parent.BaseType;
999                                                 }
1000
1001                                                 base_targs = base_type_parent.BaseType.TypeArguments;
1002                                         }
1003
1004                                         if (base_method.IsGeneric) {
1005                                                 ObsoleteAttribute oa;
1006                                                 foreach (var base_tp in base_tparams) {
1007                                                         oa = base_tp.BaseType.GetAttributeObsolete ();
1008                                                         if (oa != null) {
1009                                                                 AttributeTester.Report_ObsoleteMessage (oa, base_tp.BaseType.GetSignatureForError (), Location, Report);
1010                                                         }
1011
1012                                                         if (base_tp.InterfacesDefined != null) {
1013                                                                 foreach (var iface in base_tp.InterfacesDefined) {
1014                                                                         oa = iface.GetAttributeObsolete ();
1015                                                                         if (oa != null) {
1016                                                                                 AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
1017                                                                         }
1018                                                                 }
1019                                                         }
1020                                                 }
1021
1022                                                 if (base_decl_tparams.Length != 0) {
1023                                                         base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
1024                                                         base_targs = base_targs.Concat (tparams.Select<TypeParameter, TypeSpec> (l => l.Type)).ToArray ();
1025                                                 } else {
1026                                                         base_decl_tparams = base_tparams;
1027                                                         base_targs = tparams.Select (l => l.Type).ToArray ();
1028                                                 }
1029                                         }
1030                                 } else if (MethodData.implementing != null) {
1031                                         base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
1032                                         if (MethodData.implementing.DeclaringType.IsGeneric) {
1033                                                 base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters;
1034                                                 foreach (var iface in Parent.CurrentType.Interfaces) {
1035                                                         if (iface == MethodData.implementing.DeclaringType) {
1036                                                                 base_targs = iface.TypeArguments;
1037                                                                 break;
1038                                                         }
1039                                                 }
1040                                         }
1041                                 }
1042                         }
1043
1044                         for (int i = 0; i < tparams.Length; ++i) {
1045                                 var tp = tparams[i];
1046
1047                                 if (!tp.ResolveConstraints (this))
1048                                         continue;
1049
1050                                 //
1051                                 // Copy base constraints for override/explicit methods
1052                                 //
1053                                 if (base_tparams != null) {
1054                                         var base_tparam = base_tparams[i];
1055                                         var local_tparam = tp.Type;
1056                                         local_tparam.SpecialConstraint = base_tparam.SpecialConstraint;
1057
1058                                         var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs);
1059                                         base_tparam.InflateConstraints (inflator, local_tparam);
1060
1061                                         //
1062                                         // Check all type argument constraints for possible collision
1063                                         // introduced by inflating inherited constraints in this context
1064                                         //
1065                                         // Conflict example:
1066                                         //
1067                                         // class A<T> { virtual void Foo<U> () where U : class, T {} }
1068                                         // class B : A<int> { override void Foo<U> {} }
1069                                         //
1070                                         var local_tparam_targs = local_tparam.TypeArguments;
1071                                         if (local_tparam_targs != null) {                                       
1072                                                 for (int ii = 0; ii < local_tparam_targs.Length; ++ii) {
1073                                                         var ta = local_tparam_targs [ii];
1074                                                         if (!ta.IsClass && !ta.IsStruct)
1075                                                                 continue;
1076
1077                                                         if (Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location)) {
1078                                                                 local_tparam.ChangeTypeArgumentToBaseType (ii);
1079                                                         }
1080                                                 }
1081                                         }
1082
1083                                         continue;
1084                                 }
1085                                 
1086                                 if (MethodData.implementing != null) {
1087                                         var base_tp = MethodData.implementing.Constraints[i];
1088                                         if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
1089                                                 Report.SymbolRelatedToPreviousError (MethodData.implementing);
1090                                                 Report.Error (425, Location,
1091                                                         "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",
1092                                                         tp.GetSignatureForError (), GetSignatureForError (), base_tp.GetSignatureForError (), MethodData.implementing.GetSignatureForError ());
1093                                         }
1094                                 }
1095                         }
1096                 }
1097
1098                 //
1099                 // Creates the type
1100                 //
1101                 public override bool Define ()
1102                 {
1103                         if (!base.Define ())
1104                                 return false;
1105
1106                         if (member_type.Kind == MemberKind.Void && parameters.IsEmpty && MemberName.Arity == 0 && MemberName.Name == Destructor.MetadataName) {
1107                                 Report.Warning (465, 1, Location,
1108                                         "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
1109                         }
1110
1111                         if (partialMethodImplementation != null && IsPartialDefinition)
1112                                 MethodBuilder = partialMethodImplementation.MethodBuilder;
1113
1114                         if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) {
1115                                 Error1599 (Location, ReturnType, Report);
1116                                 return false;
1117                         }
1118
1119                         if (CurrentTypeParameters == null) {
1120                                 if (base_method != null) {
1121                                         if (parameters.Count == 1 && ParameterTypes[0].BuiltinType == BuiltinTypeSpec.Type.Object && Name == "Equals")
1122                                                 Parent.PartialContainer.Mark_HasEquals ();
1123                                         else if (parameters.IsEmpty && Name == "GetHashCode")
1124                                                 Parent.PartialContainer.Mark_HasGetHashCode ();
1125                                 }
1126                                         
1127                         } else {
1128                                 DefineTypeParameters ();
1129                         }
1130
1131                         if (block != null) {
1132                                 if (block.IsIterator) {
1133                                         //
1134                                         // Current method is turned into automatically generated
1135                                         // wrapper which creates an instance of iterator
1136                                         //
1137                                         Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1138                                         ModFlags |= Modifiers.DEBUGGER_HIDDEN;
1139                                 }
1140
1141                                 if ((ModFlags & Modifiers.ASYNC) != 0) {
1142                                         if (ReturnType.Kind != MemberKind.Void && ReturnType != Module.PredefinedTypes.Task.TypeSpec && ReturnType != Module.PredefinedTypes.TaskGeneric.TypeSpec) {
1143                                                 Report.Error (1983, type_expr.Location, "The return type of an async method `{0}' must be void, Task, or Task<T>",
1144                                                         GetSignatureForError ());
1145                                         }
1146
1147                                         if (!block.IsAsync) {
1148                                                 // TODO: Warning
1149                                         }
1150
1151                                         AsyncInitializer.Create (block, Parent.PartialContainer, ReturnType);
1152                                 }
1153                         }
1154
1155                         if ((ModFlags & Modifiers.STATIC) == 0)
1156                                 return true;
1157
1158                         if (parameters.HasExtensionMethodType) {
1159                                 if (Parent.PartialContainer.IsStatic && !Parent.IsGeneric) {
1160                                         if (!Parent.IsTopLevel)
1161                                                 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
1162                                                         GetSignatureForError ());
1163
1164                                         PredefinedAttribute pa = Module.PredefinedAttributes.Extension;
1165                                         if (!pa.IsDefined) {
1166                                                 Report.Error (1110, Location,
1167                                                         "`{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",
1168                                                         GetSignatureForError ());
1169                                         }
1170
1171                                         ModFlags |= Modifiers.METHOD_EXTENSION;
1172                                         Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
1173                                         Spec.DeclaringType.SetExtensionMethodContainer ();
1174                                         Parent.Module.HasExtensionMethod = true;
1175                                 } else {
1176                                         Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
1177                                                 GetSignatureForError ());
1178                                 }
1179                         }
1180
1181                         //
1182                         // This is used to track the Entry Point,
1183                         //
1184                         var settings = Compiler.Settings;
1185                         if (settings.NeedsEntryPoint && Name == "Main" && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
1186                                 if (IsEntryPoint ()) {
1187                                         if (Parent.DeclaringAssembly.EntryPoint == null) {
1188                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
1189                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
1190                                                                 GetSignatureForError ());
1191                                                 } else {
1192                                                         SetIsUsed ();
1193                                                         Parent.DeclaringAssembly.EntryPoint = this;
1194                                                 }
1195                                         } else {
1196                                                 Error_DuplicateEntryPoint (Parent.DeclaringAssembly.EntryPoint);
1197                                                 Error_DuplicateEntryPoint (this);
1198                                         }
1199                                 } else {
1200                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
1201                                                 GetSignatureForError ());
1202                                 }
1203                         }
1204
1205                         return true;
1206                 }
1207
1208                 //
1209                 // Emits the code
1210                 // 
1211                 public override void Emit ()
1212                 {
1213                         try {
1214                                 if (IsPartialDefinition) {
1215                                         //
1216                                         // Use partial method implementation builder for partial method declaration attributes
1217                                         //
1218                                         if (partialMethodImplementation != null) {
1219                                                 MethodBuilder = partialMethodImplementation.MethodBuilder;
1220                                         }
1221
1222                                         return;
1223                                 }
1224                                 
1225                                 if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) {
1226                                         Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
1227                                                 GetSignatureForError ());
1228                                 }
1229
1230                                 if (CurrentTypeParameters != null) {
1231                                         for (int i = 0; i < CurrentTypeParameters.Length; ++i) {
1232                                                 var tp = CurrentTypeParameters [i];
1233                                                 tp.CheckGenericConstraints (false);
1234                                                 tp.Emit ();
1235                                         }
1236                                 }
1237
1238                                 base.Emit ();
1239                                 
1240                                 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
1241                                         Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
1242                         } catch {
1243                                 Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
1244                                                    Location, MethodBuilder);
1245                                 throw;
1246                         }
1247                 }
1248
1249                 public override bool EnableOverloadChecks (MemberCore overload)
1250                 {
1251                         // TODO: It can be deleted when members will be defined in correct order
1252                         if (overload is Operator)
1253                                 return overload.EnableOverloadChecks (this);
1254
1255                         if (overload is Indexer)
1256                                 return false;
1257
1258                         return base.EnableOverloadChecks (overload);
1259                 }
1260
1261                 public static void Error1599 (Location loc, TypeSpec t, Report Report)
1262                 {
1263                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
1264                 }
1265
1266                 protected override bool ResolveMemberType ()
1267                 {
1268                         if (GenericMethod != null) {
1269                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
1270                                 if (!GenericMethod.Define (this))
1271                                         return false;
1272                         }
1273
1274                         return base.ResolveMemberType ();
1275                 }
1276
1277                 public void SetPartialDefinition (Method methodDefinition)
1278                 {
1279                         caching_flags |= Flags.PartialDefinitionExists;
1280                         methodDefinition.partialMethodImplementation = this;
1281
1282                         // Ensure we are always using method declaration parameters
1283                         for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
1284                                 parameters [i].Name = methodDefinition.parameters [i].Name;
1285                                 parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
1286                         }
1287
1288                         if (methodDefinition.attributes == null)
1289                                 return;
1290
1291                         if (attributes == null) {
1292                                 attributes = methodDefinition.attributes;
1293                         } else {
1294                                 attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
1295                         }
1296                 }
1297         }
1298
1299         public abstract class ConstructorInitializer : ExpressionStatement
1300         {
1301                 Arguments argument_list;
1302                 MethodSpec base_ctor;
1303
1304                 public ConstructorInitializer (Arguments argument_list, Location loc)
1305                 {
1306                         this.argument_list = argument_list;
1307                         this.loc = loc;
1308                 }
1309
1310                 public Arguments Arguments {
1311                         get {
1312                                 return argument_list;
1313                         }
1314                 }
1315
1316                 public override Expression CreateExpressionTree (ResolveContext ec)
1317                 {
1318                         throw new NotSupportedException ("ET");
1319                 }
1320
1321                 protected override Expression DoResolve (ResolveContext ec)
1322                 {
1323                         eclass = ExprClass.Value;
1324
1325                         // FIXME: Hack
1326                         var caller_builder = (Constructor) ec.MemberContext;
1327
1328                         //
1329                         // Spec mandates that constructor initializer will not have `this' access
1330                         //
1331                         using (ec.Set (ResolveContext.Options.BaseInitializer)) {
1332                                 if (argument_list != null) {
1333                                         bool dynamic;
1334                                         argument_list.Resolve (ec, out dynamic);
1335
1336                                         if (dynamic) {
1337                                                 ec.Report.Error (1975, loc,
1338                                                         "The constructor call cannot be dynamically dispatched within constructor initializer");
1339
1340                                                 return null;
1341                                         }
1342                                 }
1343
1344                                 type = ec.CurrentType;
1345                                 if (this is ConstructorBaseInitializer) {
1346                                         if (ec.CurrentType.BaseType == null)
1347                                                 return this;
1348
1349                                         type = ec.CurrentType.BaseType;
1350                                         if (ec.CurrentType.IsStruct) {
1351                                                 ec.Report.Error (522, loc,
1352                                                         "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
1353                                                 return this;
1354                                         }
1355                                 } else {
1356                                         //
1357                                         // It is legal to have "this" initializers that take no arguments
1358                                         // in structs, they are just no-ops.
1359                                         //
1360                                         // struct D { public D (int a) : this () {}
1361                                         //
1362                                         if (ec.CurrentType.IsStruct && argument_list == null)
1363                                                 return this;
1364                                 }
1365
1366                                 base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
1367                         }
1368         
1369                         // TODO MemberCache: Does it work for inflated types ?
1370                         if (base_ctor == caller_builder.Spec){
1371                                 ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
1372                                         caller_builder.GetSignatureForError ());
1373                         }
1374                                                 
1375                         return this;
1376                 }
1377
1378                 public override void Emit (EmitContext ec)
1379                 {
1380                         // It can be null for static initializers
1381                         if (base_ctor == null)
1382                                 return;
1383                         
1384                         ec.Mark (loc);
1385
1386                         Invocation.EmitCall (ec, new CompilerGeneratedThis (type, loc), base_ctor, argument_list, loc);
1387                 }
1388
1389                 public override void EmitStatement (EmitContext ec)
1390                 {
1391                         Emit (ec);
1392                 }
1393         }
1394
1395         public class ConstructorBaseInitializer : ConstructorInitializer {
1396                 public ConstructorBaseInitializer (Arguments argument_list, Location l) :
1397                         base (argument_list, l)
1398                 {
1399                 }
1400         }
1401
1402         class GeneratedBaseInitializer: ConstructorBaseInitializer {
1403                 public GeneratedBaseInitializer (Location loc):
1404                         base (null, loc)
1405                 {
1406                 }
1407         }
1408
1409         public class ConstructorThisInitializer : ConstructorInitializer {
1410                 public ConstructorThisInitializer (Arguments argument_list, Location l) :
1411                         base (argument_list, l)
1412                 {
1413                 }
1414         }
1415         
1416         public class Constructor : MethodCore, IMethodData {
1417                 public ConstructorBuilder ConstructorBuilder;
1418                 public ConstructorInitializer Initializer;
1419                 SecurityType declarative_security;
1420                 bool has_compliant_args;
1421
1422                 // <summary>
1423                 //   Modifiers allowed for a constructor.
1424                 // </summary>
1425                 public const Modifiers AllowedModifiers =
1426                         Modifiers.PUBLIC |
1427                         Modifiers.PROTECTED |
1428                         Modifiers.INTERNAL |
1429                         Modifiers.STATIC |
1430                         Modifiers.UNSAFE |
1431                         Modifiers.EXTERN |              
1432                         Modifiers.PRIVATE;
1433
1434                 static readonly string[] attribute_targets = new string [] { "method" };
1435
1436                 public static readonly string ConstructorName = ".ctor";
1437                 public static readonly string TypeConstructorName = ".cctor";
1438
1439                 //
1440                 // The spec claims that static is not permitted, but
1441                 // my very own code has static constructors.
1442                 //
1443                 public Constructor (DeclSpace parent, string name, Modifiers mod, Attributes attrs, ParametersCompiled args,
1444                                     ConstructorInitializer init, Location loc)
1445                         : base (parent, null, null, mod, AllowedModifiers,
1446                                 new MemberName (name, loc), attrs, args)
1447                 {
1448                         Initializer = init;
1449                 }
1450
1451                 public bool HasCompliantArgs {
1452                         get { return has_compliant_args; }
1453                 }
1454
1455                 public override AttributeTargets AttributeTargets {
1456                         get {
1457                                 return AttributeTargets.Constructor;
1458                         }
1459                 }
1460
1461                 bool IMethodData.IsAccessor {
1462                         get {
1463                                 return false;
1464                         }
1465                 }
1466
1467                 //
1468                 // Returns true if this is a default constructor
1469                 //
1470                 public bool IsDefault ()
1471                 {
1472                         if ((ModFlags & Modifiers.STATIC) != 0)
1473                                 return parameters.IsEmpty;
1474
1475                         return parameters.IsEmpty &&
1476                                         (Initializer is ConstructorBaseInitializer) &&
1477                                         (Initializer.Arguments == null);
1478                 }
1479
1480                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
1481                 {
1482                         if (a.IsValidSecurityAttribute ()) {
1483                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
1484                                 return;
1485                         }
1486
1487                         if (a.Type == pa.MethodImpl) {
1488                                 is_external_implementation = a.IsInternalCall ();
1489                         }
1490
1491                         ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
1492                 }
1493
1494                 protected override bool CheckBase ()
1495                 {
1496                         if ((ModFlags & Modifiers.STATIC) != 0) {
1497                                 if (!parameters.IsEmpty) {
1498                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
1499                                                 GetSignatureForError ());
1500                                         return false;
1501                                 }
1502
1503                                 // the rest can be ignored
1504                                 return true;
1505                         }
1506
1507                         // Check whether arguments were correct.
1508                         if (!DefineParameters (parameters))
1509                                 return false;
1510
1511                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
1512                                 Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
1513
1514                         if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
1515                                 Report.Error (568, Location, 
1516                                         "Structs cannot contain explicit parameterless constructors");
1517                                 return false;
1518                         }
1519
1520                         CheckProtectedModifier ();
1521                         
1522                         return true;
1523                 }
1524                 
1525                 //
1526                 // Creates the ConstructorBuilder
1527                 //
1528                 public override bool Define ()
1529                 {
1530                         if (ConstructorBuilder != null)
1531                                 return true;
1532
1533                         var ca = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
1534                         
1535                         if ((ModFlags & Modifiers.STATIC) != 0) {
1536                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
1537                         } else {
1538                                 ca |= ModifiersExtensions.MethodAttr (ModFlags);
1539                         }
1540
1541                         if (!CheckAbstractAndExtern (block != null))
1542                                 return false;
1543                         
1544                         // Check if arguments were correct.
1545                         if (!CheckBase ())
1546                                 return false;
1547
1548                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
1549                                 ca, CallingConventions,
1550                                 parameters.GetMetaInfo ());
1551
1552                         spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
1553                         
1554                         Parent.MemberCache.AddMember (spec);
1555                         
1556                         // It's here only to report an error
1557                         if (block != null && block.IsIterator) {
1558                                 member_type = Compiler.BuiltinTypes.Void;
1559                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
1560                         }
1561
1562                         return true;
1563                 }
1564
1565                 //
1566                 // Emits the code
1567                 //
1568                 public override void Emit ()
1569                 {
1570                         if (Parent.PartialContainer.IsComImport) {
1571                                 if (!IsDefault ()) {
1572                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
1573                                                 Parent.GetSignatureForError ());
1574                                 }
1575
1576                                 // Set as internal implementation and reset block data
1577                                 // to ensure no IL is generated
1578                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
1579                                 block = null;
1580                         }
1581
1582                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
1583                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder);
1584
1585                         if (OptAttributes != null)
1586                                 OptAttributes.Emit ();
1587
1588                         base.Emit ();
1589                         parameters.ApplyAttributes (this, ConstructorBuilder);
1590
1591                         //
1592                         // If we use a "this (...)" constructor initializer, then
1593                         // do not emit field initializers, they are initialized in the other constructor
1594                         //
1595                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
1596                                 !(Initializer is ConstructorThisInitializer);
1597
1598                         BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
1599                         bc.Set (ResolveContext.Options.ConstructorScope);
1600
1601                         if (emit_field_initializers)
1602                                 Parent.PartialContainer.ResolveFieldInitializers (bc);
1603
1604                         if (block != null) {
1605                                 // If this is a non-static `struct' constructor and doesn't have any
1606                                 // initializer, it must initialize all of the struct's fields.
1607                                 if ((Parent.PartialContainer.Kind == MemberKind.Struct) &&
1608                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
1609                                         block.AddThisVariable (bc, Parent, Location);
1610
1611                                 if (block != null && (ModFlags & Modifiers.STATIC) == 0){
1612                                         if (Parent.PartialContainer.Kind == MemberKind.Class && Initializer == null)
1613                                                 Initializer = new GeneratedBaseInitializer (Location);
1614
1615                                         if (Initializer != null) {
1616                                                 block.AddScopeStatement (new StatementExpression (Initializer));
1617                                         }
1618                                 }
1619                         }
1620
1621                         SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
1622
1623                         if (block != null) {
1624                                 if (block.Resolve (null, bc, this)) {
1625                                         EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType);
1626                                         ec.With (EmitContext.Options.ConstructorScope, true);
1627
1628                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
1629                                                 ec.ReturnLabel = bc.ReturnLabel;
1630                                                 ec.HasReturnLabel = true;
1631                                         }
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 (DeclSpace parent, string method_full_name, Report Report)
1813                 {
1814                         TypeContainer container = parent.PartialContainer;
1815
1816                         PendingImplementation pending = container.PendingImplementations;
1817                         MethodSpec ambig_iface_method;
1818                         if (pending != null) {
1819                                 implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method);
1820
1821                                 if (member.InterfaceType != null) {
1822                                         if (implementing == null) {
1823                                                 if (member is PropertyBase) {
1824                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
1825                                                                           method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
1826                                                                           member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
1827
1828                                                 } else {
1829                                                         Report.Error (539, method.Location,
1830                                                                           "`{0}.{1}' in explicit interface declaration is not a member of interface",
1831                                                                           TypeManager.CSharpName (member.InterfaceType), member.ShortName);
1832                                                 }
1833                                                 return false;
1834                                         }
1835                                         if (implementing.IsAccessor && !method.IsAccessor) {
1836                                                 Report.SymbolRelatedToPreviousError (implementing);
1837                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
1838                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1839                                                 return false;
1840                                         }
1841                                 } else {
1842                                         if (implementing != null) {
1843                                                 if (!method.IsAccessor) {
1844                                                         if (implementing.IsAccessor) {
1845                                                                 Report.SymbolRelatedToPreviousError (implementing);
1846                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'",
1847                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
1848                                                         }
1849                                                 } else if (implementing.DeclaringType.IsInterface) {
1850                                                         if (!implementing.IsAccessor) {
1851                                                                 Report.SymbolRelatedToPreviousError (implementing);
1852                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
1853                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
1854                                                         } else {
1855                                                                 PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
1856                                                                 if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
1857                                                                         Report.SymbolRelatedToPreviousError (implementing);
1858                                                                         Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
1859                                                                                 method.GetSignatureForError (), implementing.GetSignatureForError ());
1860                                                                 }
1861                                                         }
1862                                                 }
1863                                         }
1864                                 }
1865                         } else {
1866                                 ambig_iface_method = null;
1867                         }
1868
1869                         //
1870                         // For implicit implementations, make sure we are public, for
1871                         // explicit implementations, make sure we are private.
1872                         //
1873                         if (implementing != null){
1874                                 //
1875                                 // Setting null inside this block will trigger a more
1876                                 // verbose error reporting for missing interface implementations
1877                                 //
1878                                 // The "candidate" function has been flagged already
1879                                 // but it wont get cleared
1880                                 //
1881                                 if (member.IsExplicitImpl){
1882                                         if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
1883                                                 Report.SymbolRelatedToPreviousError (implementing);
1884                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
1885                                                         method.GetSignatureForError ());
1886                                         }
1887
1888                                         if (ambig_iface_method != null) {
1889                                                 Report.SymbolRelatedToPreviousError (ambig_iface_method);
1890                                                 Report.SymbolRelatedToPreviousError (implementing);
1891                                                 Report.Warning (473, 2, method.Location,
1892                                                         "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
1893                                                         method.GetSignatureForError ());
1894                                         }
1895
1896                                 } else {
1897                                         if (implementing.DeclaringType.IsInterface) {
1898                                                 //
1899                                                 // If this is an interface method implementation,
1900                                                 // check for public accessibility
1901                                                 //
1902                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
1903                                                 {
1904                                                         implementing = null;
1905                                                 }
1906                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
1907                                                 // We may never be private.
1908                                                 implementing = null;
1909
1910                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
1911                                                 //
1912                                                 // We may be protected if we're overriding something.
1913                                                 //
1914                                                 implementing = null;
1915                                         }
1916                                 }
1917                                         
1918                                 //
1919                                 // Static is not allowed
1920                                 //
1921                                 if ((modifiers & Modifiers.STATIC) != 0){
1922                                         implementing = null;
1923                                 }
1924                         }
1925                         
1926                         //
1927                         // If implementing is still valid, set flags
1928                         //
1929                         if (implementing != null){
1930                                 //
1931                                 // When implementing interface methods, set NewSlot
1932                                 // unless, we are overwriting a method.
1933                                 //
1934                                 if (implementing.DeclaringType.IsInterface){
1935                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
1936                                                 flags |= MethodAttributes.NewSlot;
1937                                 }
1938
1939                                 flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig;
1940
1941                                 // Set Final unless we're virtual, abstract or already overriding a method.
1942                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
1943                                         flags |= MethodAttributes.Final;
1944
1945                                 //
1946                                 // clear the pending implementation flag (requires explicit methods to be defined first)
1947                                 //
1948                                 parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName,
1949                                         member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method);
1950
1951                                 //
1952                                 // Update indexer accessor name to match implementing abstract accessor
1953                                 //
1954                                 if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor)
1955                                         method_full_name = implementing.MemberDefinition.Name;
1956                         }
1957
1958                         DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
1959
1960                         if (builder == null)
1961                                 return false;
1962
1963 //                      if (container.CurrentType != null)
1964 //                              declaring_type = container.CurrentType;
1965 //                      else
1966                                 declaring_type = container.Definition;
1967
1968                         if (implementing != null && member.IsExplicitImpl) {
1969                                 container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
1970                         }
1971
1972                         return true;
1973                 }
1974
1975
1976                 /// <summary>
1977                 /// Create the MethodBuilder for the method 
1978                 /// </summary>
1979                 void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param)
1980                 {
1981                         var return_type = method.ReturnType.GetMetaInfo ();
1982                         var p_types = param.GetMetaInfo ();
1983
1984                         if (builder == null) {
1985                                 builder = container.TypeBuilder.DefineMethod (
1986                                         method_name, flags, method.CallingConventions,
1987                                         return_type, p_types);
1988                                 return;
1989                         }
1990
1991                         //
1992                         // Generic method has been already defined to resolve method parameters
1993                         // correctly when they use type parameters
1994                         //
1995                         builder.SetParameters (p_types);
1996                         builder.SetReturnType (return_type);
1997                         if (builder.Attributes != flags) {
1998 #if STATIC
1999                                 builder.__SetAttributes (flags);
2000 #else
2001                                 try {
2002                                         if (methodbuilder_attrs_field == null)
2003                                                 methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
2004                                         methodbuilder_attrs_field.SetValue (builder, flags);
2005                                 } catch {
2006                                         container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
2007                                 }
2008 #endif
2009                         }
2010                 }
2011
2012                 //
2013                 // Emits the code
2014                 // 
2015                 public void Emit (DeclSpace parent)
2016                 {
2017                         if (GenericMethod != null)
2018                                 GenericMethod.EmitAttributes ();
2019
2020                         var mc = (IMemberContext) method;
2021
2022                         method.ParameterInfo.ApplyAttributes (mc, MethodBuilder);
2023
2024                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
2025
2026                         ToplevelBlock block = method.Block;
2027                         if (block != null) {
2028                                 BlockContext bc = new BlockContext (mc, block, method.ReturnType);
2029                                 if (block.Resolve (null, bc, method)) {
2030                                         EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator ());
2031                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
2032                                                 ec.ReturnLabel = bc.ReturnLabel;
2033                                                 ec.HasReturnLabel = true;
2034                                         }
2035
2036                                         block.Emit (ec);
2037                                 }
2038                         }
2039
2040                         if (source != null) {
2041                                 method.EmitExtraSymbolInfo (source);
2042                                 source.CloseMethod ();
2043                         }
2044                 }
2045         }
2046
2047         public class Destructor : MethodOrOperator
2048         {
2049                 const Modifiers AllowedModifiers =
2050                         Modifiers.UNSAFE |
2051                         Modifiers.EXTERN;
2052
2053                 static readonly string[] attribute_targets = new string [] { "method" };
2054
2055                 public static readonly string MetadataName = "Finalize";
2056
2057                 public Destructor (DeclSpace parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
2058                         : base (parent, null, null, mod, AllowedModifiers,
2059                                 new MemberName (MetadataName, l), attrs, parameters)
2060                 {
2061                         ModFlags &= ~Modifiers.PRIVATE;
2062                         ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
2063                 }
2064
2065                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2066                 {
2067                         if (a.Type == pa.Conditional) {
2068                                 Error_ConditionalAttributeIsNotValid ();
2069                                 return;
2070                         }
2071
2072                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2073                 }
2074
2075                 protected override bool CheckBase ()
2076                 {
2077                         // Don't check base, destructors have special syntax
2078                         return true;
2079                 }
2080
2081                 public override void Emit()
2082                 {
2083                         var base_type = Parent.PartialContainer.BaseType;
2084                         if (base_type != null && Block != null) {
2085                                 var base_dtor = MemberCache.FindMember (base_type,
2086                                         new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
2087
2088                                 if (base_dtor == null)
2089                                         throw new NotImplementedException ();
2090
2091                                 MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
2092                                 method_expr.InstanceExpression = new BaseThis (base_type, Location);
2093
2094                                 var try_block = new ExplicitBlock (block, block.StartLocation, block.EndLocation);
2095                                 var finaly_block = new ExplicitBlock (block, Location, Location);
2096
2097                                 //
2098                                 // 0-size arguments to avoid CS0250 error
2099                                 // TODO: Should use AddScopeStatement or something else which emits correct
2100                                 // debugger scope
2101                                 //
2102                                 finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0))));
2103
2104                                 var tf = new TryFinally (try_block, finaly_block, Location);
2105                                 block.WrapIntoDestructor (tf, try_block);
2106                         }
2107
2108                         base.Emit ();
2109                 }
2110
2111                 public override string GetSignatureForError ()
2112                 {
2113                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
2114                 }
2115
2116                 protected override bool ResolveMemberType ()
2117                 {
2118                         member_type = Compiler.BuiltinTypes.Void;
2119                         return true;
2120                 }
2121
2122                 public override string[] ValidAttributeTargets {
2123                         get {
2124                                 return attribute_targets;
2125                         }
2126                 }
2127         }
2128
2129         // Ooouh Martin, templates are missing here.
2130         // When it will be possible move here a lot of child code and template method type.
2131         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
2132                 protected MethodData method_data;
2133                 protected ToplevelBlock block;
2134                 protected SecurityType declarative_security;
2135
2136                 protected readonly string prefix;
2137
2138                 ReturnParameter return_attributes;
2139
2140                 public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
2141                         : base (member.Parent, SetupName (prefix, member, loc), attrs)
2142                 {
2143                         this.prefix = prefix;
2144                 }
2145
2146                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
2147                 {
2148                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
2149                 }
2150
2151                 public void UpdateName (InterfaceMemberBase member)
2152                 {
2153                         SetMemberName (SetupName (prefix, member, Location));
2154                 }
2155
2156                 #region IMethodData Members
2157
2158                 public ToplevelBlock Block {
2159                         get {
2160                                 return block;
2161                         }
2162
2163                         set {
2164                                 block = value;
2165                         }
2166                 }
2167
2168                 public CallingConventions CallingConventions {
2169                         get {
2170                                 return CallingConventions.Standard;
2171                         }
2172                 }
2173
2174                 public EmitContext CreateEmitContext (ILGenerator ig)
2175                 {
2176                         return new EmitContext (this, ig, ReturnType);
2177                 }
2178
2179                 public bool IsAccessor {
2180                         get {
2181                                 return true;
2182                         }
2183                 }
2184
2185                 public bool IsExcluded ()
2186                 {
2187                         return false;
2188                 }
2189
2190                 GenericMethod IMethodData.GenericMethod {
2191                         get {
2192                                 return null;
2193                         }
2194                 }
2195
2196                 public MemberName MethodName {
2197                         get {
2198                                 return MemberName;
2199                         }
2200                 }
2201
2202                 public TypeSpec[] ParameterTypes { 
2203                         get {
2204                                 return ParameterInfo.Types;
2205                         }
2206                 }
2207
2208                 public abstract ParametersCompiled ParameterInfo { get ; }
2209                 public abstract TypeSpec ReturnType { get; }
2210
2211                 #endregion
2212
2213                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2214                 {
2215                         if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
2216                                 Report.Error (1667, a.Location,
2217                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
2218                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
2219                                 return;
2220                         }
2221
2222                         if (a.IsValidSecurityAttribute ()) {
2223                                 a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
2224                                 return;
2225                         }
2226
2227                         if (a.Target == AttributeTargets.Method) {
2228                                 method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
2229                                 return;
2230                         }
2231
2232                         if (a.Target == AttributeTargets.ReturnValue) {
2233                                 if (return_attributes == null)
2234                                         return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2235
2236                                 return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
2237                                 return;
2238                         }
2239
2240                         ApplyToExtraTarget (a, ctor, cdata, pa);
2241                 }
2242
2243                 protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2244                 {
2245                         throw new NotSupportedException ("You forgot to define special attribute target handling");
2246                 }
2247
2248                 // It is not supported for the accessors
2249                 public sealed override bool Define()
2250                 {
2251                         throw new NotSupportedException ();
2252                 }
2253
2254                 public virtual void Emit (DeclSpace parent)
2255                 {
2256                         method_data.Emit (parent);
2257
2258                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
2259                                 Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
2260                         if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
2261                                 Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
2262
2263                         if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2264                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2265                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
2266                         } else if (ReturnType.HasDynamicElement) {
2267                                 return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
2268                                 Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
2269                         }
2270
2271                         if (OptAttributes != null)
2272                                 OptAttributes.Emit ();
2273
2274                         if (declarative_security != null) {
2275                                 foreach (var de in declarative_security) {
2276 #if STATIC
2277                                         method_data.MethodBuilder.__AddDeclarativeSecurity (de);
2278 #else
2279                                         method_data.MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
2280 #endif
2281                                 }
2282                         }
2283
2284                         block = null;
2285                 }
2286
2287                 public override bool EnableOverloadChecks (MemberCore overload)
2288                 {
2289                         if (overload is MethodCore) {
2290                                 caching_flags |= Flags.MethodOverloadsExist;
2291                                 return true;
2292                         }
2293
2294                         // This can only happen with indexers and it will
2295                         // be catched as indexer difference
2296                         if (overload is AbstractPropertyEventMethod)
2297                                 return true;
2298
2299                         return false;
2300                 }
2301
2302                 public override string GetSignatureForDocumentation ()
2303                 {
2304                         // should not be called
2305                         throw new NotSupportedException ();
2306                 }
2307
2308                 public override bool IsClsComplianceRequired()
2309                 {
2310                         return false;
2311                 }
2312
2313                 public MethodSpec Spec { get; protected set; }
2314
2315                 //
2316                 //   Represents header string for documentation comment.
2317                 //
2318                 public override string DocCommentHeader {
2319                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
2320                 }
2321
2322                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
2323                 { }
2324         }
2325
2326         public class Operator : MethodOrOperator {
2327
2328                 const Modifiers AllowedModifiers =
2329                         Modifiers.PUBLIC |
2330                         Modifiers.UNSAFE |
2331                         Modifiers.EXTERN |
2332                         Modifiers.STATIC;
2333
2334                 public enum OpType : byte {
2335
2336                         // Unary operators
2337                         LogicalNot,
2338                         OnesComplement,
2339                         Increment,
2340                         Decrement,
2341                         True,
2342                         False,
2343
2344                         // Unary and Binary operators
2345                         Addition,
2346                         Subtraction,
2347
2348                         UnaryPlus,
2349                         UnaryNegation,
2350                         
2351                         // Binary operators
2352                         Multiply,
2353                         Division,
2354                         Modulus,
2355                         BitwiseAnd,
2356                         BitwiseOr,
2357                         ExclusiveOr,
2358                         LeftShift,
2359                         RightShift,
2360                         Equality,
2361                         Inequality,
2362                         GreaterThan,
2363                         LessThan,
2364                         GreaterThanOrEqual,
2365                         LessThanOrEqual,
2366
2367                         // Implicit and Explicit
2368                         Implicit,
2369                         Explicit,
2370
2371                         // Just because of enum
2372                         TOP
2373                 };
2374
2375                 public readonly OpType OperatorType;
2376
2377                 static readonly string [] [] names;
2378
2379                 static Operator ()
2380                 {
2381                         names = new string[(int)OpType.TOP][];
2382                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
2383                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
2384                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
2385                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
2386                         names [(int) OpType.True] = new string [] { "true", "op_True" };
2387                         names [(int) OpType.False] = new string [] { "false", "op_False" };
2388                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
2389                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
2390                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
2391                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
2392                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
2393                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
2394                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
2395                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
2396                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
2397                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
2398                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
2399                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
2400                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
2401                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
2402                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
2403                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
2404                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
2405                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
2406                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
2407                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
2408                 }
2409                 
2410                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
2411                                  Modifiers mod_flags, ParametersCompiled parameters,
2412                                  ToplevelBlock block, Attributes attrs, Location loc)
2413                         : base (parent, null, ret_type, mod_flags, AllowedModifiers,
2414                                 new MemberName (GetMetadataName (type), loc), attrs, parameters)
2415                 {
2416                         OperatorType = type;
2417                         Block = block;
2418                 }
2419
2420                 public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
2421                 {
2422                         if (a.Type == pa.Conditional) {
2423                                 Error_ConditionalAttributeIsNotValid ();
2424                                 return;
2425                         }
2426
2427                         base.ApplyAttributeBuilder (a, ctor, cdata, pa);
2428                 }
2429                 
2430                 public override bool Define ()
2431                 {
2432                         const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
2433                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
2434                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
2435                         }
2436
2437                         if (!base.Define ())
2438                                 return false;
2439
2440                         if (block != null && block.IsIterator) {
2441                                 //
2442                                 // Current method is turned into automatically generated
2443                                 // wrapper which creates an instance of iterator
2444                                 //
2445                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
2446                                 ModFlags |= Modifiers.DEBUGGER_HIDDEN;
2447                         }
2448
2449                         // imlicit and explicit operator of same types are not allowed
2450                         if (OperatorType == OpType.Explicit)
2451                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
2452                         else if (OperatorType == OpType.Implicit)
2453                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
2454
2455                         TypeSpec declaring_type = Parent.CurrentType;
2456                         TypeSpec return_type = MemberType;
2457                         TypeSpec first_arg_type = ParameterTypes [0];
2458                         
2459                         TypeSpec first_arg_type_unwrap = first_arg_type;
2460                         if (first_arg_type.IsNullableType)
2461                                 first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
2462                         
2463                         TypeSpec return_type_unwrap = return_type;
2464                         if (return_type.IsNullableType)
2465                                 return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);
2466
2467                         //
2468                         // Rules for conversion operators
2469                         //
2470                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2471                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
2472                                         Report.Error (555, Location,
2473                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
2474                                         return false;
2475                                 }
2476
2477                                 TypeSpec conv_type;
2478                                 if (declaring_type == return_type || declaring_type == return_type_unwrap) {
2479                                         conv_type = first_arg_type;
2480                                 } else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
2481                                         conv_type = return_type;
2482                                 } else {
2483                                         Report.Error (556, Location,
2484                                                 "User-defined conversion must convert to or from the enclosing type");
2485                                         return false;
2486                                 }
2487
2488                                 if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
2489                                         Report.Error (1964, Location,
2490                                                 "User-defined conversion `{0}' cannot convert to or from the dynamic type",
2491                                                 GetSignatureForError ());
2492
2493                                         return false;
2494                                 }
2495
2496                                 if (conv_type.IsInterface) {
2497                                         Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
2498                                                 GetSignatureForError ());
2499                                         return false;
2500                                 }
2501
2502                                 if (conv_type.IsClass) {
2503                                         if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
2504                                                 Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
2505                                                         GetSignatureForError ());
2506                                                 return false;
2507                                         }
2508
2509                                         if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
2510                                                 Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
2511                                                         GetSignatureForError ());
2512                                                 return false;
2513                                         }
2514                                 }
2515                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
2516                                 if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
2517                                         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");
2518                                         return false;
2519                                 }
2520                         } else if (parameters.Count == 1) {
2521                                 // Checks for Unary operators
2522
2523                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
2524                                         if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
2525                                                 Report.Error (448, Location,
2526                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
2527                                                 return false;
2528                                         }
2529                                         if (first_arg_type != declaring_type) {
2530                                                 Report.Error (
2531                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
2532                                                 return false;
2533                                         }
2534                                 }
2535
2536                                 if (first_arg_type_unwrap != declaring_type) {
2537                                         Report.Error (562, Location,
2538                                                 "The parameter type of a unary operator must be the containing type");
2539                                         return false;
2540                                 }
2541
2542                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
2543                                         if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
2544                                                 Report.Error (
2545                                                         215, Location,
2546                                                         "The return type of operator True or False " +
2547                                                         "must be bool");
2548                                                 return false;
2549                                         }
2550                                 }
2551
2552                         } else if (first_arg_type_unwrap != declaring_type) {
2553                                 // Checks for Binary operators
2554
2555                                 var second_arg_type = ParameterTypes[1];
2556                                 if (second_arg_type.IsNullableType)
2557                                         second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);
2558
2559                                 if (second_arg_type != declaring_type) {
2560                                         Report.Error (563, Location,
2561                                                 "One of the parameters of a binary operator must be the containing type");
2562                                         return false;
2563                                 }
2564                         }
2565
2566                         return true;
2567                 }
2568
2569                 protected override bool ResolveMemberType ()
2570                 {
2571                         if (!base.ResolveMemberType ())
2572                                 return false;
2573
2574                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
2575                         return true;
2576                 }
2577
2578                 protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
2579                 {
2580                         // Operator cannot be override
2581                         bestCandidate = null;
2582                         return null;
2583                 }
2584
2585                 public static string GetName (OpType ot)
2586                 {
2587                         return names [(int) ot] [0];
2588                 }
2589
2590                 public static string GetName (string metadata_name)
2591                 {
2592                         for (int i = 0; i < names.Length; ++i) {
2593                                 if (names [i] [1] == metadata_name)
2594                                         return names [i] [0];
2595                         }
2596                         return null;
2597                 }
2598
2599                 public static string GetMetadataName (OpType ot)
2600                 {
2601                         return names [(int) ot] [1];
2602                 }
2603
2604                 public static string GetMetadataName (string name)
2605                 {
2606                         for (int i = 0; i < names.Length; ++i) {
2607                                 if (names [i] [0] == name)
2608                                         return names [i] [1];
2609                         }
2610                         return null;
2611                 }
2612
2613                 public static OpType? GetType (string metadata_name)
2614                 {
2615                         for (int i = 0; i < names.Length; ++i) {
2616                                 if (names[i][1] == metadata_name)
2617                                         return (OpType) i;
2618                         }
2619
2620                         return null;
2621                 }
2622
2623                 public OpType GetMatchingOperator ()
2624                 {
2625                         switch (OperatorType) {
2626                         case OpType.Equality:
2627                                 return OpType.Inequality;
2628                         case OpType.Inequality:
2629                                 return OpType.Equality;
2630                         case OpType.True:
2631                                 return OpType.False;
2632                         case OpType.False:
2633                                 return OpType.True;
2634                         case OpType.GreaterThan:
2635                                 return OpType.LessThan;
2636                         case OpType.LessThan:
2637                                 return OpType.GreaterThan;
2638                         case OpType.GreaterThanOrEqual:
2639                                 return OpType.LessThanOrEqual;
2640                         case OpType.LessThanOrEqual:
2641                                 return OpType.GreaterThanOrEqual;
2642                         default:
2643                                 return OpType.TOP;
2644                         }
2645                 }
2646
2647                 public override string GetSignatureForDocumentation ()
2648                 {
2649                         string s = base.GetSignatureForDocumentation ();
2650                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2651                                 s = s + "~" + ReturnType.GetSignatureForDocumentation ();
2652                         }
2653
2654                         return s;
2655                 }
2656
2657                 public override string GetSignatureForError ()
2658                 {
2659                         StringBuilder sb = new StringBuilder ();
2660                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
2661                                 sb.AppendFormat ("{0}.{1} operator {2}",
2662                                         Parent.GetSignatureForError (), GetName (OperatorType),
2663                                         member_type == null ? type_expr.GetSignatureForError () : member_type.GetSignatureForError ());
2664                         }
2665                         else {
2666                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
2667                         }
2668
2669                         sb.Append (parameters.GetSignatureForError ());
2670                         return sb.ToString ();
2671                 }
2672         }
2673 }
2674