eaa359d928b89b006b21721e21f2511da2591861
[mono.git] / mcs / mcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
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;
16 using System.Collections.Specialized;
17 using System.Reflection;
18 using System.Reflection.Emit;
19 using System.Runtime.CompilerServices;
20 using System.Runtime.InteropServices;
21 using System.Security;
22 using System.Security.Permissions;
23 using System.Text;
24
25 #if NET_2_1
26 using XmlElement = System.Object;
27 #else
28 using System.Xml;
29 #endif
30
31 using Mono.CompilerServices.SymbolWriter;
32
33 namespace Mono.CSharp {
34
35         public enum Kind {
36                 Root,
37                 Struct,
38                 Class,
39                 Interface,
40                 Enum,
41                 Delegate
42         }
43
44         /// <summary>
45         ///   This is the base class for structs and classes.  
46         /// </summary>
47         public abstract class TypeContainer : DeclSpace, IMemberContainer {
48
49                 public class MemberCoreArrayList: ArrayList
50                 {
51                         /// <summary>
52                         ///   Defines the MemberCore objects that are in this array
53                         /// </summary>
54                         public virtual void DefineContainerMembers ()
55                         {
56                                 foreach (MemberCore mc in this) {
57                                         try {
58                                                 mc.Define ();
59                                         } catch (Exception e) {
60                                                 throw new InternalErrorException (mc, e);
61                                         }
62                                 }
63                         }
64
65                         public virtual void Emit ()
66                         {
67                                 foreach (MemberCore mc in this)
68                                         mc.Emit ();
69                         }
70                 }
71
72                 public class OperatorArrayList: MemberCoreArrayList
73                 {
74                         TypeContainer container;
75
76                         public OperatorArrayList (TypeContainer container)
77                         {
78                                 this.container = container;
79                         }
80
81                         //
82                         // Checks that some operators come in pairs:
83                         //  == and !=
84                         // > and <
85                         // >= and <=
86                         // true and false
87                         //
88                         // They are matched based on the return type and the argument types
89                         //
90                         void CheckPairedOperators ()
91                         {
92                                 bool has_equality_or_inequality = false;
93                                 Operator[] operators = (Operator[]) ToArray (typeof (Operator));
94                                 bool [] has_pair = new bool [operators.Length];
95
96                                 for (int i = 0; i < Count; ++i) {
97                                         if (operators [i] == null)
98                                                 continue;
99
100                                         Operator o_a = operators [i];
101                                         Operator.OpType o_type = o_a.OperatorType;
102                                         if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
103                                                 has_equality_or_inequality = true;
104
105                                         Operator.OpType matching_type = o_a.GetMatchingOperator ();
106                                         if (matching_type == Operator.OpType.TOP) {
107                                                 operators [i] = null;
108                                                 continue;
109                                         }
110         
111                                         for (int ii = 0; ii < Count; ++ii) {
112                                                 Operator o_b = operators [ii];
113                                                 if (o_b == null || o_b.OperatorType != matching_type)
114                                                         continue;
115
116                                                 if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
117                                                         continue;
118
119                                                 if (!TypeManager.IsEqual (o_a.ParameterTypes, o_b.ParameterTypes))
120                                                         continue;
121
122                                                 operators [i] = null;
123
124                                                 //
125                                                 // Used to ignore duplicate user conversions
126                                                 //
127                                                 has_pair [ii] = true;
128                                         }
129                                 }
130
131                                 for (int i = 0; i < Count; ++i) {
132                                         if (operators [i] == null || has_pair [i])
133                                                 continue;
134
135                                         Operator o = operators [i];
136                                         container.Report.Error (216, o.Location,
137                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
138                                                 o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ()));
139                                 }
140
141                                 if (has_equality_or_inequality && container.Report.WarningLevel > 2) {
142                                         if (container.Methods == null || !container.HasEquals)
143                                                 container.Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
144  
145                                         if (container.Methods == null || !container.HasGetHashCode)
146                                                 container.Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
147                                 }
148                         }
149
150                         public override void DefineContainerMembers ()
151                         {
152                                 base.DefineContainerMembers ();
153                                 CheckPairedOperators ();
154                         }
155                 }
156
157                 //
158                 // Different context is needed when resolving type container base
159                 // types. Type names come from the parent scope but type parameter
160                 // names from the container scope.
161                 //
162                 struct BaseContext : IMemberContext
163                 {
164                         TypeContainer tc;
165
166                         public BaseContext (TypeContainer tc)
167                         {
168                                 this.tc = tc;
169                         }
170
171                         #region IMemberContext Members
172
173                         public CompilerContext Compiler {
174                                 get { return tc.Compiler; }
175                         }
176
177                         public Type CurrentType {
178                                 get { return tc.Parent.CurrentType; }
179                         }
180
181                         public TypeParameter[] CurrentTypeParameters {
182                                 get { return tc.PartialContainer.CurrentTypeParameters; }
183                         }
184
185                         public TypeContainer CurrentTypeDefinition {
186                                 get { return tc.Parent.CurrentTypeDefinition; }
187                         }
188
189                         public bool IsObsolete {
190                                 get { return tc.IsObsolete; }
191                         }
192
193                         public bool IsUnsafe {
194                                 get { return tc.IsUnsafe; }
195                         }
196
197                         public bool IsStatic {
198                                 get { return tc.IsStatic; }
199                         }
200
201                         public string GetSignatureForError ()
202                         {
203                                 throw new NotImplementedException ();
204                         }
205
206                         public ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
207                         {
208                                 return null;
209                         }
210
211                         public FullNamedExpression LookupNamespaceAlias (string name)
212                         {
213                                 return tc.Parent.LookupNamespaceAlias (name);
214                         }
215
216                         public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
217                         {
218                                 TypeParameter[] tp = CurrentTypeParameters;
219                                 if (tp != null) {
220                                         TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
221                                         if (t != null)
222                                                 return new TypeParameterExpr (t, loc);
223                                 }
224
225                                 return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104);
226                         }
227
228                         #endregion
229                 }
230
231                 [Flags]
232                 enum CachedMethods
233                 {
234                         Equals                          = 1,
235                         GetHashCode                     = 1 << 1,
236                         HasStaticFieldInitializer       = 1 << 2
237                 }
238
239
240                 // Whether this is a struct, class or interface
241                 public readonly Kind Kind;
242
243                 // Holds a list of classes and structures
244                 protected ArrayList types;
245
246                 MemberCoreArrayList ordered_explicit_member_list;
247                 MemberCoreArrayList ordered_member_list;
248
249                 // Holds the list of properties
250                 MemberCoreArrayList properties;
251
252                 // Holds the list of delegates
253                 MemberCoreArrayList delegates;
254                 
255                 // Holds the list of constructors
256                 protected MemberCoreArrayList instance_constructors;
257
258                 // Holds the list of fields
259                 protected MemberCoreArrayList fields;
260
261                 // Holds a list of fields that have initializers
262                 protected ArrayList initialized_fields;
263
264                 // Holds a list of static fields that have initializers
265                 protected ArrayList initialized_static_fields;
266
267                 // Holds the list of constants
268                 protected MemberCoreArrayList constants;
269
270                 // Holds the methods.
271                 MemberCoreArrayList methods;
272
273                 // Holds the events
274                 protected MemberCoreArrayList events;
275
276                 // Holds the indexers
277                 ArrayList indexers;
278
279                 // Holds the operators
280                 MemberCoreArrayList operators;
281
282                 // Holds the compiler generated classes
283                 ArrayList compiler_generated;
284
285                 //
286                 // Pointers to the default constructor and the default static constructor
287                 //
288                 protected Constructor default_constructor;
289                 protected Constructor default_static_constructor;
290
291                 //
292                 // Points to the first non-static field added to the container.
293                 //
294                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
295                 // and the first one's as good as any.
296                 //
297                 FieldBase first_nonstatic_field = null;
298
299                 //
300                 // This one is computed after we can distinguish interfaces
301                 // from classes from the arraylist `type_bases' 
302                 //
303                 TypeExpr base_type;
304                 TypeExpr[] iface_exprs;
305                 Type GenericType;
306                 GenericTypeParameterBuilder[] nested_gen_params;
307
308                 protected ArrayList type_bases;
309
310                 protected bool members_defined;
311                 bool members_defined_ok;
312
313                 // The interfaces we implement.
314                 protected Type[] ifaces;
315
316                 // The base member cache and our member cache
317                 MemberCache base_cache;
318                 protected MemberCache member_cache;
319
320                 public const string DefaultIndexerName = "Item";
321
322                 private bool seen_normal_indexers = false;
323                 private string indexer_name = DefaultIndexerName;
324                 protected bool requires_delayed_unmanagedtype_check;
325
326                 private CachedMethods cached_method;
327
328                 ArrayList partial_parts;
329
330                 /// <remarks>
331                 ///  The pending methods that need to be implemented
332                 //   (interfaces or abstract methods)
333                 /// </remarks>
334                 PendingImplementation pending;
335
336                 public TypeContainer (NamespaceEntry ns, DeclSpace parent, MemberName name,
337                                       Attributes attrs, Kind kind)
338                         : base (ns, parent, name, attrs)
339                 {
340                         if (parent != null && parent.NamespaceEntry != ns)
341                                 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
342
343                         this.Kind = kind;
344                         this.PartialContainer = this;
345                 }
346
347                 public bool AddMember (MemberCore symbol)
348                 {
349                         return AddToContainer (symbol, symbol.MemberName.Basename);
350                 }
351
352                 protected virtual bool AddMemberType (DeclSpace ds)
353                 {
354                         return AddToContainer (ds, ds.Basename);
355                 }
356
357                 protected virtual void RemoveMemberType (DeclSpace ds)
358                 {
359                         RemoveFromContainer (ds.Basename);
360                 }
361
362                 public void AddConstant (Const constant)
363                 {
364                         if (!AddMember (constant))
365                                 return;
366
367                         if (constants == null)
368                                 constants = new MemberCoreArrayList ();
369                         
370                         constants.Add (constant);
371                 }
372
373                 public TypeContainer AddTypeContainer (TypeContainer tc)
374                 {
375                         if (!AddMemberType (tc))
376                                 return tc;
377
378                         if (types == null)
379                                 types = new MemberCoreArrayList ();
380                         types.Add (tc);
381
382                         return tc;
383                 }
384
385                 public virtual TypeContainer AddPartial (TypeContainer next_part)
386                 {
387                         return AddPartial (next_part, next_part.Basename);
388                 }
389
390                 protected TypeContainer AddPartial (TypeContainer next_part, string name)
391                 {
392                         next_part.ModFlags |= Modifiers.PARTIAL;
393                         TypeContainer tc = defined_names [name] as TypeContainer;
394
395                         if (tc == null)
396                                 return AddTypeContainer (next_part);
397
398                         if ((tc.ModFlags & Modifiers.PARTIAL) == 0) {
399                                 Report.SymbolRelatedToPreviousError (next_part);
400                                 Error_MissingPartialModifier (tc);
401                         }
402
403                         if (tc.Kind != next_part.Kind) {
404                                 Report.SymbolRelatedToPreviousError (tc);
405                                 Report.Error (261, next_part.Location,
406                                         "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
407                                         next_part.GetSignatureForError ());
408                         }
409
410                         if ((tc.ModFlags & Modifiers.Accessibility) != (next_part.ModFlags & Modifiers.Accessibility) &&
411                                 ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
412                                  (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
413                                 Report.SymbolRelatedToPreviousError (tc);
414                                 Report.Error (262, next_part.Location,
415                                         "Partial declarations of `{0}' have conflicting accessibility modifiers",
416                                         next_part.GetSignatureForError ());
417                         }
418
419                         if (tc.partial_parts == null)
420                                 tc.partial_parts = new ArrayList (1);
421
422                         if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
423                                 tc.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.Accessibility);
424                         } else if ((tc.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
425                                 tc.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.Accessibility);
426                                 tc.ModFlags |= next_part.ModFlags;
427                         } else {
428                                 tc.ModFlags |= next_part.ModFlags;
429                         }
430
431                         if (next_part.attributes != null) {
432                                 if (tc.attributes == null)
433                                         tc.attributes = next_part.attributes;
434                                 else
435                                         tc.attributes.AddAttributes (next_part.attributes.Attrs);
436                         }
437
438                         next_part.PartialContainer = tc;
439                         tc.partial_parts.Add (next_part);
440                         return tc;
441                 }
442
443                 public virtual void RemoveTypeContainer (TypeContainer next_part)
444                 {
445                         if (types != null)
446                                 types.Remove (next_part);
447                         RemoveMemberType (next_part);
448                 }
449                 
450                 public void AddDelegate (Delegate d)
451                 {
452                         if (!AddMemberType (d))
453                                 return;
454
455                         if (delegates == null)
456                                 delegates = new MemberCoreArrayList ();
457
458                         delegates.Add (d);
459                 }
460
461                 private void AddMemberToList (MemberCore mc, ArrayList alist, bool isexplicit)
462                 {
463                         if (ordered_explicit_member_list == null)  {
464                                 ordered_explicit_member_list = new MemberCoreArrayList ();
465                                 ordered_member_list = new MemberCoreArrayList ();
466                         }
467
468                         if (isexplicit) {
469                                 if (Kind == Kind.Interface) {
470                                         Report.Error (541, mc.Location,
471                                                 "`{0}': explicit interface declaration can only be declared in a class or struct",
472                                                 mc.GetSignatureForError ());
473                                 }
474
475                                 ordered_explicit_member_list.Add (mc);
476                                 alist.Insert (0, mc);
477                         } else {
478                                 ordered_member_list.Add (mc);
479                                 alist.Add (mc);
480                         }
481
482                 }
483                 
484                 public void AddMethod (MethodOrOperator method)
485                 {
486                         if (!AddToContainer (method, method.MemberName.Basename))
487                                 return;
488                         
489                         if (methods == null)
490                                 methods = new MemberCoreArrayList ();
491
492                         if (method.MemberName.Left != null) 
493                                 AddMemberToList (method, methods, true);
494                         else 
495                                 AddMemberToList (method, methods, false);
496                 }
497
498                 public void AddConstructor (Constructor c)
499                 {
500                         bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
501                         if (!AddToContainer (c, is_static ?
502                                 ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
503                                 return;
504                         
505                         if (is_static && c.Parameters.IsEmpty){
506                                 if (default_static_constructor != null) {
507                                     Report.SymbolRelatedToPreviousError (default_static_constructor);
508                                         Report.Error (111, c.Location,
509                                                 "A member `{0}' is already defined. Rename this member or use different parameter types",
510                                                 c.GetSignatureForError ());
511                                     return;
512                                 }
513
514                                 default_static_constructor = c;
515                         } else {
516                                 if (c.Parameters.IsEmpty)
517                                         default_constructor = c;
518                                 
519                                 if (instance_constructors == null)
520                                         instance_constructors = new MemberCoreArrayList ();
521                                 
522                                 instance_constructors.Add (c);
523                         }
524                 }
525
526                 public bool AddField (FieldBase field)
527                 {
528                         if (!AddMember (field))
529                                 return false;
530
531                         if (fields == null)
532                                 fields = new MemberCoreArrayList ();
533
534                         fields.Add (field);
535
536                         if ((field.ModFlags & Modifiers.STATIC) != 0)
537                                 return true;
538
539                         if (first_nonstatic_field == null) {
540                                 first_nonstatic_field = field;
541                                 return true;
542                         }
543
544                         if (Kind == Kind.Struct && first_nonstatic_field.Parent != field.Parent) {
545                                 Report.SymbolRelatedToPreviousError (first_nonstatic_field.Parent);
546                                 Report.Warning (282, 3, field.Location,
547                                         "struct instance field `{0}' found in different declaration from instance field `{1}'",
548                                         field.GetSignatureForError (), first_nonstatic_field.GetSignatureForError ());
549                         }
550                         return true;
551                 }
552
553                 public void AddProperty (Property prop)
554                 {
555                         if (!AddMember (prop) || 
556                                 !AddMember (prop.Get) || !AddMember (prop.Set))
557                                 return;
558
559                         if (properties == null)
560                                 properties = new MemberCoreArrayList ();
561
562                         if (prop.MemberName.Left != null)
563                                 AddMemberToList (prop, properties, true);
564                         else 
565                                 AddMemberToList (prop, properties, false);
566                 }
567
568                 public void AddEvent (Event e)
569                 {
570                         if (!AddMember (e))
571                                 return;
572
573                         if (e is EventProperty) {
574                                 if (!AddMember (e.Add))
575                                         return;
576
577                                 if (!AddMember (e.Remove))
578                                         return;
579                         }
580
581                         if (events == null)
582                                 events = new MemberCoreArrayList ();
583
584                         events.Add (e);
585                 }
586
587                 /// <summary>
588                 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
589                 /// </summary>
590                 public void AddIndexer (Indexer i)
591                 {
592                         if (indexers == null)
593                                 indexers = new ArrayList ();
594
595                         if (i.IsExplicitImpl)
596                                 AddMemberToList (i, indexers, true);
597                         else 
598                                 AddMemberToList (i, indexers, false);
599                 }
600
601                 public void AddOperator (Operator op)
602                 {
603                         if (!AddMember (op))
604                                 return;
605
606                         if (operators == null)
607                                 operators = new OperatorArrayList (this);
608
609                         operators.Add (op);
610                 }
611
612                 public void AddCompilerGeneratedClass (CompilerGeneratedClass c)
613                 {
614                         Report.Debug (64, "ADD COMPILER GENERATED CLASS", this, c);
615
616                         if (compiler_generated == null)
617                                 compiler_generated = new ArrayList ();
618
619                         compiler_generated.Add (c);
620                 }
621
622                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
623                 {
624                         if (a.Type == pa.DefaultMember) {
625                                 if (Indexers != null) {
626                                         Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
627                                         return;
628                                 }
629                         }
630                         
631                         base.ApplyAttributeBuilder (a, cb, pa);
632                 } 
633
634                 public override AttributeTargets AttributeTargets {
635                         get {
636                                 throw new NotSupportedException ();
637                         }
638                 }
639
640                 public ArrayList Types {
641                         get {
642                                 return types;
643                         }
644                 }
645
646                 public MemberCoreArrayList Methods {
647                         get {
648                                 return methods;
649                         }
650                 }
651
652                 public ArrayList Constants {
653                         get {
654                                 return constants;
655                         }
656                 }
657
658                 protected Type BaseType {
659                         get {
660                                 return TypeBuilder.BaseType;
661                         }
662                 }
663
664                 public ArrayList Fields {
665                         get {
666                                 return fields;
667                         }
668                 }
669
670                 public ArrayList InstanceConstructors {
671                         get {
672                                 return instance_constructors;
673                         }
674                 }
675
676                 public ArrayList Properties {
677                         get {
678                                 return properties;
679                         }
680                 }
681
682                 public ArrayList Events {
683                         get {
684                                 return events;
685                         }
686                 }
687                 
688                 public ArrayList Indexers {
689                         get {
690                                 return indexers;
691                         }
692                 }
693
694                 public ArrayList Operators {
695                         get {
696                                 return operators;
697                         }
698                 }
699
700                 public ArrayList Delegates {
701                         get {
702                                 return delegates;
703                         }
704                 }
705                 
706                 protected override TypeAttributes TypeAttr {
707                         get {
708                                 return Modifiers.TypeAttr (ModFlags, IsTopLevel) | base.TypeAttr;
709                         }
710                 }
711
712                 public string IndexerName {
713                         get {
714                                 return indexers == null ? DefaultIndexerName : indexer_name;
715                         }
716                 }
717
718                 public bool IsComImport {
719                         get {
720                                 if (OptAttributes == null)
721                                         return false;
722
723                                 return OptAttributes.Contains (PredefinedAttributes.Get.ComImport);
724                         }
725                 }
726
727                 public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
728                 {
729                         if ((field.ModFlags & Modifiers.STATIC) != 0){
730                                 if (initialized_static_fields == null) {
731                                         PartialContainer.HasStaticFieldInitializer = true;
732                                         initialized_static_fields = new ArrayList (4);
733                                 }
734
735                                 initialized_static_fields.Add (expression);
736                         } else {
737                                 if (initialized_fields == null)
738                                         initialized_fields = new ArrayList (4);
739
740                                 initialized_fields.Add (expression);
741                         }
742                 }
743
744                 public void ResolveFieldInitializers (BlockContext ec)
745                 {
746                         if (partial_parts != null) {
747                                 foreach (TypeContainer part in partial_parts) {
748                                         part.DoResolveFieldInitializers (ec);
749                                 }
750                         }
751                         DoResolveFieldInitializers (ec);
752                 }
753
754                 void DoResolveFieldInitializers (BlockContext ec)
755                 {
756                         if (ec.IsStatic) {
757                                 if (initialized_static_fields == null)
758                                         return;
759
760                                 bool has_complex_initializer = !RootContext.Optimize;
761                                 int i;
762                                 ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
763                                 for (i = 0; i < initialized_static_fields.Count; ++i) {
764                                         FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
765                                         ExpressionStatement s = fi.ResolveStatement (ec);
766                                         if (s == null) {
767                                                 s = EmptyExpressionStatement.Instance;
768                                         } else if (fi.IsComplexInitializer) {
769                                                 has_complex_initializer |= true;
770                                         }
771
772                                         init [i] = s;
773                                 }
774
775                                 for (i = 0; i < initialized_static_fields.Count; ++i) {
776                                         FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
777                                         //
778                                         // Need special check to not optimize code like this
779                                         // static int a = b = 5;
780                                         // static int b = 0;
781                                         //
782                                         if (!has_complex_initializer && fi.IsDefaultInitializer)
783                                                 continue;
784
785                                         ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
786                                 }
787
788                                 return;
789                         }
790
791                         if (initialized_fields == null)
792                                 return;
793
794                         for (int i = 0; i < initialized_fields.Count; ++i) {
795                                 FieldInitializer fi = (FieldInitializer) initialized_fields [i];
796                                 ExpressionStatement s = fi.ResolveStatement (ec);
797                                 if (s == null)
798                                         continue;
799
800                                 //
801                                 // Field is re-initialized to its default value => removed
802                                 //
803                                 if (fi.IsDefaultInitializer && RootContext.Optimize)
804                                         continue;
805
806                                 ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
807                         }
808                 }
809
810                 public override string DocComment {
811                         get {
812                                 return comment;
813                         }
814                         set {
815                                 if (value == null)
816                                         return;
817
818                                 comment += value;
819                         }
820                 }
821
822                 public PendingImplementation PendingImplementations {
823                         get { return pending; }
824                 }
825
826                 public override bool GetClsCompliantAttributeValue ()
827                 {
828                         if (PartialContainer != this)
829                                 return PartialContainer.GetClsCompliantAttributeValue ();
830
831                         return base.GetClsCompliantAttributeValue ();
832                 }
833
834                 public virtual void AddBasesForPart (DeclSpace part, ArrayList bases)
835                 {
836                         // FIXME: get rid of partial_parts and store lists of bases of each part here
837                         // assumed, not verified: 'part' is in 'partial_parts' 
838                         ((TypeContainer) part).type_bases = bases;
839                 }
840
841                 /// <summary>
842                 ///   This function computes the Base class and also the
843                 ///   list of interfaces that the class or struct @c implements.
844                 ///   
845                 ///   The return value is an array (might be null) of
846                 ///   interfaces implemented (as Types).
847                 ///   
848                 ///   The @base_class argument is set to the base object or null
849                 ///   if this is `System.Object'. 
850                 /// </summary>
851                 protected virtual TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
852                 {
853                         base_class = null;
854                         if (type_bases == null)
855                                 return null;
856
857                         int count = type_bases.Count;
858                         TypeExpr [] ifaces = null;
859                         IMemberContext base_context = new BaseContext (this);
860                         for (int i = 0, j = 0; i < count; i++){
861                                 FullNamedExpression fne = (FullNamedExpression) type_bases [i];
862
863                                 //
864                                 // Standard ResolveAsTypeTerminal cannot be used in this case because
865                                 // it does ObsoleteAttribute and constraint checks which require
866                                 // base type to be set
867                                 //
868                                 TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (base_context, false);
869                                 if (fne_resolved == null)
870                                         continue;
871
872                                 if (i == 0 && Kind == Kind.Class && !fne_resolved.Type.IsInterface) {
873                                         if (fne_resolved is DynamicTypeExpr)
874                                                 Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type",
875                                                         GetSignatureForError ());
876                                         else
877                                                 base_class = fne_resolved;
878                                         continue;
879                                 }
880
881                                 if (ifaces == null)
882                                         ifaces = new TypeExpr [count - i];
883
884                                 if (fne_resolved.Type.IsInterface) {
885                                         for (int ii = 0; ii < j; ++ii) {
886                                                 if (TypeManager.IsEqual (fne_resolved.Type, ifaces [ii].Type)) {
887                                                         Report.Error (528, Location, "`{0}' is already listed in interface list",
888                                                                 fne_resolved.GetSignatureForError ());
889                                                         break;
890                                                 }
891                                         }
892
893                                         if (Kind == Kind.Interface && !IsAccessibleAs (fne_resolved.Type)) {
894                                                 Report.Error (61, fne.Location,
895                                                         "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
896                                                         fne_resolved.GetSignatureForError (), GetSignatureForError ());
897                                         }
898                                 } else {
899                                         Report.SymbolRelatedToPreviousError (fne_resolved.Type);
900                                         if (Kind != Kind.Class) {
901                                                 Report.Error (527, fne.Location, "Type `{0}' in interface list is not an interface", fne_resolved.GetSignatureForError ());
902                                         } else if (base_class != null)
903                                                 Report.Error (1721, fne.Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
904                                                         GetSignatureForError (), base_class.GetSignatureForError (), fne_resolved.GetSignatureForError ());
905                                         else {
906                                                 Report.Error (1722, fne.Location, "`{0}': Base class `{1}' must be specified as first",
907                                                         GetSignatureForError (), fne_resolved.GetSignatureForError ());
908                                         }
909                                 }
910
911                                 ifaces [j++] = fne_resolved;
912                         }
913
914                         return ifaces;
915                 }
916
917                 TypeExpr[] GetNormalPartialBases (ref TypeExpr base_class)
918                 {
919                         ArrayList ifaces = new ArrayList (0);
920                         if (iface_exprs != null)
921                                 ifaces.AddRange (iface_exprs);
922
923                         foreach (TypeContainer part in partial_parts) {
924                                 TypeExpr new_base_class;
925                                 TypeExpr[] new_ifaces = part.ResolveBaseTypes (out new_base_class);
926                                 if (new_base_class != TypeManager.system_object_expr) {
927                                         if (base_class == TypeManager.system_object_expr)
928                                                 base_class = new_base_class;
929                                         else {
930                                                 if (new_base_class != null && !TypeManager.IsEqual (new_base_class.Type, base_class.Type)) {
931                                                         Report.SymbolRelatedToPreviousError (base_class.Location, "");
932                                                         Report.Error (263, part.Location,
933                                                                 "Partial declarations of `{0}' must not specify different base classes",
934                                                                 part.GetSignatureForError ());
935
936                                                         return null;
937                                                 }
938                                         }
939                                 }
940
941                                 if (new_ifaces == null)
942                                         continue;
943
944                                 foreach (TypeExpr iface in new_ifaces) {
945                                         if (ifaces.Contains (iface))
946                                                 continue;
947
948                                         ifaces.Add (iface);
949                                 }
950                         }
951
952                         if (ifaces.Count == 0)
953                                 return null;
954
955                         return (TypeExpr[])ifaces.ToArray (typeof (TypeExpr));
956                 }
957
958                 bool CheckGenericInterfaces (Type[] ifaces)
959                 {
960                         ArrayList already_checked = new ArrayList ();
961
962                         for (int i = 0; i < ifaces.Length; i++) {
963                                 Type iface = ifaces [i];
964                                 foreach (Type t in already_checked) {
965                                         if (iface == t)
966                                                 continue;
967
968                                         Type[] inferred = new Type [CountTypeParameters];
969                                         if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, inferred, null))
970                                                 continue;
971
972                                         Report.Error (695, Location,
973                                                 "`{0}' cannot implement both `{1}' and `{2}' " +
974                                                 "because they may unify for some type parameter substitutions",
975                                                 TypeManager.CSharpName (TypeBuilder), TypeManager.CSharpName (iface),
976                                                 TypeManager.CSharpName (t));
977                                         return false;
978                                 }
979
980                                 already_checked.Add (iface);
981                         }
982
983                         return true;
984                 }
985
986                 bool error = false;
987                 
988                 bool CreateTypeBuilder ()
989                 {
990                         try {
991                                 Type default_parent = null;
992                                 if (Kind == Kind.Struct)
993                                         default_parent = TypeManager.value_type;
994                                 else if (Kind == Kind.Enum)
995                                         default_parent = TypeManager.enum_type;
996                                 else if (Kind == Kind.Delegate)
997                                         default_parent = TypeManager.multicast_delegate_type;
998
999                                 //
1000                                 // Sets .size to 1 for structs with no instance fields
1001                                 //
1002                                 int type_size = Kind == Kind.Struct && first_nonstatic_field == null ? 1 : 0;
1003
1004                                 if (IsTopLevel){
1005                                         if (GlobalRootNamespace.Instance.IsNamespace (Name)) {
1006                                                 Report.Error (519, Location, "`{0}' clashes with a predefined namespace", Name);
1007                                                 return false;
1008                                         }
1009
1010                                         ModuleBuilder builder = Module.Compiled.Builder;
1011                                         TypeBuilder = builder.DefineType (
1012                                                 Name, TypeAttr, default_parent, type_size);
1013                                 } else {
1014                                         TypeBuilder builder = Parent.TypeBuilder;
1015
1016                                         TypeBuilder = builder.DefineNestedType (
1017                                                 Basename, TypeAttr, default_parent, type_size);
1018                                 }
1019                         } catch (ArgumentException) {
1020                                 Report.RuntimeMissingSupport (Location, "static classes");
1021                                 return false;
1022                         }
1023
1024                         TypeManager.AddUserType (this);
1025
1026                         if (IsGeneric) {
1027                                 string[] param_names = new string [TypeParameters.Length];
1028                                 for (int i = 0; i < TypeParameters.Length; i++)
1029                                         param_names [i] = TypeParameters [i].Name;
1030
1031                                 GenericTypeParameterBuilder[] gen_params = TypeBuilder.DefineGenericParameters (param_names);
1032
1033                                 int offset = CountTypeParameters;
1034                                 if (CurrentTypeParameters != null)
1035                                         offset -= CurrentTypeParameters.Length;
1036
1037                                 if (offset > 0) {
1038                                         nested_gen_params = new GenericTypeParameterBuilder [offset];
1039                                         Array.Copy (gen_params, nested_gen_params, offset);
1040                                 }
1041
1042                                 for (int i = offset; i < gen_params.Length; i++)
1043                                         CurrentTypeParameters [i - offset].Define (gen_params [i]);
1044                         }
1045
1046                         return true;
1047                 }
1048
1049                 bool DefineBaseTypes ()
1050                 {
1051                         iface_exprs = ResolveBaseTypes (out base_type);
1052                         if (partial_parts != null) {
1053                                 iface_exprs = GetNormalPartialBases (ref base_type);
1054                         }
1055
1056                         //
1057                         // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1058                         // which in turn should have called DefineType()s on base types if necessary.
1059                         //
1060                         // None of the code below should trigger DefineType()s on classes that we depend on.
1061                         // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1062                         //
1063                         // Let's do it as soon as possible, since code below can call DefineType() on classes
1064                         // that depend on us to be populated before they are.
1065                         //
1066                         if (!(this is CompilerGeneratedClass) && !(this is Delegate))
1067                                 RootContext.RegisterOrder (this); 
1068
1069                         if (!CheckRecursiveDefinition (this))
1070                                 return false;
1071
1072                         if (base_type != null && base_type.Type != null) {
1073                                 TypeBuilder.SetParent (base_type.Type);
1074                         }
1075
1076                         // add interfaces that were not added at type creation
1077                         if (iface_exprs != null) {
1078                                 ifaces = TypeManager.ExpandInterfaces (iface_exprs);
1079                                 if (ifaces == null)
1080                                         return false;
1081
1082                                 foreach (Type itype in ifaces)
1083                                         TypeBuilder.AddInterfaceImplementation (itype);
1084
1085                                 if (!CheckGenericInterfaces (ifaces))
1086                                         return false;
1087
1088                                 TypeManager.RegisterBuilder (TypeBuilder, ifaces);
1089                         }
1090
1091                         return true;
1092                 }
1093
1094                 //
1095                 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1096                 //
1097                 public TypeBuilder CreateType ()
1098                 {
1099                         if (TypeBuilder != null)
1100                                 return TypeBuilder;
1101
1102                         if (error)
1103                                 return null;
1104
1105                         if (!CreateTypeBuilder ()) {
1106                                 error = true;
1107                                 return null;
1108                         }
1109
1110                         if (partial_parts != null) {
1111                                 foreach (TypeContainer part in partial_parts)
1112                                         part.TypeBuilder = TypeBuilder;
1113                         }
1114
1115                         if (Types != null) {
1116                                 foreach (TypeContainer tc in Types) {
1117                                         if (tc.CreateType () == null) {
1118                                                 error = true;
1119                                                 return null;
1120                                         }
1121                                 }
1122                         }
1123
1124                         return TypeBuilder;
1125                 }
1126
1127                 bool type_defined;
1128
1129                 public override TypeBuilder DefineType ()
1130                 {
1131                         if (error)
1132                                 return null;
1133                         if (type_defined)
1134                                 return TypeBuilder;
1135
1136                         type_defined = true;
1137
1138                         if (CreateType () == null) {
1139                                 error = true;
1140                                 return null;
1141                         }
1142
1143                         if (!DefineBaseTypes ()) {
1144                                 error = true;
1145                                 return null;
1146                         }
1147
1148                         if (!DefineNestedTypes ()) {
1149                                 error = true;
1150                                 return null;
1151                         }
1152
1153                         return TypeBuilder;
1154                 }
1155
1156                 public override void SetParameterInfo (ArrayList constraints_list)
1157                 {
1158                         base.SetParameterInfo (constraints_list);
1159
1160                         if (!is_generic || PartialContainer == this)
1161                                 return;
1162
1163                         TypeParameter[] tc_names = PartialContainer.TypeParameters;
1164                         for (int i = 0; i < tc_names.Length; ++i) {
1165                                 if (tc_names [i].Name != type_params [i].Name) {
1166                                         Report.SymbolRelatedToPreviousError (PartialContainer.Location, "");
1167                                         Report.Error (264, Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
1168                                                 GetSignatureForError ());
1169                                         break;
1170                                 }
1171                         }
1172                 }
1173
1174                 void UpdateTypeParameterConstraints (TypeContainer part)
1175                 {
1176                         TypeParameter[] current_params = type_params;
1177                         for (int i = 0; i < current_params.Length; i++) {
1178                                 Constraints c = part.type_params [i].Constraints;
1179                                 if (c == null)
1180                                         continue;
1181
1182                                 if (current_params [i].UpdateConstraints (part, c))
1183                                         continue;
1184
1185                                 Report.SymbolRelatedToPreviousError (Location, "");
1186                                 Report.Error (265, part.Location,
1187                                         "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1188                                         GetSignatureForError (), current_params [i].GetSignatureForError ());
1189                         }
1190                 }
1191
1192                 public bool ResolveType ()
1193                 {
1194                         if (!DoResolveType ())
1195                                 return false;
1196
1197                         if (compiler_generated != null) {
1198                                 foreach (CompilerGeneratedClass c in compiler_generated)
1199                                         if (!c.ResolveType ())
1200                                                 return false;
1201                         }
1202
1203                         return true;
1204                 }
1205
1206                 protected virtual bool DoResolveType ()
1207                 {
1208                         if (!IsGeneric)
1209                                 return true;
1210
1211                         if (PartialContainer != this)
1212                                 throw new InternalErrorException ();
1213
1214                         TypeExpr current_type = null;
1215                         if (CurrentTypeParameters != null) {
1216                                 foreach (TypeParameter type_param in CurrentTypeParameters) {
1217                                         if (!type_param.Resolve (this)) {
1218                                                 error = true;
1219                                                 return false;
1220                                         }
1221                                 }
1222
1223                                 if (partial_parts != null) {
1224                                         foreach (TypeContainer part in partial_parts)
1225                                                 UpdateTypeParameterConstraints (part);
1226                                 }
1227                         }
1228
1229                         for (int i = 0; i < TypeParameters.Length; ++i) {
1230                                 //
1231                                 // FIXME: Same should be done for delegates
1232                                 // TODO: Quite ugly way how to propagate constraints to
1233                                 // nested types
1234                                 //
1235                                 if (nested_gen_params != null && i < nested_gen_params.Length) {
1236                                         TypeParameters [i].SetConstraints (nested_gen_params [i]);
1237                                 } else {
1238                                         if (!TypeParameters [i].DefineType (this)) {
1239                                                 error = true;
1240                                                 return false;
1241                                         }
1242                                 }
1243                         }
1244
1245                         // TODO: Very strange, why not simple make generic type from
1246                         // current type parameters
1247                         current_type = new GenericTypeExpr (this, Location);
1248                         current_type = current_type.ResolveAsTypeTerminal (this, false);
1249                         if (current_type == null) {
1250                                 error = true;
1251                                 return false;
1252                         }
1253
1254                         currentType = current_type.Type;
1255                         return true;
1256                 }
1257
1258                 protected virtual bool DefineNestedTypes ()
1259                 {
1260                         if (Types != null) {
1261                                 foreach (TypeContainer tc in Types)
1262                                         if (tc.DefineType () == null)
1263                                                 return false;
1264                         }
1265
1266                         if (Delegates != null) {
1267                                 foreach (Delegate d in Delegates)
1268                                         if (d.DefineType () == null)
1269                                                 return false;
1270                         }
1271
1272                         return true;
1273                 }
1274
1275                 TypeContainer InTransit;
1276
1277                 protected bool CheckRecursiveDefinition (TypeContainer tc)
1278                 {
1279                         if (InTransit != null) {
1280                                 Report.SymbolRelatedToPreviousError (this);
1281                                 if (this is Interface)
1282                                         Report.Error (
1283                                                 529, tc.Location, "Inherited interface `{0}' causes a " +
1284                                                 "cycle in the interface hierarchy of `{1}'",
1285                                                 GetSignatureForError (), tc.GetSignatureForError ());
1286                                 else
1287                                         Report.Error (
1288                                                 146, tc.Location, "Circular base class dependency " +
1289                                                 "involving `{0}' and `{1}'",
1290                                                 tc.GetSignatureForError (), GetSignatureForError ());
1291                                 return false;
1292                         }
1293
1294                         InTransit = tc;
1295
1296                         if (base_type != null && base_type.Type != null) {
1297                                 Type t = TypeManager.DropGenericTypeArguments (base_type.Type);
1298                                 TypeContainer ptc = TypeManager.LookupTypeContainer (t);
1299                                 if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1300                                         return false;
1301                         }
1302
1303                         if (iface_exprs != null) {
1304                                 foreach (TypeExpr iface in iface_exprs) {
1305                                         Type itype = TypeManager.DropGenericTypeArguments (iface.Type);
1306                                         TypeContainer ptc = TypeManager.LookupTypeContainer (itype);
1307                                         if ((ptc != null) && !ptc.CheckRecursiveDefinition (this))
1308                                                 return false;
1309                                 }
1310                         }
1311
1312                         if (!IsTopLevel && !Parent.PartialContainer.CheckRecursiveDefinition (this))
1313                                 return false;
1314
1315                         InTransit = null;
1316                         return true;
1317                 }
1318
1319                 public override TypeParameter[] CurrentTypeParameters {
1320                         get {
1321                                 return PartialContainer.type_params;
1322                         }
1323                 }
1324
1325                 /// <summary>
1326                 ///   Populates our TypeBuilder with fields and methods
1327                 /// </summary>
1328                 public override bool Define ()
1329                 {
1330                         if (members_defined)
1331                                 return members_defined_ok;
1332
1333                         members_defined_ok = DoDefineMembers ();
1334                         members_defined = true;
1335
1336                         return members_defined_ok;
1337                 }
1338
1339                 protected virtual bool DoDefineMembers ()
1340                 {
1341                         if (iface_exprs != null) {
1342                                 foreach (TypeExpr iface in iface_exprs) {
1343                                         ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (iface.Type);
1344                                         if ((oa != null) && !IsObsolete)
1345                                                 AttributeTester.Report_ObsoleteMessage (
1346                                                         oa, iface.GetSignatureForError (), Location, Report);
1347
1348                                         GenericTypeExpr ct = iface as GenericTypeExpr;
1349                                         if (ct != null) {
1350                                                 // TODO: passing `this' is wrong, should be base type iface instead
1351                                                 TypeManager.CheckTypeVariance (ct.Type, Variance.Covariant, this);
1352
1353                                                 if (!ct.CheckConstraints (this))
1354                                                         return false;
1355                                         }
1356                                 }
1357                         }
1358
1359                         if (base_type != null) {
1360                                 ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type);
1361                                 if (obsolete_attr != null && !IsObsolete)
1362                                         AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report);
1363
1364                                 GenericTypeExpr ct = base_type as GenericTypeExpr;
1365                                 if ((ct != null) && !ct.CheckConstraints (this))
1366                                         return false;
1367                                 
1368                                 TypeContainer baseContainer = TypeManager.LookupTypeContainer(base_type.Type);
1369                                 if (baseContainer != null)
1370                                         baseContainer.Define();                         
1371                                 
1372                                 member_cache = new MemberCache (base_type.Type, this);
1373                         } else if (Kind == Kind.Interface) {
1374                                 member_cache = new MemberCache (null, this);
1375                                 Type [] ifaces = TypeManager.GetInterfaces (TypeBuilder);
1376                                 for (int i = 0; i < ifaces.Length; ++i)
1377                                         member_cache.AddInterface (TypeManager.LookupMemberCache (ifaces [i]));
1378                         } else {
1379                                 member_cache = new MemberCache (null, this);
1380                         }
1381
1382                         if (types != null)
1383                                 foreach (TypeContainer tc in types)
1384                                         member_cache.AddNestedType (tc);
1385
1386                         if (delegates != null)
1387                                 foreach (Delegate d in delegates)
1388                                         member_cache.AddNestedType (d);
1389
1390                         if (partial_parts != null) {
1391                                 foreach (TypeContainer part in partial_parts)
1392                                         part.member_cache = member_cache;
1393                         }
1394
1395                         if (!IsTopLevel) {
1396                                 MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false);
1397                                 if (conflict_symbol == null) {
1398                                         if ((ModFlags & Modifiers.NEW) != 0)
1399                                                 Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1400                                 } else {
1401                                         if ((ModFlags & Modifiers.NEW) == 0) {
1402                                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
1403                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1404                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
1405                                         }
1406                                 }
1407                         }
1408
1409                         DefineContainerMembers (constants);
1410                         DefineContainerMembers (fields);
1411
1412                         if (Kind == Kind.Struct || Kind == Kind.Class) {
1413                                 pending = PendingImplementation.GetPendingImplementations (this);
1414
1415                                 if (requires_delayed_unmanagedtype_check) {
1416                                         requires_delayed_unmanagedtype_check = false;
1417                                         foreach (FieldBase f in fields) {
1418                                                 if (f.MemberType != null && f.MemberType.IsPointer)
1419                                                         TypeManager.VerifyUnManaged (f.MemberType, f.Location);
1420                                         }
1421                                 }
1422                         }
1423                 
1424                         //
1425                         // Constructors are not in the defined_names array
1426                         //
1427                         DefineContainerMembers (instance_constructors);
1428                 
1429                         DefineContainerMembers (events);
1430                         DefineContainerMembers (ordered_explicit_member_list);
1431                         DefineContainerMembers (ordered_member_list);
1432
1433                         DefineContainerMembers (operators);
1434                         DefineContainerMembers (delegates);
1435
1436                         ComputeIndexerName();
1437                         CheckEqualsAndGetHashCode();
1438
1439                         if (CurrentType != null) {
1440                                 GenericType = CurrentType;
1441                         }
1442
1443                         //
1444                         // FIXME: This hack is needed because member cache does not work
1445                         // with generic types, we rely on runtime to inflate dynamic types.
1446                         // TODO: This hack requires member cache refactoring to be removed
1447                         //
1448                         if (TypeManager.IsGenericType (TypeBuilder))
1449                                 member_cache = new MemberCache (this);
1450
1451                         return true;
1452                 }
1453
1454                 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
1455                 {
1456                         if (mcal != null)
1457                                 mcal.DefineContainerMembers ();
1458                 }
1459                 
1460                 protected virtual void ComputeIndexerName ()
1461                 {
1462                         if (indexers == null)
1463                                 return;
1464
1465                         string class_indexer_name = null;
1466
1467                         //
1468                         // If there's both an explicit and an implicit interface implementation, the
1469                         // explicit one actually implements the interface while the other one is just
1470                         // a normal indexer.  See bug #37714.
1471                         //
1472
1473                         // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1474                         foreach (Indexer i in indexers) {
1475                                 if (i.InterfaceType != null) {
1476                                         if (seen_normal_indexers)
1477                                                 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1478                                         continue;
1479                                 }
1480
1481                                 seen_normal_indexers = true;
1482
1483                                 if (class_indexer_name == null) {
1484                                         class_indexer_name = i.ShortName;
1485                                         continue;
1486                                 }
1487
1488                                 if (i.ShortName != class_indexer_name)
1489                                         Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
1490                         }
1491
1492                         if (class_indexer_name != null)
1493                                 indexer_name = class_indexer_name;
1494                 }
1495
1496                 protected virtual void EmitIndexerName ()
1497                 {
1498                         if (!seen_normal_indexers)
1499                                 return;
1500
1501                         PredefinedAttribute pa = PredefinedAttributes.Get.DefaultMember;
1502                         if (pa.Constructor == null &&
1503                                 !pa.ResolveConstructor (Location, TypeManager.string_type))
1504                                 return;
1505
1506                         CustomAttributeBuilder cb = new CustomAttributeBuilder (pa.Constructor, new string [] { IndexerName });
1507                         TypeBuilder.SetCustomAttribute (cb);
1508                 }
1509
1510                 protected virtual void CheckEqualsAndGetHashCode ()
1511                 {
1512                         if (methods == null)
1513                                 return;
1514
1515                         if (HasEquals && !HasGetHashCode) {
1516                                 Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
1517                         }
1518                 }
1519
1520                 public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
1521                 {
1522                         return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
1523                 }
1524
1525                 /// <summary>
1526                 ///   This function is based by a delegate to the FindMembers routine
1527                 /// </summary>
1528                 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1529                 {
1530                         return true;
1531                 }
1532
1533                 /// <summary>
1534                 ///   This filter is used by FindMembers, and we just keep
1535                 ///   a global for the filter to `AlwaysAccept'
1536                 /// </summary>
1537                 static MemberFilter accepting_filter;
1538
1539                 
1540                 static TypeContainer ()
1541                 {
1542                         accepting_filter = new MemberFilter (AlwaysAccept);
1543                 }
1544
1545                 public MethodInfo[] GetMethods ()
1546                 {
1547                         ArrayList members = new ArrayList ();
1548
1549                         Define ();
1550
1551                         if (methods != null) {
1552                                 int len = methods.Count;
1553                                 for (int i = 0; i < len; i++) {
1554                                         Method m = (Method) methods [i];
1555
1556                                         members.Add (m.MethodBuilder);
1557                                 }
1558                         }
1559
1560                         if (operators != null) {
1561                                 int len = operators.Count;
1562                                 for (int i = 0; i < len; i++) {
1563                                         Operator o = (Operator) operators [i];
1564
1565                                         members.Add (o.MethodBuilder);
1566                                 }
1567                         }
1568
1569                         if (properties != null) {
1570                                 int len = properties.Count;
1571                                 for (int i = 0; i < len; i++) {
1572                                         Property p = (Property) properties [i];
1573
1574                                         if (p.GetBuilder != null)
1575                                                 members.Add (p.GetBuilder);
1576                                         if (p.SetBuilder != null)
1577                                                 members.Add (p.SetBuilder);
1578                                 }
1579                         }
1580                                 
1581                         if (indexers != null) {
1582                                 int len = indexers.Count;
1583                                 for (int i = 0; i < len; i++) {
1584                                         Indexer ix = (Indexer) indexers [i];
1585
1586                                         if (ix.GetBuilder != null)
1587                                                 members.Add (ix.GetBuilder);
1588                                         if (ix.SetBuilder != null)
1589                                                 members.Add (ix.SetBuilder);
1590                                 }
1591                         }
1592
1593                         if (events != null) {
1594                                 int len = events.Count;
1595                                 for (int i = 0; i < len; i++) {
1596                                         Event e = (Event) events [i];
1597
1598                                         if (e.AddBuilder != null)
1599                                                 members.Add (e.AddBuilder);
1600                                         if (e.RemoveBuilder != null)
1601                                                 members.Add (e.RemoveBuilder);
1602                                 }
1603                         }
1604
1605                         MethodInfo[] retMethods = new MethodInfo [members.Count];
1606                         members.CopyTo (retMethods, 0);
1607                         return retMethods;
1608                 }
1609                 
1610                 // Indicated whether container has StructLayout attribute set Explicit
1611                 public bool HasExplicitLayout {
1612                         get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1613                         set { caching_flags |= Flags.HasExplicitLayout; }
1614                 }
1615
1616                 public bool HasStructLayout {
1617                         get { return (caching_flags & Flags.HasStructLayout) != 0; }
1618                         set { caching_flags |= Flags.HasStructLayout; }
1619                 }
1620
1621                 //
1622                 // Return the nested type with name @name.  Ensures that the nested type
1623                 // is defined if necessary.  Do _not_ use this when you have a MemberCache handy.
1624                 //
1625                 public Type FindNestedType (string name)
1626                 {
1627                         if (PartialContainer != this)
1628                                 throw new InternalErrorException ("should not happen");
1629
1630                         ArrayList [] lists = { types, delegates };
1631
1632                         for (int j = 0; j < lists.Length; ++j) {
1633                                 ArrayList list = lists [j];
1634                                 if (list == null)
1635                                         continue;
1636                                 
1637                                 int len = list.Count;
1638                                 for (int i = 0; i < len; ++i) {
1639                                         DeclSpace ds = (DeclSpace) list [i];
1640                                         if (ds.Basename == name) {
1641                                                 return ds.DefineType ();
1642                                         }
1643                                 }
1644                         }
1645
1646                         return null;
1647                 }
1648
1649                 private void FindMembers_NestedTypes (int modflags,
1650                                                       BindingFlags bf, MemberFilter filter, object criteria,
1651                                                       ref ArrayList members)
1652                 {
1653                         ArrayList [] lists = { types, delegates };
1654
1655                         for (int j = 0; j < lists.Length; ++j) {
1656                                 ArrayList list = lists [j];
1657                                 if (list == null)
1658                                         continue;
1659                         
1660                                 int len = list.Count;
1661                                 for (int i = 0; i < len; i++) {
1662                                         DeclSpace ds = (DeclSpace) list [i];
1663                                         
1664                                         if ((ds.ModFlags & modflags) == 0)
1665                                                 continue;
1666                                         
1667                                         TypeBuilder tb = ds.TypeBuilder;
1668                                         if (tb == null) {
1669                                                 if (!(criteria is string) || ds.Basename.Equals (criteria))
1670                                                         tb = ds.DefineType ();
1671                                         }
1672                                         
1673                                         if (tb != null && (filter (tb, criteria) == true)) {
1674                                                 if (members == null)
1675                                                         members = new ArrayList ();
1676                                                 
1677                                                 members.Add (tb);
1678                                         }
1679                                 }
1680                         }
1681                 }
1682                 
1683                 /// <summary>
1684                 ///   This method returns the members of this type just like Type.FindMembers would
1685                 ///   Only, we need to use this for types which are _being_ defined because MS' 
1686                 ///   implementation can't take care of that.
1687                 /// </summary>
1688                 //
1689                 // FIXME: return an empty static array instead of null, that cleans up
1690                 // some code and is consistent with some coding conventions I just found
1691                 // out existed ;-)
1692                 //
1693                 //
1694                 // Notice that in various cases we check if our field is non-null,
1695                 // something that would normally mean that there was a bug elsewhere.
1696                 //
1697                 // The problem happens while we are defining p-invoke methods, as those
1698                 // will trigger a FindMembers, but this happens before things are defined
1699                 //
1700                 // Since the whole process is a no-op, it is fine to check for null here.
1701                 //
1702                 // TODO: This approach will be one day completely removed, it's already
1703                 // used at few places only
1704                 //
1705                 //
1706                 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1707                                                         MemberFilter filter, object criteria)
1708                 {
1709                         ArrayList members = null;
1710
1711                         int modflags = 0;
1712                         if ((bf & BindingFlags.Public) != 0)
1713                                 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1714                                         Modifiers.INTERNAL;
1715                         if ((bf & BindingFlags.NonPublic) != 0)
1716                                 modflags |= Modifiers.PRIVATE;
1717
1718                         int static_mask = 0, static_flags = 0;
1719                         switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1720                         case BindingFlags.Static:
1721                                 static_mask = static_flags = Modifiers.STATIC;
1722                                 break;
1723
1724                         case BindingFlags.Instance:
1725                                 static_mask = Modifiers.STATIC;
1726                                 static_flags = 0;
1727                                 break;
1728
1729                         default:
1730                                 static_mask = static_flags = 0;
1731                                 break;
1732                         }
1733
1734                         Timer.StartTimer (TimerType.TcFindMembers);
1735
1736                         if (filter == null)
1737                                 filter = accepting_filter; 
1738
1739                         if ((mt & MemberTypes.Field) != 0) {
1740                                 if (fields != null) {
1741                                         int len = fields.Count;
1742                                         for (int i = 0; i < len; i++) {
1743                                                 FieldBase f = (FieldBase) fields [i];
1744                                                 
1745                                                 if ((f.ModFlags & modflags) == 0)
1746                                                         continue;
1747                                                 if ((f.ModFlags & static_mask) != static_flags)
1748                                                         continue;
1749
1750                                                 FieldBuilder fb = f.FieldBuilder;
1751                                                 if (fb != null && filter (fb, criteria) == true) {
1752                                                         if (members == null)
1753                                                                 members = new ArrayList ();
1754                                                         
1755                                                         members.Add (fb);
1756                                                 }
1757                                         }
1758                                 }
1759
1760                                 if (constants != null) {
1761                                         int len = constants.Count;
1762                                         for (int i = 0; i < len; i++) {
1763                                                 Const con = (Const) constants [i];
1764                                                 
1765                                                 if ((con.ModFlags & modflags) == 0)
1766                                                         continue;
1767                                                 if ((con.ModFlags & static_mask) != static_flags)
1768                                                         continue;
1769
1770                                                 FieldBuilder fb = con.FieldBuilder;
1771                                                 if (fb == null) {
1772                                                         if (con.Define ())
1773                                                                 fb = con.FieldBuilder;
1774                                                 }
1775                                                 if (fb != null && filter (fb, criteria) == true) {
1776                                                         if (members == null)
1777                                                                 members = new ArrayList ();
1778                                                         
1779                                                         members.Add (fb);
1780                                                 }
1781                                         }
1782                                 }
1783                         }
1784
1785                         if ((mt & MemberTypes.Method) != 0) {
1786                                 if (methods != null) {
1787                                         int len = methods.Count;
1788                                         for (int i = 0; i < len; i++) {
1789                                                 MethodOrOperator m = (MethodOrOperator) methods [i];
1790                                                 
1791                                                 if ((m.ModFlags & modflags) == 0)
1792                                                         continue;
1793                                                 if ((m.ModFlags & static_mask) != static_flags)
1794                                                         continue;
1795                                                 
1796                                                 MethodBuilder mb = m.MethodBuilder;
1797
1798                                                 if (mb != null && filter (mb, criteria) == true) {
1799                                                         if (members == null)
1800                                                                 members = new ArrayList ();
1801                                                         
1802                                                         members.Add (mb);
1803                                                 }
1804                                         }
1805                                 }
1806
1807                                 if (operators != null) {
1808                                         int len = operators.Count;
1809                                         for (int i = 0; i < len; i++) {
1810                                                 Operator o = (Operator) operators [i];
1811                                                 
1812                                                 if ((o.ModFlags & modflags) == 0)
1813                                                         continue;
1814                                                 if ((o.ModFlags & static_mask) != static_flags)
1815                                                         continue;
1816                                                 
1817                                                 MethodBuilder ob = o.MethodBuilder;
1818                                                 if (ob != null && filter (ob, criteria) == true) {
1819                                                         if (members == null)
1820                                                                 members = new ArrayList ();
1821                                                         
1822                                                         members.Add (ob);
1823                                                 }
1824                                         }
1825                                 }
1826
1827                                 if (events != null) {
1828                                         foreach (Event e in events) {
1829                                                 if ((e.ModFlags & modflags) == 0)
1830                                                         continue;
1831                                                 if ((e.ModFlags & static_mask) != static_flags)
1832                                                         continue;
1833
1834                                                 MethodBuilder b = e.AddBuilder;
1835                                                 if (b != null && filter (b, criteria)) {
1836                                                         if (members == null)
1837                                                                 members = new ArrayList (4);
1838
1839                                                         members.Add (b);
1840                                                 }
1841
1842                                                 b = e.RemoveBuilder;
1843                                                 if (b != null && filter (b, criteria)) {
1844                                                         if (members == null) 
1845                                                                 members = new ArrayList (4);
1846
1847                                                         members.Add (b);
1848                                                 }
1849                                         }
1850                                 }
1851
1852                                 if (properties != null) {
1853                                         int len = properties.Count;
1854                                         for (int i = 0; i < len; i++) {
1855                                                 Property p = (Property) properties [i];
1856                                                 
1857                                                 if ((p.ModFlags & modflags) == 0)
1858                                                         continue;
1859                                                 if ((p.ModFlags & static_mask) != static_flags)
1860                                                         continue;
1861                                                 
1862                                                 MethodBuilder b;
1863
1864                                                 b = p.GetBuilder;
1865                                                 if (b != null && filter (b, criteria) == true) {
1866                                                         if (members == null)
1867                                                                 members = new ArrayList ();
1868                                                         
1869                                                         members.Add (b);
1870                                                 }
1871
1872                                                 b = p.SetBuilder;
1873                                                 if (b != null && filter (b, criteria) == true) {
1874                                                         if (members == null)
1875                                                                 members = new ArrayList ();
1876                                                         
1877                                                         members.Add (b);
1878                                                 }
1879                                         }
1880                                 }
1881                                 
1882                                 if (indexers != null) {
1883                                         int len = indexers.Count;
1884                                         for (int i = 0; i < len; i++) {
1885                                                 Indexer ix = (Indexer) indexers [i];
1886                                                 
1887                                                 if ((ix.ModFlags & modflags) == 0)
1888                                                         continue;
1889                                                 if ((ix.ModFlags & static_mask) != static_flags)
1890                                                         continue;
1891                                                 
1892                                                 MethodBuilder b;
1893
1894                                                 b = ix.GetBuilder;
1895                                                 if (b != null && filter (b, criteria) == true) {
1896                                                         if (members == null)
1897                                                                 members = new ArrayList ();
1898                                                         
1899                                                         members.Add (b);
1900                                                 }
1901
1902                                                 b = ix.SetBuilder;
1903                                                 if (b != null && filter (b, criteria) == true) {
1904                                                         if (members == null)
1905                                                                 members = new ArrayList ();
1906                                                         
1907                                                         members.Add (b);
1908                                                 }
1909                                         }
1910                                 }
1911                         }
1912
1913                         if ((mt & MemberTypes.Event) != 0) {
1914                                 if (events != null) {
1915                                         int len = events.Count;
1916                                         for (int i = 0; i < len; i++) {
1917                                                 Event e = (Event) events [i];
1918                                                 
1919                                                 if ((e.ModFlags & modflags) == 0)
1920                                                         continue;
1921                                                 if ((e.ModFlags & static_mask) != static_flags)
1922                                                         continue;
1923
1924                                                 MemberInfo eb = e.EventBuilder;
1925                                                 if (eb != null && filter (eb, criteria) == true) {
1926                                                         if (members == null)
1927                                                                 members = new ArrayList ();
1928                                                         
1929                                                         members.Add (e.EventBuilder);
1930                                                 }
1931                                         }
1932                                 }
1933                         }
1934                         
1935                         if ((mt & MemberTypes.Property) != 0){
1936                                 if (properties != null) {
1937                                         int len = properties.Count;
1938                                         for (int i = 0; i < len; i++) {
1939                                                 Property p = (Property) properties [i];
1940                                                 
1941                                                 if ((p.ModFlags & modflags) == 0)
1942                                                         continue;
1943                                                 if ((p.ModFlags & static_mask) != static_flags)
1944                                                         continue;
1945
1946                                                 MemberInfo pb = p.PropertyBuilder;
1947                                                 if (pb != null && filter (pb, criteria) == true) {
1948                                                         if (members == null)
1949                                                                 members = new ArrayList ();
1950                                                         
1951                                                         members.Add (p.PropertyBuilder);
1952                                                 }
1953                                         }
1954                                 }
1955
1956                                 if (indexers != null) {
1957                                         int len = indexers.Count;
1958                                         for (int i = 0; i < len; i++) {
1959                                                 Indexer ix = (Indexer) indexers [i];
1960                                                 
1961                                                 if ((ix.ModFlags & modflags) == 0)
1962                                                         continue;
1963                                                 if ((ix.ModFlags & static_mask) != static_flags)
1964                                                         continue;
1965
1966                                                 MemberInfo ib = ix.PropertyBuilder;
1967                                                 if (ib != null && filter (ib, criteria) == true) {
1968                                                         if (members == null)
1969                                                                 members = new ArrayList ();
1970                                                         
1971                                                         members.Add (ix.PropertyBuilder);
1972                                                 }
1973                                         }
1974                                 }
1975                         }
1976                         
1977                         if ((mt & MemberTypes.NestedType) != 0)
1978                                 FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
1979
1980                         if ((mt & MemberTypes.Constructor) != 0){
1981                                 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1982                                         int len = instance_constructors.Count;
1983                                         for (int i = 0; i < len; i++) {
1984                                                 Constructor c = (Constructor) instance_constructors [i];
1985                                                 
1986                                                 ConstructorBuilder cb = c.ConstructorBuilder;
1987                                                 if (cb != null && filter (cb, criteria) == true) {
1988                                                         if (members == null)
1989                                                                 members = new ArrayList ();
1990
1991                                                         members.Add (cb);
1992                                                 }
1993                                         }
1994                                 }
1995
1996                                 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1997                                         ConstructorBuilder cb =
1998                                                 default_static_constructor.ConstructorBuilder;
1999                                         
2000                                         if (cb != null && filter (cb, criteria) == true) {
2001                                                 if (members == null)
2002                                                         members = new ArrayList ();
2003                                                 
2004                                                 members.Add (cb);
2005                                         }
2006                                 }
2007                         }
2008
2009                         //
2010                         // Lookup members in base if requested.
2011                         //
2012                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
2013                                 if (TypeBuilder.BaseType != null) {
2014                                         MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
2015                                         if (list.Count > 0) {
2016                                                 if (members == null)
2017                                                         members = new ArrayList ();
2018                                         
2019                                                 members.AddRange (list);
2020                                         }
2021                                 }
2022                         }
2023
2024                         Timer.StopTimer (TimerType.TcFindMembers);
2025
2026                         if (members == null)
2027                                 return MemberList.Empty;
2028                         else
2029                                 return new MemberList (members);
2030                 }
2031
2032                 public override MemberCache MemberCache {
2033                         get {
2034                                 return member_cache;
2035                         }
2036                 }
2037
2038                 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
2039                                                       MemberFilter filter, object criteria)
2040                 {
2041                         DeclSpace ds = TypeManager.LookupDeclSpace (t);
2042
2043                         if (ds != null)
2044                                 return ds.FindMembers (mt, bf, filter, criteria);
2045                         else
2046                                 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
2047                 }
2048
2049                 /// <summary>
2050                 ///   Emits the values for the constants
2051                 /// </summary>
2052                 public void EmitConstants ()
2053                 {
2054                         if (constants != null)
2055                                 foreach (Const con in constants)
2056                                         con.Emit ();
2057                         return;
2058                 }
2059
2060                 void CheckMemberUsage (MemberCoreArrayList al, string member_type)
2061                 {
2062                         if (al == null)
2063                                 return;
2064
2065                         foreach (MemberCore mc in al) {
2066                                 if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2067                                         continue;
2068
2069                                 if (!mc.IsUsed && (mc.caching_flags & Flags.Excluded) == 0) {
2070                                         Report.Warning (169, 3, mc.Location, "The private {0} `{1}' is never used", member_type, mc.GetSignatureForError ());
2071                                 }
2072                         }
2073                 }
2074
2075                 public virtual void VerifyMembers ()
2076                 {
2077                         //
2078                         // Check for internal or private fields that were never assigned
2079                         //
2080                         if (Report.WarningLevel >= 3) {
2081                                 CheckMemberUsage (properties, "property");
2082                                 CheckMemberUsage (methods, "method");
2083                                 CheckMemberUsage (constants, "constant");
2084
2085                                 if (fields != null){
2086                                         bool is_type_exposed = Kind == Kind.Struct || IsExposedFromAssembly ();
2087                                         foreach (FieldBase f in fields) {
2088                                                 if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE) {
2089                                                         if (is_type_exposed)
2090                                                                 continue;
2091
2092                                                         f.SetMemberIsUsed ();
2093                                                 }                               
2094                                                 
2095                                                 if (!f.IsUsed){
2096                                                         if ((f.caching_flags & Flags.IsAssigned) == 0)
2097                                                                 Report.Warning (169, 3, f.Location, "The private field `{0}' is never used", f.GetSignatureForError ());
2098                                                         else {
2099                                                                 Report.Warning (414, 3, f.Location, "The private field `{0}' is assigned but its value is never used",
2100                                                                         f.GetSignatureForError ());
2101                                                         }
2102                                                         continue;
2103                                                 }
2104                                                 
2105                                                 //
2106                                                 // Only report 649 on level 4
2107                                                 //
2108                                                 if (Report.WarningLevel < 4)
2109                                                         continue;
2110                                                 
2111                                                 if ((f.caching_flags & Flags.IsAssigned) != 0)
2112                                                         continue;
2113
2114                                                 //
2115                                                 // Don't be pendatic over serializable attributes
2116                                                 //
2117                                                 if (f.OptAttributes != null || PartialContainer.HasStructLayout)
2118                                                         continue;
2119                                                 
2120                                                 Constant c = New.Constantify (f.MemberType);
2121                                                 Report.Warning (649, 4, f.Location, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2122                                                         f.GetSignatureForError (), c == null ? "null" : c.AsString ());
2123                                         }
2124                                 }
2125                         }
2126                 }
2127
2128                 // TODO: move to ClassOrStruct
2129                 void EmitConstructors ()
2130                 {
2131                         if (instance_constructors == null)
2132                                 return;
2133
2134                         if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsComplianceRequired ()) {
2135                                 bool has_compliant_args = false;
2136
2137                                 foreach (Constructor c in instance_constructors) {
2138                                         try {
2139                                                 c.Emit ();
2140                                         }
2141                                         catch (Exception e) {
2142                                                 throw new InternalErrorException (c, e);
2143                                         }
2144
2145                                         if (has_compliant_args)
2146                                                 continue;
2147
2148                                         has_compliant_args = c.HasCompliantArgs;
2149                                 }
2150                                 if (!has_compliant_args)
2151                                         Report.Warning (3015, 1, Location, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2152                         } else {
2153                                 foreach (Constructor c in instance_constructors) {
2154                                         try {
2155                                                 c.Emit ();
2156                                         }
2157                                         catch (Exception e) {
2158                                                 throw new InternalErrorException (c, e);
2159                                         }
2160                                 }
2161                         }
2162                 }
2163
2164                 /// <summary>
2165                 ///   Emits the code, this step is performed after all
2166                 ///   the types, enumerations, constructors
2167                 /// </summary>
2168                 public virtual void EmitType ()
2169                 {
2170                         if (OptAttributes != null)
2171                                 OptAttributes.Emit ();
2172
2173                         Emit ();
2174
2175                         EmitConstructors ();
2176
2177                         // Can not continue if constants are broken
2178                         EmitConstants ();
2179                         if (Report.Errors > 0)
2180                                 return;
2181
2182                         if (default_static_constructor != null)
2183                                 default_static_constructor.Emit ();
2184                         
2185                         if (operators != null)
2186                                 foreach (Operator o in operators)
2187                                         o.Emit ();
2188
2189                         if (properties != null)
2190                                 foreach (Property p in properties)
2191                                         p.Emit ();
2192
2193                         if (indexers != null) {
2194                                 foreach (Indexer indx in indexers)
2195                                         indx.Emit ();
2196                                 EmitIndexerName ();
2197                         }
2198
2199                         if (events != null){
2200                                 foreach (Event e in Events)
2201                                         e.Emit ();
2202                         }
2203
2204                         if (methods != null) {
2205                                 for (int i = 0; i < methods.Count; ++i)
2206                                         ((MethodOrOperator) methods [i]).Emit ();
2207                         }
2208                         
2209                         if (fields != null)
2210                                 foreach (FieldBase f in fields)
2211                                         f.Emit ();
2212
2213                         if (delegates != null) {
2214                                 foreach (Delegate d in Delegates) {
2215                                         d.Emit ();
2216                                 }
2217                         }
2218
2219                         if (pending != null)
2220                                 pending.VerifyPendingMethods (Report);
2221
2222                         if (Report.Errors > 0)
2223                                 return;
2224
2225                         if (compiler_generated != null) {
2226                                 for (int i = 0; i < compiler_generated.Count; ++i)
2227                                         ((CompilerGeneratedClass) compiler_generated [i]).EmitType ();
2228                         }
2229                 }
2230                 
2231                 public override void CloseType ()
2232                 {
2233                         if ((caching_flags & Flags.CloseTypeCreated) != 0)
2234                                 return;
2235
2236                         try {
2237                                 caching_flags |= Flags.CloseTypeCreated;
2238                                 TypeBuilder.CreateType ();
2239                         } catch (TypeLoadException){
2240                                 //
2241                                 // This is fine, the code still created the type
2242                                 //
2243 //                              Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2244 //                              Console.WriteLine (e.Message);
2245                         } catch (Exception e) {
2246                                 throw new InternalErrorException (this, e);
2247                         }
2248                         
2249                         if (Types != null){
2250                                 foreach (TypeContainer tc in Types)
2251                                         if (tc.Kind == Kind.Struct)
2252                                                 tc.CloseType ();
2253
2254                                 foreach (TypeContainer tc in Types)
2255                                         if (tc.Kind != Kind.Struct)
2256                                                 tc.CloseType ();
2257                         }
2258
2259                         if (Delegates != null)
2260                                 foreach (Delegate d in Delegates)
2261                                         d.CloseType ();
2262
2263                         if (compiler_generated != null)
2264                                 foreach (CompilerGeneratedClass c in compiler_generated)
2265                                         c.CloseType ();
2266                         
2267                         PartialContainer = null;
2268                         types = null;
2269                         properties = null;
2270                         delegates = null;
2271                         fields = null;
2272                         initialized_fields = null;
2273                         initialized_static_fields = null;
2274                         constants = null;
2275                         ordered_explicit_member_list = null;
2276                         ordered_member_list = null;
2277                         methods = null;
2278                         events = null;
2279                         indexers = null;
2280                         operators = null;
2281                         compiler_generated = null;
2282                         default_constructor = null;
2283                         default_static_constructor = null;
2284                         type_bases = null;
2285                         OptAttributes = null;
2286                         ifaces = null;
2287                         base_cache = null;
2288                         member_cache = null;
2289                 }
2290
2291                 //
2292                 // Performs the validation on a Method's modifiers (properties have
2293                 // the same properties).
2294                 //
2295                 public bool MethodModifiersValid (MemberCore mc)
2296                 {
2297                         const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
2298                         const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
2299                         const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
2300                         bool ok = true;
2301                         int flags = mc.ModFlags;
2302                         
2303                         //
2304                         // At most one of static, virtual or override
2305                         //
2306                         if ((flags & Modifiers.STATIC) != 0){
2307                                 if ((flags & vao) != 0){
2308                                         Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract",
2309                                                 mc.GetSignatureForError ());
2310                                         ok = false;
2311                                 }
2312                         }
2313
2314                         if (Kind == Kind.Struct){
2315                                 if ((flags & va) != 0){
2316                                         Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract", Report);
2317                                         ok = false;
2318                                 }
2319                         }
2320
2321                         if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
2322                                 Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual",
2323                                         mc.GetSignatureForError ());
2324                                 ok = false;
2325                         }
2326
2327                         //
2328                         // If the declaration includes the abstract modifier, then the
2329                         // declaration does not include static, virtual or extern
2330                         //
2331                         if ((flags & Modifiers.ABSTRACT) != 0){
2332                                 if ((flags & Modifiers.EXTERN) != 0){
2333                                         Report.Error (
2334                                                 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ());
2335                                         ok = false;
2336                                 }
2337
2338                                 if ((flags & Modifiers.SEALED) != 0) {
2339                                         Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ());
2340                                         ok = false;
2341                                 }
2342
2343                                 if ((flags & Modifiers.VIRTUAL) != 0){
2344                                         Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ());
2345                                         ok = false;
2346                                 }
2347
2348                                 if ((ModFlags & Modifiers.ABSTRACT) == 0){
2349                                         Report.SymbolRelatedToPreviousError (this);
2350                                         Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2351                                                 mc.GetSignatureForError (), GetSignatureForError ());
2352                                         ok = false;
2353                                 }
2354                         }
2355
2356                         if ((flags & Modifiers.PRIVATE) != 0){
2357                                 if ((flags & vao) != 0){
2358                                         Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ());
2359                                         ok = false;
2360                                 }
2361                         }
2362
2363                         if ((flags & Modifiers.SEALED) != 0){
2364                                 if ((flags & Modifiers.OVERRIDE) == 0){
2365                                         Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ());
2366                                         ok = false;
2367                                 }
2368                         }
2369
2370                         return ok;
2371                 }
2372
2373                 public Constructor DefaultStaticConstructor {
2374                         get { return default_static_constructor; }
2375                 }
2376
2377                 protected override bool VerifyClsCompliance ()
2378                 {
2379                         if (!base.VerifyClsCompliance ())
2380                                 return false;
2381
2382                         VerifyClsName ();
2383
2384                         Type base_type = TypeBuilder.BaseType;
2385                         if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
2386                                 Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
2387                         }
2388                         return true;
2389                 }
2390
2391
2392                 /// <summary>
2393                 /// Checks whether container name is CLS Compliant
2394                 /// </summary>
2395                 void VerifyClsName ()
2396                 {
2397                         Hashtable base_members = base_cache == null ? 
2398                                 new Hashtable () :
2399                                 base_cache.GetPublicMembers ();
2400                         Hashtable this_members = new Hashtable ();
2401
2402                         foreach (DictionaryEntry entry in defined_names) {
2403                                 MemberCore mc = (MemberCore)entry.Value;
2404                                 if (!mc.IsClsComplianceRequired ())
2405                                         continue;
2406
2407                                 string name = (string) entry.Key;
2408                                 string basename = name.Substring (name.LastIndexOf ('.') + 1);
2409
2410                                 string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
2411                                 object found = base_members [lcase];
2412                                 if (found == null) {
2413                                         found = this_members [lcase];
2414                                         if (found == null) {
2415                                                 this_members.Add (lcase, mc);
2416                                                 continue;
2417                                         }
2418                                 }
2419
2420                                 if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
2421                                         continue;                                       
2422
2423                                 if (found is MemberInfo) {
2424                                         if (basename == ((MemberInfo) found).Name)
2425                                                 continue;
2426                                         Report.SymbolRelatedToPreviousError ((MemberInfo) found);
2427                                 } else {
2428                                         Report.SymbolRelatedToPreviousError ((MemberCore) found);
2429                                 }
2430
2431                                 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2432                         }
2433                 }
2434
2435
2436                 /// <summary>
2437                 ///   Performs checks for an explicit interface implementation.  First it
2438                 ///   checks whether the `interface_type' is a base inteface implementation.
2439                 ///   Then it checks whether `name' exists in the interface type.
2440                 /// </summary>
2441                 public bool VerifyImplements (InterfaceMemberBase mb)
2442                 {
2443                         if (ifaces != null) {
2444                                 foreach (Type t in ifaces){
2445                                         if (TypeManager.IsEqual (t, mb.InterfaceType))
2446                                                 return true;
2447                                 }
2448                         }
2449                         
2450                         Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2451                         Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2452                                 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2453                         return false;
2454                 }
2455
2456                 public override Type LookupAnyGeneric (string typeName)
2457                 {
2458                         if (types != null) {
2459                                 foreach (TypeContainer tc in types) {
2460                                         if (!tc.IsGeneric)
2461                                                 continue;
2462
2463                                         int pos = tc.Basename.LastIndexOf ('`');
2464                                         if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
2465                                                 return tc.TypeBuilder;
2466                                 }
2467                         }
2468
2469                         return base.LookupAnyGeneric (typeName);
2470                 }
2471
2472                 public void Mark_HasEquals ()
2473                 {
2474                         cached_method |= CachedMethods.Equals;
2475                 }
2476
2477                 public void Mark_HasGetHashCode ()
2478                 {
2479                         cached_method |= CachedMethods.GetHashCode;
2480                 }
2481
2482                 /// <summary>
2483                 /// Method container contains Equals method
2484                 /// </summary>
2485                 public bool HasEquals {
2486                         get {
2487                                 return (cached_method & CachedMethods.Equals) != 0;
2488                         }
2489                 }
2490  
2491                 /// <summary>
2492                 /// Method container contains GetHashCode method
2493                 /// </summary>
2494                 public bool HasGetHashCode {
2495                         get {
2496                                 return (cached_method & CachedMethods.GetHashCode) != 0;
2497                         }
2498                 }
2499
2500                 public bool HasStaticFieldInitializer {
2501                         get {
2502                                 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2503                         }
2504                         set {
2505                                 if (value)
2506                                         cached_method |= CachedMethods.HasStaticFieldInitializer;
2507                                 else
2508                                         cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2509                         }
2510                 }
2511
2512                 //
2513                 // IMemberContainer
2514                 //
2515
2516                 string IMemberContainer.Name {
2517                         get {
2518                                 return Name;
2519                         }
2520                 }
2521
2522                 Type IMemberContainer.Type {
2523                         get {
2524                                 return TypeBuilder;
2525                         }
2526                 }
2527
2528                 bool IMemberContainer.IsInterface {
2529                         get {
2530                                 return Kind == Kind.Interface;
2531                         }
2532                 }
2533
2534                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2535                 {
2536                         BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2537
2538                         if (GenericType != null)
2539                                 return TypeManager.FindMembers (GenericType, mt, new_bf,
2540                                                                 null, null);
2541                         else
2542                                 return FindMembers (mt, new_bf, null, null);
2543                 }
2544
2545                 //
2546                 // Generates xml doc comments (if any), and if required,
2547                 // handle warning report.
2548                 //
2549                 internal override void GenerateDocComment (DeclSpace ds)
2550                 {
2551                         DocUtil.GenerateTypeDocComment (this, ds, Report);
2552                 }
2553
2554                 public override string DocCommentHeader {
2555                         get { return "T:"; }
2556                 }
2557
2558                 public MemberCache BaseCache {
2559                         get {
2560                                 if (base_cache != null)
2561                                         return base_cache;
2562                                 if (TypeBuilder.BaseType != null)
2563                                         base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2564                                 if (TypeBuilder.IsInterface)
2565                                         base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2566                                 return base_cache;
2567                         }
2568                 }
2569         }
2570
2571         public abstract class ClassOrStruct : TypeContainer {
2572                 ListDictionary declarative_security;
2573
2574                 public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
2575                                       MemberName name, Attributes attrs, Kind kind)
2576                         : base (ns, parent, name, attrs, kind)
2577                 {
2578                 }
2579
2580                 protected override bool AddToContainer (MemberCore symbol, string name)
2581                 {
2582                         if (name == MemberName.Name) {
2583                                 if (symbol is TypeParameter) {
2584                                         Report.Error (694, symbol.Location,
2585                                                 "Type parameter `{0}' has same name as containing type, or method",
2586                                                 symbol.GetSignatureForError ());
2587                                         return false;
2588                                 }
2589
2590                                 InterfaceMemberBase imb = symbol as InterfaceMemberBase;
2591                                 if (imb == null || !imb.IsExplicitImpl) {
2592                                         Report.SymbolRelatedToPreviousError (this);
2593                                         Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2594                                                 symbol.GetSignatureForError ());
2595                                         return false;
2596                                 }
2597                         }
2598
2599                         return base.AddToContainer (symbol, name);
2600                 }
2601
2602                 public override void VerifyMembers ()
2603                 {
2604                         base.VerifyMembers ();
2605
2606                         if ((events != null) && Report.WarningLevel >= 3) {
2607                                 foreach (Event e in events){
2608                                         // Note: The event can be assigned from same class only, so we can report
2609                                         // this warning for all accessibility modes
2610                                         if ((e.caching_flags & Flags.IsUsed) == 0)
2611                                                 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2612                                 }
2613                         }
2614                 }
2615
2616                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
2617                 {
2618                         if (a.IsValidSecurityAttribute ()) {
2619                                 if (declarative_security == null)
2620                                         declarative_security = new ListDictionary ();
2621
2622                                 a.ExtractSecurityPermissionSet (declarative_security);
2623                                 return;
2624                         }
2625
2626                         if (a.Type == pa.StructLayout) {
2627                                 PartialContainer.HasStructLayout = true;
2628
2629                                 if (a.GetLayoutKindValue () == LayoutKind.Explicit)
2630                                         PartialContainer.HasExplicitLayout = true;
2631                         }
2632
2633                         base.ApplyAttributeBuilder (a, cb, pa);
2634                 }
2635
2636                 /// <summary>
2637                 /// Defines the default constructors 
2638                 /// </summary>
2639                 protected void DefineDefaultConstructor (bool is_static)
2640                 {
2641                         // The default instance constructor is public
2642                         // If the class is abstract, the default constructor is protected
2643                         // The default static constructor is private
2644
2645                         int mods;
2646                         if (is_static) {
2647                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2648                         } else {
2649                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2650                         }
2651
2652                         Constructor c = new Constructor (this, MemberName.Name, mods,
2653                                 null, ParametersCompiled.EmptyReadOnlyParameters,
2654                                 new GeneratedBaseInitializer (Location),
2655                                 Location);
2656                         
2657                         AddConstructor (c);
2658                         c.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
2659                 }
2660
2661                 public override bool Define ()
2662                 {
2663                         CheckProtectedModifier ();
2664
2665                         base.Define ();
2666
2667                         if (default_static_constructor != null)
2668                                 default_static_constructor.Define ();
2669
2670                         return true;
2671                 }
2672
2673                 public override void Emit ()
2674                 {
2675                         if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer) {
2676                                 DefineDefaultConstructor (true);
2677                                 default_static_constructor.Define ();
2678                         }
2679
2680                         base.Emit ();
2681
2682                         if (declarative_security != null) {
2683                                 foreach (DictionaryEntry de in declarative_security) {
2684                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2685                                 }
2686                         }
2687                 }
2688
2689                 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
2690                 {
2691                         DeclSpace top_level = Parent;
2692                         if (top_level != null) {
2693                                 while (top_level.Parent != null)
2694                                         top_level = top_level.Parent;
2695
2696                                 ArrayList candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name);
2697                                 if (candidates != null)
2698                                         return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
2699                         }
2700
2701                         return NamespaceEntry.LookupExtensionMethod (extensionType, name, loc);
2702                 }
2703
2704                 protected override TypeAttributes TypeAttr {
2705                         get {
2706                                 if (default_static_constructor == null)
2707                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2708
2709                                 return base.TypeAttr;
2710                         }
2711                 }
2712         }
2713
2714
2715         // TODO: should be sealed
2716         public class Class : ClassOrStruct {
2717                 const int AllowedModifiers =
2718                         Modifiers.NEW |
2719                         Modifiers.PUBLIC |
2720                         Modifiers.PROTECTED |
2721                         Modifiers.INTERNAL |
2722                         Modifiers.PRIVATE |
2723                         Modifiers.ABSTRACT |
2724                         Modifiers.SEALED |
2725                         Modifiers.STATIC |
2726                         Modifiers.UNSAFE;
2727
2728                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2729
2730                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2731                               Attributes attrs)
2732                         : base (ns, parent, name, attrs, Kind.Class)
2733                 {
2734                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2735                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location, Report);
2736
2737                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2738                                 Report.FeatureIsNotAvailable (Location, "static classes");
2739                         }
2740                 }
2741
2742                 public override void AddBasesForPart (DeclSpace part, ArrayList bases)
2743                 {
2744                         if (part.Name == "System.Object")
2745                                 Report.Error (537, part.Location,
2746                                         "The class System.Object cannot have a base class or implement an interface.");
2747                         base.AddBasesForPart (part, bases);
2748                 }
2749
2750                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
2751                 {
2752                         if (a.Type == pa.AttributeUsage) {
2753                                 if (!TypeManager.IsAttributeType (BaseType) &&
2754                                         TypeBuilder.FullName != "System.Attribute") {
2755                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2756                                 }
2757                         }
2758
2759                         if (a.Type == pa.Conditional && !TypeManager.IsAttributeType (BaseType)) {
2760                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2761                                 return;
2762                         }
2763
2764                         if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
2765                                 a.Error_MissingGuidAttribute ();
2766                                 return;
2767                         }
2768
2769                         if (a.Type == pa.Extension) {
2770                                 a.Error_MisusedExtensionAttribute ();
2771                                 return;
2772                         }
2773
2774                         if (AttributeTester.IsAttributeExcluded (a.Type, Location))
2775                                 return;
2776
2777                         base.ApplyAttributeBuilder (a, cb, pa);
2778                 }
2779
2780                 public override AttributeTargets AttributeTargets {
2781                         get {
2782                                 return AttributeTargets.Class;
2783                         }
2784                 }
2785
2786                 protected override void DefineContainerMembers (MemberCoreArrayList list)
2787                 {
2788                         if (list == null)
2789                                 return;
2790
2791                         if (!IsStatic) {
2792                                 base.DefineContainerMembers (list);
2793                                 return;
2794                         }
2795
2796                         foreach (MemberCore m in list) {
2797                                 if (m is Operator) {
2798                                         Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2799                                         continue;
2800                                 }
2801
2802                                 if (m is Destructor) {
2803                                         Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2804                                         continue;
2805                                 }
2806
2807                                 if (m is Indexer) {
2808                                         Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2809                                         continue;
2810                                 }
2811
2812                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2813                                         continue;
2814
2815                                 if (m is Constructor) {
2816                                         Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2817                                         continue;
2818                                 }
2819
2820                                 Method method = m as Method;
2821                                 if (method != null && method.Parameters.HasExtensionMethodType) {
2822                                         Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
2823                                         continue;
2824                                 }
2825
2826                                 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2827                         }
2828
2829                         base.DefineContainerMembers (list);
2830                 }
2831
2832                 public override bool Define ()
2833                 {
2834                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2835                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2836                         }
2837
2838                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2839                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2840                         }
2841
2842                         return base.Define ();
2843                 }
2844
2845                 protected override bool DoDefineMembers ()
2846                 {
2847                         if (InstanceConstructors == null && !IsStatic)
2848                                 DefineDefaultConstructor (false);
2849
2850                         return base.DoDefineMembers ();
2851                 }
2852
2853                 public override void Emit ()
2854                 {
2855                         base.Emit ();
2856
2857                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2858                                 PredefinedAttributes.Get.Extension.EmitAttribute (TypeBuilder);
2859                 }
2860
2861                 protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
2862                 {
2863                         TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
2864
2865                         if (base_class == null) {
2866                                 if (RootContext.StdLib)
2867                                         base_class = TypeManager.system_object_expr;
2868                                 else if (Name != "System.Object")
2869                                         base_class = TypeManager.system_object_expr;
2870                         } else {
2871                                 if (Kind == Kind.Class && TypeManager.IsGenericParameter (base_class.Type)){
2872                                         Report.Error (
2873                                                 689, base_class.Location,
2874                                                 "Cannot derive from `{0}' because it is a type parameter",
2875                                                 base_class.GetSignatureForError ());
2876                                         return ifaces;
2877                                 }
2878
2879                                 if (IsGeneric && TypeManager.IsAttributeType (base_class.Type)) {
2880                                         Report.Error (698, base_class.Location,
2881                                                 "A generic type cannot derive from `{0}' because it is an attribute class",
2882                                                 base_class.GetSignatureForError ());
2883                                 }
2884
2885                                 if (base_class.IsSealed){
2886                                         Report.SymbolRelatedToPreviousError (base_class.Type);
2887                                         if (base_class.Type.IsAbstract) {
2888                                                 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2889                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
2890                                         } else {
2891                                                 Report.Error (509, Location, "`{0}': cannot derive from sealed type `{1}'",
2892                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
2893                                         }
2894                                         return ifaces;
2895                                 }
2896
2897                                 if (!base_class.CanInheritFrom ()){
2898                                         Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2899                                                 GetSignatureForError (), base_class.GetSignatureForError ());
2900                                         return ifaces;
2901                                 }
2902
2903                                 if (!IsAccessibleAs (base_class.Type)) {
2904                                         Report.SymbolRelatedToPreviousError (base_class.Type);
2905                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
2906                                                 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
2907                                 }
2908                         }
2909
2910                         if (PartialContainer.IsStaticClass) {
2911                                 if (base_class.Type != TypeManager.object_type) {
2912                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2913                                                 GetSignatureForError (), base_class.GetSignatureForError ());
2914                                         return ifaces;
2915                                 }
2916
2917                                 if (ifaces != null) {
2918                                         foreach (TypeExpr t in ifaces)
2919                                                 Report.SymbolRelatedToPreviousError (t.Type);
2920                                         Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2921                                 }
2922                         }
2923
2924                         return ifaces;
2925                 }
2926
2927                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2928                 /// Valid only for attribute classes.
2929                 public bool IsExcluded ()
2930                 {
2931                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
2932                                 return (caching_flags & Flags.Excluded) != 0;
2933
2934                         caching_flags &= ~Flags.Excluded_Undetected;
2935
2936                         if (OptAttributes == null)
2937                                 return false;
2938
2939                         Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
2940                         if (attrs == null)
2941                                 return false;
2942
2943                         foreach (Attribute a in attrs) {
2944                                 string condition = a.GetConditionalAttributeValue ();
2945                                 if (Location.CompilationUnit.IsConditionalDefined (condition))
2946                                         return false;
2947                         }
2948
2949                         caching_flags |= Flags.Excluded;
2950                         return true;
2951                 }
2952
2953                 //
2954                 // FIXME: How do we deal with the user specifying a different
2955                 // layout?
2956                 //
2957                 protected override TypeAttributes TypeAttr {
2958                         get {
2959                                 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2960                                 if (IsStatic)
2961                                         ta |= StaticClassAttribute;
2962                                 return ta;
2963                         }
2964                 }
2965         }
2966
2967         public sealed class Struct : ClassOrStruct {
2968
2969                 bool is_unmanaged, has_unmanaged_check_done;
2970
2971                 // <summary>
2972                 //   Modifiers allowed in a struct declaration
2973                 // </summary>
2974                 const int AllowedModifiers =
2975                         Modifiers.NEW       |
2976                         Modifiers.PUBLIC    |
2977                         Modifiers.PROTECTED |
2978                         Modifiers.INTERNAL  |
2979                         Modifiers.UNSAFE    |
2980                         Modifiers.PRIVATE;
2981
2982                 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
2983                                int mod, Attributes attrs)
2984                         : base (ns, parent, name, attrs, Kind.Struct)
2985                 {
2986                         int accmods;
2987                         
2988                         if (parent.Parent == null)
2989                                 accmods = Modifiers.INTERNAL;
2990                         else
2991                                 accmods = Modifiers.PRIVATE;
2992                         
2993                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location, Report);
2994
2995                         this.ModFlags |= Modifiers.SEALED;
2996                 }
2997
2998                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
2999                 {
3000                         base.ApplyAttributeBuilder (a, cb, pa);
3001
3002                         //
3003                         // When struct constains fixed fixed and struct layout has explicitly
3004                         // set CharSet, its value has to be propagated to compiler generated
3005                         // fixed field types
3006                         //
3007                         if (a.Type == pa.StructLayout && Fields != null && a.HasField ("CharSet")) {
3008                                 for (int i = 0; i < Fields.Count; ++i) {
3009                                         FixedField ff = Fields [i] as FixedField;
3010                                         if (ff != null)
3011                                                 ff.SetCharSet (TypeBuilder.Attributes);
3012                                 }
3013                         }
3014                 }
3015
3016                 public override AttributeTargets AttributeTargets {
3017                         get {
3018                                 return AttributeTargets.Struct;
3019                         }
3020                 }
3021
3022                 public override bool IsUnmanagedType ()
3023                 {
3024                         if (fields == null)
3025                                 return true;
3026
3027                         if (requires_delayed_unmanagedtype_check)
3028                                 return true;
3029
3030                         if (has_unmanaged_check_done)
3031                                 return is_unmanaged;
3032
3033                         has_unmanaged_check_done = true;
3034
3035                         foreach (FieldBase f in fields) {
3036                                 if ((f.ModFlags & Modifiers.STATIC) != 0)
3037                                         continue;
3038
3039                                 // It can happen when recursive unmanaged types are defined
3040                                 // struct S { S* s; }
3041                                 Type mt = f.MemberType;
3042                                 if (mt == null) {
3043                                         has_unmanaged_check_done = false;
3044                                         requires_delayed_unmanagedtype_check = true;
3045                                         return true;
3046                                 }
3047
3048                                 // TODO: Remove when pointer types are under mcs control
3049                                 while (mt.IsPointer)
3050                                         mt = TypeManager.GetElementType (mt);
3051                                 if (TypeManager.IsEqual (mt, TypeBuilder))
3052                                         continue;
3053
3054                                 if (TypeManager.IsUnmanagedType (mt))
3055                                         continue;
3056
3057                                 return false;
3058                         }
3059
3060                         is_unmanaged = true;
3061                         return true;
3062                 }
3063
3064                 protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class)
3065                 {
3066                         TypeExpr[] ifaces = base.ResolveBaseTypes (out base_class);
3067                         //
3068                         // If we are compiling our runtime,
3069                         // and we are defining ValueType, then our
3070                         // base is `System.Object'.
3071                         //
3072                         if (base_class == null) {
3073                                 if (!RootContext.StdLib && Name == "System.ValueType")
3074                                         base_class = TypeManager.system_object_expr;
3075                                 else
3076                                         base_class = TypeManager.system_valuetype_expr;
3077                         }
3078
3079                         return ifaces;
3080                 }
3081
3082                 //
3083                 // FIXME: Allow the user to specify a different set of attributes
3084                 // in some cases (Sealed for example is mandatory for a class,
3085                 // but what SequentialLayout can be changed
3086                 //
3087                 protected override TypeAttributes TypeAttr {
3088                         get {
3089                                 const TypeAttributes DefaultTypeAttributes =
3090                                         TypeAttributes.SequentialLayout |
3091                                         TypeAttributes.Sealed;
3092
3093                                 return base.TypeAttr | DefaultTypeAttributes;
3094                         }
3095                 }
3096
3097                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3098                 {
3099                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3100                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3101                                         field.GetSignatureForError ());
3102                                 return;
3103                         }
3104                         base.RegisterFieldForInitialization (field, expression);
3105                 }
3106
3107         }
3108
3109         /// <summary>
3110         ///   Interfaces
3111         /// </summary>
3112         public sealed class Interface : TypeContainer, IMemberContainer {
3113
3114                 /// <summary>
3115                 ///   Modifiers allowed in a class declaration
3116                 /// </summary>
3117                 public const int AllowedModifiers =
3118                         Modifiers.NEW       |
3119                         Modifiers.PUBLIC    |
3120                         Modifiers.PROTECTED |
3121                         Modifiers.INTERNAL  |
3122                         Modifiers.UNSAFE    |
3123                         Modifiers.PRIVATE;
3124
3125                 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
3126                                   Attributes attrs)
3127                         : base (ns, parent, name, attrs, Kind.Interface)
3128                 {
3129                         int accmods;
3130
3131                         if (parent.Parent == null)
3132                                 accmods = Modifiers.INTERNAL;
3133                         else
3134                                 accmods = Modifiers.PRIVATE;
3135
3136                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location, Report);
3137                 }
3138
3139                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
3140                 {
3141                         if (a.Type == pa.ComImport && !attributes.Contains (pa.Guid)) {
3142                                 a.Error_MissingGuidAttribute ();
3143                                 return;
3144                         }
3145
3146                         base.ApplyAttributeBuilder (a, cb, pa);
3147                 }
3148
3149
3150                 public override AttributeTargets AttributeTargets {
3151                         get {
3152                                 return AttributeTargets.Interface;
3153                         }
3154                 }
3155
3156                 protected override TypeAttributes TypeAttr {
3157                         get {
3158                                 const TypeAttributes DefaultTypeAttributes =
3159                                         TypeAttributes.AutoLayout |
3160                                         TypeAttributes.Abstract |
3161                                         TypeAttributes.Interface;
3162
3163                                 return base.TypeAttr | DefaultTypeAttributes;
3164                         }
3165                 }
3166
3167                 protected override bool VerifyClsCompliance ()
3168                 {
3169                         if (!base.VerifyClsCompliance ())
3170                                 return false;
3171
3172                         if (ifaces != null) {
3173                                 foreach (Type t in ifaces) {
3174                                         if (AttributeTester.IsClsCompliant (t))
3175                                                 continue;
3176
3177                                         Report.SymbolRelatedToPreviousError (t);
3178                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3179                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3180                                 }
3181                         }
3182
3183                         return true;
3184                 }
3185         }
3186
3187         // It is used as a base class for all property based members
3188         // This includes properties, indexers, and events
3189         public abstract class PropertyBasedMember : InterfaceMemberBase
3190         {
3191                 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3192                         FullNamedExpression type, int mod, int allowed_mod,
3193                         MemberName name, Attributes attrs)
3194                         : base (parent, generic, type, mod, allowed_mod, name, attrs)
3195                 {
3196                 }
3197
3198                 protected override bool VerifyClsCompliance ()
3199                 {
3200                         if (!base.VerifyClsCompliance ())
3201                                 return false;
3202
3203                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3204                                 Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
3205                                         GetSignatureForError ());
3206                         }
3207                         return true;
3208                 }
3209
3210         }
3211
3212
3213         public abstract class MethodCore : InterfaceMemberBase
3214         {
3215                 public readonly ParametersCompiled Parameters;
3216                 protected ToplevelBlock block;
3217
3218                 public MethodCore (DeclSpace parent, GenericMethod generic,
3219                         FullNamedExpression type, int mod, int allowed_mod,
3220                         MemberName name, Attributes attrs, ParametersCompiled parameters)
3221                         : base (parent, generic, type, mod, allowed_mod, name, attrs)
3222                 {
3223                         Parameters = parameters;
3224                 }
3225
3226                 //
3227                 //  Returns the System.Type array for the parameters of this method
3228                 //
3229                 public Type [] ParameterTypes {
3230                         get {
3231                                 return Parameters.Types;
3232                         }
3233                 }
3234
3235                 public ParametersCompiled ParameterInfo {
3236                         get {
3237                                 return Parameters;
3238                         }
3239                 }
3240                 
3241                 public ToplevelBlock Block {
3242                         get {
3243                                 return block;
3244                         }
3245
3246                         set {
3247                                 block = value;
3248                         }
3249                 }
3250
3251                 public CallingConventions CallingConventions {
3252                         get {
3253                                 CallingConventions cc = Parameters.CallingConvention;
3254                                 if (!IsInterface)
3255                                         if ((ModFlags & Modifiers.STATIC) == 0)
3256                                                 cc |= CallingConventions.HasThis;
3257
3258                                 // FIXME: How is `ExplicitThis' used in C#?
3259                         
3260                                 return cc;
3261                         }
3262                 }
3263
3264                 protected override bool CheckBase ()
3265                 {
3266                         // Check whether arguments were correct.
3267                         if (!DefineParameters (Parameters))
3268                                 return false;
3269
3270                         return base.CheckBase ();
3271                 }
3272
3273                 //
3274                 // Returns a string that represents the signature for this 
3275                 // member which should be used in XML documentation.
3276                 //
3277                 public override string GetDocCommentName (DeclSpace ds)
3278                 {
3279                         return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
3280                 }
3281
3282                 //
3283                 // Raised (and passed an XmlElement that contains the comment)
3284                 // when GenerateDocComment is writing documentation expectedly.
3285                 //
3286                 // FIXME: with a few effort, it could be done with XmlReader,
3287                 // that means removal of DOM use.
3288                 //
3289                 internal override void OnGenerateDocComment (XmlElement el)
3290                 {
3291                         DocUtil.OnMethodGenerateDocComment (this, el, Report);
3292                 }
3293
3294                 //
3295                 //   Represents header string for documentation comment.
3296                 //
3297                 public override string DocCommentHeader 
3298                 {
3299                         get { return "M:"; }
3300                 }
3301
3302                 public override bool EnableOverloadChecks (MemberCore overload)
3303                 {
3304                         if (overload is MethodCore || overload is AbstractPropertyEventMethod) {
3305                                 caching_flags |= Flags.MethodOverloadsExist;
3306                                 return true;
3307                         }
3308
3309                         return base.EnableOverloadChecks (overload);
3310                 }
3311
3312                 protected override bool VerifyClsCompliance ()
3313                 {
3314                         if (!base.VerifyClsCompliance ())
3315                                 return false;
3316
3317                         if (Parameters.HasArglist) {
3318                                 Report.Warning (3000, 1, Location, "Methods with variable arguments are not CLS-compliant");
3319                         }
3320
3321                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3322                                 Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
3323                                         GetSignatureForError ());
3324                         }
3325
3326                         Parameters.VerifyClsCompliance ();
3327                         return true;
3328                 }
3329
3330         }
3331
3332         public abstract class InterfaceMemberBase : MemberBase {
3333                 //
3334                 // Whether this is an interface member.
3335                 //
3336                 public bool IsInterface;
3337
3338                 //
3339                 // If true, this is an explicit interface implementation
3340                 //
3341                 public bool IsExplicitImpl;
3342
3343                 protected bool is_external_implementation;
3344
3345                 //
3346                 // The interface type we are explicitly implementing
3347                 //
3348                 public Type InterfaceType;
3349
3350                 //
3351                 // The method we're overriding if this is an override method.
3352                 //
3353                 protected MethodInfo base_method;
3354
3355                 readonly int explicit_mod_flags;
3356                 public MethodAttributes flags;
3357
3358                 public InterfaceMemberBase (DeclSpace parent, GenericMethod generic,
3359                                    FullNamedExpression type, int mod, int allowed_mod,
3360                                    MemberName name, Attributes attrs)
3361                         : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3362                                 name, attrs)
3363                 {
3364                         IsInterface = parent.PartialContainer.Kind == Kind.Interface;
3365                         IsExplicitImpl = (MemberName.Left != null);
3366                         explicit_mod_flags = mod;
3367                 }
3368                 
3369                 protected override bool CheckBase ()
3370                 {
3371                         if (!base.CheckBase ())
3372                                 return false;
3373
3374                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
3375                                 CheckForDuplications ();
3376                         
3377                         if (IsExplicitImpl)
3378                                 return true;
3379
3380                         // Is null for System.Object while compiling corlib and base interfaces
3381                         if (Parent.PartialContainer.BaseCache == null) {
3382                                 if ((ModFlags & Modifiers.NEW) != 0) {
3383                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3384                                 }
3385                                 return true;
3386                         }
3387
3388                         Type base_ret_type = null;
3389                         base_method = FindOutBaseMethod (ref base_ret_type);
3390
3391                         // method is override
3392                         if (base_method != null) {
3393                                 if (!CheckMethodAgainstBase (base_ret_type))
3394                                         return false;
3395
3396                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3397                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3398                                         if (oa != null) {
3399                                                 if (OptAttributes == null || !OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
3400                                                         Report.SymbolRelatedToPreviousError (base_method);
3401                                                                 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3402                                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3403                                                 }
3404                                         } else {
3405                                                 if (OptAttributes != null && OptAttributes.Contains (PredefinedAttributes.Get.Obsolete)) {
3406                                                         Report.SymbolRelatedToPreviousError (base_method);
3407                                                         Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3408                                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3409                                                 }
3410                                         }
3411                                 }
3412                                 return true;
3413                         }
3414
3415                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
3416                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3417                                 if (conflict_symbol != null) {
3418                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3419                                         if (this is Event)
3420                                                 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3421                                         else if (this is PropertyBase)
3422                                                 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3423                                         else
3424                                                 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3425                                 } else {
3426                                         Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3427                                                 GetSignatureForError (), SimpleName.GetMemberType (this));
3428                                 }
3429                                 return false;
3430                         }
3431
3432                         if (conflict_symbol == null) {
3433                                 if ((ModFlags & Modifiers.NEW) != 0) {
3434                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3435                                 }
3436                                 return true;
3437                         }
3438
3439                         if ((ModFlags & Modifiers.NEW) == 0) {
3440                                 if (this is MethodOrOperator && conflict_symbol.MemberType == MemberTypes.Method)
3441                                         return true;
3442
3443                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3444                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3445                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3446                         }
3447
3448                         return true;
3449                 }
3450
3451                 protected virtual bool CheckForDuplications ()
3452                 {
3453                         return Parent.MemberCache.CheckExistingMembersOverloads (
3454                                 this, GetFullName (MemberName), ParametersCompiled.EmptyReadOnlyParameters, Report);
3455                 }
3456
3457                 //
3458                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3459                 // that have been defined.
3460                 //
3461                 // `name' is the user visible name for reporting errors (this is used to
3462                 // provide the right name regarding method names and properties)
3463                 //
3464                 bool CheckMethodAgainstBase (Type base_method_type)
3465                 {
3466                         bool ok = true;
3467
3468                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3469                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3470                                         Report.SymbolRelatedToPreviousError (base_method);
3471                                         Report.Error (506, Location,
3472                                                 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3473                                                  GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3474                                         ok = false;
3475                                 }
3476                                 
3477                                 // Now we check that the overriden method is not final
3478                                 
3479                                 if (base_method.IsFinal) {
3480                                         Report.SymbolRelatedToPreviousError (base_method);
3481                                         Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3482                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3483                                         ok = false;
3484                                 }
3485                                 //
3486                                 // Check that the permissions are not being changed
3487                                 //
3488                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3489                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3490
3491                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3492                                         Error_CannotChangeAccessModifiers (Location, base_method, base_classp, null);
3493                                         ok = false;
3494                                 }
3495
3496                                 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_method_type))) {
3497                                         Report.SymbolRelatedToPreviousError (base_method);
3498                                         if (this is PropertyBasedMember) {
3499                                                 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
3500                                                         GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
3501                                         }
3502                                         else {
3503                                                 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3504                                                         GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
3505                                         }
3506                                         ok = false;
3507                                 }
3508                         }
3509
3510                         if ((ModFlags & Modifiers.NEW) == 0) {
3511                                 if ((ModFlags & Modifiers.OVERRIDE) == 0) {
3512                                         ModFlags |= Modifiers.NEW;
3513                                         Report.SymbolRelatedToPreviousError (base_method);
3514                                         if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3515                                                 Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3516                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3517                                                 if (base_method.IsAbstract){
3518                                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3519                                                                       GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3520                                                         ok = false;
3521                                                 }
3522                                         } else {
3523                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3524                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3525                                         }
3526                                 }
3527                         } else {
3528                                 if (base_method.IsAbstract && !IsInterface) {
3529                                         Report.SymbolRelatedToPreviousError (base_method);
3530                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3531                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3532                                         return ok = false;
3533                                 }
3534                         }
3535
3536                         return ok;
3537                 }
3538                 
3539                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3540                 {
3541                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3542                                 //
3543                                 // when overriding protected internal, the method can be declared
3544                                 // protected internal only within the same assembly or assembly
3545                                 // which has InternalsVisibleTo
3546                                 //
3547                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3548                                         return TypeManager.IsThisOrFriendAssembly (Parent.Module.Assembly, base_method.DeclaringType.Assembly);
3549                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3550                                         //
3551                                         // if it's not "protected internal", it must be "protected"
3552                                         //
3553
3554                                         return false;
3555                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3556                                         //
3557                                         // protected within the same assembly - an error
3558                                         //
3559                                         return false;
3560                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3561                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3562                                         //
3563                                         // protected ok, but other attributes differ - report an error
3564                                         //
3565                                         return false;
3566                                 }
3567                                 return true;
3568                         } else {
3569                                 return (thisp == base_classp);
3570                         }
3571                 }
3572
3573                 public override bool Define ()
3574                 {
3575                         if (IsInterface) {
3576                                 ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
3577                                         Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
3578
3579                                 flags = MethodAttributes.Public |
3580                                         MethodAttributes.Abstract |
3581                                         MethodAttributes.HideBySig |
3582                                         MethodAttributes.NewSlot |
3583                                         MethodAttributes.Virtual;
3584                         } else {
3585                                 Parent.PartialContainer.MethodModifiersValid (this);
3586
3587                                 flags = Modifiers.MethodAttr (ModFlags);
3588                         }
3589
3590                         if (IsExplicitImpl) {
3591                                 TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
3592                                 if (iface_texpr == null)
3593                                         return false;
3594
3595                                 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3596                                         Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3597                                                 GetSignatureForError ());
3598                                 }
3599
3600                                 InterfaceType = iface_texpr.Type;
3601
3602                                 if (!InterfaceType.IsInterface) {
3603                                         Report.SymbolRelatedToPreviousError (InterfaceType);
3604                                         Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
3605                                                 TypeManager.CSharpName (InterfaceType));
3606                                 } else {
3607                                         Parent.PartialContainer.VerifyImplements (this);
3608                                 }
3609
3610                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location, Report);
3611                         }
3612
3613                         return base.Define ();
3614                 }
3615
3616                 protected bool DefineParameters (ParametersCompiled parameters)
3617                 {
3618                         if (!parameters.Resolve (this))
3619                                 return false;
3620
3621                         bool error = false;
3622                         for (int i = 0; i < parameters.Count; ++i) {
3623                                 Parameter p = parameters [i];
3624
3625                                 if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1)))
3626                                         p.Warning_UselessOptionalParameter (Report);
3627
3628                                 if (p.CheckAccessibility (this))
3629                                         continue;
3630
3631                                 Type t = parameters.Types [i];
3632                                 Report.SymbolRelatedToPreviousError (t);
3633                                 if (this is Indexer)
3634                                         Report.Error (55, Location,
3635                                                       "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3636                                                       TypeManager.CSharpName (t), GetSignatureForError ());
3637                                 else if (this is Operator)
3638                                         Report.Error (57, Location,
3639                                                       "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3640                                                       TypeManager.CSharpName (t), GetSignatureForError ());
3641                                 else
3642                                         Report.Error (51, Location,
3643                                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3644                                                 TypeManager.CSharpName (t), GetSignatureForError ());
3645                                 error = true;
3646                         }
3647                         return !error;
3648                 }
3649
3650                 public override void Emit()
3651                 {
3652                         // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3653                         // We are more strict than csc and report this as an error because SRE does not allow emit that
3654                         if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
3655                                 if (this is Constructor) {
3656                                         Report.Error (824, Location,
3657                                                 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3658                                 } else {
3659                                         Report.Error (626, Location,
3660                                                 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3661                                                 GetSignatureForError ());
3662                                 }
3663                         }
3664
3665                         base.Emit ();
3666                 }
3667
3668                 public override bool EnableOverloadChecks (MemberCore overload)
3669                 {
3670                         //
3671                         // Two members can differ in their explicit interface
3672                         // type parameter only
3673                         //
3674                         InterfaceMemberBase imb = overload as InterfaceMemberBase;
3675                         if (imb != null && imb.IsExplicitImpl) {
3676                                 if (IsExplicitImpl) {
3677                                         caching_flags |= Flags.MethodOverloadsExist;
3678                                 }
3679                                 return true;
3680                         }
3681
3682                         return IsExplicitImpl;
3683                 }
3684
3685                 protected void Error_CannotChangeAccessModifiers (Location loc, MemberInfo base_method, MethodAttributes ma, string suffix)
3686                 {
3687                         Report.SymbolRelatedToPreviousError (base_method);
3688                         string base_name = TypeManager.GetFullNameSignature (base_method);
3689                         string this_name = GetSignatureForError ();
3690                         if (suffix != null) {
3691                                 base_name += suffix;
3692                                 this_name += suffix;
3693                         }
3694
3695                         Report.Error (507, loc, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3696                                 this_name, Modifiers.GetDescription (ma), base_name);
3697                 }
3698
3699                 protected static string Error722 {
3700                         get {
3701                                 return "`{0}': static types cannot be used as return types";
3702                         }
3703                 }
3704
3705                 /// <summary>
3706                 /// Gets base method and its return type
3707                 /// </summary>
3708                 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3709
3710                 //
3711                 // The "short" name of this property / indexer / event.  This is the
3712                 // name without the explicit interface.
3713                 //
3714                 public string ShortName 
3715                 {
3716                         get { return MemberName.Name; }
3717                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3718                 }
3719                 
3720                 //
3721                 // Returns full metadata method name
3722                 //
3723                 public string GetFullName (MemberName name)
3724                 {
3725                         if (!IsExplicitImpl)
3726                                 return name.Name;
3727
3728                         //
3729                         // When dealing with explicit members a full interface type
3730                         // name is added to member name to avoid possible name conflicts
3731                         //
3732                         // We use CSharpName which gets us full name with benefit of
3733                         // replacing predefined names which saves some space and name
3734                         // is still unique
3735                         //
3736                         return TypeManager.CSharpName (InterfaceType) + "." + name.Name;
3737                 }
3738
3739                 protected override bool VerifyClsCompliance ()
3740                 {
3741                         if (!base.VerifyClsCompliance ()) {
3742                                 if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
3743                                         Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3744                                 }
3745
3746                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3747                                         Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3748                                 }
3749                                 return false;
3750                         }
3751
3752                         if (GenericMethod != null)
3753                                 GenericMethod.VerifyClsCompliance ();
3754
3755                         return true;
3756                 }
3757
3758                 public override bool IsUsed 
3759                 {
3760                         get { return IsExplicitImpl || base.IsUsed; }
3761                 }
3762
3763         }
3764
3765         public abstract class MethodOrOperator : MethodCore, IMethodData
3766         {
3767                 public MethodBuilder MethodBuilder;
3768                 ReturnParameter return_attributes;
3769                 ListDictionary declarative_security;
3770                 protected MethodData MethodData;
3771
3772                 static string[] attribute_targets = new string [] { "method", "return" };
3773
3774                 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, FullNamedExpression type, int mod,
3775                                 int allowed_mod, MemberName name,
3776                                 Attributes attrs, ParametersCompiled parameters)
3777                         : base (parent, generic, type, mod, allowed_mod, name,
3778                                         attrs, parameters)
3779                 {
3780                 }
3781
3782                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
3783                 {
3784                         if (a.Target == AttributeTargets.ReturnValue) {
3785                                 if (return_attributes == null)
3786                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
3787
3788                                 return_attributes.ApplyAttributeBuilder (a, cb, pa);
3789                                 return;
3790                         }
3791
3792                         if (a.IsInternalMethodImplAttribute) {
3793                                 is_external_implementation = true;
3794                         }
3795
3796                         if (a.Type == pa.DllImport) {
3797                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3798                                 if ((ModFlags & extern_static) != extern_static) {
3799                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3800                                 }
3801                                 is_external_implementation = true;
3802                         }
3803
3804                         if (a.IsValidSecurityAttribute ()) {
3805                                 if (declarative_security == null)
3806                                         declarative_security = new ListDictionary ();
3807                                 a.ExtractSecurityPermissionSet (declarative_security);
3808                                 return;
3809                         }
3810
3811                         if (MethodBuilder != null)
3812                                 MethodBuilder.SetCustomAttribute (cb);
3813                 }
3814
3815                 public override AttributeTargets AttributeTargets {
3816                         get {
3817                                 return AttributeTargets.Method; 
3818                         }
3819                 }
3820
3821                 protected override bool CheckForDuplications ()
3822                 {
3823                         string name = GetFullName (MemberName);
3824                         if (MemberName.IsGeneric)
3825                                 name = MemberName.MakeName (name, MemberName.TypeArguments);
3826
3827                         return Parent.MemberCache.CheckExistingMembersOverloads (this, name, Parameters, Report);
3828                 }
3829
3830                 public virtual EmitContext CreateEmitContext (ILGenerator ig)
3831                 {
3832                         return new EmitContext (
3833                                 this, ig, MemberType);
3834                 }
3835
3836                 protected override bool ResolveMemberType ()
3837                 {
3838                         if (GenericMethod != null) {
3839                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
3840                                 if (!GenericMethod.Define (this))
3841                                         return false;
3842                         }
3843
3844                         return base.ResolveMemberType ();
3845                 }
3846
3847                 public override bool Define ()
3848                 {
3849                         if (!base.Define ())
3850                                 return false;
3851
3852                         if (!CheckBase ())
3853                                 return false;
3854
3855                         if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
3856                                 //
3857                                 // Current method is turned into automatically generated
3858                                 // wrapper which creates an instance of iterator
3859                                 //
3860                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
3861                                 ModFlags |= Modifiers.DEBUGGER_HIDDEN;
3862                         }
3863
3864                         if (IsPartialDefinition) {
3865                                 caching_flags &= ~Flags.Excluded_Undetected;
3866                                 caching_flags |= Flags.Excluded;
3867                                 // Add to member cache only when a partial method implementation is not there
3868                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0) {
3869                                         MethodBase mb = new PartialMethodDefinitionInfo (this);
3870                                         Parent.MemberCache.AddMember (mb, this);
3871                                         TypeManager.AddMethod (mb, this);
3872                                 }
3873
3874                                 return true;
3875                         }
3876
3877                         MethodData = new MethodData (
3878                                 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
3879
3880                         if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName), Report))
3881                                 return false;
3882                                         
3883                         MethodBuilder = MethodData.MethodBuilder;
3884
3885                         if (TypeManager.IsGenericMethod (MethodBuilder))
3886                                 Parent.MemberCache.AddGenericMember (MethodBuilder, this);
3887                         
3888                         Parent.MemberCache.AddMember (MethodBuilder, this);
3889
3890                         return true;
3891                 }
3892
3893                 protected override void DoMemberTypeIndependentChecks ()
3894                 {
3895                         base.DoMemberTypeIndependentChecks ();
3896
3897                         CheckAbstractAndExtern (block != null);
3898
3899                         if ((ModFlags & Modifiers.PARTIAL) != 0) {
3900                                 for (int i = 0; i < Parameters.Count; ++i) {
3901                                         IParameterData p = Parameters.FixedParameters [i];
3902                                         if (p.ModFlags == Parameter.Modifier.OUT) {
3903                                                 Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
3904                                                         GetSignatureForError ());
3905                                         }
3906
3907                                         if (p.HasDefaultValue && IsPartialImplementation)
3908                                                 ((Parameter) p).Warning_UselessOptionalParameter (Report);
3909                                 }
3910                         }
3911                 }
3912
3913                 protected override void DoMemberTypeDependentChecks ()
3914                 {
3915                         base.DoMemberTypeDependentChecks ();
3916
3917                         if (!TypeManager.IsGenericParameter (MemberType)) {
3918                                 if (MemberType.IsAbstract && MemberType.IsSealed) {
3919                                         Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3920                                 }
3921                         }
3922                 }
3923
3924                 public override void Emit ()
3925                 {
3926                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
3927                                 PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (MethodBuilder);
3928                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
3929                                 PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder);
3930
3931                         if (TypeManager.IsDynamicType (ReturnType)) {
3932                                 return_attributes = new ReturnParameter (MethodBuilder, Location);
3933                                 return_attributes.EmitPredefined (PredefinedAttributes.Get.Dynamic, Location);
3934                         }
3935
3936                         if (OptAttributes != null)
3937                                 OptAttributes.Emit ();
3938
3939                         if (declarative_security != null) {
3940                                 foreach (DictionaryEntry de in declarative_security) {
3941                                         MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3942                                 }
3943                         }
3944
3945                         if (MethodData != null)
3946                                 MethodData.Emit (Parent);
3947
3948                         base.Emit ();
3949
3950                         Block = null;
3951                         MethodData = null;
3952                 }
3953
3954                 protected void Error_ConditionalAttributeIsNotValid ()
3955                 {
3956                         Report.Error (577, Location,
3957                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
3958                                 GetSignatureForError ());
3959                 }
3960
3961                 public bool IsPartialDefinition {
3962                         get {
3963                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
3964                         }
3965                 }
3966
3967                 public bool IsPartialImplementation {
3968                         get {
3969                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
3970                         }
3971                 }
3972
3973                 public override string[] ValidAttributeTargets {
3974                         get {
3975                                 return attribute_targets;
3976                         }
3977                 }
3978
3979                 #region IMethodData Members
3980
3981                 public Type ReturnType {
3982                         get {
3983                                 return MemberType;
3984                         }
3985                 }
3986
3987                 public MemberName MethodName {
3988                         get {
3989                                 return MemberName;
3990                         }
3991                 }
3992
3993                 /// <summary>
3994                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3995                 /// </summary>
3996                 public bool IsExcluded () {
3997                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3998                                 return (caching_flags & Flags.Excluded) != 0;
3999
4000                         caching_flags &= ~Flags.Excluded_Undetected;
4001
4002                         if (base_method == null) {
4003                                 if (OptAttributes == null)
4004                                         return false;
4005
4006                                 Attribute[] attrs = OptAttributes.SearchMulti (PredefinedAttributes.Get.Conditional);
4007
4008                                 if (attrs == null)
4009                                         return false;
4010
4011                                 foreach (Attribute a in attrs) {
4012                                         string condition = a.GetConditionalAttributeValue ();
4013                                         if (condition == null)
4014                                                 return false;
4015
4016                                         if (Location.CompilationUnit.IsConditionalDefined (condition))
4017                                                 return false;
4018                                 }
4019
4020                                 caching_flags |= Flags.Excluded;
4021                                 return true;
4022                         }
4023
4024                         IMethodData md = TypeManager.GetMethod (TypeManager.DropGenericMethodArguments (base_method));
4025                         if (md == null) {
4026                                 if (AttributeTester.IsConditionalMethodExcluded (base_method, Location)) {
4027                                         caching_flags |= Flags.Excluded;
4028                                         return true;
4029                                 }
4030                                 return false;
4031                         }
4032
4033                         if (md.IsExcluded ()) {
4034                                 caching_flags |= Flags.Excluded;
4035                                 return true;
4036                         }
4037                         return false;
4038                 }
4039
4040                 GenericMethod IMethodData.GenericMethod {
4041                         get {
4042                                 return GenericMethod;
4043                         }
4044                 }
4045
4046                 public virtual void EmitExtraSymbolInfo (SourceMethod source)
4047                 { }
4048
4049                 #endregion
4050
4051         }
4052
4053         public class SourceMethod : IMethodDef
4054         {
4055                 MethodBase method;
4056                 SourceMethodBuilder builder;
4057
4058                 protected SourceMethod (DeclSpace parent, MethodBase method, ICompileUnit file)
4059                 {
4060                         this.method = method;
4061                         
4062                         builder = SymbolWriter.OpenMethod (file, parent.NamespaceEntry.SymbolFileID, this);
4063                 }
4064
4065                 public string Name {
4066                         get { return method.Name; }
4067                 }
4068
4069                 public int Token {
4070                         get {
4071                                 if (method is MethodBuilder)
4072                                         return ((MethodBuilder) method).GetToken ().Token;
4073                                 else if (method is ConstructorBuilder)
4074                                         return ((ConstructorBuilder) method).GetToken ().Token;
4075                                 else
4076                                         throw new NotSupportedException ();
4077                         }
4078                 }
4079
4080                 public void CloseMethod ()
4081                 {
4082                         SymbolWriter.CloseMethod ();
4083                 }
4084
4085                 public void SetRealMethodName (string name)
4086                 {
4087                         if (builder != null)
4088                                 builder.SetRealMethodName (name);
4089                 }
4090
4091                 public static SourceMethod Create (DeclSpace parent, MethodBase method, Block block)
4092                 {
4093                         if (!SymbolWriter.HasSymbolWriter)
4094                                 return null;
4095                         if (block == null)
4096                                 return null;
4097
4098                         Location start_loc = block.StartLocation;
4099                         if (start_loc.IsNull)
4100                                 return null;
4101
4102                         ICompileUnit compile_unit = start_loc.CompilationUnit;
4103                         if (compile_unit == null)
4104                                 return null;
4105
4106                         return new SourceMethod (parent, method, compile_unit);
4107                 }
4108         }
4109
4110         public class Method : MethodOrOperator {
4111
4112                 /// <summary>
4113                 ///   Modifiers allowed in a class declaration
4114                 /// </summary>
4115                 const int AllowedModifiers =
4116                         Modifiers.NEW |
4117                         Modifiers.PUBLIC |
4118                         Modifiers.PROTECTED |
4119                         Modifiers.INTERNAL |
4120                         Modifiers.PRIVATE |
4121                         Modifiers.STATIC |
4122                         Modifiers.VIRTUAL |
4123                         Modifiers.SEALED |
4124                         Modifiers.OVERRIDE |
4125                         Modifiers.ABSTRACT |
4126                         Modifiers.UNSAFE |
4127                         Modifiers.EXTERN;
4128
4129                 const int AllowedInterfaceModifiers =
4130                         Modifiers.NEW | Modifiers.UNSAFE;
4131
4132                 Method partialMethodImplementation;
4133
4134                 public Method (DeclSpace parent, GenericMethod generic,
4135                                FullNamedExpression return_type, int mod,
4136                                MemberName name, ParametersCompiled parameters, Attributes attrs)
4137                         : base (parent, generic, return_type, mod,
4138                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
4139                                 name, attrs, parameters)
4140                 {
4141                 }
4142
4143                 protected Method (DeclSpace parent, FullNamedExpression return_type, int mod, int amod,
4144                                         MemberName name, ParametersCompiled parameters, Attributes attrs)
4145                         : base (parent, null, return_type, mod, amod, name, attrs, parameters)
4146                 {
4147                 }
4148                 
4149                 public override string GetSignatureForError()
4150                 {
4151                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4152                 }
4153
4154                 void Error_DuplicateEntryPoint (Method b)
4155                 {
4156                         Report.Error (17, b.Location,
4157                                 "Program `{0}' has more than one entry point defined: `{1}'",
4158                                 CodeGen.FileName, b.GetSignatureForError ());
4159                 }
4160
4161                 bool IsEntryPoint ()
4162                 {
4163                         if (ReturnType != TypeManager.void_type &&
4164                                 ReturnType != TypeManager.int32_type)
4165                                 return false;
4166
4167                         if (Parameters.Count == 0)
4168                                 return true;
4169
4170                         if (Parameters.Count > 1)
4171                                 return false;
4172
4173                         Type t = Parameters.Types [0];
4174                         return t.IsArray && t.GetArrayRank () == 1 &&
4175                                         TypeManager.GetElementType (t) == TypeManager.string_type &&
4176                                         (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
4177                 }
4178
4179                 public override FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104)
4180                 {
4181                         TypeParameter[] tp = CurrentTypeParameters;
4182                         if (tp != null) {
4183                                 TypeParameter t = TypeParameter.FindTypeParameter (tp, name);
4184                                 if (t != null)
4185                                         return new TypeParameterExpr (t, loc);
4186                         }
4187
4188                         return base.LookupNamespaceOrType (name, loc, ignore_cs0104);
4189                 }
4190
4191                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4192                 {
4193                         if (a.Type == pa.Conditional) {
4194                                 if (IsExplicitImpl) {
4195                                         Error_ConditionalAttributeIsNotValid ();
4196                                         return;
4197                                 }
4198
4199                                 if (ReturnType != TypeManager.void_type) {
4200                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4201                                         return;
4202                                 }
4203
4204                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4205                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4206                                         return;
4207                                 }
4208
4209                                 if (IsInterface) {
4210                                         Report.Error (582, Location, "Conditional not valid on interface members");
4211                                         return;
4212                                 }
4213
4214                                 if (MethodData.implementing != null) {
4215                                         Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
4216                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4217                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4218                                         return;
4219                                 }
4220
4221                                 for (int i = 0; i < Parameters.Count; ++i) {
4222                                         if (Parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
4223                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4224                                                 return;
4225                                         }
4226                                 }
4227                         }
4228
4229                         if (a.Type == pa.Extension) {
4230                                 a.Error_MisusedExtensionAttribute ();
4231                                 return;
4232                         }
4233
4234                         base.ApplyAttributeBuilder (a, cb, pa);
4235                 }
4236
4237                 protected override bool CheckForDuplications ()
4238                 {
4239                         if (!base.CheckForDuplications ())
4240                                 return false;
4241
4242                         ArrayList ar = Parent.PartialContainer.Properties;
4243                         if (ar != null) {
4244                                 for (int i = 0; i < ar.Count; ++i) {
4245                                         PropertyBase pb = (PropertyBase) ar [i];
4246                                         if (pb.AreAccessorsDuplicateImplementation (this))
4247                                                 return false;
4248                                 }
4249                         }
4250
4251                         ar = Parent.PartialContainer.Indexers;
4252                         if (ar != null) {
4253                                 for (int i = 0; i < ar.Count; ++i) {
4254                                         PropertyBase pb = (PropertyBase) ar [i];
4255                                         if (pb.AreAccessorsDuplicateImplementation (this))
4256                                                 return false;
4257                                 }
4258                         }
4259
4260                         return true;
4261                 }
4262
4263                 protected override bool CheckBase ()
4264                 {
4265                         if (!base.CheckBase ())
4266                                 return false;
4267
4268                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == Destructor.MetadataName) {
4269                                 Report.Error (249, Location, "Do not override `{0}'. Use destructor syntax instead",
4270                                         TypeManager.CSharpSignature (base_method));
4271                         }
4272
4273                         return true;
4274                 }
4275
4276                 public override TypeParameter[] CurrentTypeParameters {
4277                         get {
4278                                 if (GenericMethod != null)
4279                                         return GenericMethod.CurrentTypeParameters;
4280
4281                                 return null;
4282                         }
4283                 }
4284
4285                 //
4286                 // Creates the type
4287                 //
4288                 public override bool Define ()
4289                 {
4290                         if (type_name == TypeManager.system_void_expr && Parameters.IsEmpty && Name == Destructor.MetadataName) {
4291                                 Report.Warning (465, 1, Location, "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4292                         }
4293
4294                         if (!base.Define ())
4295                                 return false;
4296
4297                         if (partialMethodImplementation != null && IsPartialDefinition)
4298                                 MethodBuilder = partialMethodImplementation.MethodBuilder;
4299
4300                         if (RootContext.StdLib && TypeManager.IsSpecialType (ReturnType)) {
4301                                 Error1599 (Location, ReturnType, Report);
4302                                 return false;
4303                         }
4304
4305                         if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
4306                                 if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
4307                                         Parent.PartialContainer.Mark_HasEquals ();
4308                                 else if (Parameters.IsEmpty && Name == "GetHashCode")
4309                                         Parent.PartialContainer.Mark_HasGetHashCode ();
4310                         }
4311
4312                         if ((ModFlags & Modifiers.STATIC) == 0)
4313                                 return true;
4314
4315                         if (Parameters.HasExtensionMethodType) {
4316                                 if (Parent.PartialContainer.IsStaticClass && !Parent.IsGeneric) {
4317                                         if (!Parent.IsTopLevel)
4318                                                 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
4319                                                         GetSignatureForError ());
4320
4321                                         PredefinedAttribute pa = PredefinedAttributes.Get.Extension;
4322                                         if (!pa.IsDefined) {
4323                                                 Report.Error (1110, Location,
4324                                                         "`{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",
4325                                                         GetSignatureForError ());
4326                                         }
4327
4328                                         ModFlags |= Modifiers.METHOD_EXTENSION;
4329                                         Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
4330                                         CodeGen.Assembly.HasExtensionMethods = true;
4331                                 } else {
4332                                         Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
4333                                                 GetSignatureForError ());
4334                                 }
4335                         }
4336
4337                         //
4338                         // This is used to track the Entry Point,
4339                         //
4340                         if (RootContext.NeedsEntryPoint &&
4341                                 Name == "Main" &&
4342                                 (RootContext.MainClass == null ||
4343                                 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4344                                 if (IsEntryPoint ()) {
4345
4346                                         if (RootContext.EntryPoint == null) {
4347                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
4348                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
4349                                                                 GetSignatureForError ());
4350                                                 } else {
4351                                                         SetMemberIsUsed ();
4352                                                         RootContext.EntryPoint = this;
4353                                                 }
4354                                         } else {
4355                                                 Error_DuplicateEntryPoint (RootContext.EntryPoint);
4356                                                 Error_DuplicateEntryPoint (this);
4357                                         }
4358                                 } else {
4359                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
4360                                                 GetSignatureForError ());
4361                                 }
4362                         }
4363
4364                         return true;
4365                 }
4366
4367                 //
4368                 // Emits the code
4369                 // 
4370                 public override void Emit ()
4371                 {
4372                         try {
4373                                 Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4374                                 if (IsPartialDefinition) {
4375                                         //
4376                                         // Use partial method implementation builder for partial method declaration attributes
4377                                         //
4378                                         if (partialMethodImplementation != null) {
4379                                                 MethodBuilder = partialMethodImplementation.MethodBuilder;
4380                                                 return;
4381                                         }
4382                                 } else if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) {
4383                                         Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
4384                                                 GetSignatureForError ());
4385                                 }
4386
4387                                 base.Emit ();
4388                                 
4389                                 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
4390                                         PredefinedAttributes.Get.Extension.EmitAttribute (MethodBuilder);
4391                         } catch {
4392                                 Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
4393                                                    Location, MethodBuilder);
4394                                 throw;
4395                         }
4396                 }
4397
4398                 public override bool EnableOverloadChecks (MemberCore overload)
4399                 {
4400                         // TODO: It can be deleted when members will be defined in correct order
4401                         if (overload is Operator)
4402                                 return overload.EnableOverloadChecks (this);
4403
4404                         if (overload is Indexer)
4405                                 return false;
4406
4407                         return base.EnableOverloadChecks (overload);
4408                 }
4409
4410                 public static void Error1599 (Location loc, Type t, Report Report)
4411                 {
4412                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4413                 }
4414
4415                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4416                 {
4417                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4418                                 Parent.TypeBuilder, Name, Parameters, GenericMethod, false);
4419
4420                         if (mi == null)
4421                                 return null;
4422
4423                         if (mi.IsSpecialName)
4424                                 return null;
4425
4426                         base_ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
4427                         return mi;
4428                 }
4429
4430                 public void SetPartialDefinition (Method methodDefinition)
4431                 {
4432                         caching_flags |= Flags.PartialDefinitionExists;
4433                         methodDefinition.partialMethodImplementation = this;
4434
4435                         for (int i = 0; i < methodDefinition.Parameters.Count; ++i ) {
4436                                 Parameters [i].DefaultValue = methodDefinition.Parameters [i].DefaultValue;
4437                         }
4438
4439                         if (methodDefinition.attributes == null)
4440                                 return;
4441
4442                         if (attributes == null) {
4443                                 attributes = methodDefinition.attributes;
4444                         } else {
4445                                 attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
4446                         }
4447                 }
4448
4449                 protected override bool VerifyClsCompliance ()
4450                 {
4451                         if (!base.VerifyClsCompliance ())
4452                                 return false;
4453
4454                         if (!Parameters.IsEmpty) {
4455                                 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4456                                 if (al.Count > 1)
4457                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder, Report);
4458                         }
4459
4460                         return true;
4461                 }
4462         }
4463
4464         public abstract class ConstructorInitializer : ExpressionStatement
4465         {
4466                 Arguments argument_list;
4467                 MethodGroupExpr base_constructor_group;
4468
4469                 public ConstructorInitializer (Arguments argument_list, Location loc)
4470                 {
4471                         this.argument_list = argument_list;
4472                         this.loc = loc;
4473                 }
4474
4475                 public Arguments Arguments {
4476                         get {
4477                                 return argument_list;
4478                         }
4479                 }
4480
4481                 public override Expression CreateExpressionTree (ResolveContext ec)
4482                 {
4483                         throw new NotSupportedException ("ET");
4484                 }
4485
4486                 public override Expression DoResolve (ResolveContext ec)
4487                 {
4488                         eclass = ExprClass.Value;
4489
4490                         // TODO: ec.GetSignatureForError ()
4491                         ConstructorBuilder caller_builder = ((Constructor) ec.MemberContext).ConstructorBuilder;
4492
4493                         if (argument_list != null) {
4494                                 bool dynamic;
4495
4496                                 //
4497                                 // Spec mandates that constructor initializer will not have `this' access
4498                                 //
4499                                 using (ec.Set (ResolveContext.Options.BaseInitializer)) {
4500                                         argument_list.Resolve (ec, out dynamic);
4501                                 }
4502
4503                                 if (dynamic) {
4504                                         SimpleName ctor = new SimpleName (ConstructorBuilder.ConstructorName, loc);
4505                                         return new DynamicInvocation (ctor, argument_list, loc).Resolve (ec) as ExpressionStatement;
4506                                 }
4507                         }
4508
4509                         type = ec.CurrentType;
4510                         if (this is ConstructorBaseInitializer) {
4511                                 if (ec.CurrentType.BaseType == null)
4512                                         return this;
4513
4514                                 type = ec.CurrentType.BaseType;
4515                                 if (TypeManager.IsStruct (ec.CurrentType)) {
4516                                         ec.Report.Error (522, loc,
4517                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4518                                         return this;
4519                                 }
4520                         } else {
4521                                 //
4522                                 // It is legal to have "this" initializers that take no arguments
4523                                 // in structs, they are just no-ops.
4524                                 //
4525                                 // struct D { public D (int a) : this () {}
4526                                 //
4527                                 if (TypeManager.IsStruct (ec.CurrentType) && argument_list == null)
4528                                         return this;                    
4529                         }
4530
4531                         base_constructor_group = MemberLookupFinal (
4532                                 ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor,
4533                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4534                                 loc) as MethodGroupExpr;
4535                         
4536                         if (base_constructor_group == null)
4537                                 return this;
4538                         
4539                         base_constructor_group = base_constructor_group.OverloadResolve (
4540                                 ec, ref argument_list, false, loc);
4541                         
4542                         if (base_constructor_group == null)
4543                                 return this;
4544
4545                         if (!ec.IsStatic)
4546                                 base_constructor_group.InstanceExpression = ec.GetThis (loc);
4547                         
4548                         ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group;
4549
4550                         if (base_ctor == caller_builder){
4551                                 ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4552                         }
4553                                                 
4554                         return this;
4555                 }
4556
4557                 public override void Emit (EmitContext ec)
4558                 {
4559                         // It can be null for static initializers
4560                         if (base_constructor_group == null)
4561                                 return;
4562                         
4563                         ec.Mark (loc);
4564
4565                         base_constructor_group.EmitCall (ec, argument_list);
4566                 }
4567
4568                 public override void EmitStatement (EmitContext ec)
4569                 {
4570                         Emit (ec);
4571                 }
4572         }
4573
4574         public class ConstructorBaseInitializer : ConstructorInitializer {
4575                 public ConstructorBaseInitializer (Arguments argument_list, Location l) :
4576                         base (argument_list, l)
4577                 {
4578                 }
4579         }
4580
4581         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4582                 public GeneratedBaseInitializer (Location loc):
4583                         base (null, loc)
4584                 {
4585                 }
4586         }
4587
4588         public class ConstructorThisInitializer : ConstructorInitializer {
4589                 public ConstructorThisInitializer (Arguments argument_list, Location l) :
4590                         base (argument_list, l)
4591                 {
4592                 }
4593         }
4594         
4595         public class Constructor : MethodCore, IMethodData {
4596                 public ConstructorBuilder ConstructorBuilder;
4597                 public ConstructorInitializer Initializer;
4598                 ListDictionary declarative_security;
4599                 bool has_compliant_args;
4600
4601                 // <summary>
4602                 //   Modifiers allowed for a constructor.
4603                 // </summary>
4604                 public const int AllowedModifiers =
4605                         Modifiers.PUBLIC |
4606                         Modifiers.PROTECTED |
4607                         Modifiers.INTERNAL |
4608                         Modifiers.STATIC |
4609                         Modifiers.UNSAFE |
4610                         Modifiers.EXTERN |              
4611                         Modifiers.PRIVATE;
4612
4613                 static readonly string[] attribute_targets = new string [] { "method" };
4614
4615                 //
4616                 // The spec claims that static is not permitted, but
4617                 // my very own code has static constructors.
4618                 //
4619                 public Constructor (DeclSpace parent, string name, int mod, Attributes attrs, ParametersCompiled args,
4620                                     ConstructorInitializer init, Location loc)
4621                         : base (parent, null, null, mod, AllowedModifiers,
4622                                 new MemberName (name, loc), attrs, args)
4623                 {
4624                         Initializer = init;
4625                 }
4626
4627                 public bool HasCompliantArgs {
4628                         get { return has_compliant_args; }
4629                 }
4630
4631                 public override AttributeTargets AttributeTargets {
4632                         get { return AttributeTargets.Constructor; }
4633                 }
4634
4635                 //
4636                 // Returns true if this is a default constructor
4637                 //
4638                 public bool IsDefault ()
4639                 {
4640                         if ((ModFlags & Modifiers.STATIC) != 0)
4641                                 return Parameters.IsEmpty;
4642                         
4643                         return Parameters.IsEmpty &&
4644                                         (Initializer is ConstructorBaseInitializer) &&
4645                                         (Initializer.Arguments == null);
4646                 }
4647
4648                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
4649                 {
4650                         if (a.IsValidSecurityAttribute ()) {
4651                                 if (declarative_security == null) {
4652                                         declarative_security = new ListDictionary ();
4653                                 }
4654                                 a.ExtractSecurityPermissionSet (declarative_security);
4655                                 return;
4656                         }
4657
4658                         if (a.IsInternalMethodImplAttribute) {
4659                                 is_external_implementation = true;
4660                         }
4661
4662                         ConstructorBuilder.SetCustomAttribute (cb);
4663                 }
4664
4665                 protected override bool CheckBase ()
4666                 {
4667                         if ((ModFlags & Modifiers.STATIC) != 0) {
4668                                 if (!Parameters.IsEmpty) {
4669                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4670                                                 GetSignatureForError ());
4671                                         return false;
4672                                 }
4673
4674                                 // the rest can be ignored
4675                                 return true;
4676                         }
4677
4678                         // Check whether arguments were correct.
4679                         if (!DefineParameters (Parameters))
4680                                 return false;
4681
4682                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
4683                                 Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorInfo.ConstructorName,
4684                                         Parameters, Report);
4685
4686                         if (Parent.PartialContainer.Kind == Kind.Struct) {
4687                                 if (Parameters.Count == 0) {
4688                                         Report.Error (568, Location, 
4689                                                 "Structs cannot contain explicit parameterless constructors");
4690                                         return false;
4691                                 }
4692                         }
4693
4694                         CheckProtectedModifier ();
4695                         
4696                         return true;
4697                 }
4698                 
4699                 //
4700                 // Creates the ConstructorBuilder
4701                 //
4702                 public override bool Define ()
4703                 {
4704                         if (ConstructorBuilder != null)
4705                                 return true;
4706
4707                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4708                                                MethodAttributes.SpecialName);
4709                         
4710                         if ((ModFlags & Modifiers.STATIC) != 0) {
4711                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4712                         } else {
4713                                 ca |= MethodAttributes.HideBySig;
4714
4715                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4716                                         ca |= MethodAttributes.Public;
4717                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4718                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4719                                                 ca |= MethodAttributes.FamORAssem;
4720                                         else 
4721                                                 ca |= MethodAttributes.Family;
4722                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4723                                         ca |= MethodAttributes.Assembly;
4724                                 else
4725                                         ca |= MethodAttributes.Private;
4726                         }
4727
4728                         if (!CheckAbstractAndExtern (block != null))
4729                                 return false;
4730                         
4731                         // Check if arguments were correct.
4732                         if (!CheckBase ())
4733                                 return false;
4734
4735                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4736                                 ca, CallingConventions,
4737                                 Parameters.GetEmitTypes ());
4738
4739                         if (Parent.PartialContainer.IsComImport) {
4740                                 if (!IsDefault ()) {
4741                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4742                                                 Parent.GetSignatureForError ());
4743                                 }
4744                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4745                         }
4746                         
4747                         Parent.MemberCache.AddMember (ConstructorBuilder, this);
4748                         TypeManager.AddMethod (ConstructorBuilder, this);
4749                         
4750                         // It's here only to report an error
4751                         if (block != null && block.IsIterator) {
4752                                 member_type = TypeManager.void_type;
4753                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
4754                         }
4755
4756                         return true;
4757                 }
4758
4759                 //
4760                 // Emits the code
4761                 //
4762                 public override void Emit ()
4763                 {
4764                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
4765                                 PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (ConstructorBuilder);
4766
4767                         if (OptAttributes != null)
4768                                 OptAttributes.Emit ();
4769
4770                         base.Emit ();
4771
4772                         //
4773                         // If we use a "this (...)" constructor initializer, then
4774                         // do not emit field initializers, they are initialized in the other constructor
4775                         //
4776                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
4777                                 !(Initializer is ConstructorThisInitializer);
4778
4779                         BlockContext bc = new BlockContext (this, block, TypeManager.void_type);
4780                         bc.Set (ResolveContext.Options.ConstructorScope);
4781
4782                         if (emit_field_initializers)
4783                                 Parent.PartialContainer.ResolveFieldInitializers (bc);
4784
4785                         if (block != null) {
4786                                 // If this is a non-static `struct' constructor and doesn't have any
4787                                 // initializer, it must initialize all of the struct's fields.
4788                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4789                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4790                                         block.AddThisVariable (Parent, Location);
4791
4792                                 if (block != null && (ModFlags & Modifiers.STATIC) == 0){
4793                                         if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4794                                                 Initializer = new GeneratedBaseInitializer (Location);
4795
4796                                         if (Initializer != null) {
4797                                                 block.AddScopeStatement (new StatementExpression (Initializer));
4798                                         }
4799                                 }
4800                         }
4801
4802                         Parameters.ApplyAttributes (ConstructorBuilder);
4803
4804                         SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
4805
4806                         if (block != null) {
4807                                 if (block.Resolve (null, bc, Parameters, this)) {
4808                                         EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType);
4809                                         ec.With (EmitContext.Options.ConstructorScope, true);
4810
4811                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
4812                                                 ec.ReturnLabel = bc.ReturnLabel;
4813                                                 ec.HasReturnLabel = true;
4814                                         }
4815
4816                                         block.Emit (ec);
4817                                 }
4818                         }
4819
4820                         if (source != null)
4821                                 source.CloseMethod ();
4822
4823                         if (declarative_security != null) {
4824                                 foreach (DictionaryEntry de in declarative_security) {
4825                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4826                                 }
4827                         }
4828
4829                         block = null;
4830                 }
4831
4832                 // Is never override
4833                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4834                 {
4835                         return null;
4836                 }
4837
4838                 public override string GetSignatureForError()
4839                 {
4840                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4841                 }
4842
4843                 public override string[] ValidAttributeTargets {
4844                         get {
4845                                 return attribute_targets;
4846                         }
4847                 }
4848
4849                 protected override bool VerifyClsCompliance ()
4850                 {
4851                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4852                                 return false;
4853                         }
4854                         
4855                         if (!Parameters.IsEmpty) {
4856                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [ConstructorInfo.ConstructorName];
4857                                 if (al.Count > 2)
4858                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder, Report);
4859  
4860                                 if (TypeManager.IsSubclassOf (Parent.TypeBuilder, TypeManager.attribute_type)) {
4861                                         foreach (Type param in Parameters.Types) {
4862                                                 if (param.IsArray) {
4863                                                         return true;
4864                                                 }
4865                                         }
4866                                 }
4867                         }
4868                         has_compliant_args = true;
4869                         return true;
4870                 }
4871
4872                 #region IMethodData Members
4873
4874                 public MemberName MethodName {
4875                         get {
4876                                 return MemberName;
4877                         }
4878                 }
4879
4880                 public Type ReturnType {
4881                         get {
4882                                 return MemberType;
4883                         }
4884                 }
4885
4886                 public EmitContext CreateEmitContext (ILGenerator ig)
4887                 {
4888                         throw new NotImplementedException ();
4889                 }
4890
4891                 public bool IsExcluded()
4892                 {
4893                         return false;
4894                 }
4895
4896                 GenericMethod IMethodData.GenericMethod {
4897                         get {
4898                                 return null;
4899                         }
4900                 }
4901
4902                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
4903                 { }
4904
4905                 #endregion
4906         }
4907
4908         /// <summary>
4909         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4910         /// </summary>
4911         public interface IMethodData
4912         {
4913                 CallingConventions CallingConventions { get; }
4914                 Location Location { get; }
4915                 MemberName MethodName { get; }
4916                 Type ReturnType { get; }
4917                 GenericMethod GenericMethod { get; }
4918                 ParametersCompiled ParameterInfo { get; }
4919
4920                 Attributes OptAttributes { get; }
4921                 ToplevelBlock Block { get; set; }
4922
4923                 EmitContext CreateEmitContext (ILGenerator ig);
4924                 ObsoleteAttribute GetObsoleteAttribute ();
4925                 string GetSignatureForError ();
4926                 bool IsExcluded ();
4927                 bool IsClsComplianceRequired ();
4928                 void SetMemberIsUsed ();
4929                 void EmitExtraSymbolInfo (SourceMethod source);
4930         }
4931
4932         //
4933         // Encapsulates most of the Method's state
4934         //
4935         public class MethodData {
4936                 static FieldInfo methodbuilder_attrs_field;
4937                 public readonly IMethodData method;
4938
4939                 public readonly GenericMethod GenericMethod;
4940
4941                 //
4942                 // Are we implementing an interface ?
4943                 //
4944                 public MethodInfo implementing;
4945
4946                 //
4947                 // Protected data.
4948                 //
4949                 protected InterfaceMemberBase member;
4950                 protected int modifiers;
4951                 protected MethodAttributes flags;
4952                 protected Type declaring_type;
4953                 protected MethodInfo parent_method;
4954
4955                 MethodBuilder builder = null;
4956                 public MethodBuilder MethodBuilder {
4957                         get {
4958                                 return builder;
4959                         }
4960                 }
4961
4962                 public Type DeclaringType {
4963                         get {
4964                                 return declaring_type;
4965                         }
4966                 }
4967
4968                 public MethodData (InterfaceMemberBase member,
4969                                    int modifiers, MethodAttributes flags, IMethodData method)
4970                 {
4971                         this.member = member;
4972                         this.modifiers = modifiers;
4973                         this.flags = flags;
4974
4975                         this.method = method;
4976                 }
4977
4978                 public MethodData (InterfaceMemberBase member, 
4979                                    int modifiers, MethodAttributes flags, 
4980                                    IMethodData method, MethodBuilder builder,
4981                                    GenericMethod generic, MethodInfo parent_method)
4982                         : this (member, modifiers, flags, method)
4983                 {
4984                         this.builder = builder;
4985                         this.GenericMethod = generic;
4986                         this.parent_method = parent_method;
4987                 }
4988
4989                 public bool Define (DeclSpace parent, string method_full_name, Report Report)
4990                 {
4991                         string name = method.MethodName.Basename;
4992
4993                         TypeContainer container = parent.PartialContainer;
4994
4995                         PendingImplementation pending = container.PendingImplementations;
4996                         if (pending != null){
4997                                 implementing = pending.IsInterfaceMethod (name, member.InterfaceType, this);
4998
4999                                 if (member.InterfaceType != null){
5000                                         if (implementing == null){
5001                                                 if (member is PropertyBase) {
5002                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5003                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5004                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5005
5006                                                 } else {
5007                                                         Report.Error (539, method.Location,
5008                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5009                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5010                                                 }
5011                                                 return false;
5012                                         }
5013                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5014                                                 Report.SymbolRelatedToPreviousError (implementing);
5015                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5016                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5017                                                 return false;
5018                                         }
5019                                 } else {
5020                                         if (implementing != null) {
5021                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5022                                                 if (prop_method == null) {
5023                                                         if (TypeManager.IsSpecialMethod (implementing)) {
5024                                                                 Report.SymbolRelatedToPreviousError (implementing);
5025                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5026                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5027                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5028                                                         }
5029                                                 } else if (implementing.DeclaringType.IsInterface) {
5030                                                         if (!implementing.IsSpecialName) {
5031                                                                 Report.SymbolRelatedToPreviousError (implementing);
5032                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5033                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5034                                                                 return false;
5035                                                         }
5036                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5037                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5038                                                                 Report.SymbolRelatedToPreviousError (implementing);
5039                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5040                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5041                                                                 return false;
5042                                                         }
5043                                                 }
5044                                         }
5045                                 }
5046                         }
5047
5048                         //
5049                         // For implicit implementations, make sure we are public, for
5050                         // explicit implementations, make sure we are private.
5051                         //
5052                         if (implementing != null){
5053                                 //
5054                                 // Setting null inside this block will trigger a more
5055                                 // verbose error reporting for missing interface implementations
5056                                 //
5057                                 // The "candidate" function has been flagged already
5058                                 // but it wont get cleared
5059                                 //
5060                                 if (member.IsExplicitImpl){
5061                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5062                                                 Report.SymbolRelatedToPreviousError (implementing);
5063                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5064                                                         method.GetSignatureForError ());
5065                                                 return false;
5066                                         }
5067                                 } else {
5068                                         if (implementing.DeclaringType.IsInterface) {
5069                                                 //
5070                                                 // If this is an interface method implementation,
5071                                                 // check for public accessibility
5072                                                 //
5073                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5074                                                 {
5075                                                         implementing = null;
5076                                                 }
5077                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5078                                                 // We may never be private.
5079                                                 implementing = null;
5080
5081                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5082                                                 //
5083                                                 // We may be protected if we're overriding something.
5084                                                 //
5085                                                 implementing = null;
5086                                         }
5087                                 }
5088                                         
5089                                 //
5090                                 // Static is not allowed
5091                                 //
5092                                 if ((modifiers & Modifiers.STATIC) != 0){
5093                                         implementing = null;
5094                                 }
5095                         }
5096                         
5097                         //
5098                         // If implementing is still valid, set flags
5099                         //
5100                         if (implementing != null){
5101                                 //
5102                                 // When implementing interface methods, set NewSlot
5103                                 // unless, we are overwriting a method.
5104                                 //
5105                                 if (implementing.DeclaringType.IsInterface){
5106                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5107                                                 flags |= MethodAttributes.NewSlot;
5108                                 }
5109                                 flags |=
5110                                         MethodAttributes.Virtual |
5111                                         MethodAttributes.HideBySig;
5112
5113                                 // Set Final unless we're virtual, abstract or already overriding a method.
5114                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5115                                         flags |= MethodAttributes.Final;
5116                         }
5117
5118                         DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
5119
5120                         if (builder == null)
5121                                 return false;
5122
5123                         if (container.CurrentType != null)
5124                                 declaring_type = container.CurrentType;
5125                         else
5126                                 declaring_type = container.TypeBuilder;
5127
5128                         if (implementing != null && member.IsExplicitImpl) {
5129                                         container.TypeBuilder.DefineMethodOverride (builder, implementing);
5130                         }
5131
5132                         TypeManager.AddMethod (builder, method);
5133
5134                         if (GenericMethod != null) {
5135                                 bool is_override = member.IsExplicitImpl |
5136                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5137
5138                                 if (implementing != null)
5139                                         parent_method = implementing;
5140
5141                                 if (!GenericMethod.DefineType (GenericMethod, builder, parent_method, is_override))
5142                                         return false;
5143                         }
5144
5145                         return true;
5146                 }
5147
5148
5149                 /// <summary>
5150                 /// Create the MethodBuilder for the method 
5151                 /// </summary>
5152                 void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param)
5153                 {
5154                         if (builder == null) {
5155                                 builder = container.TypeBuilder.DefineMethod (
5156                                         method_name, flags, method.CallingConventions,
5157                                         TypeManager.TypeToReflectionType (method.ReturnType),
5158                                         param.GetEmitTypes ());
5159                                 return;
5160                         }
5161
5162                         //
5163                         // Generic method has been already defined to resolve method parameters
5164                         // correctly when they use type parameters
5165                         //
5166                         builder.SetParameters (param.GetEmitTypes ());
5167                         builder.SetReturnType (method.ReturnType);
5168                         if (builder.Attributes != flags) {
5169                                 try {
5170                                         if (methodbuilder_attrs_field == null)
5171                                                 methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
5172                                         methodbuilder_attrs_field.SetValue (builder, flags);
5173                                 } catch {
5174                                         RootContext.ToplevelTypes.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
5175                                 }
5176                         }
5177                 }
5178
5179                 //
5180                 // Emits the code
5181                 // 
5182                 public void Emit (DeclSpace parent)
5183                 {
5184                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5185
5186                         if (GenericMethod != null)
5187                                 GenericMethod.EmitAttributes ();
5188
5189                         //
5190                         // clear the pending implementation flag
5191                         //
5192                         if (implementing != null)
5193                                 parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName.Basename,
5194                                         member.InterfaceType, this, member.IsExplicitImpl);
5195
5196                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5197
5198                         ToplevelBlock block = method.Block;
5199                         if (block != null) {
5200                                 BlockContext bc = new BlockContext ((IMemberContext) method, block, method.ReturnType);
5201                                 if (block.Resolve (null, bc, method.ParameterInfo, method)) {
5202                                         EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator ());
5203                                         if (!ec.HasReturnLabel && bc.HasReturnLabel) {
5204                                                 ec.ReturnLabel = bc.ReturnLabel;
5205                                                 ec.HasReturnLabel = true;
5206                                         }
5207
5208                                         block.Emit (ec);
5209                                 }
5210                         }
5211
5212                         if (source != null) {
5213                                 method.EmitExtraSymbolInfo (source);
5214                                 source.CloseMethod ();
5215                         }
5216                 }
5217         }
5218
5219         public class Destructor : MethodOrOperator
5220         {
5221                 const int AllowedModifiers =
5222                         Modifiers.UNSAFE |
5223                         Modifiers.EXTERN;
5224
5225                 static readonly string[] attribute_targets = new string [] { "method" };
5226
5227                 public static readonly string MetadataName = "Finalize";
5228
5229                 public Destructor (DeclSpace parent, int mod, ParametersCompiled parameters, Attributes attrs, Location l)
5230                         : base (parent, null, TypeManager.system_void_expr, mod, AllowedModifiers,
5231                                 new MemberName (MetadataName, l), attrs, parameters)
5232                 {
5233                         ModFlags &= ~Modifiers.PRIVATE;
5234                         ModFlags |= Modifiers.PROTECTED;
5235                 }
5236
5237                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
5238                 {
5239                         if (a.Type == pa.Conditional) {
5240                                 Error_ConditionalAttributeIsNotValid ();
5241                                 return;
5242                         }
5243
5244                         base.ApplyAttributeBuilder (a, cb, pa);
5245                 }
5246
5247                 protected override bool CheckBase ()
5248                 {
5249                         flags |= MethodAttributes.Virtual;
5250
5251                         if (!base.CheckBase ())
5252                                 return false;
5253
5254                         if (Parent.PartialContainer.BaseCache == null)
5255                                 return true;
5256
5257                         Type base_type = Parent.PartialContainer.BaseCache.Container.Type;
5258                         if (base_type != null && Block != null) {
5259                                 MethodGroupExpr method_expr = Expression.MethodLookup (Parent.Module.Compiler, Parent.TypeBuilder, base_type, MetadataName, Location);
5260                                 if (method_expr == null)
5261                                         throw new NotImplementedException ();
5262
5263                                 method_expr.IsBase = true;
5264                                 method_expr.InstanceExpression = new CompilerGeneratedThis (Parent.TypeBuilder, Location);
5265
5266                                 ToplevelBlock new_block = new ToplevelBlock (Compiler, Block.StartLocation);
5267                                 new_block.EndLocation = Block.EndLocation;
5268
5269                                 Block finaly_block = new ExplicitBlock (new_block, Location, Location);
5270                                 Block try_block = new Block (new_block, block);
5271
5272                                 //
5273                                 // 0-size arguments to avoid CS0250 error
5274                                 // TODO: Should use AddScopeStatement or something else which emits correct
5275                                 // debugger scope
5276                                 //
5277                                 finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0))));
5278                                 new_block.AddStatement (new TryFinally (try_block, finaly_block, Location));
5279
5280                                 block = new_block;
5281                         }
5282
5283                         return true;
5284                 }
5285
5286                 public override string GetSignatureForError ()
5287                 {
5288                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5289                 }
5290
5291                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
5292                 {
5293                         return null;
5294                 }
5295
5296                 public override string[] ValidAttributeTargets {
5297                         get {
5298                                 return attribute_targets;
5299                         }
5300                 }
5301         }
5302         
5303         public abstract class MemberBase : MemberCore
5304         {
5305                 protected FullNamedExpression type_name;
5306                 protected Type member_type;
5307
5308                 public readonly DeclSpace ds;
5309                 public readonly GenericMethod GenericMethod;
5310
5311                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5312                                       FullNamedExpression type, int mod, int allowed_mod, int def_mod,
5313                                       MemberName name, Attributes attrs)
5314                         : base (parent, name, attrs)
5315                 {
5316                         this.ds = generic != null ? generic : (DeclSpace) parent;
5317                         this.type_name = type;
5318                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location, Report);
5319                         GenericMethod = generic;
5320                         if (GenericMethod != null)
5321                                 GenericMethod.ModFlags = ModFlags;
5322                 }
5323
5324                 //
5325                 // Main member define entry
5326                 //
5327                 public override bool Define ()
5328                 {
5329                         DoMemberTypeIndependentChecks ();
5330
5331                         //
5332                         // Returns false only when type resolution failed
5333                         //
5334                         if (!ResolveMemberType ())
5335                                 return false;
5336
5337                         DoMemberTypeDependentChecks ();
5338                         return true;
5339                 }
5340
5341                 //
5342                 // Any type_name independent checks
5343                 //
5344                 protected virtual void DoMemberTypeIndependentChecks ()
5345                 {
5346                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 &&
5347                                 (ModFlags & (Modifiers.VIRTUAL | Modifiers.ABSTRACT)) != 0) {
5348                                 Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5349                                         GetSignatureForError (), Parent.GetSignatureForError ());
5350                         }
5351                 }
5352
5353                 //
5354                 // Any type_name dependent checks
5355                 //
5356                 protected virtual void DoMemberTypeDependentChecks ()
5357                 {
5358                         // verify accessibility
5359                         if (!IsAccessibleAs (MemberType)) {
5360                                 Report.SymbolRelatedToPreviousError (MemberType);
5361                                 if (this is Property)
5362                                         Report.Error (53, Location,
5363                                                       "Inconsistent accessibility: property type `" +
5364                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5365                                                       "accessible than property `" + GetSignatureForError () + "'");
5366                                 else if (this is Indexer)
5367                                         Report.Error (54, Location,
5368                                                       "Inconsistent accessibility: indexer return type `" +
5369                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5370                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5371                                 else if (this is MethodCore) {
5372                                         if (this is Operator)
5373                                                 Report.Error (56, Location,
5374                                                               "Inconsistent accessibility: return type `" +
5375                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5376                                                               "accessible than operator `" + GetSignatureForError () + "'");
5377                                         else
5378                                                 Report.Error (50, Location,
5379                                                               "Inconsistent accessibility: return type `" +
5380                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5381                                                               "accessible than method `" + GetSignatureForError () + "'");
5382                                 } else {
5383                                         Report.Error (52, Location,
5384                                                       "Inconsistent accessibility: field type `" +
5385                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5386                                                       "accessible than field `" + GetSignatureForError () + "'");
5387                                 }
5388                         }
5389
5390                         Variance variance = this is Event ? Variance.Contravariant : Variance.Covariant;
5391                         TypeManager.CheckTypeVariance (MemberType, variance, this);
5392                 }
5393
5394                 protected bool IsTypePermitted ()
5395                 {
5396                         if (TypeManager.IsSpecialType (MemberType)) {
5397                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5398                                 return false;
5399                         }
5400                         return true;
5401                 }
5402
5403                 protected virtual bool CheckBase ()
5404                 {
5405                         CheckProtectedModifier ();
5406
5407                         return true;
5408                 }
5409
5410                 public Type MemberType {
5411                         get { return member_type; }
5412                 }
5413
5414                 protected virtual bool ResolveMemberType ()
5415                 {
5416                         if (member_type != null)
5417                                 throw new InternalErrorException ("Multi-resolve");
5418
5419                         TypeExpr te = type_name.ResolveAsTypeTerminal (this, false);
5420                         if (te == null)
5421                                 return false;
5422                         
5423                         //
5424                         // Replace original type name, error reporting can use fully resolved name
5425                         //
5426                         type_name = te;
5427
5428                         member_type = te.Type;
5429                         return true;
5430                 }
5431         }
5432
5433         //
5434         // Abstract class for all fields
5435         //
5436         abstract public class FieldBase : MemberBase {
5437                 public FieldBuilder FieldBuilder;
5438                 public Status status;
5439                 protected Expression initializer;
5440
5441                 [Flags]
5442                 public enum Status : byte {
5443                         HAS_OFFSET = 4          // Used by FieldMember.
5444                 }
5445
5446                 static readonly string[] attribute_targets = new string [] { "field" };
5447
5448                 protected FieldBase (DeclSpace parent, FullNamedExpression type, int mod,
5449                                      int allowed_mod, MemberName name, Attributes attrs)
5450                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5451                                 name, attrs)
5452                 {
5453                         if ((mod & Modifiers.ABSTRACT) != 0)
5454                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5455                 }
5456
5457                 public override AttributeTargets AttributeTargets {
5458                         get {
5459                                 return AttributeTargets.Field;
5460                         }
5461                 }
5462
5463                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
5464                 {
5465                         if (a.Type == pa.FieldOffset) {
5466                                 status |= Status.HAS_OFFSET;
5467
5468                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5469                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5470                                         return;
5471                                 }
5472
5473                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5474                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5475                                         return;
5476                                 }
5477                         }
5478
5479                         if (a.Type == pa.FixedBuffer) {
5480                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5481                                 return;
5482                         }
5483
5484 #if false
5485                         if (a.Type == pa.MarshalAs) {
5486                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5487                                 if (marshal != null) {
5488                                         FieldBuilder.SetMarshal (marshal);
5489                                 }
5490                                 return;
5491                         }
5492 #endif
5493                         if ((a.HasSecurityAttribute)) {
5494                                 a.Error_InvalidSecurityParent ();
5495                                 return;
5496                         }
5497
5498                         FieldBuilder.SetCustomAttribute (cb);
5499                 }
5500
5501                 protected override bool CheckBase ()
5502                 {
5503                         if (!base.CheckBase ())
5504                                 return false;
5505  
5506                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5507                         if (conflict_symbol == null) {
5508                                 if ((ModFlags & Modifiers.NEW) != 0) {
5509                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5510                                 }
5511                                 return true;
5512                         }
5513  
5514                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) {
5515                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5516                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5517                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5518                         }
5519  
5520                         return true;
5521                 }
5522
5523                 protected override void DoMemberTypeDependentChecks ()
5524                 {
5525                         base.DoMemberTypeDependentChecks ();
5526
5527                         if (TypeManager.IsGenericParameter (MemberType))
5528                                 return;
5529
5530                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5531                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType, Report);
5532                         }
5533
5534                         CheckBase ();
5535                         IsTypePermitted ();
5536                 }
5537
5538                 //
5539                 //   Represents header string for documentation comment.
5540                 //
5541                 public override string DocCommentHeader {
5542                         get { return "F:"; }
5543                 }
5544
5545                 public override void Emit ()
5546                 {
5547                         if (TypeManager.IsDynamicType (member_type))
5548                                 PredefinedAttributes.Get.Dynamic.EmitAttribute (FieldBuilder);
5549
5550                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
5551                                 PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (FieldBuilder);
5552
5553                         if (OptAttributes != null) {
5554                                 OptAttributes.Emit ();
5555                         }
5556
5557                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & (Modifiers.STATIC | Modifiers.BACKING_FIELD)) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5558                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute", GetSignatureForError ());
5559                         }
5560
5561                         base.Emit ();
5562                 }
5563
5564                 public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class, Report Report)
5565                 {
5566                         Report.SymbolRelatedToPreviousError (static_class);
5567                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5568                                 variable_name);
5569                 }
5570
5571                 public Expression Initializer {
5572                         set {
5573                                 if (value != null) {
5574                                         this.initializer = value;
5575                                 }
5576                         }
5577                 }
5578
5579                 protected virtual bool IsFieldClsCompliant {
5580                         get {
5581                                 if (FieldBuilder == null)
5582                                         return true;
5583
5584                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5585                         }
5586                 }
5587
5588                 public override string[] ValidAttributeTargets 
5589                 {
5590                         get {
5591                                 return attribute_targets;
5592                         }
5593                 }
5594
5595                 protected override bool VerifyClsCompliance ()
5596                 {
5597                         if (!base.VerifyClsCompliance ())
5598                                 return false;
5599
5600                         if (!IsFieldClsCompliant) {
5601                                 Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
5602                                         GetSignatureForError ());
5603                         }
5604                         return true;
5605                 }
5606
5607                 public void SetAssigned ()
5608                 {
5609                         caching_flags |= Flags.IsAssigned;
5610                 }
5611         }
5612
5613         interface IFixedBuffer
5614         {
5615                 FieldInfo Element { get; }
5616                 Type ElementType { get; }
5617         }
5618
5619         public class FixedFieldExternal: IFixedBuffer
5620         {
5621                 FieldInfo element_field;
5622
5623                 public FixedFieldExternal (FieldInfo fi)
5624                 {
5625                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5626                 }
5627
5628                 #region IFixedField Members
5629
5630                 public FieldInfo Element {
5631                         get {
5632                                 return element_field;
5633                         }
5634                 }
5635
5636                 public Type ElementType {
5637                         get {
5638                                 return element_field.FieldType;
5639                         }
5640                 }
5641
5642                 #endregion
5643         }
5644
5645         /// <summary>
5646         /// Fixed buffer implementation
5647         /// </summary>
5648         public class FixedField : FieldBase, IFixedBuffer
5649         {
5650                 public const string FixedElementName = "FixedElementField";
5651                 static int GlobalCounter = 0;
5652                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5653                 static FieldInfo[] fi;
5654
5655                 TypeBuilder fixed_buffer_type;
5656                 FieldBuilder element;
5657                 Expression size_expr;
5658
5659                 const int AllowedModifiers =
5660                         Modifiers.NEW |
5661                         Modifiers.PUBLIC |
5662                         Modifiers.PROTECTED |
5663                         Modifiers.INTERNAL |
5664                         Modifiers.PRIVATE;
5665
5666                 public FixedField (DeclSpace parent, FullNamedExpression type, int mod, string name,
5667                         Expression size_expr, Attributes attrs, Location loc):
5668                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5669                 {
5670                         if (RootContext.Version < LanguageVersion.ISO_2)
5671                                 Report.FeatureIsNotAvailable (loc, "fixed size buffers");
5672
5673                         this.size_expr = size_expr;
5674                 }
5675
5676                 public override bool Define()
5677                 {
5678                         if (!base.Define ())
5679                                 return false;
5680
5681                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5682                                 Report.Error (1663, Location, "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double",
5683                                         GetSignatureForError ());
5684                         }                       
5685                         
5686                         // Create nested fixed buffer container
5687                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5688                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name, Parent.Module.DefaultCharSetType |
5689                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5690                         
5691                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5692                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5693                         
5694                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5695                         Parent.MemberCache.AddMember (FieldBuilder, this);
5696                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5697
5698                         return true;
5699                 }
5700
5701                 protected override void DoMemberTypeIndependentChecks ()
5702                 {
5703                         base.DoMemberTypeIndependentChecks ();
5704
5705                         if (!Parent.IsUnsafe)
5706                                 Expression.UnsafeError (Report, Location);
5707
5708                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5709                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5710                                         GetSignatureForError ());
5711                         }
5712                 }
5713
5714                 public override void Emit()
5715                 {
5716                         ResolveContext rc = new ResolveContext (this);
5717                         Constant c = size_expr.ResolveAsConstant (rc, this);
5718                         if (c == null)
5719                                 return;
5720                         
5721                         IntConstant buffer_size_const = c.ImplicitConversionRequired (rc, TypeManager.int32_type, Location) as IntConstant;
5722                         if (buffer_size_const == null)
5723                                 return;
5724
5725                         int buffer_size = buffer_size_const.Value;
5726
5727                         if (buffer_size <= 0) {
5728                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5729                                 return;
5730                         }
5731
5732                         int type_size = Expression.GetTypeSize (MemberType);
5733
5734                         if (buffer_size > int.MaxValue / type_size) {
5735                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5736                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5737                                 return;
5738                         }
5739
5740                         buffer_size *= type_size;
5741                         EmitFieldSize (buffer_size);
5742
5743                         PredefinedAttributes.Get.UnsafeValueType.EmitAttribute (fixed_buffer_type);
5744
5745                         base.Emit ();
5746                 }
5747
5748                 void EmitFieldSize (int buffer_size)
5749                 {
5750                         CustomAttributeBuilder cab;
5751                         PredefinedAttribute pa;
5752
5753                         pa = PredefinedAttributes.Get.StructLayout;
5754                         if (pa.Constructor == null &&
5755                                 !pa.ResolveConstructor (Location, TypeManager.short_type))
5756                                         return;
5757
5758                         // TODO: It's not cleared
5759                         if (fi == null)
5760                                 fi = new FieldInfo[] { pa.Type.GetField ("Size") };
5761
5762                         object[] fi_val = new object[] { buffer_size };
5763                         cab = new CustomAttributeBuilder (pa.Constructor,
5764                                 ctor_args, fi, fi_val);
5765                         fixed_buffer_type.SetCustomAttribute (cab);
5766                         
5767                         //
5768                         // Don't emit FixedBufferAttribute attribute for private types
5769                         //
5770                         if ((ModFlags & Modifiers.PRIVATE) != 0)
5771                                 return;
5772
5773                         pa = PredefinedAttributes.Get.FixedBuffer;
5774                         if (pa.Constructor == null &&
5775                                 !pa.ResolveConstructor (Location, TypeManager.type_type, TypeManager.int32_type))
5776                                 return;
5777
5778                         cab = new CustomAttributeBuilder (pa.Constructor, new object[] { MemberType, buffer_size });
5779                         FieldBuilder.SetCustomAttribute (cab);
5780                 }
5781
5782                 protected override bool IsFieldClsCompliant {
5783                         get {
5784                                 return false;
5785                         }
5786                 }
5787
5788                 public void SetCharSet (TypeAttributes ta)
5789                 {
5790                         TypeAttributes cta = fixed_buffer_type.Attributes;
5791                         if ((cta & TypeAttributes.UnicodeClass) != (ta & TypeAttributes.UnicodeClass))
5792                                 SetTypeBuilderCharSet ((cta & ~TypeAttributes.AutoClass) | TypeAttributes.UnicodeClass);
5793                         else if ((cta & TypeAttributes.AutoClass) != (ta & TypeAttributes.AutoClass))
5794                                 SetTypeBuilderCharSet ((cta & ~TypeAttributes.UnicodeClass) | TypeAttributes.AutoClass);
5795                         else if (cta == 0 && ta != 0)
5796                                 SetTypeBuilderCharSet (cta & ~(TypeAttributes.UnicodeClass | TypeAttributes.AutoClass));
5797                 }
5798
5799                 void SetTypeBuilderCharSet (TypeAttributes ta)
5800                 {
5801                         MethodInfo mi = typeof (TypeBuilder).GetMethod ("SetCharSet", BindingFlags.Instance | BindingFlags.NonPublic);
5802                         if (mi == null) {
5803                                 Report.RuntimeMissingSupport (Location, "TypeBuilder::SetCharSet");
5804                         } else {
5805                                 mi.Invoke (fixed_buffer_type, new object [] { ta });
5806                         }
5807                 }
5808
5809                 #region IFixedField Members
5810
5811                 public FieldInfo Element {
5812                         get {
5813                                 return element;
5814                         }
5815                 }
5816
5817                 public Type ElementType {
5818                         get {
5819                                 return MemberType;
5820                         }
5821                 }
5822
5823                 #endregion
5824         }
5825
5826         //
5827         // The Field class is used to represents class/struct fields during parsing.
5828         //
5829         public class Field : FieldBase {
5830                 // <summary>
5831                 //   Modifiers allowed in a class declaration
5832                 // </summary>
5833                 const int AllowedModifiers =
5834                         Modifiers.NEW |
5835                         Modifiers.PUBLIC |
5836                         Modifiers.PROTECTED |
5837                         Modifiers.INTERNAL |
5838                         Modifiers.PRIVATE |
5839                         Modifiers.STATIC |
5840                         Modifiers.VOLATILE |
5841                         Modifiers.UNSAFE |
5842                         Modifiers.READONLY;
5843
5844                 public Field (DeclSpace parent, FullNamedExpression type, int mod, MemberName name,
5845                               Attributes attrs)
5846                         : base (parent, type, mod, AllowedModifiers, name, attrs)
5847                 {
5848                 }
5849
5850                 bool CanBeVolatile ()
5851                 {
5852                         if (TypeManager.IsReferenceType (MemberType))
5853                                 return true;
5854
5855                         if (MemberType == TypeManager.bool_type || MemberType == TypeManager.char_type ||
5856                                 MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type ||
5857                                 MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type ||
5858                                 MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type ||
5859                                 MemberType == TypeManager.float_type ||
5860                                 MemberType == TypeManager.intptr_type || MemberType == TypeManager.uintptr_type)
5861                                 return true;
5862
5863                         if (TypeManager.IsEnumType (MemberType))
5864                                 return true;
5865
5866                         return false;
5867                 }
5868
5869                 bool CheckStructLayout (Type type, bool isStatic)
5870                 {
5871                         if (TypeManager.IsBuiltinType (type))
5872                                 return true;
5873
5874                         if (isStatic) {
5875                                 if (!TypeManager.IsValueType (type) || TypeManager.IsEqual (type, Parent.TypeBuilder))
5876                                         return true;
5877                         }
5878
5879                         if (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (type), Parent.TypeBuilder)) {
5880                                 if (!TypeManager.IsGenericType (type))
5881                                         return true;
5882
5883                                 foreach (Type t in TypeManager.GetTypeArguments (type)) {
5884                                         if (!CheckStructLayout (t, false))
5885                                                 return false;
5886                                 }
5887                                 return true;
5888                         }
5889                         
5890                         Report.Error (523, Location,
5891                                 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
5892                                 GetSignatureForError (), TypeManager.CSharpName (MemberType));
5893                         return false;
5894                 }
5895
5896                 public override bool Define ()
5897                 {
5898                         if (!base.Define ())
5899                                 return false;
5900
5901                         try {
5902                                 Type[] required_modifier = null;
5903                                 if ((ModFlags & Modifiers.VOLATILE) != 0) {
5904                                         if (TypeManager.isvolatile_type == null)
5905                                                 TypeManager.isvolatile_type = TypeManager.CoreLookupType (Compiler,
5906                                                         "System.Runtime.CompilerServices", "IsVolatile", Kind.Class, true);
5907
5908                                         if (TypeManager.isvolatile_type != null)
5909                                                 required_modifier = new Type [] { TypeManager.isvolatile_type };
5910                                 }
5911
5912                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5913                                         Name, MemberType, required_modifier, null, Modifiers.FieldAttr (ModFlags));
5914
5915                                 // Don't cache inaccessible fields
5916                                 if ((ModFlags & Modifiers.BACKING_FIELD) == 0) {
5917                                         Parent.MemberCache.AddMember (FieldBuilder, this);
5918                                 }
5919
5920                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
5921                         }
5922                         catch (ArgumentException) {
5923                                 Report.RuntimeMissingSupport (Location, "`void' or `void*' field type");
5924                                 return false;
5925                         }
5926
5927                         if (initializer != null) {
5928                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
5929                                         new FieldInitializer (FieldBuilder, initializer, this));
5930                         } else {
5931                                 if (Parent.PartialContainer.Kind == Kind.Struct)
5932                                         CheckStructLayout (member_type, (ModFlags & Modifiers.STATIC) != 0);
5933                         }
5934
5935                         return true;
5936                 }
5937
5938                 protected override void DoMemberTypeDependentChecks ()
5939                 {
5940                         base.DoMemberTypeDependentChecks ();
5941
5942                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5943                                 if (!CanBeVolatile ()) {
5944                                         Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5945                                                 GetSignatureForError (), TypeManager.CSharpName (MemberType));
5946                                 }
5947
5948                                 if ((ModFlags & Modifiers.READONLY) != 0) {
5949                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5950                                                 GetSignatureForError ());
5951                                 }
5952                         }
5953                 }
5954
5955                 protected override bool VerifyClsCompliance ()
5956                 {
5957                         if (!base.VerifyClsCompliance ())
5958                                 return false;
5959
5960                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5961                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5962                         }
5963
5964                         return true;
5965                 }
5966         }
5967
5968         //
5969         // `set' and `get' accessors are represented with an Accessor.
5970         // 
5971         public class Accessor {
5972                 //
5973                 // Null if the accessor is empty, or a Block if not
5974                 //
5975                 public const int AllowedModifiers = 
5976                         Modifiers.PUBLIC |
5977                         Modifiers.PROTECTED |
5978                         Modifiers.INTERNAL |
5979                         Modifiers.PRIVATE;
5980                 
5981                 public ToplevelBlock Block;
5982                 public Attributes Attributes;
5983                 public Location Location;
5984                 public int ModFlags;
5985                 public ParametersCompiled Parameters;
5986                 
5987                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, ParametersCompiled p, Location loc)
5988                 {
5989                         Block = b;
5990                         Attributes = attrs;
5991                         Location = loc;
5992                         Parameters = p;
5993                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc, RootContext.ToplevelTypes.Compiler.Report);
5994                 }
5995         }
5996
5997         // Ooouh Martin, templates are missing here.
5998         // When it will be possible move here a lot of child code and template method type.
5999         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6000                 protected MethodData method_data;
6001                 protected ToplevelBlock block;
6002                 protected ListDictionary declarative_security;
6003
6004                 // The accessor are created even if they are not wanted.
6005                 // But we need them because their names are reserved.
6006                 // Field says whether accessor will be emited or not
6007                 public readonly bool IsDummy;
6008
6009                 protected readonly string prefix;
6010
6011                 ReturnParameter return_attributes;
6012
6013                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6014                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
6015                 {
6016                         this.prefix = prefix;
6017                         IsDummy = true;
6018                 }
6019
6020                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6021                                                     string prefix)
6022                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
6023                                 accessor.Attributes)
6024                 {
6025                         this.prefix = prefix;
6026                         this.block = accessor.Block;
6027                 }
6028
6029                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6030                 {
6031                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6032                 }
6033
6034                 public void UpdateName (InterfaceMemberBase member)
6035                 {
6036                         SetMemberName (SetupName (prefix, member, Location));
6037                 }
6038
6039                 #region IMethodData Members
6040
6041                 public ToplevelBlock Block {
6042                         get {
6043                                 return block;
6044                         }
6045
6046                         set {
6047                                 block = value;
6048                         }
6049                 }
6050
6051                 public CallingConventions CallingConventions {
6052                         get {
6053                                 return CallingConventions.Standard;
6054                         }
6055                 }
6056
6057                 public EmitContext CreateEmitContext (ILGenerator ig)
6058                 {
6059                         return new EmitContext (this, ig, ReturnType);
6060                 }
6061
6062                 public bool IsExcluded ()
6063                 {
6064                         return false;
6065                 }
6066
6067                 GenericMethod IMethodData.GenericMethod {
6068                         get {
6069                                 return null;
6070                         }
6071                 }
6072
6073                 public MemberName MethodName {
6074                         get {
6075                                 return MemberName;
6076                         }
6077                 }
6078
6079                 public Type[] ParameterTypes { 
6080                         get {
6081                                 return ParameterInfo.Types;
6082                         }
6083                 }
6084
6085                 public abstract ParametersCompiled ParameterInfo { get ; }
6086                 public abstract Type ReturnType { get; }
6087
6088                 #endregion
6089
6090                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
6091                 {
6092                         if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
6093                                 Report.Error (1667, a.Location,
6094                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6095                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6096                                 return;
6097                         }
6098
6099                         if (a.IsValidSecurityAttribute ()) {
6100                                 if (declarative_security == null)
6101                                         declarative_security = new ListDictionary ();
6102                                 a.ExtractSecurityPermissionSet (declarative_security);
6103                                 return;
6104                         }
6105
6106                         if (a.Target == AttributeTargets.Method) {
6107                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6108                                 return;
6109                         }
6110
6111                         if (a.Target == AttributeTargets.ReturnValue) {
6112                                 if (return_attributes == null)
6113                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6114
6115                                 return_attributes.ApplyAttributeBuilder (a, cb, pa);
6116                                 return;
6117                         }
6118
6119                         ApplyToExtraTarget (a, cb, pa);
6120                 }
6121
6122                 protected virtual void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
6123                 {
6124                         throw new NotSupportedException ("You forgot to define special attribute target handling");
6125                 }
6126
6127                 // It is not supported for the accessors
6128                 public sealed override bool Define()
6129                 {
6130                         throw new NotSupportedException ();
6131                 }
6132
6133                 public virtual void Emit (DeclSpace parent)
6134                 {
6135                         method_data.Emit (parent);
6136
6137                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
6138                                 PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
6139                         if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
6140                                 PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
6141
6142                         if (TypeManager.IsDynamicType (ReturnType)) {
6143                                 return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6144                                 return_attributes.EmitPredefined (PredefinedAttributes.Get.Dynamic, Location);
6145                         }
6146
6147                         if (OptAttributes != null)
6148                                 OptAttributes.Emit ();
6149
6150                         if (declarative_security != null) {
6151                                 foreach (DictionaryEntry de in declarative_security) {
6152                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6153                                 }
6154                         }
6155
6156                         block = null;
6157                 }
6158
6159                 public override bool EnableOverloadChecks (MemberCore overload)
6160                 {
6161                         // This can only happen with indexers and it will
6162                         // be catched as indexer difference
6163                         if (overload is AbstractPropertyEventMethod)
6164                                 return true;
6165
6166                         if (overload is MethodCore) {
6167                                 caching_flags |= Flags.MethodOverloadsExist;
6168                                 return true;
6169                         }
6170                         return false;
6171                 }
6172
6173                 public override bool IsClsComplianceRequired()
6174                 {
6175                         return false;
6176                 }
6177
6178                 public bool IsDuplicateImplementation (MethodCore method)
6179                 {
6180                         if (!MemberName.Equals (method.MemberName))
6181                                 return false;
6182
6183                         Type[] param_types = method.ParameterTypes;
6184
6185                         if (param_types == null || param_types.Length != ParameterTypes.Length)
6186                                 return false;
6187
6188                         for (int i = 0; i < param_types.Length; i++)
6189                                 if (param_types [i] != ParameterTypes [i])
6190                                         return false;
6191
6192                         Report.SymbolRelatedToPreviousError (method);
6193                         Report.Error (82, Location, "A member `{0}' is already reserved",
6194                                 method.GetSignatureForError ());
6195                         return true;
6196                 }
6197
6198                 public override bool IsUsed
6199                 {
6200                         get {
6201                                 if (IsDummy)
6202                                         return false;
6203
6204                                 return base.IsUsed;
6205                         }
6206                 }
6207
6208                 //
6209                 //   Represents header string for documentation comment.
6210                 //
6211                 public override string DocCommentHeader {
6212                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6213                 }
6214
6215                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
6216                 { }
6217         }
6218
6219         //
6220         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6221         // their common bits.
6222         //
6223         abstract public class PropertyBase : PropertyBasedMember {
6224
6225                 public class GetMethod : PropertyMethod
6226                 {
6227                         static string[] attribute_targets = new string [] { "method", "return" };
6228
6229                         public GetMethod (PropertyBase method):
6230                                 base (method, "get_")
6231                         {
6232                         }
6233
6234                         public GetMethod (PropertyBase method, Accessor accessor):
6235                                 base (method, accessor, "get_")
6236                         {
6237                         }
6238
6239                         public override MethodBuilder Define (DeclSpace parent)
6240                         {
6241                                 base.Define (parent);
6242
6243                                 if (IsDummy)
6244                                         return null;
6245                                 
6246                                 method_data = new MethodData (method, ModFlags, flags, this);
6247
6248                                 if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
6249                                         return null;
6250
6251                                 return method_data.MethodBuilder;
6252                         }
6253
6254                         public override Type ReturnType {
6255                                 get {
6256                                         return method.MemberType;
6257                                 }
6258                         }
6259
6260                         public override ParametersCompiled ParameterInfo {
6261                                 get {
6262                                         return ParametersCompiled.EmptyReadOnlyParameters;
6263                                 }
6264                         }
6265
6266                         public override string[] ValidAttributeTargets {
6267                                 get {
6268                                         return attribute_targets;
6269                                 }
6270                         }
6271                 }
6272
6273                 public class SetMethod : PropertyMethod {
6274
6275                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6276                         ImplicitParameter param_attr;
6277                         protected ParametersCompiled parameters;
6278
6279                         public SetMethod (PropertyBase method) :
6280                                 base (method, "set_")
6281                         {
6282                                 parameters = new ParametersCompiled (
6283                                         new Parameter (method.type_name, "value", Parameter.Modifier.NONE, null, Location));
6284                         }
6285
6286                         public SetMethod (PropertyBase method, Accessor accessor):
6287                                 base (method, accessor, "set_")
6288                         {
6289                                 this.parameters = accessor.Parameters;
6290                         }
6291
6292                         protected override void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
6293                         {
6294                                 if (a.Target == AttributeTargets.Parameter) {
6295                                         if (param_attr == null)
6296                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6297
6298                                         param_attr.ApplyAttributeBuilder (a, cb, pa);
6299                                         return;
6300                                 }
6301
6302                                 base.ApplyAttributeBuilder (a, cb, pa);
6303                         }
6304
6305                         public override ParametersCompiled ParameterInfo {
6306                             get {
6307                                 return parameters;
6308                             }
6309                         }
6310
6311                         public override MethodBuilder Define (DeclSpace parent)
6312                         {
6313                                 parameters.Resolve (this);
6314                                 
6315                                 base.Define (parent);
6316
6317                                 if (IsDummy)
6318                                         return null;
6319
6320                                 method_data = new MethodData (method, ModFlags, flags, this);
6321
6322                                 if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
6323                                         return null;
6324
6325                                 return method_data.MethodBuilder;
6326                         }
6327
6328                         public override Type ReturnType {
6329                                 get {
6330                                         return TypeManager.void_type;
6331                                 }
6332                         }
6333
6334                         public override string[] ValidAttributeTargets {
6335                                 get {
6336                                         return attribute_targets;
6337                                 }
6338                         }
6339                 }
6340
6341                 static string[] attribute_targets = new string [] { "property" };
6342
6343                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6344                 {
6345                         protected readonly PropertyBase method;
6346                         protected MethodAttributes flags;
6347
6348                         public PropertyMethod (PropertyBase method, string prefix)
6349                                 : base (method, prefix)
6350                         {
6351                                 this.method = method;
6352                                 this.ModFlags = method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE);                                
6353                         }
6354
6355                         public PropertyMethod (PropertyBase method, Accessor accessor,
6356                                                string prefix)
6357                                 : base (method, accessor, prefix)
6358                         {
6359                                 this.method = method;
6360                                 this.ModFlags = accessor.ModFlags | (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE));
6361
6362                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6363                                         Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
6364                                 }
6365                         }
6366
6367                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
6368                         {
6369                                 if (a.IsInternalMethodImplAttribute) {
6370                                         method.is_external_implementation = true;
6371                                 }
6372
6373                                 base.ApplyAttributeBuilder (a, cb, pa);
6374                         }
6375
6376                         public override AttributeTargets AttributeTargets {
6377                                 get {
6378                                         return AttributeTargets.Method;
6379                                 }
6380                         }
6381
6382                         public override bool IsClsComplianceRequired ()
6383                         {
6384                                 return method.IsClsComplianceRequired ();
6385                         }
6386
6387                         public virtual MethodBuilder Define (DeclSpace parent)
6388                         {
6389                                 CheckForDuplications ();
6390
6391                                 if (IsDummy) {
6392                                         if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
6393                                                 MethodInfo mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
6394                                                         MethodName.Name, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
6395                                                 if (mi != null) {
6396                                                         Report.SymbolRelatedToPreviousError (mi);
6397                                                         Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
6398                                                                 method.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
6399                                                 }
6400                                         }
6401                                         return null;
6402                                 }
6403
6404                                 TypeContainer container = parent.PartialContainer;
6405
6406                                 //
6407                                 // Check for custom access modifier
6408                                 //
6409                                 if ((ModFlags & Modifiers.Accessibility) == 0) {
6410                                         ModFlags |= method.ModFlags;
6411                                         flags = method.flags;
6412                                 } else {
6413                                         if (container.Kind == Kind.Interface)
6414                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6415                                                         GetSignatureForError ());
6416
6417                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6418                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6419                                         }
6420
6421                                         CheckModifiers (ModFlags);
6422                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6423                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6424                                         flags = Modifiers.MethodAttr (ModFlags);
6425                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6426                                 }
6427
6428                                 CheckAbstractAndExtern (block != null);
6429                                 CheckProtectedModifier ();
6430
6431                                 if (block != null && block.IsIterator)
6432                                         Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
6433
6434                                 return null;
6435                         }
6436
6437                         public bool HasCustomAccessModifier {
6438                                 get {
6439                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6440                                 }
6441                         }
6442
6443                         public PropertyBase Property {
6444                                 get {
6445                                         return method;
6446                                 }
6447                         }
6448
6449                         public override ObsoleteAttribute GetObsoleteAttribute ()
6450                         {
6451                                 return method.GetObsoleteAttribute ();
6452                         }
6453
6454                         public override string GetSignatureForError()
6455                         {
6456                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6457                         }
6458                         
6459                         void CheckModifiers (int modflags)
6460                         {
6461                                 modflags &= Modifiers.Accessibility;
6462                                 int flags = 0;
6463                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6464
6465                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6466                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6467                                 }
6468                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6469                                         if ((mflags & Modifiers.INTERNAL) != 0)
6470                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6471
6472                                         flags |= Modifiers.PRIVATE;
6473                                 }
6474                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6475                                         flags |= Modifiers.PRIVATE;
6476
6477                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6478                                         Report.Error (273, Location,
6479                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6480                                                 GetSignatureForError (), method.GetSignatureForError ());
6481                                 }
6482                         }
6483
6484                         protected bool CheckForDuplications ()
6485                         {
6486                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0)
6487                                         return true;
6488
6489                                 return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo, Report);
6490                         }
6491                 }
6492
6493                 public PropertyMethod Get, Set;
6494                 public PropertyBuilder PropertyBuilder;
6495                 public MethodBuilder GetBuilder, SetBuilder;
6496
6497                 protected bool define_set_first = false;
6498
6499                 public PropertyBase (DeclSpace parent, FullNamedExpression type, int mod_flags,
6500                                      int allowed_mod, MemberName name,
6501                                      Attributes attrs, bool define_set_first)
6502                         : base (parent, null, type, mod_flags, allowed_mod, name, attrs)
6503                 {
6504                          this.define_set_first = define_set_first;
6505                 }
6506
6507                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
6508                 {
6509                         if (a.HasSecurityAttribute) {
6510                                 a.Error_InvalidSecurityParent ();
6511                                 return;
6512                         }
6513
6514                         PropertyBuilder.SetCustomAttribute (cb);
6515                 }
6516
6517                 public override AttributeTargets AttributeTargets {
6518                         get {
6519                                 return AttributeTargets.Property;
6520                         }
6521                 }
6522
6523                 protected override void DoMemberTypeDependentChecks ()
6524                 {
6525                         base.DoMemberTypeDependentChecks ();
6526
6527                         IsTypePermitted ();
6528 #if MS_COMPATIBLE
6529                         if (MemberType.IsGenericParameter)
6530                                 return;
6531 #endif
6532
6533                         if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
6534                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6535                         }
6536                 }
6537
6538                 protected override void DoMemberTypeIndependentChecks ()
6539                 {
6540                         base.DoMemberTypeIndependentChecks ();
6541
6542                         //
6543                         // Accessors modifiers check
6544                         //
6545                         if ((Get.ModFlags & Modifiers.Accessibility) != 0 &&
6546                                 (Set.ModFlags & Modifiers.Accessibility) != 0) {
6547                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6548                                                 GetSignatureForError ());
6549                         }
6550
6551                         if ((ModFlags & Modifiers.OVERRIDE) == 0 && 
6552                                 (Get.IsDummy && (Set.ModFlags & Modifiers.Accessibility) != 0) ||
6553                                 (Set.IsDummy && (Get.ModFlags & Modifiers.Accessibility) != 0)) {
6554                                 Report.Error (276, Location, 
6555                                               "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6556                                               GetSignatureForError ());
6557                         }
6558                 }
6559
6560                 bool DefineGet ()
6561                 {
6562                         GetBuilder = Get.Define (Parent);
6563                         return (Get.IsDummy) ? true : GetBuilder != null;
6564                 }
6565
6566                 bool DefineSet (bool define)
6567                 {
6568                         if (!define)
6569                                 return true;
6570
6571                         SetBuilder = Set.Define (Parent);
6572                         return (Set.IsDummy) ? true : SetBuilder != null;
6573                 }
6574
6575                 protected bool DefineAccessors ()
6576                 {
6577                         return DefineSet (define_set_first) &&
6578                                 DefineGet () &&
6579                                 DefineSet (!define_set_first);
6580                 }
6581
6582                 protected abstract PropertyInfo ResolveBaseProperty ();
6583
6584                 // TODO: rename to Resolve......
6585                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6586                 {
6587                         PropertyInfo base_property = ResolveBaseProperty ();
6588                         if (base_property == null)
6589                                 return null;
6590
6591                         base_ret_type = base_property.PropertyType;
6592                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6593                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6594                         MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
6595
6596                         //
6597                         // Check base property accessors conflict
6598                         //
6599                         if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
6600                                 if (get_accessor == null) {
6601                                         if (Get != null && !Get.IsDummy) {
6602                                                 Report.SymbolRelatedToPreviousError (base_property);
6603                                                 Report.Error (545, Location,
6604                                                         "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
6605                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6606                                         }
6607                                 } else {
6608                                         get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
6609
6610                                         if (!Get.IsDummy && !CheckAccessModifiers (
6611                                                 Modifiers.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6612                                                 Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
6613                                 }
6614
6615                                 if (set_accessor == null) {
6616                                         if (Set != null && !Set.IsDummy) {
6617                                                 Report.SymbolRelatedToPreviousError (base_property);
6618                                                 Report.Error (546, Location,
6619                                                         "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
6620                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6621                                         }
6622                                 } else {
6623                                         set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
6624
6625                                         if (!Set.IsDummy && !CheckAccessModifiers (
6626                                                 Modifiers.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6627                                                 Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
6628                                 }
6629                         }
6630
6631                         // When one accessor does not exist and property hides base one
6632                         // we need to propagate this upwards
6633                         if (set_accessor == null)
6634                                 set_accessor = get_accessor;
6635
6636                         //
6637                         // Get the less restrictive access
6638                         //
6639                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6640                 }
6641
6642                 public override void Emit ()
6643                 {
6644                         //
6645                         // The PropertyBuilder can be null for explicit implementations, in that
6646                         // case, we do not actually emit the ".property", so there is nowhere to
6647                         // put the attribute
6648                         //
6649                         if (PropertyBuilder != null) {
6650                                 if (OptAttributes != null)
6651                                         OptAttributes.Emit ();
6652
6653                                 if (TypeManager.IsDynamicType (member_type))
6654                                         PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
6655                         }
6656
6657                         if (!Get.IsDummy)
6658                                 Get.Emit (Parent);
6659
6660                         if (!Set.IsDummy)
6661                                 Set.Emit (Parent);
6662
6663                         base.Emit ();
6664                 }
6665
6666                 /// <summary>
6667                 /// Tests whether accessors are not in collision with some method (CS0111)
6668                 /// </summary>
6669                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6670                 {
6671                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6672                 }
6673
6674                 public override bool IsUsed
6675                 {
6676                         get {
6677                                 if (IsExplicitImpl)
6678                                         return true;
6679
6680                                 return Get.IsUsed | Set.IsUsed;
6681                         }
6682                 }
6683
6684                 protected override void SetMemberName (MemberName new_name)
6685                 {
6686                         base.SetMemberName (new_name);
6687
6688                         Get.UpdateName (this);
6689                         Set.UpdateName (this);
6690                 }
6691
6692                 public override string[] ValidAttributeTargets {
6693                         get {
6694                                 return attribute_targets;
6695                         }
6696                 }
6697
6698                 //
6699                 //   Represents header string for documentation comment.
6700                 //
6701                 public override string DocCommentHeader {
6702                         get { return "P:"; }
6703                 }
6704         }
6705                         
6706         public class Property : PropertyBase
6707         {
6708                 public sealed class BackingField : Field
6709                 {
6710                         readonly Property property;
6711
6712                         public BackingField (Property p)
6713                                 : base (p.Parent, p.type_name,
6714                                 Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
6715                                 new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
6716                         {
6717                                 this.property = p;
6718                         }
6719
6720                         public override string GetSignatureForError ()
6721                         {
6722                                 return property.GetSignatureForError ();
6723                         }
6724                 }
6725
6726                 const int AllowedModifiers =
6727                         Modifiers.NEW |
6728                         Modifiers.PUBLIC |
6729                         Modifiers.PROTECTED |
6730                         Modifiers.INTERNAL |
6731                         Modifiers.PRIVATE |
6732                         Modifiers.STATIC |
6733                         Modifiers.SEALED |
6734                         Modifiers.OVERRIDE |
6735                         Modifiers.ABSTRACT |
6736                         Modifiers.UNSAFE |
6737                         Modifiers.EXTERN |
6738                         Modifiers.VIRTUAL;
6739
6740                 const int AllowedInterfaceModifiers =
6741                         Modifiers.NEW;
6742
6743                 public Property (DeclSpace parent, FullNamedExpression type, int mod,
6744                                  MemberName name, Attributes attrs, Accessor get_block,
6745                                  Accessor set_block, bool define_set_first)
6746                         : this (parent, type, mod, name, attrs, get_block, set_block,
6747                                 define_set_first, null)
6748                 {
6749                 }
6750                 
6751                 public Property (DeclSpace parent, FullNamedExpression type, int mod,
6752                                  MemberName name, Attributes attrs, Accessor get_block,
6753                                  Accessor set_block, bool define_set_first, Block current_block)
6754                         : base (parent, type, mod,
6755                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
6756                                 name, attrs, define_set_first)
6757                 {
6758                         if (get_block == null)
6759                                 Get = new GetMethod (this);
6760                         else
6761                                 Get = new GetMethod (this, get_block);
6762
6763                         if (set_block == null)
6764                                 Set = new SetMethod (this);
6765                         else
6766                                 Set = new SetMethod (this, set_block);
6767
6768                         if (!IsInterface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
6769                                 get_block != null && get_block.Block == null &&
6770                                 set_block != null && set_block.Block == null) {
6771                                 if (RootContext.Version <= LanguageVersion.ISO_2)
6772                                         Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
6773
6774                                 Get.ModFlags |= Modifiers.COMPILER_GENERATED;
6775                                 Set.ModFlags |= Modifiers.COMPILER_GENERATED;
6776                         }
6777                 }
6778
6779                 void CreateAutomaticProperty ()
6780                 {
6781                         // Create backing field
6782                         Field field = new BackingField (this);
6783                         if (!field.Define ())
6784                                 return;
6785
6786                         Parent.PartialContainer.AddField (field);
6787
6788                         FieldExpr fe = new FieldExpr (field.FieldBuilder, Location);
6789                         if ((field.ModFlags & Modifiers.STATIC) == 0)
6790                                 fe.InstanceExpression = new CompilerGeneratedThis (fe.Type, Location);
6791
6792                         // Create get block
6793                         Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
6794                         Return r = new Return (fe, Location);
6795                         Get.Block.AddStatement (r);
6796
6797                         // Create set block
6798                         Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location);
6799                         Assign a = new SimpleAssign (fe, new SimpleName ("value", Location));
6800                         Set.Block.AddStatement (new StatementExpression (a));
6801                 }
6802
6803                 public override bool Define ()
6804                 {
6805                         if (!base.Define ())
6806                                 return false;
6807
6808                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6809
6810                         if ((Get.ModFlags & Modifiers.COMPILER_GENERATED) != 0)
6811                                 CreateAutomaticProperty ();
6812
6813                         if (!DefineAccessors ())
6814                                 return false;
6815
6816                         if (!CheckBase ())
6817                                 return false;
6818
6819                         // FIXME - PropertyAttributes.HasDefault ?
6820
6821                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6822                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, null);
6823
6824                         if (!Get.IsDummy) {
6825                                 PropertyBuilder.SetGetMethod (GetBuilder);
6826                                 Parent.MemberCache.AddMember (GetBuilder, Get);
6827                         }
6828
6829                         if (!Set.IsDummy) {
6830                                 PropertyBuilder.SetSetMethod (SetBuilder);
6831                                 Parent.MemberCache.AddMember (SetBuilder, Set);
6832                         }
6833                         
6834                         TypeManager.RegisterProperty (PropertyBuilder, this);
6835                         Parent.MemberCache.AddMember (PropertyBuilder, this);
6836                         return true;
6837                 }
6838
6839                 public override void Emit ()
6840                 {
6841                         if (((Set.ModFlags | Get.ModFlags) & (Modifiers.STATIC | Modifiers.COMPILER_GENERATED)) == Modifiers.COMPILER_GENERATED && Parent.PartialContainer.HasExplicitLayout) {
6842                                 Report.Error (842, Location,
6843                                         "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
6844                                         GetSignatureForError ());
6845                         }
6846
6847                         base.Emit ();
6848                 }
6849
6850                 protected override PropertyInfo ResolveBaseProperty ()
6851                 {
6852                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6853                                 Parent.TypeBuilder, Name, ParametersCompiled.EmptyReadOnlyParameters, null, true) as PropertyInfo;
6854                 }
6855         }
6856
6857         /// </summary>
6858         ///  Gigantic workaround  for lameness in SRE follows :
6859         ///  This class derives from EventInfo and attempts to basically
6860         ///  wrap around the EventBuilder so that FindMembers can quickly
6861         ///  return this in it search for members
6862         /// </summary>
6863         public class MyEventBuilder : EventInfo {
6864                 
6865                 //
6866                 // We use this to "point" to our Builder which is
6867                 // not really a MemberInfo
6868                 //
6869                 EventBuilder MyBuilder;
6870                 
6871                 //
6872                 // We "catch" and wrap these methods
6873                 //
6874                 MethodInfo raise, remove, add;
6875
6876                 EventAttributes attributes;
6877                 Type declaring_type, reflected_type, event_type;
6878                 string name;
6879
6880                 Event my_event;
6881
6882                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6883                 {
6884                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6885
6886                         // And now store the values in our own fields.
6887                         
6888                         declaring_type = type_builder;
6889
6890                         reflected_type = type_builder;
6891                         
6892                         attributes = event_attr;
6893                         this.name = name;
6894                         my_event = ev;
6895                         this.event_type = event_type;
6896                 }
6897                 
6898                 //
6899                 // Methods that you have to override.  Note that you only need 
6900                 // to "implement" the variants that take the argument (those are
6901                 // the "abstract" methods, the others (GetAddMethod()) are 
6902                 // regular.
6903                 //
6904                 public override MethodInfo GetAddMethod (bool nonPublic)
6905                 {
6906                         return add;
6907                 }
6908                 
6909                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6910                 {
6911                         return remove;
6912                 }
6913                 
6914                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6915                 {
6916                         return raise;
6917                 }
6918                 
6919                 //
6920                 // These methods make "MyEventInfo" look like a Builder
6921                 //
6922                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6923                 {
6924                         raise = raiseMethod;
6925                         MyBuilder.SetRaiseMethod (raiseMethod);
6926                 }
6927
6928                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6929                 {
6930                         remove = removeMethod;
6931                         MyBuilder.SetRemoveOnMethod (removeMethod);
6932                 }
6933
6934                 public void SetAddOnMethod (MethodBuilder addMethod)
6935                 {
6936                         add = addMethod;
6937                         MyBuilder.SetAddOnMethod (addMethod);
6938                 }
6939
6940                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6941                 {
6942                         MyBuilder.SetCustomAttribute (cb);
6943                 }
6944                 
6945                 public override object [] GetCustomAttributes (bool inherit)
6946                 {
6947                         // FIXME : There's nothing which can be seemingly done here because
6948                         // we have no way of getting at the custom attribute objects of the
6949                         // EventBuilder !
6950                         return null;
6951                 }
6952
6953                 public override object [] GetCustomAttributes (Type t, bool inherit)
6954                 {
6955                         // FIXME : Same here !
6956                         return null;
6957                 }
6958
6959                 public override bool IsDefined (Type t, bool b)
6960                 {
6961                         return true;
6962                 }
6963
6964                 public override EventAttributes Attributes {
6965                         get {
6966                                 return attributes;
6967                         }
6968                 }
6969
6970                 public override string Name {
6971                         get {
6972                                 return name;
6973                         }
6974                 }
6975
6976                 public override Type DeclaringType {
6977                         get {
6978                                 return declaring_type;
6979                         }
6980                 }
6981
6982                 public override Type ReflectedType {
6983                         get {
6984                                 return reflected_type;
6985                         }
6986                 }
6987
6988                 public Type EventType {
6989                         get {
6990                                 return event_type;
6991                         }
6992                 }
6993                 
6994                 public void SetUsed ()
6995                 {
6996                         if (my_event != null) {
6997 //                              my_event.SetAssigned ();
6998                                 my_event.SetMemberIsUsed ();
6999                         }
7000                 }
7001         }
7002         
7003         /// <summary>
7004         /// For case when event is declared like property (with add and remove accessors).
7005         /// </summary>
7006         public class EventProperty: Event {
7007                 abstract class AEventPropertyAccessor : AEventAccessor
7008                 {
7009                         protected AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7010                                 base (method, accessor, prefix)
7011                         {
7012                         }
7013
7014                         public override MethodBuilder Define (DeclSpace ds)
7015                         {
7016                                 CheckAbstractAndExtern (block != null);
7017                                 return base.Define (ds);
7018                         }
7019                         
7020                         public override string GetSignatureForError ()
7021                         {
7022                                 return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
7023                         }
7024                 }
7025
7026                 sealed class AddDelegateMethod: AEventPropertyAccessor
7027                 {
7028                         public AddDelegateMethod (Event method, Accessor accessor):
7029                                 base (method, accessor, AddPrefix)
7030                         {
7031                         }
7032                 }
7033
7034                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7035                 {
7036                         public RemoveDelegateMethod (Event method, Accessor accessor):
7037                                 base (method, accessor, RemovePrefix)
7038                         {
7039                         }
7040                 }
7041
7042
7043                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7044
7045                 public EventProperty (DeclSpace parent, FullNamedExpression type, int mod_flags,
7046                                       MemberName name,
7047                                       Attributes attrs, Accessor add, Accessor remove)
7048                         : base (parent, type, mod_flags, name, attrs)
7049                 {
7050                         Add = new AddDelegateMethod (this, add);
7051                         Remove = new RemoveDelegateMethod (this, remove);
7052                 }
7053
7054                 public override bool Define()
7055                 {
7056                         if (!base.Define ())
7057                                 return false;
7058
7059                         SetMemberIsUsed ();
7060                         return true;
7061                 }
7062
7063                 public override string[] ValidAttributeTargets {
7064                         get {
7065                                 return attribute_targets;
7066                         }
7067                 }
7068         }
7069
7070         /// <summary>
7071         /// Event is declared like field.
7072         /// </summary>
7073         public class EventField : Event {
7074                 abstract class EventFieldAccessor : AEventAccessor
7075                 {
7076                         protected EventFieldAccessor (Event method, string prefix)
7077                                 : base (method, prefix)
7078                         {
7079                         }
7080
7081                         public override void Emit (DeclSpace parent)
7082                         {
7083                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
7084                                         if (parent is Class) {
7085                                                 MethodBuilder mb = method_data.MethodBuilder;
7086                                                 mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7087                                         }
7088
7089                                         // TODO: because we cannot use generics yet
7090                                         FieldInfo field_info = ((EventField) method).BackingField.FieldBuilder;
7091                                         FieldExpr f_expr = new FieldExpr (field_info, Location);
7092                                         if ((method.ModFlags & Modifiers.STATIC) == 0)
7093                                                 f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.FieldType, Location);
7094
7095                                         block = new ToplevelBlock (Compiler, ParameterInfo, Location);
7096                                         block.AddStatement (new StatementExpression (
7097                                                 new CompoundAssign (Operation,
7098                                                         f_expr,
7099                                                         block.GetParameterReference (ParameterInfo[0].Name, Location))));
7100                                 }
7101
7102                                 base.Emit (parent);
7103                         }
7104
7105                         protected abstract Binary.Operator Operation { get; }
7106                 }
7107
7108                 sealed class AddDelegateMethod: EventFieldAccessor
7109                 {
7110                         public AddDelegateMethod (Event method):
7111                                 base (method, AddPrefix)
7112                         {
7113                         }
7114
7115                         protected override Binary.Operator Operation {
7116                                 get { return Binary.Operator.Addition; }
7117                         }
7118                 }
7119
7120                 sealed class RemoveDelegateMethod: EventFieldAccessor
7121                 {
7122                         public RemoveDelegateMethod (Event method):
7123                                 base (method, RemovePrefix)
7124                         {
7125                         }
7126
7127                         protected override Binary.Operator Operation {
7128                                 get { return Binary.Operator.Subtraction; }
7129                         }
7130                 }
7131
7132
7133                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7134                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7135
7136                 public Field BackingField;
7137                 public Expression Initializer;
7138
7139                 public EventField (DeclSpace parent, FullNamedExpression type, int mod_flags, MemberName name, Attributes attrs)
7140                         : base (parent, type, mod_flags, name, attrs)
7141                 {
7142                         Add = new AddDelegateMethod (this);
7143                         Remove = new RemoveDelegateMethod (this);
7144                 }
7145
7146                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
7147                 {
7148                         if (a.Target == AttributeTargets.Field) {
7149                                 BackingField.ApplyAttributeBuilder (a, cb, pa);
7150                                 return;
7151                         }
7152
7153                         if (a.Target == AttributeTargets.Method) {
7154                                 int errors = Report.Errors;
7155                                 Add.ApplyAttributeBuilder (a, cb, pa);
7156                                 if (errors == Report.Errors)
7157                                         Remove.ApplyAttributeBuilder (a, cb, pa);
7158                                 return;
7159                         }
7160
7161                         base.ApplyAttributeBuilder (a, cb, pa);
7162                 }
7163
7164                 public override bool Define()
7165                 {
7166                         if (!base.Define ())
7167                                 return false;
7168
7169                         if (Initializer != null && (ModFlags & Modifiers.ABSTRACT) != 0) {
7170                                 Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7171                                         GetSignatureForError ());
7172                         }
7173
7174                         if (!HasBackingField) {
7175                                 SetMemberIsUsed ();
7176                                 return true;
7177                         }
7178
7179                         // FIXME: We are unable to detect whether generic event is used because
7180                         // we are using FieldExpr instead of EventExpr for event access in that
7181                         // case.  When this issue will be fixed this hack can be removed.
7182                         if (TypeManager.IsGenericType (MemberType))
7183                                 SetMemberIsUsed ();
7184
7185                         if (Add.IsInterfaceImplementation)
7186                                 SetMemberIsUsed ();
7187
7188                         TypeManager.RegisterEventField (EventBuilder, this);
7189
7190                         BackingField = new Field (Parent,
7191                                 new TypeExpression (MemberType, Location),
7192                                 Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
7193                                 MemberName, null);
7194
7195                         Parent.PartialContainer.AddField (BackingField);
7196                         BackingField.Initializer = Initializer;
7197                         BackingField.ModFlags &= ~Modifiers.COMPILER_GENERATED;
7198
7199                         // Call define because we passed fields definition
7200                         return BackingField.Define ();
7201                 }
7202
7203                 bool HasBackingField {
7204                         get {
7205                                 return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0;
7206                         }
7207                 }
7208
7209                 public override string[] ValidAttributeTargets 
7210                 {
7211                         get {
7212                                 return HasBackingField ? attribute_targets : attribute_targets_interface;
7213                         }
7214                 }
7215         }
7216
7217         public abstract class Event : PropertyBasedMember {
7218                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7219                 {
7220                         protected readonly Event method;
7221                         ImplicitParameter param_attr;
7222
7223                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7224
7225                         public const string AddPrefix = "add_";
7226                         public const string RemovePrefix = "remove_";
7227
7228                         protected AEventAccessor (Event method, string prefix)
7229                                 : base (method, prefix)
7230                         {
7231                                 this.method = method;
7232                                 this.ModFlags = method.ModFlags;
7233                         }
7234
7235                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7236                                 : base (method, accessor, prefix)
7237                         {
7238                                 this.method = method;
7239                                 this.ModFlags = method.ModFlags;
7240                         }
7241
7242                         public bool IsInterfaceImplementation {
7243                                 get { return method_data.implementing != null; }
7244                         }
7245
7246                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
7247                         {
7248                                 if (a.IsInternalMethodImplAttribute) {
7249                                         method.is_external_implementation = true;
7250                                 }
7251
7252                                 base.ApplyAttributeBuilder (a, cb, pa);
7253                         }
7254
7255                         protected override void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
7256                         {
7257                                 if (a.Target == AttributeTargets.Parameter) {
7258                                         if (param_attr == null)
7259                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7260
7261                                         param_attr.ApplyAttributeBuilder (a, cb, pa);
7262                                         return;
7263                                 }
7264
7265                                 base.ApplyAttributeBuilder (a, cb, pa);
7266                         }
7267
7268                         public override AttributeTargets AttributeTargets {
7269                                 get {
7270                                         return AttributeTargets.Method;
7271                                 }
7272                         }
7273
7274                         public override bool IsClsComplianceRequired ()
7275                         {
7276                                 return method.IsClsComplianceRequired ();
7277                         }
7278
7279                         public virtual MethodBuilder Define (DeclSpace parent)
7280                         {
7281                                 method_data = new MethodData (method, method.ModFlags,
7282                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7283
7284                                 if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
7285                                         return null;
7286
7287                                 MethodBuilder mb = method_data.MethodBuilder;
7288                                 ParameterInfo.ApplyAttributes (mb);
7289                                 return mb;
7290                         }
7291
7292                         public override Type ReturnType {
7293                                 get {
7294                                         return TypeManager.void_type;
7295                                 }
7296                         }
7297
7298                         public override ObsoleteAttribute GetObsoleteAttribute ()
7299                         {
7300                                 return method.GetObsoleteAttribute ();
7301                         }
7302
7303                         public override string[] ValidAttributeTargets {
7304                                 get {
7305                                         return attribute_targets;
7306                                 }
7307                         }
7308
7309                         public override ParametersCompiled ParameterInfo {
7310                                 get {
7311                                         return method.parameters;
7312                                 }
7313                         }
7314                 }
7315
7316
7317                 const int AllowedModifiers =
7318                         Modifiers.NEW |
7319                         Modifiers.PUBLIC |
7320                         Modifiers.PROTECTED |
7321                         Modifiers.INTERNAL |
7322                         Modifiers.PRIVATE |
7323                         Modifiers.STATIC |
7324                         Modifiers.VIRTUAL |
7325                         Modifiers.SEALED |
7326                         Modifiers.OVERRIDE |
7327                         Modifiers.UNSAFE |
7328                         Modifiers.ABSTRACT |
7329                         Modifiers.EXTERN;
7330
7331                 const int AllowedInterfaceModifiers =
7332                         Modifiers.NEW;
7333
7334                 public AEventAccessor Add, Remove;
7335                 public MyEventBuilder     EventBuilder;
7336                 public MethodBuilder AddBuilder, RemoveBuilder;
7337
7338                 ParametersCompiled parameters;
7339
7340                 protected Event (DeclSpace parent, FullNamedExpression type, int mod_flags, MemberName name, Attributes attrs)
7341                         : base (parent, null, type, mod_flags,
7342                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
7343                                 name, attrs)
7344                 {
7345                 }
7346
7347                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
7348                 {
7349                         if ((a.HasSecurityAttribute)) {
7350                                 a.Error_InvalidSecurityParent ();
7351                                 return;
7352                         }
7353                         
7354                         EventBuilder.SetCustomAttribute (cb);
7355                 }
7356
7357                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7358                 {
7359                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7360                 }
7361
7362                 public override AttributeTargets AttributeTargets {
7363                         get {
7364                                 return AttributeTargets.Event;
7365                         }
7366                 }
7367
7368                 public override bool Define ()
7369                 {
7370                         if (!base.Define ())
7371                                 return false;
7372
7373                         if (!TypeManager.IsDelegateType (MemberType)) {
7374                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7375                         }
7376
7377                         parameters = ParametersCompiled.CreateFullyResolved (
7378                                 new Parameter (null, "value", Parameter.Modifier.NONE, null, Location), MemberType);
7379
7380                         if (!CheckBase ())
7381                                 return false;
7382
7383                         if (TypeManager.delegate_combine_delegate_delegate == null) {
7384                                 TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
7385                                         TypeManager.delegate_type, "Combine", Location,
7386                                         TypeManager.delegate_type, TypeManager.delegate_type);
7387                         }
7388                         if (TypeManager.delegate_remove_delegate_delegate == null) {
7389                                 TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
7390                                         TypeManager.delegate_type, "Remove", Location,
7391                                         TypeManager.delegate_type, TypeManager.delegate_type);
7392                         }
7393
7394                         //
7395                         // Now define the accessors
7396                         //
7397
7398                         AddBuilder = Add.Define (Parent);
7399                         if (AddBuilder == null)
7400                                 return false;
7401
7402                         RemoveBuilder = Remove.Define (Parent);
7403                         if (RemoveBuilder == null)
7404                                 return false;
7405
7406                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7407                         EventBuilder.SetAddOnMethod (AddBuilder);
7408                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7409
7410                         Parent.MemberCache.AddMember (EventBuilder, this);
7411                         Parent.MemberCache.AddMember (AddBuilder, Add);
7412                         Parent.MemberCache.AddMember (RemoveBuilder, Remove);
7413                         
7414                         return true;
7415                 }
7416
7417                 public override void Emit ()
7418                 {
7419                         if (OptAttributes != null) {
7420                                 OptAttributes.Emit ();
7421                         }
7422
7423                         Add.Emit (Parent);
7424                         Remove.Emit (Parent);
7425
7426                         base.Emit ();
7427                 }
7428
7429                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7430                 {
7431                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7432                                 Parent.TypeBuilder, Name);
7433
7434                         if (mi == null)
7435                                 return null;
7436
7437                         AParametersCollection pd = TypeManager.GetParameterData (mi);
7438                         base_ret_type = pd.Types [0];
7439                         return mi;
7440                 }
7441
7442                 //
7443                 //   Represents header string for documentation comment.
7444                 //
7445                 public override string DocCommentHeader {
7446                         get { return "E:"; }
7447                 }
7448         }
7449
7450  
7451         public class Indexer : PropertyBase
7452         {
7453                 public class GetIndexerMethod : GetMethod
7454                 {
7455                         ParametersCompiled parameters;
7456
7457                         public GetIndexerMethod (Indexer method):
7458                                 base (method)
7459                         {
7460                                 this.parameters = method.parameters;
7461                         }
7462
7463                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7464                                 base (method, accessor)
7465                         {
7466                                 parameters = accessor.Parameters;
7467                         }
7468
7469                         public override MethodBuilder Define (DeclSpace parent)
7470                         {
7471                                 parameters.Resolve (this);
7472                                 return base.Define (parent);
7473                         }
7474                         
7475                         public override bool EnableOverloadChecks (MemberCore overload)
7476                         {
7477                                 if (base.EnableOverloadChecks (overload)) {
7478                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7479                                         return true;
7480                                 }
7481
7482                                 return false;
7483                         }                       
7484
7485                         public override ParametersCompiled ParameterInfo {
7486                                 get {
7487                                         return parameters;
7488                                 }
7489                         }
7490                 }
7491
7492                 public class SetIndexerMethod: SetMethod
7493                 {
7494                         public SetIndexerMethod (Indexer method):
7495                                 base (method)
7496                         {
7497                                 parameters = ParametersCompiled.MergeGenerated (method.parameters, false, parameters [0], null);
7498                         }
7499
7500                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7501                                 base (method, accessor)
7502                         {
7503                                 parameters = method.Get.IsDummy ? accessor.Parameters : accessor.Parameters.Clone ();                   
7504                         }
7505
7506                         public override bool EnableOverloadChecks (MemberCore overload)
7507                         {
7508                                 if (base.EnableOverloadChecks (overload)) {
7509                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7510                                         return true;
7511                                 }
7512
7513                                 return false;
7514                         }
7515                 }
7516
7517                 const int AllowedModifiers =
7518                         Modifiers.NEW |
7519                         Modifiers.PUBLIC |
7520                         Modifiers.PROTECTED |
7521                         Modifiers.INTERNAL |
7522                         Modifiers.PRIVATE |
7523                         Modifiers.VIRTUAL |
7524                         Modifiers.SEALED |
7525                         Modifiers.OVERRIDE |
7526                         Modifiers.UNSAFE |
7527                         Modifiers.EXTERN |
7528                         Modifiers.ABSTRACT;
7529
7530                 const int AllowedInterfaceModifiers =
7531                         Modifiers.NEW;
7532
7533                 public readonly ParametersCompiled parameters;
7534
7535                 public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, int mod,
7536                                 ParametersCompiled parameters, Attributes attrs,
7537                                 Accessor get_block, Accessor set_block, bool define_set_first)
7538                         : base (parent, type, mod,
7539                                 parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
7540                                 name, attrs, define_set_first)
7541                 {
7542                         this.parameters = parameters;
7543
7544                         if (get_block == null)
7545                                 Get = new GetIndexerMethod (this);
7546                         else
7547                                 Get = new GetIndexerMethod (this, get_block);
7548
7549                         if (set_block == null)
7550                                 Set = new SetIndexerMethod (this);
7551                         else
7552                                 Set = new SetIndexerMethod (this, set_block);
7553                 }
7554
7555                 protected override bool CheckForDuplications ()
7556                 {
7557                         return Parent.MemberCache.CheckExistingMembersOverloads (this, GetFullName (MemberName), parameters, Report);
7558                 }
7559                 
7560                 public override bool Define ()
7561                 {
7562                         if (!base.Define ())
7563                                 return false;
7564
7565                         if (!DefineParameters (parameters))
7566                                 return false;
7567
7568                         if (OptAttributes != null) {
7569                                 Attribute indexer_attr = OptAttributes.Search (PredefinedAttributes.Get.IndexerName);
7570                                 if (indexer_attr != null) {
7571                                         // Remove the attribute from the list because it is not emitted
7572                                         OptAttributes.Attrs.Remove (indexer_attr);
7573
7574                                         string name = indexer_attr.GetIndexerAttributeValue ();
7575                                         if (name == null)
7576                                                 return false;
7577
7578                                         ShortName = name;
7579
7580                                         if (IsExplicitImpl) {
7581                                                 Report.Error (415, indexer_attr.Location,
7582                                                               "The `IndexerName' attribute is valid only on an " +
7583                                                               "indexer that is not an explicit interface member declaration");
7584                                                 return false;
7585                                         }
7586
7587                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7588                                                 Report.Error (609, indexer_attr.Location,
7589                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7590                                                 return false;
7591                                         }
7592                                 }
7593                         }
7594
7595                         if (InterfaceType != null) {
7596                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7597                                 if (base_IndexerName != Name)
7598                                         ShortName = base_IndexerName;
7599                         }
7600
7601                         if (!Parent.PartialContainer.AddMember (this) ||
7602                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7603                                 return false;
7604
7605                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7606                         
7607                         if (!DefineAccessors ())
7608                                 return false;
7609
7610                         if (!CheckBase ())
7611                                 return false;
7612
7613                         //
7614                         // Now name the parameters
7615                         //
7616                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7617                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, parameters.GetEmitTypes ());
7618
7619                         if (!Get.IsDummy) {
7620                                 PropertyBuilder.SetGetMethod (GetBuilder);
7621                                 Parent.MemberCache.AddMember (GetBuilder, Get);
7622                         }
7623
7624                         if (!Set.IsDummy) {
7625                                 PropertyBuilder.SetSetMethod (SetBuilder);
7626                                 Parent.MemberCache.AddMember (SetBuilder, Set);
7627                         }
7628                                 
7629                         TypeManager.RegisterIndexer (PropertyBuilder, parameters);
7630                         Parent.MemberCache.AddMember (PropertyBuilder, this);
7631                         return true;
7632                 }
7633
7634                 public override bool EnableOverloadChecks (MemberCore overload)
7635                 {
7636                         if (overload is Indexer) {
7637                                 caching_flags |= Flags.MethodOverloadsExist;
7638                                 return true;
7639                         }
7640
7641                         return base.EnableOverloadChecks (overload);
7642                 }
7643
7644                 public override string GetDocCommentName (DeclSpace ds)
7645                 {
7646                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7647                 }
7648
7649                 public override string GetSignatureForError ()
7650                 {
7651                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7652                         if (MemberName.Left != null) {
7653                                 sb.Append ('.');
7654                                 sb.Append (MemberName.Left.GetSignatureForError ());
7655                         }
7656
7657                         sb.Append (".this");
7658                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7659                         return sb.ToString ();
7660                 }
7661
7662                 protected override PropertyInfo ResolveBaseProperty ()
7663                 {
7664                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7665                                 Parent.TypeBuilder, Name, parameters, null, true) as PropertyInfo;
7666                 }
7667
7668                 protected override bool VerifyClsCompliance ()
7669                 {
7670                         if (!base.VerifyClsCompliance ())
7671                                 return false;
7672
7673                         parameters.VerifyClsCompliance ();
7674                         return true;
7675                 }
7676         }
7677
7678         public class Operator : MethodOrOperator {
7679
7680                 const int AllowedModifiers =
7681                         Modifiers.PUBLIC |
7682                         Modifiers.UNSAFE |
7683                         Modifiers.EXTERN |
7684                         Modifiers.STATIC;
7685
7686                 public enum OpType : byte {
7687
7688                         // Unary operators
7689                         LogicalNot,
7690                         OnesComplement,
7691                         Increment,
7692                         Decrement,
7693                         True,
7694                         False,
7695
7696                         // Unary and Binary operators
7697                         Addition,
7698                         Subtraction,
7699
7700                         UnaryPlus,
7701                         UnaryNegation,
7702                         
7703                         // Binary operators
7704                         Multiply,
7705                         Division,
7706                         Modulus,
7707                         BitwiseAnd,
7708                         BitwiseOr,
7709                         ExclusiveOr,
7710                         LeftShift,
7711                         RightShift,
7712                         Equality,
7713                         Inequality,
7714                         GreaterThan,
7715                         LessThan,
7716                         GreaterThanOrEqual,
7717                         LessThanOrEqual,
7718
7719                         // Implicit and Explicit
7720                         Implicit,
7721                         Explicit,
7722
7723                         // Just because of enum
7724                         TOP
7725                 };
7726
7727                 public readonly OpType OperatorType;
7728
7729                 static readonly string [] [] names;
7730
7731                 static Operator ()
7732                 {
7733                         names = new string[(int)OpType.TOP][];
7734                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
7735                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
7736                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
7737                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
7738                         names [(int) OpType.True] = new string [] { "true", "op_True" };
7739                         names [(int) OpType.False] = new string [] { "false", "op_False" };
7740                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
7741                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
7742                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
7743                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
7744                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
7745                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
7746                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
7747                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
7748                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
7749                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
7750                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
7751                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
7752                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
7753                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
7754                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
7755                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
7756                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
7757                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
7758                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
7759                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
7760                 }
7761                 
7762                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
7763                                  int mod_flags, ParametersCompiled parameters,
7764                                  ToplevelBlock block, Attributes attrs, Location loc)
7765                         : base (parent, null, ret_type, mod_flags, AllowedModifiers,
7766                                 new MemberName (GetMetadataName (type), loc), attrs, parameters)
7767                 {
7768                         OperatorType = type;
7769                         Block = block;
7770                 }
7771
7772                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
7773                 {
7774                         if (a.Type == pa.Conditional) {
7775                                 Error_ConditionalAttributeIsNotValid ();
7776                                 return;
7777                         }
7778
7779                         base.ApplyAttributeBuilder (a, cb, pa);
7780                 }
7781                 
7782                 public override bool Define ()
7783                 {
7784                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7785                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7786                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7787                         }
7788
7789                         if (!base.Define ())
7790                                 return false;
7791
7792                         // imlicit and explicit operator of same types are not allowed
7793                         if (OperatorType == OpType.Explicit)
7794                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), Parameters, Report);
7795                         else if (OperatorType == OpType.Implicit)
7796                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters, Report);
7797
7798                         Type declaring_type = MethodData.DeclaringType;
7799                         Type return_type = MemberType;
7800                         Type first_arg_type = ParameterTypes [0];
7801                         
7802                         Type first_arg_type_unwrap = first_arg_type;
7803                         if (TypeManager.IsNullableType (first_arg_type))
7804                                 first_arg_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (first_arg_type) [0]);
7805                         
7806                         Type return_type_unwrap = return_type;
7807                         if (TypeManager.IsNullableType (return_type))
7808                                 return_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (return_type) [0]);
7809
7810                         if (TypeManager.IsDynamicType (return_type) || TypeManager.IsDynamicType (first_arg_type)) {
7811                                 Report.Error (1964, Location,
7812                                         "User-defined operator `{0}' cannot convert to or from the dynamic type",
7813                                         GetSignatureForError ());
7814
7815                                 return false;
7816                         }
7817
7818                         //
7819                         // Rules for conversion operators
7820                         //
7821                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7822                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type){
7823                                         Report.Error (555, Location,
7824                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7825                                         return false;
7826                                 }
7827                                 
7828                                 Type conv_type;
7829                                 if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
7830                                         conv_type = first_arg_type;
7831                                 } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
7832                                         conv_type = return_type;
7833                                 } else {
7834                                         Report.Error (556, Location, 
7835                                                 "User-defined conversion must convert to or from the enclosing type");
7836                                         return false;
7837                                 }
7838
7839                                 //
7840                                 // Because IsInterface and IsClass are not supported
7841                                 //
7842                                 if (!TypeManager.IsGenericParameter (conv_type)) {
7843                                         if (conv_type.IsInterface) {
7844                                                 Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7845                                                         GetSignatureForError ());
7846                                                 return false;
7847                                         }
7848
7849                                         if (conv_type.IsClass) {
7850                                                 if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
7851                                                         Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
7852                                                                 GetSignatureForError ());
7853                                                         return false;
7854                                                 }
7855
7856                                                 if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
7857                                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
7858                                                                 GetSignatureForError ());
7859                                                         return false;
7860                                                 }
7861                                         }
7862                                 }
7863                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7864                                 if (first_arg_type != declaring_type || Parameters.Types [1] != TypeManager.int32_type) {
7865                                         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");
7866                                         return false;
7867                                 }
7868                         } else if (Parameters.Count == 1) {
7869                                 // Checks for Unary operators
7870
7871                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7872                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7873                                                 Report.Error (448, Location,
7874                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7875                                                 return false;
7876                                         }
7877                                         if (first_arg_type != declaring_type) {
7878                                                 Report.Error (
7879                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7880                                                 return false;
7881                                         }
7882                                 }
7883                                 
7884                                 if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)){
7885                                         Report.Error (562, Location,
7886                                                 "The parameter type of a unary operator must be the containing type");
7887                                         return false;
7888                                 }
7889                                 
7890                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7891                                         if (return_type != TypeManager.bool_type){
7892                                                 Report.Error (
7893                                                         215, Location,
7894                                                         "The return type of operator True or False " +
7895                                                         "must be bool");
7896                                                 return false;
7897                                         }
7898                                 }
7899                                 
7900                         } else {
7901                                 // Checks for Binary operators
7902                                 
7903                                 if (first_arg_type != declaring_type &&
7904                                     Parameters.Types [1] != declaring_type){
7905                                         Report.Error (
7906                                                 563, Location,
7907                                                 "One of the parameters of a binary operator must " +
7908                                                 "be the containing type");
7909                                         return false;
7910                                 }
7911                         }
7912
7913                         return true;
7914                 }
7915
7916                 protected override bool ResolveMemberType ()
7917                 {
7918                         if (!base.ResolveMemberType ())
7919                                 return false;
7920
7921                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7922                         return true;
7923                 }
7924
7925                 // Operator cannot be override
7926                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7927                 {
7928                         return null;
7929                 }
7930
7931                 public static string GetName (OpType ot)
7932                 {
7933                         return names [(int) ot] [0];
7934                 }
7935
7936                 public static string GetName (string metadata_name)
7937                 {
7938                         for (int i = 0; i < names.Length; ++i) {
7939                                 if (names [i] [1] == metadata_name)
7940                                         return names [i] [0];
7941                         }
7942                         return null;
7943                 }
7944
7945                 public static string GetMetadataName (OpType ot)
7946                 {
7947                         return names [(int) ot] [1];
7948                 }
7949
7950                 public static string GetMetadataName (string name)
7951                 {
7952                         for (int i = 0; i < names.Length; ++i) {
7953                                 if (names [i] [0] == name)
7954                                         return names [i] [1];
7955                         }
7956                         return null;
7957                 }
7958
7959                 public OpType GetMatchingOperator ()
7960                 {
7961                         switch (OperatorType) {
7962                         case OpType.Equality:
7963                                 return OpType.Inequality;
7964                         case OpType.Inequality:
7965                                 return OpType.Equality;
7966                         case OpType.True:
7967                                 return OpType.False;
7968                         case OpType.False:
7969                                 return OpType.True;
7970                         case OpType.GreaterThan:
7971                                 return OpType.LessThan;
7972                         case OpType.LessThan:
7973                                 return OpType.GreaterThan;
7974                         case OpType.GreaterThanOrEqual:
7975                                 return OpType.LessThanOrEqual;
7976                         case OpType.LessThanOrEqual:
7977                                 return OpType.GreaterThanOrEqual;
7978                         default:
7979                                 return OpType.TOP;
7980                         }
7981                 }
7982
7983                 public override string GetSignatureForError ()
7984                 {
7985                         StringBuilder sb = new StringBuilder ();
7986                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7987                                 sb.AppendFormat ("{0}.{1} operator {2}",
7988                                         Parent.GetSignatureForError (), GetName (OperatorType), type_name.GetSignatureForError ());
7989                         }
7990                         else {
7991                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7992                         }
7993
7994                         sb.Append (Parameters.GetSignatureForError ());
7995                         return sb.ToString ();
7996                 }
7997         }
7998
7999         //
8000         // This is used to compare method signatures
8001         //
8002         struct MethodSignature {
8003                 public string Name;
8004                 public Type RetType;
8005                 public Type [] Parameters;
8006                 
8007                 /// <summary>
8008                 ///    This delegate is used to extract methods which have the
8009                 ///    same signature as the argument
8010                 /// </summary>
8011                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8012                 
8013                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8014                 {
8015                         Name = name;
8016                         RetType = ret_type;
8017
8018                         if (parameters == null)
8019                                 Parameters = Type.EmptyTypes;
8020                         else
8021                                 Parameters = parameters;
8022                 }
8023
8024                 public override string ToString ()
8025                 {
8026                         string pars = "";
8027                         if (Parameters.Length != 0){
8028                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8029                                 for (int i = 0; i < Parameters.Length; i++){
8030                                         sb.Append (Parameters [i]);
8031                                         if (i+1 < Parameters.Length)
8032                                                 sb.Append (", ");
8033                                 }
8034                                 pars = sb.ToString ();
8035                         }
8036
8037                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8038                 }
8039                 
8040                 public override int GetHashCode ()
8041                 {
8042                         return Name.GetHashCode ();
8043                 }
8044
8045                 public override bool Equals (Object o)
8046                 {
8047                         MethodSignature other = (MethodSignature) o;
8048
8049                         if (other.Name != Name)
8050                                 return false;
8051
8052                         if (other.RetType != RetType)
8053                                 return false;
8054                         
8055                         if (Parameters == null){
8056                                 if (other.Parameters == null)
8057                                         return true;
8058                                 return false;
8059                         }
8060
8061                         if (other.Parameters == null)
8062                                 return false;
8063                         
8064                         int c = Parameters.Length;
8065                         if (other.Parameters.Length != c)
8066                                 return false;
8067
8068                         for (int i = 0; i < c; i++)
8069                                 if (other.Parameters [i] != Parameters [i])
8070                                         return false;
8071
8072                         return true;
8073                 }
8074
8075                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8076                 {
8077                         MethodSignature sig = (MethodSignature) filter_criteria;
8078
8079                         if (m.Name != sig.Name)
8080                                 return false;
8081
8082                         Type ReturnType;
8083                         MethodInfo mi = m as MethodInfo;
8084                         PropertyInfo pi = m as PropertyInfo;
8085
8086                         if (mi != null)
8087                                 ReturnType = mi.ReturnType;
8088                         else if (pi != null)
8089                                 ReturnType = pi.PropertyType;
8090                         else
8091                                 return false;
8092
8093                         //
8094                         // we use sig.RetType == null to mean `do not check the
8095                         // method return value.  
8096                         //
8097                         if (sig.RetType != null) {
8098                                 if (!TypeManager.IsEqual (ReturnType, sig.RetType))
8099                                         return false;
8100                         }
8101
8102                         Type [] args;
8103                         if (mi != null)
8104                                 args = TypeManager.GetParameterData (mi).Types;
8105                         else
8106                                 args = TypeManager.GetParameterData (pi).Types;
8107                         Type [] sigp = sig.Parameters;
8108
8109                         if (args.Length != sigp.Length)
8110                                 return false;
8111
8112                         for (int i = args.Length - 1; i >= 0; i--)
8113                                 if (!TypeManager.IsEqual (args [i], sigp [i]))
8114                                         return false;
8115
8116                         return true;
8117                 }
8118         }
8119 }
8120