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