2007-10-24 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
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                                         if ((e.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
2846                                                 continue;
2847
2848                                         if ((e.caching_flags & Flags.IsUsed) == 0)
2849                                                 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2850                                 }
2851                         }
2852                 }
2853
2854                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2855                 {
2856                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
2857                                 if (declarative_security == null)
2858                                         declarative_security = new ListDictionary ();
2859
2860                                 a.ExtractSecurityPermissionSet (declarative_security);
2861                                 return;
2862                         }
2863
2864                         if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit) {
2865                                 HasExplicitLayout = true;
2866                         }
2867
2868                         base.ApplyAttributeBuilder (a, cb);
2869                 }
2870
2871                 /// <summary>
2872                 /// Defines the default constructors 
2873                 /// </summary>
2874                 protected void DefineDefaultConstructor (bool is_static)
2875                 {
2876                         // The default instance constructor is public
2877                         // If the class is abstract, the default constructor is protected
2878                         // The default static constructor is private
2879
2880                         int mods;
2881                         if (is_static) {
2882                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2883                         } else {
2884                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2885                         }
2886
2887                         Constructor c = new Constructor (this, MemberName.Name, mods,
2888                                 Parameters.EmptyReadOnlyParameters,
2889                                 new GeneratedBaseInitializer (Location),
2890                                 Location);
2891                         
2892                         AddConstructor (c);
2893                         c.Block = new ToplevelBlock (null, Location);
2894                 }
2895
2896                 public override bool Define ()
2897                 {
2898                         if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer)
2899                                 DefineDefaultConstructor (true);
2900
2901                         if (default_static_constructor != null)
2902                                 default_static_constructor.Define ();
2903
2904                         return base.Define ();
2905                 }
2906
2907                 public override void Emit ()
2908                 {
2909                         base.Emit ();
2910
2911                         if (declarative_security != null) {
2912                                 foreach (DictionaryEntry de in declarative_security) {
2913                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2914                                 }
2915                         }
2916                 }
2917
2918                 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name)
2919                 {
2920                         return NamespaceEntry.LookupExtensionMethod (extensionType, this, name);
2921                 }
2922
2923                 protected override TypeAttributes TypeAttr {
2924                         get {
2925                                 if (default_static_constructor == null)
2926                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2927
2928                                 return base.TypeAttr;
2929                         }
2930                 }
2931         }
2932
2933
2934         // TODO: should be sealed
2935         public class Class : ClassOrStruct {
2936                 const int AllowedModifiers =
2937                         Modifiers.NEW |
2938                         Modifiers.PUBLIC |
2939                         Modifiers.PROTECTED |
2940                         Modifiers.INTERNAL |
2941                         Modifiers.PRIVATE |
2942                         Modifiers.ABSTRACT |
2943                         Modifiers.SEALED |
2944                         Modifiers.STATIC |
2945                         Modifiers.UNSAFE;
2946
2947                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2948
2949                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2950                               Attributes attrs)
2951                         : base (ns, parent, name, attrs, Kind.Class)
2952                 {
2953                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2954                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2955
2956                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2957                                 Report.FeatureIsNotISO1 (Location, "static classes");
2958                         }
2959                 }
2960
2961                 public override void AddBasesForPart (DeclSpace part, ArrayList bases)
2962                 {
2963                         if (part.Name == "System.Object")
2964                                 Report.Error (537, part.Location,
2965                                         "The class System.Object cannot have a base class or implement an interface.");
2966                         base.AddBasesForPart (part, bases);
2967                 }
2968
2969                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2970                 {
2971                         if (a.Type == TypeManager.attribute_usage_type) {
2972                                 if (BaseType != TypeManager.attribute_type && !BaseType.IsSubclassOf (TypeManager.attribute_type) &&
2973                                         TypeBuilder.FullName != "System.Attribute") {
2974                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2975                                 }
2976                         }
2977
2978                         if (a.Type == TypeManager.conditional_attribute_type &&
2979                                 !(BaseType == TypeManager.attribute_type || BaseType.IsSubclassOf (TypeManager.attribute_type))) {
2980                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2981                                 return;
2982                         }
2983
2984                         if (a.Type == TypeManager.comimport_attr_type &&
2985                                 !attributes.Contains (TypeManager.guid_attr_type)) {
2986                                         a.Error_MissingGuidAttribute ();
2987                                         return;
2988                         }
2989
2990                         if (a.Type == TypeManager.extension_attribute_type) {
2991                                 a.Error_MisusedExtensionAttribute ();
2992                                 return;
2993                         }
2994
2995                         if (AttributeTester.IsAttributeExcluded (a.Type))
2996                                 return;
2997
2998                         base.ApplyAttributeBuilder (a, cb);
2999                 }
3000
3001                 public override AttributeTargets AttributeTargets {
3002                         get {
3003                                 return AttributeTargets.Class;
3004                         }
3005                 }
3006
3007                 protected override void DefineContainerMembers (MemberCoreArrayList list)
3008                 {
3009                         if (list == null)
3010                                 return;
3011
3012                         if (!IsStatic) {
3013                                 base.DefineContainerMembers (list);
3014                                 return;
3015                         }
3016
3017                         foreach (MemberCore m in list) {
3018                                 if (m is Operator) {
3019                                         Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
3020                                         continue;
3021                                 }
3022
3023                                 if (m is Destructor) {
3024                                         Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
3025                                         continue;
3026                                 }
3027
3028                                 if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
3029                                         Report.Error (1057, m.Location, "`{0}': Static classes cannot contain protected members", m.GetSignatureForError ());
3030                                         continue;
3031                                 }
3032
3033                                 if (m is Indexer) {
3034                                         Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
3035                                         continue;
3036                                 }
3037
3038                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
3039                                         continue;
3040
3041                                 if (m is Constructor) {
3042                                         Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
3043                                         continue;
3044                                 }
3045
3046                                 Method method = m as Method;
3047                                 if (method != null && method.Parameters.HasExtensionMethodType) {
3048                                         Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
3049                                         continue;
3050                                 }
3051
3052                                 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
3053                         }
3054
3055                         base.DefineContainerMembers (list);
3056                 }
3057
3058                 public override TypeBuilder DefineType ()
3059                 {
3060                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
3061                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3062                                 return null;
3063                         }
3064
3065                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
3066                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
3067                                 return null;
3068                         }
3069
3070                         return base.DefineType ();
3071                 }
3072
3073                 protected override bool DoDefineMembers ()
3074                 {
3075                         if (InstanceConstructors == null && !IsStatic)
3076                                 DefineDefaultConstructor (false);
3077
3078                         return base.DoDefineMembers ();
3079                 }
3080
3081                 public override void Emit ()
3082                 {
3083                         base.Emit ();
3084
3085                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
3086                                 TypeBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
3087                 }
3088
3089                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3090                 {
3091                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3092
3093                         if (base_class == null) {
3094                                 if (RootContext.StdLib)
3095                                         base_class = TypeManager.system_object_expr;
3096                                 else if (Name != "System.Object")
3097                                         base_class = TypeManager.system_object_expr;
3098                         } else {
3099                                 if (Kind == Kind.Class && base_class is TypeParameterExpr){
3100                                         Report.Error (
3101                                                 689, base_class.Location,
3102                                                 "Cannot derive from `{0}' because it is a type parameter",
3103                                                 base_class.GetSignatureForError ());
3104                                         return ifaces;
3105                                 }
3106
3107                                 if (base_class.Type.IsArray || base_class.Type.IsPointer) {
3108                                         Report.Error (1521, base_class.Location, "Invalid base type");
3109                                         return ifaces;
3110                                 }
3111
3112                                 if (base_class.IsSealed){
3113                                         Report.SymbolRelatedToPreviousError (base_class.Type);
3114                                         if (base_class.Type.IsAbstract) {
3115                                                 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
3116                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3117                                         } else {
3118                                                 Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'",
3119                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
3120                                         }
3121                                         return ifaces;
3122                                 }
3123
3124                                 if (!base_class.CanInheritFrom ()){
3125                                         Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
3126                                                 GetSignatureForError (), base_class.GetSignatureForError ());
3127                                         return ifaces;
3128                                 }
3129
3130                                 if (!base_class.AsAccessible (this, ModFlags)) {
3131                                         Report.SymbolRelatedToPreviousError (base_class.Type);
3132                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
3133                                                 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
3134                                 }
3135                         }
3136
3137                         if (IsStatic) {
3138                                 if (base_class.Type != TypeManager.object_type) {
3139                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
3140                                                 GetSignatureForError (), base_class.GetSignatureForError ());
3141                                         return ifaces;
3142                                 }
3143
3144                                 if (ifaces != null) {
3145                                         foreach (TypeExpr t in ifaces)
3146                                                 Report.SymbolRelatedToPreviousError (t.Type);
3147                                         Report.Error (714, Location, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3148                                 }
3149                         }
3150
3151                         return ifaces;
3152                 }
3153
3154                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3155                 /// Valid only for attribute classes.
3156                 public bool IsExcluded ()
3157                 {
3158                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
3159                                 return (caching_flags & Flags.Excluded) != 0;
3160
3161                         caching_flags &= ~Flags.Excluded_Undetected;
3162
3163                         if (OptAttributes == null)
3164                                 return false;
3165
3166                         Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
3167
3168                         if (attrs == null)
3169                                 return false;
3170
3171                         foreach (Attribute a in attrs) {
3172                                 string condition = a.GetConditionalAttributeValue ();
3173                                 if (RootContext.AllDefines.Contains (condition))
3174                                         return false;
3175                         }
3176
3177                         caching_flags |= Flags.Excluded;
3178                         return true;
3179                 }
3180
3181                 bool IsStatic {
3182                         get {
3183                                 return (ModFlags & Modifiers.STATIC) != 0;
3184                         }
3185                 }
3186
3187                 //
3188                 // FIXME: How do we deal with the user specifying a different
3189                 // layout?
3190                 //
3191                 protected override TypeAttributes TypeAttr {
3192                         get {
3193                                 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
3194                                 if (IsStatic)
3195                                         ta |= StaticClassAttribute;
3196                                 return ta;
3197                         }
3198                 }
3199         }
3200
3201         public sealed class Struct : ClassOrStruct {
3202                 // <summary>
3203                 //   Modifiers allowed in a struct declaration
3204                 // </summary>
3205                 const int AllowedModifiers =
3206                         Modifiers.NEW       |
3207                         Modifiers.PUBLIC    |
3208                         Modifiers.PROTECTED |
3209                         Modifiers.INTERNAL  |
3210                         Modifiers.UNSAFE    |
3211                         Modifiers.PRIVATE;
3212
3213                 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
3214                                int mod, Attributes attrs)
3215                         : base (ns, parent, name, attrs, Kind.Struct)
3216                 {
3217                         int accmods;
3218                         
3219                         if (parent.Parent == null)
3220                                 accmods = Modifiers.INTERNAL;
3221                         else
3222                                 accmods = Modifiers.PRIVATE;
3223                         
3224                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
3225
3226                         this.ModFlags |= Modifiers.SEALED;
3227                 }
3228
3229                 public override AttributeTargets AttributeTargets {
3230                         get {
3231                                 return AttributeTargets.Struct;
3232                         }
3233                 }
3234
3235                 const TypeAttributes DefaultTypeAttributes =
3236                         TypeAttributes.SequentialLayout |
3237                         TypeAttributes.Sealed |
3238                         TypeAttributes.BeforeFieldInit;
3239
3240
3241                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3242                 {
3243                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3244                         //
3245                         // If we are compiling our runtime,
3246                         // and we are defining ValueType, then our
3247                         // base is `System.Object'.
3248                         //
3249                         if (base_class == null) {
3250                                 if (!RootContext.StdLib && Name == "System.ValueType")
3251                                         base_class = TypeManager.system_object_expr;
3252                                 else
3253                                         base_class = TypeManager.system_valuetype_expr;
3254                         }
3255
3256                         return ifaces;
3257                 }
3258
3259                 //
3260                 // FIXME: Allow the user to specify a different set of attributes
3261                 // in some cases (Sealed for example is mandatory for a class,
3262                 // but what SequentialLayout can be changed
3263                 //
3264                 protected override TypeAttributes TypeAttr {
3265                         get {
3266                                 return base.TypeAttr | DefaultTypeAttributes;
3267                         }
3268                 }
3269
3270                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3271                 {
3272                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3273                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3274                                         field.GetSignatureForError ());
3275                                 return;
3276                         }
3277                         base.RegisterFieldForInitialization (field, expression);
3278                 }
3279
3280         }
3281
3282         /// <summary>
3283         ///   Interfaces
3284         /// </summary>
3285         public sealed class Interface : TypeContainer, IMemberContainer {
3286
3287                 /// <summary>
3288                 ///   Modifiers allowed in a class declaration
3289                 /// </summary>
3290                 public const int AllowedModifiers =
3291                         Modifiers.NEW       |
3292                         Modifiers.PUBLIC    |
3293                         Modifiers.PROTECTED |
3294                         Modifiers.INTERNAL  |
3295                         Modifiers.UNSAFE    |
3296                         Modifiers.PRIVATE;
3297
3298                 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
3299                                   Attributes attrs)
3300                         : base (ns, parent, name, attrs, Kind.Interface)
3301                 {
3302                         int accmods;
3303
3304                         if (parent.Parent == null)
3305                                 accmods = Modifiers.INTERNAL;
3306                         else
3307                                 accmods = Modifiers.PRIVATE;
3308
3309                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location);
3310                 }
3311
3312                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3313                 {
3314                         if (a.Type == TypeManager.comimport_attr_type &&
3315                                 !attributes.Contains (TypeManager.guid_attr_type)) {
3316                                         a.Error_MissingGuidAttribute ();
3317                                         return;
3318                         }
3319                         base.ApplyAttributeBuilder (a, cb);
3320                 }
3321
3322
3323                 public override AttributeTargets AttributeTargets {
3324                         get {
3325                                 return AttributeTargets.Interface;
3326                         }
3327                 }
3328
3329                 const TypeAttributes DefaultTypeAttributes =
3330                         TypeAttributes.AutoLayout |
3331                         TypeAttributes.Abstract |
3332                         TypeAttributes.Interface;
3333
3334                 protected override TypeAttributes TypeAttr {
3335                         get {
3336                                 return base.TypeAttr | DefaultTypeAttributes;
3337                         }
3338                 }
3339
3340                 protected override bool VerifyClsCompliance ()
3341                 {
3342                         if (!base.VerifyClsCompliance ())
3343                                 return false;
3344
3345                         if (ifaces != null) {
3346                                 foreach (Type t in ifaces) {
3347                                         if (AttributeTester.IsClsCompliant (t))
3348                                                 continue;
3349
3350                                         Report.SymbolRelatedToPreviousError (t);
3351                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3352                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3353                                 }
3354                         }
3355
3356                         return true;
3357                 }
3358         }
3359
3360         // It is used as a base class for all property based members
3361         // This includes properties, indexers, and events
3362         public abstract class PropertyBasedMember : InterfaceMemberBase
3363         {
3364                 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3365                         Expression type, int mod, int allowed_mod, bool is_iface,
3366                         MemberName name, Attributes attrs)
3367                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3368                 {
3369                 }
3370
3371                 protected override bool VerifyClsCompliance ()
3372                 {
3373                         if (!base.VerifyClsCompliance ())
3374                                 return false;
3375
3376                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3377                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3378                                         GetSignatureForError ());
3379                         }
3380                         return true;
3381                 }
3382
3383         }
3384
3385
3386         public abstract class MethodCore : InterfaceMemberBase
3387         {
3388                 public readonly Parameters Parameters;
3389                 protected ToplevelBlock block;
3390
3391                 public MethodCore (DeclSpace parent, GenericMethod generic,
3392                         Expression type, int mod, int allowed_mod, bool is_iface,
3393                         MemberName name, Attributes attrs, Parameters parameters)
3394                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3395                 {
3396                         Parameters = parameters;
3397                 }
3398
3399                 //
3400                 //  Returns the System.Type array for the parameters of this method
3401                 //
3402                 public Type [] ParameterTypes {
3403                         get {
3404                                 return Parameters.Types;
3405                         }
3406                 }
3407
3408                 public Parameters ParameterInfo
3409                 {
3410                         get {
3411                                 return Parameters;
3412                         }
3413                 }
3414                 
3415                 public ToplevelBlock Block {
3416                         get {
3417                                 return block;
3418                         }
3419
3420                         set {
3421                                 block = value;
3422                         }
3423                 }
3424
3425                 protected override bool CheckBase ()
3426                 {
3427                         // Check whether arguments were correct.
3428                         if (!DefineParameters (Parameters))
3429                                 return false;
3430
3431                         if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
3432                                 if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, 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 (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                         return true;
4944                 }
4945
4946                 //
4947                 // Emits the code
4948                 //
4949                 public override void Emit ()
4950                 {
4951                         if (OptAttributes != null)
4952                                 OptAttributes.Emit ();
4953
4954                         base.Emit ();
4955
4956                         EmitContext ec = CreateEmitContext (null, null);
4957
4958                         //
4959                         // If we use a "this (...)" constructor initializer, then
4960                         // do not emit field initializers, they are initialized in the other constructor
4961                         //
4962                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
4963                                 !(Initializer is ConstructorThisInitializer);
4964
4965                         if (emit_field_initializers)
4966                                 Parent.PartialContainer.ResolveFieldInitializers (ec);
4967
4968                         if (block != null) {
4969                                 // If this is a non-static `struct' constructor and doesn't have any
4970                                 // initializer, it must initialize all of the struct's fields.
4971                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4972                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4973                                         block.AddThisVariable (Parent, Location);
4974
4975                                 if (!block.ResolveMeta (ec, ParameterInfo))
4976                                         block = null;
4977                         }
4978
4979                         if ((ModFlags & Modifiers.STATIC) == 0){
4980                                 if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4981                                         Initializer = new GeneratedBaseInitializer (Location);
4982
4983                                 //
4984                                 // Spec mandates that Initializers will not have
4985                                 // `this' access
4986                                 //
4987                                 ec.IsStatic = true;
4988                                 if ((Initializer != null) &&
4989                                     !Initializer.Resolve (ConstructorBuilder, ec))
4990                                         return;
4991                                 ec.IsStatic = false;
4992                         }
4993
4994                         Parameters.ApplyAttributes (ConstructorBuilder);
4995                         
4996                         SourceMethod source = SourceMethod.Create (
4997                                 Parent, ConstructorBuilder, block);
4998
4999                         bool unreachable = false;
5000                         if (block != null) {
5001                                 if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
5002                                         return;
5003
5004                                 ec.EmitMeta (block);
5005
5006                                 if (Report.Errors > 0)
5007                                         return;
5008
5009                                 if (emit_field_initializers)
5010                                         Parent.PartialContainer.EmitFieldInitializers (ec);
5011
5012                                 if (block.ScopeInfo != null) {
5013                                         ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
5014                                         init.EmitStatement (ec);
5015                                 }
5016
5017                                 if (Initializer != null)
5018                                         Initializer.Emit (ec);
5019                         
5020                                 ec.EmitResolvedTopBlock (block, unreachable);
5021                         }
5022
5023                         if (source != null)
5024                                 source.CloseMethod ();
5025
5026                         if (declarative_security != null) {
5027                                 foreach (DictionaryEntry de in declarative_security) {
5028                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
5029                                 }
5030                         }
5031
5032                         block = null;
5033                 }
5034
5035                 // Is never override
5036                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
5037                 {
5038                         return null;
5039                 }
5040
5041                 public override string GetSignatureForError()
5042                 {
5043                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
5044                 }
5045
5046                 public override string[] ValidAttributeTargets {
5047                         get {
5048                                 return attribute_targets;
5049                         }
5050                 }
5051
5052                 protected override bool VerifyClsCompliance ()
5053                 {
5054                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
5055                                 return false;
5056                         }
5057                         
5058                         if (ParameterInfo.Count > 0) {
5059                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
5060                                 if (al.Count > 2)
5061                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
5062  
5063                                 if (Parent.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
5064                                         foreach (Type param in ParameterTypes) {
5065                                                 if (param.IsArray) {
5066                                                         return true;
5067                                                 }
5068                                         }
5069                                 }
5070                         }
5071                         has_compliant_args = true;
5072                         return true;
5073                 }
5074
5075                 #region IMethodData Members
5076
5077                 public System.Reflection.CallingConventions CallingConventions {
5078                         get {
5079                                 CallingConventions cc = Parameters.CallingConvention;
5080
5081                                 if (Parent.PartialContainer.Kind == Kind.Class)
5082                                         if ((ModFlags & Modifiers.STATIC) == 0)
5083                                                 cc |= CallingConventions.HasThis;
5084
5085                                 // FIXME: How is `ExplicitThis' used in C#?
5086                         
5087                                 return cc;
5088                         }
5089                 }
5090
5091                 public new Location Location {
5092                         get {
5093                                 return base.Location;
5094                         }
5095                 }
5096
5097                 public MemberName MethodName {
5098                         get {
5099                                 return MemberName;
5100                         }
5101                 }
5102
5103                 public Type ReturnType {
5104                         get {
5105                                 return MemberType;
5106                         }
5107                 }
5108
5109                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
5110                 {
5111                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
5112                         EmitContext ec = new EmitContext (this, Parent, Location, ig_, TypeManager.void_type, ModFlags, true);
5113                         ec.CurrentBlock = block;
5114                         return ec;
5115                 }
5116
5117                 public bool IsExcluded()
5118                 {
5119                         return false;
5120                 }
5121
5122                 GenericMethod IMethodData.GenericMethod {
5123                         get {
5124                                 return null;
5125                         }
5126                 }
5127
5128                 #endregion
5129         }
5130
5131         /// <summary>
5132         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5133         /// </summary>
5134         public interface IMethodData
5135         {
5136                 CallingConventions CallingConventions { get; }
5137                 Location Location { get; }
5138                 MemberName MethodName { get; }
5139                 Type ReturnType { get; }
5140                 GenericMethod GenericMethod { get; }
5141                 Parameters ParameterInfo { get; }
5142
5143                 Iterator Iterator { get; }
5144
5145                 Attributes OptAttributes { get; }
5146                 ToplevelBlock Block { get; set; }
5147
5148                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5149                 ObsoleteAttribute GetObsoleteAttribute ();
5150                 string GetSignatureForError ();
5151                 bool IsExcluded ();
5152                 bool IsClsComplianceRequired ();
5153                 void SetMemberIsUsed ();
5154         }
5155
5156         //
5157         // Encapsulates most of the Method's state
5158         //
5159         public class MethodData {
5160
5161                 readonly IMethodData method;
5162
5163                 public readonly GenericMethod GenericMethod;
5164
5165                 //
5166                 // Are we implementing an interface ?
5167                 //
5168                 public MethodInfo implementing;
5169
5170                 //
5171                 // Protected data.
5172                 //
5173                 protected InterfaceMemberBase member;
5174                 protected int modifiers;
5175                 protected MethodAttributes flags;
5176                 protected Type declaring_type;
5177                 protected MethodInfo parent_method;
5178
5179                 MethodBuilder builder = null;
5180                 public MethodBuilder MethodBuilder {
5181                         get {
5182                                 return builder;
5183                         }
5184                 }
5185
5186                 public Type DeclaringType {
5187                         get {
5188                                 return declaring_type;
5189                         }
5190                 }
5191
5192                 public MethodData (InterfaceMemberBase member,
5193                                    int modifiers, MethodAttributes flags, IMethodData method)
5194                 {
5195                         this.member = member;
5196                         this.modifiers = modifiers;
5197                         this.flags = flags;
5198
5199                         this.method = method;
5200                 }
5201
5202                 public MethodData (InterfaceMemberBase member, 
5203                                    int modifiers, MethodAttributes flags, 
5204                                    IMethodData method, MethodBuilder builder,
5205                                    GenericMethod generic, MethodInfo parent_method)
5206                         : this (member, modifiers, flags, method)
5207                 {
5208                         this.builder = builder;
5209                         this.GenericMethod = generic;
5210                         this.parent_method = parent_method;
5211                 }
5212
5213                 public bool Define (DeclSpace parent)
5214                 {
5215                         string name = method.MethodName.Basename;
5216                         string method_name = method.MethodName.FullName;
5217
5218                         TypeContainer container = parent.PartialContainer;
5219
5220                         PendingImplementation pending = container.PendingImplementations;
5221                         if (pending != null){
5222                                 if (member is Indexer) // TODO: test it, but it should work without this IF
5223                                         implementing = pending.IsInterfaceIndexer (
5224                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
5225                                 else
5226                                         implementing = pending.IsInterfaceMethod (
5227                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5228
5229                                 if (member.InterfaceType != null){
5230                                         if (implementing == null){
5231                                                 if (member is PropertyBase) {
5232                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5233                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5234                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5235
5236                                                 } else {
5237                                                         Report.Error (539, method.Location,
5238                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5239                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5240                                                 }
5241                                                 return false;
5242                                         }
5243                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5244                                                 Report.SymbolRelatedToPreviousError (implementing);
5245                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5246                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5247                                                 return false;
5248                                         }
5249
5250                                         method_name = member.InterfaceType.FullName + 
5251                                                 '.' + method_name;
5252                                 } else {
5253                                         if (implementing != null) {
5254                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5255                                                 if (prop_method == null) {
5256                                                         if (TypeManager.IsSpecialMethod (implementing)) {
5257                                                                 Report.SymbolRelatedToPreviousError (implementing);
5258                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5259                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5260                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5261                                                         }
5262                                                 } else if (implementing.DeclaringType.IsInterface) {
5263                                                         if (!implementing.IsSpecialName) {
5264                                                                 Report.SymbolRelatedToPreviousError (implementing);
5265                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5266                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5267                                                                 return false;
5268                                                         }
5269                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5270                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5271                                                                 Report.SymbolRelatedToPreviousError (implementing);
5272                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5273                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5274                                                                 return false;
5275                                                         }
5276                                                 }
5277                                         }
5278                                 }
5279                         }
5280
5281                         //
5282                         // For implicit implementations, make sure we are public, for
5283                         // explicit implementations, make sure we are private.
5284                         //
5285                         if (implementing != null){
5286                                 //
5287                                 // Setting null inside this block will trigger a more
5288                                 // verbose error reporting for missing interface implementations
5289                                 //
5290                                 // The "candidate" function has been flagged already
5291                                 // but it wont get cleared
5292                                 //
5293                                 if (member.IsExplicitImpl){
5294                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5295                                                 Report.SymbolRelatedToPreviousError (implementing);
5296                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5297                                                         method.GetSignatureForError ());
5298                                                 return false;
5299                                         }
5300                                 } else {
5301                                         if (implementing.DeclaringType.IsInterface) {
5302                                                 //
5303                                                 // If this is an interface method implementation,
5304                                                 // check for public accessibility
5305                                                 //
5306                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5307                                                 {
5308                                                         implementing = null;
5309                                                 }
5310                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5311                                                 // We may never be private.
5312                                                 implementing = null;
5313
5314                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5315                                                 //
5316                                                 // We may be protected if we're overriding something.
5317                                                 //
5318                                                 implementing = null;
5319                                         }
5320                                 }
5321                                         
5322                                 //
5323                                 // Static is not allowed
5324                                 //
5325                                 if ((modifiers & Modifiers.STATIC) != 0){
5326                                         implementing = null;
5327                                 }
5328                         }
5329                         
5330                         //
5331                         // If implementing is still valid, set flags
5332                         //
5333                         if (implementing != null){
5334                                 //
5335                                 // When implementing interface methods, set NewSlot
5336                                 // unless, we are overwriting a method.
5337                                 //
5338                                 if (implementing.DeclaringType.IsInterface){
5339                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5340                                                 flags |= MethodAttributes.NewSlot;
5341                                 }
5342                                 flags |=
5343                                         MethodAttributes.Virtual |
5344                                         MethodAttributes.HideBySig;
5345
5346                                 // Set Final unless we're virtual, abstract or already overriding a method.
5347                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5348                                         flags |= MethodAttributes.Final;
5349                         }
5350
5351                         DefineMethodBuilder (container, method_name, method.ParameterInfo.Types);
5352
5353                         if (builder == null)
5354                                 return false;
5355
5356                         if (container.CurrentType != null)
5357                                 declaring_type = container.CurrentType;
5358                         else
5359                                 declaring_type = container.TypeBuilder;
5360
5361                         if ((modifiers & Modifiers.UNSAFE) != 0)
5362                                 builder.InitLocals = false;
5363
5364
5365                         if (implementing != null){
5366                                 //
5367                                 // clear the pending implemntation flag
5368                                 //
5369                                 if (member is Indexer) {
5370                                         pending.ImplementIndexer (
5371                                                 member.InterfaceType, builder, method.ReturnType,
5372                                                 method.ParameterInfo, member.IsExplicitImpl);
5373                                 } else
5374                                         pending.ImplementMethod (
5375                                                 member.InterfaceType, name, method.ReturnType,
5376                                                 method.ParameterInfo, member.IsExplicitImpl);
5377
5378                                 if (member.IsExplicitImpl)
5379                                         container.TypeBuilder.DefineMethodOverride (
5380                                                 builder, implementing);
5381                         }
5382
5383                         TypeManager.AddMethod (builder, method);
5384
5385                         if (GenericMethod != null) {
5386                                 bool is_override = member.IsExplicitImpl |
5387                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5388
5389                                 if (implementing != null)
5390                                         parent_method = implementing;
5391
5392                                 EmitContext ec = method.CreateEmitContext (container, null);
5393                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5394                                         return false;
5395                         }
5396
5397                         return true;
5398                 }
5399
5400
5401                 /// <summary>
5402                 /// Create the MethodBuilder for the method 
5403                 /// </summary>
5404                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5405                 {
5406                         if (builder == null) {
5407                                 builder = container.TypeBuilder.DefineMethod (
5408                                         method_name, flags, method.CallingConventions,
5409                                         method.ReturnType, ParameterTypes);
5410                                 return;
5411                         }
5412
5413 #if GMCS_SOURCE && !MS_COMPATIBLE
5414                         builder.SetGenericMethodSignature (
5415                                 flags, method.CallingConventions,
5416                                 method.ReturnType, ParameterTypes);
5417 #endif
5418                 }
5419
5420                 //
5421                 // Emits the code
5422                 // 
5423                 public void Emit (DeclSpace parent)
5424                 {
5425                         ToplevelBlock block = method.Block;
5426
5427                         EmitContext ec;
5428                         if (block != null)
5429                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5430                         else
5431                                 ec = method.CreateEmitContext (parent, null);
5432
5433                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5434
5435                         if (GenericMethod != null)
5436                                 GenericMethod.EmitAttributes ();
5437                         
5438                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5439
5440                         //
5441                         // Handle destructors specially
5442                         //
5443                         // FIXME: This code generates buggy code
5444                         //
5445                         if (member is Destructor)
5446                                 EmitDestructor (ec, block);
5447                         else
5448                                 ec.EmitTopBlock (method, block);
5449
5450                         if (source != null)
5451                                 source.CloseMethod ();
5452                 }
5453
5454                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5455                 {
5456                         ILGenerator ig = ec.ig;
5457                         
5458                         Label finish = ig.DefineLabel ();
5459
5460                         block.SetDestructor ();
5461                         
5462                         ig.BeginExceptionBlock ();
5463                         ec.ReturnLabel = finish;
5464                         ec.HasReturnLabel = true;
5465                         ec.EmitTopBlock (method, block);
5466                         
5467                         // ig.MarkLabel (finish);
5468                         ig.BeginFinallyBlock ();
5469                         
5470                         if (ec.ContainerType.BaseType != null) {
5471                                 Expression member_lookup = Expression.MemberLookup (
5472                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5473                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5474
5475                                 if (member_lookup != null){
5476                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5477                                 
5478                                         ig.Emit (OpCodes.Ldarg_0);
5479                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5480                                 }
5481                         }
5482                         
5483                         ig.EndExceptionBlock ();
5484                         //ig.MarkLabel (ec.ReturnLabel);
5485                         ig.Emit (OpCodes.Ret);
5486                 }
5487         }
5488
5489         // TODO: Should derive from MethodCore
5490         public class Destructor : Method {
5491
5492                 static string[] attribute_targets = new string [] { "method" };
5493
5494                 public Destructor (DeclSpace parent, Expression return_type, int mod,
5495                                    string name, Parameters parameters, Attributes attrs,
5496                                    Location l)
5497                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5498                                 parameters, attrs)
5499                 { }
5500
5501                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5502                 {
5503                         if (a.Type == TypeManager.conditional_attribute_type) {
5504                                 Error_ConditionalAttributeIsNotValid ();
5505                                 return;
5506                         }
5507
5508                         base.ApplyAttributeBuilder (a, cb);
5509                 }
5510
5511                 public override string GetSignatureForError ()
5512                 {
5513                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5514                 }
5515
5516                 public override string[] ValidAttributeTargets {
5517                         get {
5518                                 return attribute_targets;
5519                         }
5520                 }
5521         }
5522         
5523         abstract public class MemberBase : MemberCore {
5524                 public Expression Type;
5525                 public readonly DeclSpace ds;
5526                 public readonly GenericMethod GenericMethod;
5527
5528                 //
5529                 // The type of this property / indexer / event
5530                 //
5531                 protected Type member_type;
5532                 public Type MemberType {
5533                         get {
5534                                 if (member_type == null && Type != null) {
5535                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5536                                         Type = Type.ResolveAsTypeTerminal (rc, false);
5537                                         if (Type != null) {
5538                                                 member_type = Type.Type;
5539                                         }
5540                                 }
5541                                 return member_type;
5542                         }
5543                 }
5544
5545                 //
5546                 // The constructor is only exposed to our children
5547                 //
5548                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5549                                       Expression type, int mod, int allowed_mod, int def_mod,
5550                                       MemberName name, Attributes attrs)
5551                         : base (parent, name, attrs)
5552                 {
5553                         this.ds = generic != null ? generic : (DeclSpace) parent;
5554                         Type = type;
5555                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5556                         GenericMethod = generic;
5557                         if (GenericMethod != null)
5558                                 GenericMethod.ModFlags = ModFlags;
5559                 }
5560
5561                 protected virtual bool CheckBase ()
5562                 {
5563                         if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.PartialContainer.Kind == Kind.Struct) {
5564                                 Report.Error (666, Location, "`{0}': new protected member declared in struct", GetSignatureForError ());
5565                                 return false;
5566                         }
5567    
5568                         if (Report.WarningLevel >= 4 &&
5569                             ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
5570                             ((ModFlags & Modifiers.PROTECTED) != 0) &&
5571                             ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
5572                                 Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5573                         }
5574                                 return true;
5575                 }
5576
5577                 protected virtual bool DoDefine ()
5578                 {
5579                         if (MemberType == null)
5580                                 return false;
5581
5582                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5583                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5584                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5585                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5586                                         return false;
5587                         }
5588                         
5589                         // verify accessibility
5590                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5591                                 Report.SymbolRelatedToPreviousError (MemberType);
5592                                 if (this is Property)
5593                                         Report.Error (53, Location,
5594                                                       "Inconsistent accessibility: property type `" +
5595                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5596                                                       "accessible than property `" + GetSignatureForError () + "'");
5597                                 else if (this is Indexer)
5598                                         Report.Error (54, Location,
5599                                                       "Inconsistent accessibility: indexer return type `" +
5600                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5601                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5602                                 else if (this is MethodCore) {
5603                                         if (this is Operator)
5604                                                 Report.Error (56, Location,
5605                                                               "Inconsistent accessibility: return type `" +
5606                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5607                                                               "accessible than operator `" + GetSignatureForError () + "'");
5608                                         else
5609                                                 Report.Error (50, Location,
5610                                                               "Inconsistent accessibility: return type `" +
5611                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5612                                                               "accessible than method `" + GetSignatureForError () + "'");
5613                                 } else {
5614                                         Report.Error (52, Location,
5615                                                       "Inconsistent accessibility: field type `" +
5616                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5617                                                       "accessible than field `" + GetSignatureForError () + "'");
5618                                 }
5619                                 return false;
5620                         }
5621
5622                         return true;
5623                 }
5624
5625                 protected bool IsTypePermitted ()
5626                 {
5627                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5628                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5629                                 return false;
5630                         }
5631                         return true;
5632                 }
5633         }
5634
5635         //
5636         // Abstract class for all fields
5637         //
5638         abstract public class FieldBase : MemberBase {
5639                 public FieldBuilder FieldBuilder;
5640                 public Status status;
5641                 protected Expression initializer;
5642
5643                 [Flags]
5644                 public enum Status : byte {
5645                         HAS_OFFSET = 4          // Used by FieldMember.
5646                 }
5647
5648                 static readonly string[] attribute_targets = new string [] { "field" };
5649
5650                 protected FieldBase (DeclSpace parent, Expression type, int mod,
5651                                      int allowed_mod, MemberName name, Attributes attrs)
5652                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5653                                 name, attrs)
5654                 {
5655                         if ((mod & Modifiers.ABSTRACT) != 0)
5656                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5657                 }
5658
5659                 public override AttributeTargets AttributeTargets {
5660                         get {
5661                                 return AttributeTargets.Field;
5662                         }
5663                 }
5664
5665                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5666                 {
5667                         if (a.Type == TypeManager.field_offset_attribute_type) {
5668                                 status |= Status.HAS_OFFSET;
5669
5670                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5671                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5672                                         return;
5673                                 }
5674
5675                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5676                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5677                                         return;
5678                                 }
5679                         }
5680
5681 #if NET_2_0
5682                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5683                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5684                                 return;
5685                         }
5686 #endif
5687
5688                         if (a.Type == TypeManager.marshal_as_attr_type) {
5689                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5690                                 if (marshal != null) {
5691                                         FieldBuilder.SetMarshal (marshal);
5692                                 }
5693                                 return;
5694                         }
5695
5696                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
5697                                 a.Error_InvalidSecurityParent ();
5698                                 return;
5699                         }
5700
5701                         FieldBuilder.SetCustomAttribute (cb);
5702                 }
5703
5704                 protected override bool CheckBase ()
5705                 {
5706                         if (!base.CheckBase ())
5707                                 return false;
5708  
5709                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5710                         if (conflict_symbol == null) {
5711                                 if ((ModFlags & Modifiers.NEW) != 0) {
5712                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5713                                 }
5714                                 return true;
5715                         }
5716  
5717                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5718                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5719                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5720                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5721                         }
5722  
5723                         return true;
5724                 }
5725
5726                 public override bool Define()
5727                 {
5728                         if (MemberType == null || Type == null)
5729                                 return false;
5730
5731                         if (TypeManager.IsGenericParameter (MemberType))
5732                                 return true;
5733
5734                         if (MemberType == TypeManager.void_type) {
5735                                 // TODO: wrong location
5736                                 Expression.Error_VoidInvalidInTheContext (Location);
5737                                 return false;
5738                         }
5739
5740                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5741                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5742                                 return false;
5743                         }
5744
5745                         if (!CheckBase ())
5746                                 return false;
5747                         
5748                         if (!Parent.AsAccessible (MemberType, ModFlags)) {
5749                                 Report.Error (52, Location,
5750                                         "Inconsistent accessibility: field type `" +
5751                                         TypeManager.CSharpName (MemberType) + "' is less " +
5752                                         "accessible than field `" + GetSignatureForError () + "'");
5753                                 return false;
5754                         }
5755
5756                         if (!IsTypePermitted ())
5757                                 return false;
5758
5759                         return true;
5760                 }
5761
5762                 //
5763                 //   Represents header string for documentation comment.
5764                 //
5765                 public override string DocCommentHeader {
5766                         get { return "F:"; }
5767                 }
5768
5769                 public override void Emit ()
5770                 {
5771 #if GMCS_SOURCE
5772                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0) {
5773                                 FieldBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
5774                         }
5775 #endif
5776
5777                         if (OptAttributes != null) {
5778                                 OptAttributes.Emit ();
5779                         }
5780
5781                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5782                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5783                         }
5784
5785                         base.Emit ();
5786                 }
5787
5788                 public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class)
5789                 {
5790                         Report.SymbolRelatedToPreviousError (static_class);
5791                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5792                                 variable_name);
5793                 }
5794
5795                 public Expression Initializer {
5796                         set {
5797                                 if (value != null) {
5798                                         this.initializer = value;
5799                                 }
5800                         }
5801                 }
5802
5803                 protected virtual bool IsFieldClsCompliant {
5804                         get {
5805                                 if (FieldBuilder == null)
5806                                         return true;
5807
5808                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5809                         }
5810                 }
5811
5812                 public override string[] ValidAttributeTargets 
5813                 {
5814                         get {
5815                                 return attribute_targets;
5816                         }
5817                 }
5818
5819                 protected override bool VerifyClsCompliance ()
5820                 {
5821                         if (!base.VerifyClsCompliance ())
5822                                 return false;
5823
5824                         if (!IsFieldClsCompliant) {
5825                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5826                         }
5827                         return true;
5828                 }
5829
5830                 public void SetAssigned ()
5831                 {
5832                         caching_flags |= Flags.IsAssigned;
5833                 }
5834         }
5835
5836         interface IFixedBuffer
5837         {
5838                 FieldInfo Element { get; }
5839                 Type ElementType { get; }
5840         }
5841
5842         public class FixedFieldExternal: IFixedBuffer
5843         {
5844                 FieldInfo element_field;
5845
5846                 public FixedFieldExternal (FieldInfo fi)
5847                 {
5848                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5849                 }
5850
5851                 #region IFixedField Members
5852
5853                 public FieldInfo Element {
5854                         get {
5855                                 return element_field;
5856                         }
5857                 }
5858
5859                 public Type ElementType {
5860                         get {
5861                                 return element_field.FieldType;
5862                         }
5863                 }
5864
5865                 #endregion
5866         }
5867
5868         /// <summary>
5869         /// Fixed buffer implementation
5870         /// </summary>
5871         public class FixedField : FieldBase, IFixedBuffer
5872         {
5873                 public const string FixedElementName = "FixedElementField";
5874                 static int GlobalCounter = 0;
5875                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5876                 static FieldInfo[] fi;
5877
5878                 TypeBuilder fixed_buffer_type;
5879                 FieldBuilder element;
5880                 Expression size_expr;
5881                 int buffer_size;
5882
5883                 const int AllowedModifiers =
5884                         Modifiers.NEW |
5885                         Modifiers.PUBLIC |
5886                         Modifiers.PROTECTED |
5887                         Modifiers.INTERNAL |
5888                         Modifiers.PRIVATE;
5889
5890                 public FixedField (DeclSpace parent, Expression type, int mod, string name,
5891                         Expression size_expr, Attributes attrs, Location loc):
5892                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5893                 {
5894                         if (RootContext.Version == LanguageVersion.ISO_1)
5895                                 Report.FeatureIsNotISO1 (loc, "fixed size buffers");
5896
5897                         this.size_expr = size_expr;
5898                 }
5899
5900                 public override bool Define()
5901                 {
5902 #if !NET_2_0
5903                         if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
5904                                 Report.Warning (-23, 1, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5905 #endif
5906
5907                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5908                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5909                                         GetSignatureForError ());
5910                         }
5911
5912                         if (!Parent.IsInUnsafeScope)
5913                                 Expression.UnsafeError (Location);
5914
5915                         if (!base.Define ())
5916                                 return false;
5917
5918                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5919                                 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",
5920                                         GetSignatureForError ());
5921                                 return false;
5922                         }
5923
5924                         EmitContext ec = new EmitContext (this, Parent, Location, null, TypeManager.void_type, ModFlags);
5925                         Constant c = size_expr.ResolveAsConstant (ec, this);
5926                         if (c == null)
5927                                 return false;
5928
5929                         IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5930                         if (buffer_size_const == null)
5931                                 return false;
5932
5933                         buffer_size = buffer_size_const.Value;
5934
5935                         if (buffer_size <= 0) {
5936                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5937                                 return false;
5938                         }
5939
5940                         int type_size = Expression.GetTypeSize (MemberType);
5941
5942                         if (buffer_size > int.MaxValue / type_size) {
5943                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5944                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5945                                 return false;
5946                         }
5947
5948                         buffer_size *= type_size;
5949
5950                         // Define nested
5951                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5952
5953                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5954                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5955                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5956                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5957
5958                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5959
5960                         Parent.MemberCache.AddMember (FieldBuilder, this);
5961                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5962
5963                         return true;
5964                 }
5965
5966                 public override void Emit()
5967                 {
5968                         if (fi == null)
5969                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5970
5971                         object[] fi_val = new object[1];
5972                         fi_val [0] = buffer_size;
5973
5974                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor, 
5975                                 ctor_args, fi, fi_val);
5976                         fixed_buffer_type.SetCustomAttribute (cab);
5977
5978 #if NET_2_0
5979                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
5980                         FieldBuilder.SetCustomAttribute (cab);
5981 #endif
5982                         base.Emit ();
5983                 }
5984
5985                 protected override bool IsFieldClsCompliant {
5986                         get {
5987                                 return false;
5988                         }
5989                 }
5990
5991                 #region IFixedField Members
5992
5993                 public FieldInfo Element {
5994                         get {
5995                                 return element;
5996                         }
5997                 }
5998
5999                 public Type ElementType {
6000                         get {
6001                                 return MemberType;
6002                         }
6003                 }
6004
6005                 #endregion
6006         }
6007
6008         //
6009         // The Field class is used to represents class/struct fields during parsing.
6010         //
6011         public class Field : FieldBase {
6012                 // <summary>
6013                 //   Modifiers allowed in a class declaration
6014                 // </summary>
6015                 const int AllowedModifiers =
6016                         Modifiers.NEW |
6017                         Modifiers.PUBLIC |
6018                         Modifiers.PROTECTED |
6019                         Modifiers.INTERNAL |
6020                         Modifiers.PRIVATE |
6021                         Modifiers.STATIC |
6022                         Modifiers.VOLATILE |
6023                         Modifiers.UNSAFE |
6024                         Modifiers.READONLY;
6025
6026                 public Field (DeclSpace parent, Expression type, int mod, string name,
6027                               Attributes attrs, Location loc)
6028                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
6029                                 attrs)
6030                 {
6031                 }
6032
6033                 public override bool Define ()
6034                 {
6035                         if (!base.Define ())
6036                                 return false;
6037
6038                         if ((ModFlags & Modifiers.VOLATILE) != 0){
6039                                 if (!MemberType.IsClass){
6040                                         Type vt = MemberType;
6041                                         
6042                                         if (TypeManager.IsEnumType (vt))
6043                                                 vt = TypeManager.EnumToUnderlying (MemberType);
6044
6045                                         if (!((vt == TypeManager.bool_type) ||
6046                                               (vt == TypeManager.sbyte_type) ||
6047                                               (vt == TypeManager.byte_type) ||
6048                                               (vt == TypeManager.short_type) ||
6049                                               (vt == TypeManager.ushort_type) ||
6050                                               (vt == TypeManager.int32_type) ||
6051                                               (vt == TypeManager.uint32_type) ||    
6052                                               (vt == TypeManager.char_type) ||
6053                                               (vt == TypeManager.float_type) ||
6054                                               (!vt.IsValueType))){
6055                                                 Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
6056                                                         GetSignatureForError (), TypeManager.CSharpName (vt));
6057                                                 return false;
6058                                         }
6059                                 }
6060
6061                                 if ((ModFlags & Modifiers.READONLY) != 0){
6062                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6063                                                 GetSignatureForError ());
6064                                         return false;
6065                                 }
6066                         }
6067
6068                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6069
6070                         if (Parent.PartialContainer.Kind == Kind.Struct && 
6071                             ((fa & FieldAttributes.Static) == 0) &&
6072                             MemberType == Parent.TypeBuilder &&
6073                             !TypeManager.IsBuiltinType (MemberType)){
6074                                 Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
6075                                               "' causes a cycle in the structure layout");
6076                                 return false;
6077                         }
6078
6079                         try {
6080                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6081                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
6082
6083                                 Parent.MemberCache.AddMember (FieldBuilder, this);
6084                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
6085                         }
6086                         catch (ArgumentException) {
6087                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6088                                 return false;
6089                         }
6090
6091                         if (initializer != null)
6092                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
6093                                         new FieldInitializer (FieldBuilder, initializer));
6094                         return true;
6095                 }
6096
6097                 protected override bool VerifyClsCompliance ()
6098                 {
6099                         if (!base.VerifyClsCompliance ())
6100                                 return false;
6101
6102                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
6103                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6104                         }
6105
6106                         return true;
6107                 }
6108         }
6109
6110         //
6111         // `set' and `get' accessors are represented with an Accessor.
6112         // 
6113         public class Accessor : IAnonymousHost {
6114                 //
6115                 // Null if the accessor is empty, or a Block if not
6116                 //
6117                 public const int AllowedModifiers = 
6118                         Modifiers.PUBLIC |
6119                         Modifiers.PROTECTED |
6120                         Modifiers.INTERNAL |
6121                         Modifiers.PRIVATE;
6122                 
6123                 public ToplevelBlock Block;
6124                 public Attributes Attributes;
6125                 public Location Location;
6126                 public int ModFlags;
6127                 public bool Yields;
6128                 public ArrayList AnonymousMethods;
6129                 
6130                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6131                 {
6132                         Block = b;
6133                         Attributes = attrs;
6134                         Location = loc;
6135                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6136                 }
6137
6138                 public void SetYields ()
6139                 {
6140                         Yields = true;
6141                 }
6142
6143                 public void AddAnonymousMethod (AnonymousMethodExpression ame)
6144                 {
6145                         if (AnonymousMethods == null)
6146                                 AnonymousMethods = new ArrayList ();
6147                         AnonymousMethods.Add (ame);
6148                 }
6149         }
6150
6151         // Ooouh Martin, templates are missing here.
6152         // When it will be possible move here a lot of child code and template method type.
6153         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6154                 protected MethodData method_data;
6155                 protected ToplevelBlock block;
6156                 protected ListDictionary declarative_security;
6157
6158                 // The accessor are created event if they are not wanted.
6159                 // But we need them because their names are reserved.
6160                 // Field says whether accessor will be emited or not
6161                 public readonly bool IsDummy;
6162
6163                 protected readonly string prefix;
6164
6165                 ReturnParameter return_attributes;
6166
6167                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6168                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
6169                 {
6170                         this.prefix = prefix;
6171                         IsDummy = true;
6172                 }
6173
6174                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6175                                                     string prefix)
6176                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
6177                                 accessor.Attributes)
6178                 {
6179                         this.prefix = prefix;
6180                         this.block = accessor.Block;
6181                 }
6182
6183                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6184                 {
6185                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6186                 }
6187
6188                 public void UpdateName (InterfaceMemberBase member)
6189                 {
6190                         SetMemberName (SetupName (prefix, member, Location));
6191                 }
6192
6193                 #region IMethodData Members
6194
6195                 public abstract Iterator Iterator {
6196                         get;
6197                 }
6198
6199                 public ToplevelBlock Block {
6200                         get {
6201                                 return block;
6202                         }
6203
6204                         set {
6205                                 block = value;
6206                         }
6207                 }
6208
6209                 public CallingConventions CallingConventions {
6210                         get {
6211                                 return CallingConventions.Standard;
6212                         }
6213                 }
6214
6215                 public bool IsExcluded ()
6216                 {
6217                         return false;
6218                 }
6219
6220                 GenericMethod IMethodData.GenericMethod {
6221                         get {
6222                                 return null;
6223                         }
6224                 }
6225
6226                 public MemberName MethodName {
6227                         get {
6228                                 return MemberName;
6229                         }
6230                 }
6231
6232                 public Type[] ParameterTypes { 
6233                         get {
6234                                 return ParameterInfo.Types;
6235                         }
6236                 }
6237
6238                 public abstract Parameters ParameterInfo { get ; }
6239                 public abstract Type ReturnType { get; }
6240                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6241
6242                 #endregion
6243
6244                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6245                 {
6246                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6247                                         a.Type == TypeManager.conditional_attribute_type) {
6248                                 Report.Error (1667, a.Location,
6249                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6250                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6251                                 return;
6252                         }
6253
6254                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
6255                                 if (declarative_security == null)
6256                                         declarative_security = new ListDictionary ();
6257                                 a.ExtractSecurityPermissionSet (declarative_security);
6258                                 return;
6259                         }
6260
6261                         if (a.Target == AttributeTargets.Method) {
6262                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6263                                 return;
6264                         }
6265
6266                         if (a.Target == AttributeTargets.ReturnValue) {
6267                                 if (return_attributes == null)
6268                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6269
6270                                 return_attributes.ApplyAttributeBuilder (a, cb);
6271                                 return;
6272                         }
6273
6274                         ApplyToExtraTarget (a, cb);
6275                 }
6276
6277                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6278                 {
6279                         throw new NotSupportedException ("You forgot to define special attribute target handling");
6280                 }
6281
6282                 // It is not supported for the accessors
6283                 public sealed override bool Define()
6284                 {
6285                         throw new NotSupportedException ();
6286                 }
6287
6288                 public void Emit (DeclSpace parent)
6289                 {
6290                         EmitMethod (parent);
6291
6292 #if GMCS_SOURCE                 
6293                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0)
6294                                 method_data.MethodBuilder.SetCustomAttribute (TypeManager.compiler_generated_attr);
6295 #endif                  
6296                         if (OptAttributes != null)
6297                                 OptAttributes.Emit ();
6298
6299                         if (declarative_security != null) {
6300                                 foreach (DictionaryEntry de in declarative_security) {
6301                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6302                                 }
6303                         }
6304
6305                         block = null;
6306                 }
6307
6308                 protected virtual void EmitMethod (DeclSpace parent)
6309                 {
6310                         method_data.Emit (parent);
6311                 }
6312
6313                 public override bool EnableOverloadChecks (MemberCore overload)
6314                 {
6315                         // This can only happen with indexers and it will
6316                         // be catched as indexer difference
6317                         if (overload is AbstractPropertyEventMethod)
6318                                 return true;
6319
6320                         if (overload is MethodCore) {
6321                                 caching_flags |= Flags.MethodOverloadsExist;
6322                                 return true;
6323                         }
6324                         return false;
6325                 }
6326
6327                 public override bool IsClsComplianceRequired()
6328                 {
6329                         return false;
6330                 }
6331
6332                 public bool IsDuplicateImplementation (MethodCore method)
6333                 {
6334                         if (!MemberName.Equals (method.MemberName))
6335                                 return false;
6336
6337                         Type[] param_types = method.ParameterTypes;
6338
6339                         if (param_types == null || param_types.Length != ParameterTypes.Length)
6340                                 return false;
6341
6342                         for (int i = 0; i < param_types.Length; i++)
6343                                 if (param_types [i] != ParameterTypes [i])
6344                                         return false;
6345
6346                         Report.SymbolRelatedToPreviousError (method);
6347                         Report.Error (82, Location, "A member `{0}' is already reserved",
6348                                 method.GetSignatureForError ());
6349                         return true;
6350                 }
6351
6352                 public override bool IsUsed
6353                 {
6354                         get {
6355                                 if (IsDummy)
6356                                         return false;
6357
6358                                 return base.IsUsed;
6359                         }
6360                 }
6361
6362                 public new Location Location { 
6363                         get {
6364                                 return base.Location;
6365                         }
6366                 }
6367
6368                 public virtual bool ResolveMembers ()
6369                 {
6370                         return true;
6371                 }
6372
6373                 //
6374                 //   Represents header string for documentation comment.
6375                 //
6376                 public override string DocCommentHeader {
6377                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6378                 }
6379
6380         }
6381
6382         //
6383         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6384         // their common bits.
6385         //
6386         abstract public class PropertyBase : PropertyBasedMember {
6387
6388                 public class GetMethod : PropertyMethod
6389                 {
6390                         static string[] attribute_targets = new string [] { "method", "return" };
6391
6392                         public GetMethod (PropertyBase method):
6393                                 base (method, "get_")
6394                         {
6395                         }
6396
6397                         public GetMethod (PropertyBase method, Accessor accessor):
6398                                 base (method, accessor, "get_")
6399                         {
6400                         }
6401
6402                         public override MethodBuilder Define (DeclSpace parent)
6403                         {
6404                                 if (!CheckForDuplications ())
6405                                         return null;
6406
6407                                 if (IsDummy)
6408                                         return null;
6409                                 
6410                                 base.Define (parent);
6411                                 
6412                                 method_data = new MethodData (method, ModFlags, flags, this);
6413
6414                                 if (!method_data.Define (parent))
6415                                         return null;
6416
6417                                 return method_data.MethodBuilder;
6418                         }
6419
6420                         public override Type ReturnType {
6421                                 get {
6422                                         return method.MemberType;
6423                                 }
6424                         }
6425
6426                         public override Parameters ParameterInfo {
6427                                 get {
6428                                         return Parameters.EmptyReadOnlyParameters;
6429                                 }
6430                         }
6431
6432                         public override string[] ValidAttributeTargets {
6433                                 get {
6434                                         return attribute_targets;
6435                                 }
6436                         }
6437                 }
6438
6439                 public class SetMethod : PropertyMethod {
6440
6441                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6442                         ImplicitParameter param_attr;
6443                         protected Parameters parameters;
6444
6445                         public SetMethod (PropertyBase method):
6446                                 base (method, "set_")
6447                         {
6448                         }
6449
6450                         public SetMethod (PropertyBase method, Accessor accessor):
6451                                 base (method, accessor, "set_")
6452                         {
6453                         }
6454
6455                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6456                         {
6457                                 if (a.Target == AttributeTargets.Parameter) {
6458                                         if (param_attr == null)
6459                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6460
6461                                         param_attr.ApplyAttributeBuilder (a, cb);
6462                                         return;
6463                                 }
6464
6465                                 base.ApplyAttributeBuilder (a, cb);
6466                         }
6467
6468                         public override Parameters ParameterInfo {
6469                                 get {
6470                                         if (parameters == null)
6471                                                 DefineParameters ();
6472                                         return parameters;
6473                                 }
6474                         }
6475
6476                         protected virtual void DefineParameters ()
6477                         {
6478                                 parameters = Parameters.CreateFullyResolved (
6479                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location));
6480                         }
6481
6482                         public override MethodBuilder Define (DeclSpace parent)
6483                         {
6484                                 if (!CheckForDuplications ())
6485                                         return null;
6486                                 
6487                                 if (IsDummy)
6488                                         return null;
6489
6490                                 base.Define (parent);
6491
6492                                 method_data = new MethodData (method, ModFlags, flags, this);
6493
6494                                 if (!method_data.Define (parent))
6495                                         return null;
6496
6497                                 return method_data.MethodBuilder;
6498                         }
6499
6500                         public override Type ReturnType {
6501                                 get {
6502                                         return TypeManager.void_type;
6503                                 }
6504                         }
6505
6506                         public override string[] ValidAttributeTargets {
6507                                 get {
6508                                         return attribute_targets;
6509                                 }
6510                         }
6511                 }
6512
6513                 static string[] attribute_targets = new string [] { "property" };
6514
6515                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6516                 {
6517                         protected readonly PropertyBase method;
6518                         protected MethodAttributes flags;
6519                         Iterator iterator;
6520                         ArrayList anonymous_methods;
6521                         bool yields;
6522
6523                         public PropertyMethod (PropertyBase method, string prefix)
6524                                 : base (method, prefix)
6525                         {
6526                                 this.method = method;
6527                         }
6528
6529                         public PropertyMethod (PropertyBase method, Accessor accessor,
6530                                                string prefix)
6531                                 : base (method, accessor, prefix)
6532                         {
6533                                 this.method = method;
6534                                 this.ModFlags = accessor.ModFlags;
6535                                 yields = accessor.Yields;
6536                                 anonymous_methods = accessor.AnonymousMethods;
6537
6538                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6539                                         Report.FeatureIsNotISO1 (Location, "access modifiers on properties");
6540                                 }
6541                         }
6542
6543                         public override Iterator Iterator {
6544                                 get { return iterator; }
6545                         }
6546
6547                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6548                         {
6549                                 if (a.IsInternalMethodImplAttribute) {
6550                                         method.is_external_implementation = true;
6551                                 }
6552
6553                                 base.ApplyAttributeBuilder (a, cb);
6554                         }
6555
6556                         public override AttributeTargets AttributeTargets {
6557                                 get {
6558                                         return AttributeTargets.Method;
6559                                 }
6560                         }
6561
6562                         public override bool IsClsComplianceRequired ()
6563                         {
6564                                 return method.IsClsComplianceRequired ();
6565                         }
6566
6567                         public override bool ResolveMembers ()
6568                         {
6569                                 if (yields) {
6570                                         iterator = Iterator.CreateIterator (this, Parent, null, ModFlags);
6571                                         if (iterator == null)
6572                                                 return false;
6573                                 }
6574
6575                                 if (anonymous_methods != null) {
6576                                         foreach (AnonymousMethodExpression ame in anonymous_methods) {
6577                                                 if (!ame.CreateAnonymousHelpers ())
6578                                                         return false;
6579                                         }
6580                                 }
6581
6582                                 return true;
6583                         }
6584
6585                         public virtual MethodBuilder Define (DeclSpace parent)
6586                         {
6587                                 TypeContainer container = parent.PartialContainer;
6588
6589                                 //
6590                                 // Check for custom access modifier
6591                                 //
6592                                 if ((ModFlags & Modifiers.Accessibility) == 0) {
6593                                         ModFlags |= method.ModFlags;
6594                                         flags = method.flags;
6595                                 } else {
6596                                         if (container.Kind == Kind.Interface)
6597                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6598                                                         GetSignatureForError ());
6599
6600                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6601                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6602                                         }
6603
6604                                         CheckModifiers (ModFlags);
6605                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6606                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6607                                         flags = Modifiers.MethodAttr (ModFlags);
6608                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6609                                 }
6610
6611                                 CheckAbstractAndExtern (block != null);
6612                                 return null;
6613                         }
6614
6615                         public bool HasCustomAccessModifier
6616                         {
6617                                 get {
6618                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6619                                 }
6620                         }
6621
6622                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6623                         {
6624                                 return new EmitContext (method,
6625                                         ds, method.ds, method.Location, ig, ReturnType,
6626                                         method.ModFlags, false);
6627                         }
6628
6629                         public override ObsoleteAttribute GetObsoleteAttribute ()
6630                         {
6631                                 return method.GetObsoleteAttribute ();
6632                         }
6633
6634                         public override string GetSignatureForError()
6635                         {
6636                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6637                         }
6638                         
6639                         void CheckModifiers (int modflags)
6640                         {
6641                                 modflags &= Modifiers.Accessibility;
6642                                 int flags = 0;
6643                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6644
6645                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6646                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6647                                 }
6648                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6649                                         if ((mflags & Modifiers.INTERNAL) != 0)
6650                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6651
6652                                         flags |= Modifiers.PRIVATE;
6653                                 }
6654                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6655                                         flags |= Modifiers.PRIVATE;
6656
6657                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6658                                         Report.Error (273, Location,
6659                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6660                                                 GetSignatureForError (), method.GetSignatureForError ());
6661                                 }
6662                         }
6663
6664                         protected bool CheckForDuplications () 
6665                         {
6666                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0)
6667                                         return true;
6668
6669                                 return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo);
6670                         }
6671                 }
6672
6673                 public PropertyMethod Get, Set;
6674                 public PropertyBuilder PropertyBuilder;
6675                 public MethodBuilder GetBuilder, SetBuilder;
6676
6677                 protected bool define_set_first = false;
6678
6679                 public PropertyBase (DeclSpace parent, Expression type, int mod_flags,
6680                                      int allowed_mod, bool is_iface, MemberName name,
6681                                      Attributes attrs, bool define_set_first)
6682                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,     attrs)
6683                 {
6684                          this.define_set_first = define_set_first;
6685                 }
6686
6687                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6688                 {
6689                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
6690                                 a.Error_InvalidSecurityParent ();
6691                                 return;
6692                         }
6693
6694                         PropertyBuilder.SetCustomAttribute (cb);
6695                 }
6696
6697                 public override AttributeTargets AttributeTargets {
6698                         get {
6699                                 return AttributeTargets.Property;
6700                         }
6701                 }
6702
6703                 public override bool Define ()
6704                 {
6705                         if (!DoDefine ())
6706                                 return false;
6707
6708                         if (!IsTypePermitted ())
6709                                 return false;
6710
6711                         return true;
6712                 }
6713
6714                 protected override bool DoDefine ()
6715                 {
6716                         if (!base.DoDefine ())
6717                                 return false;
6718
6719                         //
6720                         // Accessors modifiers check
6721                         //
6722                         if ((Get.ModFlags & Modifiers.Accessibility) != 0 &&
6723                                 (Set.ModFlags & Modifiers.Accessibility) != 0) {
6724                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6725                                                 GetSignatureForError ());
6726                                 return false;
6727                         }
6728
6729                         if ((Get.IsDummy || Set.IsDummy)
6730                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6731                                 Report.Error (276, Location, 
6732                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6733                                         GetSignatureForError ());
6734                                 return false;
6735                         }
6736
6737 #if MS_COMPATIBLE
6738                         if (MemberType.IsGenericParameter)
6739                                 return true;
6740 #endif
6741
6742                         if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
6743                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6744                                 return false;
6745                         }
6746
6747                         return true;
6748                 }
6749
6750                 bool DefineGet ()
6751                 {
6752                         GetBuilder = Get.Define (Parent);
6753                         return (Get.IsDummy) ? true : GetBuilder != null;
6754                 }
6755
6756                 bool DefineSet (bool define)
6757                 {
6758                         if (!define)
6759                                 return true;
6760
6761                         SetBuilder = Set.Define (Parent);
6762                         return (Set.IsDummy) ? true : SetBuilder != null;
6763                 }
6764
6765                 protected bool DefineAccessors ()
6766                 {
6767                         return DefineSet (define_set_first) &&
6768                                 DefineGet () &&
6769                                 DefineSet (!define_set_first);
6770                 }
6771
6772                 protected abstract PropertyInfo ResolveBaseProperty ();
6773
6774                 // TODO: rename to Resolve......
6775                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6776                 {
6777                         PropertyInfo base_property = ResolveBaseProperty ();
6778                         if (base_property == null)
6779                                 return null;
6780   
6781                         base_ret_type = base_property.PropertyType;
6782                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6783                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6784                         MethodAttributes get_accessor_access, set_accessor_access;
6785
6786                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
6787                                 if (Get != null && !Get.IsDummy && get_accessor == null) {
6788                                         Report.SymbolRelatedToPreviousError (base_property);
6789                                         Report.Error (545, Location, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6790                                 }
6791
6792                                 if (Set != null && !Set.IsDummy && set_accessor == null) {
6793                                         Report.SymbolRelatedToPreviousError (base_property);
6794                                         Report.Error (546, Location, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6795                                 }
6796                         }
6797                         
6798                         //
6799                         // Check base class accessors access
6800                         //
6801
6802                         // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6803                         get_accessor_access = set_accessor_access = 0;
6804                         if ((ModFlags & Modifiers.NEW) == 0) {
6805                                 if (get_accessor != null) {
6806                                         MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
6807                                         get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
6808
6809                                         if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6810                                                 Error_CannotChangeAccessModifiers (get_accessor, get_accessor_access,  ".get");
6811                                 }
6812
6813                                 if (set_accessor != null)  {
6814                                         MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
6815                                         set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
6816
6817                                         if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6818                                                 Error_CannotChangeAccessModifiers (set_accessor, set_accessor_access, ".set");
6819                                 }
6820                         }
6821
6822                         // When one accessor does not exist and property hides base one
6823                         // we need to propagate this upwards
6824                         if (set_accessor == null)
6825                                 set_accessor = get_accessor;
6826
6827                         //
6828                         // Get the less restrictive access
6829                         //
6830                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6831                 }
6832
6833                 public override void Emit ()
6834                 {
6835                         //
6836                         // The PropertyBuilder can be null for explicit implementations, in that
6837                         // case, we do not actually emit the ".property", so there is nowhere to
6838                         // put the attribute
6839                         //
6840                         if (PropertyBuilder != null && OptAttributes != null)
6841                                 OptAttributes.Emit ();
6842
6843                         if (!Get.IsDummy)
6844                                 Get.Emit (Parent);
6845
6846                         if (!Set.IsDummy)
6847                                 Set.Emit (Parent);
6848
6849                         base.Emit ();
6850                 }
6851
6852                 /// <summary>
6853                 /// Tests whether accessors are not in collision with some method (CS0111)
6854                 /// </summary>
6855                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6856                 {
6857                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6858                 }
6859
6860                 public override bool IsUsed
6861                 {
6862                         get {
6863                                 if (IsExplicitImpl)
6864                                         return true;
6865
6866                                 return Get.IsUsed | Set.IsUsed;
6867                         }
6868                 }
6869
6870                 protected override void SetMemberName (MemberName new_name)
6871                 {
6872                         base.SetMemberName (new_name);
6873
6874                         Get.UpdateName (this);
6875                         Set.UpdateName (this);
6876                 }
6877
6878                 public override string[] ValidAttributeTargets {
6879                         get {
6880                                 return attribute_targets;
6881                         }
6882                 }
6883
6884                 //
6885                 //   Represents header string for documentation comment.
6886                 //
6887                 public override string DocCommentHeader {
6888                         get { return "P:"; }
6889                 }
6890         }
6891                         
6892         public class Property : PropertyBase {
6893                 const int AllowedModifiers =
6894                         Modifiers.NEW |
6895                         Modifiers.PUBLIC |
6896                         Modifiers.PROTECTED |
6897                         Modifiers.INTERNAL |
6898                         Modifiers.PRIVATE |
6899                         Modifiers.STATIC |
6900                         Modifiers.SEALED |
6901                         Modifiers.OVERRIDE |
6902                         Modifiers.ABSTRACT |
6903                         Modifiers.UNSAFE |
6904                         Modifiers.EXTERN |
6905                         Modifiers.METHOD_YIELDS |
6906                         Modifiers.VIRTUAL;
6907
6908                 const int AllowedInterfaceModifiers =
6909                         Modifiers.NEW;
6910
6911                 void CreateAutomaticProperty (Block block, Accessor get_block, Accessor set_block)
6912                 {
6913                         // Make the field
6914                         Field field = new Field (
6915                                 Parent, Type,
6916                                 Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & Modifiers.STATIC),
6917                                 CompilerGeneratedClass.MakeName (null, "CompilerGeneratedField"),
6918                                 null, Location);
6919                         ((TypeContainer)Parent).AddField (field);
6920
6921                         // Make get block
6922                         get_block.Block = new ToplevelBlock (block, null, Location);
6923                         Return r = new Return (new SimpleName(field.Name, Location), Location);
6924                         get_block.Block.AddStatement (r);
6925                         get_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6926
6927                         // Make set block
6928                         Parameters parameters = new Parameters (new Parameter (Type, "value", Parameter.Modifier.NONE, null, Location));
6929                         set_block.Block = new ToplevelBlock (block, parameters, Location);
6930                         Assign a = new Assign (new SimpleName(field.Name, Location), new SimpleName ("value", Location));
6931                         set_block.Block.AddStatement (new StatementExpression(a));
6932                         set_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6933                 }
6934
6935                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6936                                  MemberName name, Attributes attrs, Accessor get_block,
6937                                  Accessor set_block, bool define_set_first)
6938                         : this (parent, type, mod, is_iface, name, attrs, get_block, set_block,
6939                                 define_set_first, null)
6940                 {
6941                 }
6942                 
6943                 public Property (DeclSpace parent, Expression type, int mod, bool is_iface,
6944                                  MemberName name, Attributes attrs, Accessor get_block,
6945                                  Accessor set_block, bool define_set_first, Block current_block)
6946                         : base (parent, type, mod,
6947                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6948                                 is_iface, name, attrs, define_set_first)
6949                 {
6950                         if (RootContext.Version >= LanguageVersion.LINQ &&
6951                                 !is_iface &&
6952                                 (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
6953                                 get_block != null && get_block.Block == null &&
6954                                 set_block != null && set_block.Block == null)
6955                                 CreateAutomaticProperty (current_block, get_block, set_block);
6956
6957                         if (get_block == null)
6958                                 Get = new GetMethod (this);
6959                         else
6960                                 Get = new GetMethod (this, get_block);
6961
6962                         if (set_block == null)
6963                                 Set = new SetMethod (this);
6964                         else
6965                                 Set = new SetMethod (this, set_block);
6966                 }
6967
6968                 public override bool Define ()
6969                 {
6970                         if (!DoDefineBase ())
6971                                 return false;
6972
6973                         if (!base.Define ())
6974                                 return false;
6975
6976                         if (!CheckBase ())
6977                                 return false;
6978
6979                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6980
6981                         if (!DefineAccessors ())
6982                                 return false;
6983
6984                         // FIXME - PropertyAttributes.HasDefault ?
6985
6986                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6987                                 MemberName.ToString (), PropertyAttributes.None, MemberType, null);
6988
6989                         if (!Get.IsDummy) {
6990                                 PropertyBuilder.SetGetMethod (GetBuilder);
6991                                 Parent.MemberCache.AddMember (GetBuilder, Get);
6992                         }
6993
6994                         if (!Set.IsDummy) {
6995                                 PropertyBuilder.SetSetMethod (SetBuilder);
6996                                 Parent.MemberCache.AddMember (SetBuilder, Set);
6997                         }
6998                         
6999                         TypeManager.RegisterProperty (PropertyBuilder, this);
7000                         Parent.MemberCache.AddMember (PropertyBuilder, this);
7001                         return true;
7002                 }
7003
7004                 protected override PropertyInfo ResolveBaseProperty ()
7005                 {
7006                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7007                                 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
7008                 }
7009         }
7010
7011         /// </summary>
7012         ///  Gigantic workaround  for lameness in SRE follows :
7013         ///  This class derives from EventInfo and attempts to basically
7014         ///  wrap around the EventBuilder so that FindMembers can quickly
7015         ///  return this in it search for members
7016         /// </summary>
7017         public class MyEventBuilder : EventInfo {
7018                 
7019                 //
7020                 // We use this to "point" to our Builder which is
7021                 // not really a MemberInfo
7022                 //
7023                 EventBuilder MyBuilder;
7024                 
7025                 //
7026                 // We "catch" and wrap these methods
7027                 //
7028                 MethodInfo raise, remove, add;
7029
7030                 EventAttributes attributes;
7031                 Type declaring_type, reflected_type, event_type;
7032                 string name;
7033
7034                 Event my_event;
7035
7036                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
7037                 {
7038                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
7039
7040                         // And now store the values in our own fields.
7041                         
7042                         declaring_type = type_builder;
7043
7044                         reflected_type = type_builder;
7045                         
7046                         attributes = event_attr;
7047                         this.name = name;
7048                         my_event = ev;
7049                         this.event_type = event_type;
7050                 }
7051                 
7052                 //
7053                 // Methods that you have to override.  Note that you only need 
7054                 // to "implement" the variants that take the argument (those are
7055                 // the "abstract" methods, the others (GetAddMethod()) are 
7056                 // regular.
7057                 //
7058                 public override MethodInfo GetAddMethod (bool nonPublic)
7059                 {
7060                         return add;
7061                 }
7062                 
7063                 public override MethodInfo GetRemoveMethod (bool nonPublic)
7064                 {
7065                         return remove;
7066                 }
7067                 
7068                 public override MethodInfo GetRaiseMethod (bool nonPublic)
7069                 {
7070                         return raise;
7071                 }
7072                 
7073                 //
7074                 // These methods make "MyEventInfo" look like a Builder
7075                 //
7076                 public void SetRaiseMethod (MethodBuilder raiseMethod)
7077                 {
7078                         raise = raiseMethod;
7079                         MyBuilder.SetRaiseMethod (raiseMethod);
7080                 }
7081
7082                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
7083                 {
7084                         remove = removeMethod;
7085                         MyBuilder.SetRemoveOnMethod (removeMethod);
7086                 }
7087
7088                 public void SetAddOnMethod (MethodBuilder addMethod)
7089                 {
7090                         add = addMethod;
7091                         MyBuilder.SetAddOnMethod (addMethod);
7092                 }
7093
7094                 public void SetCustomAttribute (CustomAttributeBuilder cb)
7095                 {
7096                         MyBuilder.SetCustomAttribute (cb);
7097                 }
7098                 
7099                 public override object [] GetCustomAttributes (bool inherit)
7100                 {
7101                         // FIXME : There's nothing which can be seemingly done here because
7102                         // we have no way of getting at the custom attribute objects of the
7103                         // EventBuilder !
7104                         return null;
7105                 }
7106
7107                 public override object [] GetCustomAttributes (Type t, bool inherit)
7108                 {
7109                         // FIXME : Same here !
7110                         return null;
7111                 }
7112
7113                 public override bool IsDefined (Type t, bool b)
7114                 {
7115                         return true;
7116                 }
7117
7118                 public override EventAttributes Attributes {
7119                         get {
7120                                 return attributes;
7121                         }
7122                 }
7123
7124                 public override string Name {
7125                         get {
7126                                 return name;
7127                         }
7128                 }
7129
7130                 public override Type DeclaringType {
7131                         get {
7132                                 return declaring_type;
7133                         }
7134                 }
7135
7136                 public override Type ReflectedType {
7137                         get {
7138                                 return reflected_type;
7139                         }
7140                 }
7141
7142                 public Type EventType {
7143                         get {
7144                                 return event_type;
7145                         }
7146                 }
7147                 
7148                 public void SetUsed ()
7149                 {
7150                         if (my_event != null) {
7151 //                              my_event.SetAssigned ();
7152                                 my_event.SetMemberIsUsed ();
7153                         }
7154                 }
7155         }
7156         
7157         /// <summary>
7158         /// For case when event is declared like property (with add and remove accessors).
7159         /// </summary>
7160         public class EventProperty: Event {
7161                 abstract class AEventPropertyAccessor : AEventAccessor
7162                 {
7163                         readonly ArrayList anonymous_methods;
7164
7165                         public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7166                                 base (method, accessor, prefix)
7167                         {
7168                                 this.anonymous_methods = accessor.AnonymousMethods;
7169                         }
7170
7171                         public override MethodBuilder Define (DeclSpace ds)
7172                         {
7173                                 CheckAbstractAndExtern (block != null);
7174                                 return base.Define (ds);
7175                         }
7176                         
7177                         public override string GetSignatureForError ()
7178                         {
7179                                 return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
7180                         }
7181
7182                         public override bool ResolveMembers ()
7183                         {
7184                                 if (anonymous_methods == null)
7185                                         return true;
7186
7187                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
7188                                         if (!ame.CreateAnonymousHelpers ())
7189                                                 return false;
7190                                 }
7191
7192                                 return true;
7193                         }
7194
7195                 }
7196
7197                 sealed class AddDelegateMethod: AEventPropertyAccessor
7198                 {
7199                         public AddDelegateMethod (Event method, Accessor accessor):
7200                                 base (method, accessor, "add_")
7201                         {
7202                         }
7203
7204                         protected override MethodInfo DelegateMethodInfo {
7205                                 get {
7206                                         return TypeManager.delegate_combine_delegate_delegate;
7207                                 }
7208                         }
7209                 }
7210
7211                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7212                 {
7213                         public RemoveDelegateMethod (Event method, Accessor accessor):
7214                                 base (method, accessor, "remove_")
7215                         {
7216                         }
7217
7218                         protected override MethodInfo DelegateMethodInfo {
7219                                 get {
7220                                         return TypeManager.delegate_remove_delegate_delegate;
7221                                 }
7222                         }
7223                 }
7224
7225
7226                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7227
7228                 public EventProperty (DeclSpace parent, Expression type, int mod_flags,
7229                                       bool is_iface, MemberName name,
7230                                       Attributes attrs, Accessor add, Accessor remove)
7231                         : base (parent, type, mod_flags, is_iface, name, attrs)
7232                 {
7233                         Add = new AddDelegateMethod (this, add);
7234                         Remove = new RemoveDelegateMethod (this, remove);
7235                 }
7236
7237                 public override bool Define()
7238                 {
7239                         if (!base.Define ())
7240                                 return false;
7241
7242                         if (IsExplicitImpl)
7243                                 SetMemberIsUsed ();
7244
7245                         return true;
7246                 }
7247
7248                 public override string[] ValidAttributeTargets {
7249                         get {
7250                                 return attribute_targets;
7251                         }
7252                 }
7253         }
7254
7255         /// <summary>
7256         /// Event is declared like field.
7257         /// </summary>
7258         public class EventField : Event {
7259                 abstract class EventFieldAccessor : AEventAccessor
7260                 {
7261                         protected EventFieldAccessor (Event method, string prefix)
7262                                 : base (method, prefix)
7263                         {
7264                         }
7265
7266                         protected override void EmitMethod(DeclSpace parent)
7267                         {
7268                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7269                                         return;
7270
7271                                 MethodBuilder mb = method_data.MethodBuilder;
7272                                 ILGenerator ig = mb.GetILGenerator ();
7273
7274                                 // TODO: because we cannot use generics yet
7275                                 FieldInfo field_info = ((EventField)method).FieldBuilder;
7276
7277                                 if (parent is Class) {
7278                                         mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7279                                 }
7280                                 
7281                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7282                                         ig.Emit (OpCodes.Ldsfld, field_info);
7283                                         ig.Emit (OpCodes.Ldarg_0);
7284                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7285                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7286                                         ig.Emit (OpCodes.Stsfld, field_info);
7287                                 } else {
7288                                         ig.Emit (OpCodes.Ldarg_0);
7289                                         ig.Emit (OpCodes.Ldarg_0);
7290                                         ig.Emit (OpCodes.Ldfld, field_info);
7291                                         ig.Emit (OpCodes.Ldarg_1);
7292                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7293                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7294                                         ig.Emit (OpCodes.Stfld, field_info);
7295                                 }
7296                                 ig.Emit (OpCodes.Ret);
7297                         }
7298                 }
7299
7300                 sealed class AddDelegateMethod: EventFieldAccessor
7301                 {
7302                         public AddDelegateMethod (Event method):
7303                                 base (method, "add_")
7304                         {
7305                         }
7306
7307                         protected override MethodInfo DelegateMethodInfo {
7308                                 get {
7309                                         return TypeManager.delegate_combine_delegate_delegate;
7310                                 }
7311                         }
7312                 }
7313
7314                 sealed class RemoveDelegateMethod: EventFieldAccessor
7315                 {
7316                         public RemoveDelegateMethod (Event method):
7317                                 base (method, "remove_")
7318                         {
7319                         }
7320
7321                         protected override MethodInfo DelegateMethodInfo {
7322                                 get {
7323                                         return TypeManager.delegate_remove_delegate_delegate;
7324                                 }
7325                         }
7326                 }
7327
7328
7329                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7330                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7331
7332                 public FieldBuilder FieldBuilder;
7333                 public Expression Initializer;
7334
7335                 public EventField (DeclSpace parent, Expression type, int mod_flags,
7336                                    bool is_iface, MemberName name,
7337                                    Attributes attrs)
7338                         : base (parent, type, mod_flags, is_iface, name, attrs)
7339                 {
7340                         Add = new AddDelegateMethod (this);
7341                         Remove = new RemoveDelegateMethod (this);
7342                 }
7343
7344                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7345                 {
7346                         if (a.Target == AttributeTargets.Field) {
7347                                 FieldBuilder.SetCustomAttribute (cb);
7348                                 return;
7349                         }
7350
7351                         if (a.Target == AttributeTargets.Method) {
7352                                 int errors = Report.Errors;
7353                                 Add.ApplyAttributeBuilder (a, cb);
7354                                 if (errors == Report.Errors)
7355                                         Remove.ApplyAttributeBuilder (a, cb);
7356                                 return;
7357                         }
7358
7359                         base.ApplyAttributeBuilder (a, cb);
7360                 }
7361
7362                 public override bool Define()
7363                 {
7364                         if (!base.Define ())
7365                                 return false;
7366
7367                         if (IsInterface)
7368                                 return true;
7369
7370                         // FIXME: We are unable to detect whether generic event is used because
7371                         // we are using FieldExpr instead of EventExpr for event access in that
7372                         // case.  When this issue will be fixed this hack can be removed.
7373                         if (TypeManager.IsGenericType (MemberType))
7374                                 SetMemberIsUsed();
7375
7376                         FieldBuilder = Parent.TypeBuilder.DefineField (
7377                                 Name, MemberType,
7378                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7379                         TypeManager.RegisterEventField (EventBuilder, this);
7380
7381                         if (Initializer != null) {
7382                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7383                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7384                                                 GetSignatureForError ());
7385                                         return false;
7386                                 }
7387
7388                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
7389                                         new FieldInitializer (FieldBuilder, Initializer));
7390                         }
7391
7392                         return true;
7393                 }
7394
7395                 public override string[] ValidAttributeTargets 
7396                 {
7397                         get {
7398                                 return IsInterface ? attribute_targets_interface : attribute_targets;
7399                         }
7400                 }
7401         }
7402
7403         public abstract class Event : PropertyBasedMember {
7404                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7405                 {
7406                         protected readonly Event method;
7407                         ImplicitParameter param_attr;
7408
7409                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7410
7411                         protected AEventAccessor (Event method, string prefix)
7412                                 : base (method, prefix)
7413                         {
7414                                 this.method = method;
7415                                 this.ModFlags = method.ModFlags;
7416                         }
7417
7418                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7419                                 : base (method, accessor, prefix)
7420                         {
7421                                 this.method = method;
7422                                 this.ModFlags = method.ModFlags;
7423                         }
7424
7425                         public override Iterator Iterator {
7426                                 get { return null; }
7427                         }
7428
7429                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7430                         {
7431                                 if (a.IsInternalMethodImplAttribute) {
7432                                         method.is_external_implementation = true;
7433                                 }
7434
7435                                 base.ApplyAttributeBuilder (a, cb);
7436                         }
7437
7438                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7439                         {
7440                                 if (a.Target == AttributeTargets.Parameter) {
7441                                         if (param_attr == null)
7442                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7443
7444                                         param_attr.ApplyAttributeBuilder (a, cb);
7445                                         return;
7446                                 }
7447
7448                                 base.ApplyAttributeBuilder (a, cb);
7449                         }
7450
7451                         public override AttributeTargets AttributeTargets {
7452                                 get {
7453                                         return AttributeTargets.Method;
7454                                 }
7455                         }
7456
7457                         public override bool IsClsComplianceRequired ()
7458                         {
7459                                 return method.IsClsComplianceRequired ();
7460                         }
7461
7462                         public virtual MethodBuilder Define (DeclSpace parent)
7463                         {
7464                                 method_data = new MethodData (method, method.ModFlags,
7465                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7466
7467                                 if (!method_data.Define (parent))
7468                                         return null;
7469
7470                                 MethodBuilder mb = method_data.MethodBuilder;
7471                                 ParameterInfo.ApplyAttributes (mb);
7472                                 return mb;
7473                         }
7474
7475                         protected abstract MethodInfo DelegateMethodInfo { get; }
7476
7477                         public override Type ReturnType {
7478                                 get {
7479                                         return TypeManager.void_type;
7480                                 }
7481                         }
7482
7483                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7484                         {
7485                                 return new EmitContext (
7486                                         ds, method.Parent, Location, ig, ReturnType,
7487                                         method.ModFlags, false);
7488                         }
7489
7490                         public override ObsoleteAttribute GetObsoleteAttribute ()
7491                         {
7492                                 return method.GetObsoleteAttribute ();
7493                         }
7494
7495                         public override string[] ValidAttributeTargets {
7496                                 get {
7497                                         return attribute_targets;
7498                                 }
7499                         }
7500
7501                         public override Parameters ParameterInfo {
7502                                 get {
7503                                         return method.parameters;
7504                                 }
7505                         }
7506                 }
7507
7508
7509                 const int AllowedModifiers =
7510                         Modifiers.NEW |
7511                         Modifiers.PUBLIC |
7512                         Modifiers.PROTECTED |
7513                         Modifiers.INTERNAL |
7514                         Modifiers.PRIVATE |
7515                         Modifiers.STATIC |
7516                         Modifiers.VIRTUAL |
7517                         Modifiers.SEALED |
7518                         Modifiers.OVERRIDE |
7519                         Modifiers.UNSAFE |
7520                         Modifiers.ABSTRACT |
7521                         Modifiers.EXTERN;
7522
7523                 const int AllowedInterfaceModifiers =
7524                         Modifiers.NEW;
7525
7526                 public AEventAccessor Add, Remove;
7527                 public MyEventBuilder     EventBuilder;
7528                 public MethodBuilder AddBuilder, RemoveBuilder;
7529
7530                 Parameters parameters;
7531
7532                 protected Event (DeclSpace parent, Expression type, int mod_flags,
7533                               bool is_iface, MemberName name, Attributes attrs)
7534                         : base (parent, null, type, mod_flags,
7535                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7536                                 name, attrs)
7537                 {
7538                 }
7539
7540                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7541                 {
7542                         if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
7543                                 a.Error_InvalidSecurityParent ();
7544                                 return;
7545                         }
7546                         
7547                         EventBuilder.SetCustomAttribute (cb);
7548                 }
7549
7550                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7551                 {
7552                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7553                 }
7554
7555                 public override AttributeTargets AttributeTargets {
7556                         get {
7557                                 return AttributeTargets.Event;
7558                         }
7559                 }
7560
7561                 public override bool Define ()
7562                 {
7563                         if (!DoDefineBase ())
7564                                 return false;
7565
7566                         if (!DoDefine ())
7567                                 return false;
7568
7569                         if (!TypeManager.IsDelegateType (MemberType)) {
7570                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7571                                 return false;
7572                         }
7573
7574                         parameters = Parameters.CreateFullyResolved (
7575                                 new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location));
7576
7577                         if (!CheckBase ())
7578                                 return false;
7579
7580                         //
7581                         // Now define the accessors
7582                         //
7583
7584                         AddBuilder = Add.Define (Parent);
7585                         if (AddBuilder == null)
7586                                 return false;
7587
7588                         RemoveBuilder = Remove.Define (Parent);
7589                         if (RemoveBuilder == null)
7590                                 return false;
7591
7592                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7593                         EventBuilder.SetAddOnMethod (AddBuilder);
7594                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7595
7596                         Parent.MemberCache.AddMember (EventBuilder, this);
7597                         Parent.MemberCache.AddMember (AddBuilder, Add);
7598                         Parent.MemberCache.AddMember (RemoveBuilder, Remove);
7599                         
7600                         return true;
7601                 }
7602
7603                 public override void Emit ()
7604                 {
7605                         if (OptAttributes != null) {
7606                                 OptAttributes.Emit ();
7607                         }
7608
7609                         Add.Emit (Parent);
7610                         Remove.Emit (Parent);
7611
7612                         base.Emit ();
7613                 }
7614
7615                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7616                 {
7617                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7618                                 Parent.TypeBuilder, Name);
7619
7620                         if (mi == null)
7621                                 return null;
7622
7623                         ParameterData pd = TypeManager.GetParameterData (mi);
7624                         base_ret_type = pd.ParameterType (0);
7625                         return mi;
7626                 }
7627
7628                 //
7629                 //   Represents header string for documentation comment.
7630                 //
7631                 public override string DocCommentHeader {
7632                         get { return "E:"; }
7633                 }
7634         }
7635
7636  
7637         public class Indexer : PropertyBase
7638         {
7639                 class GetIndexerMethod : GetMethod
7640                 {
7641                         public GetIndexerMethod (PropertyBase method):
7642                                 base (method)
7643                         {
7644                         }
7645
7646                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7647                                 base (method, accessor)
7648                         {
7649                         }
7650                         
7651                         public override bool EnableOverloadChecks (MemberCore overload)
7652                         {
7653                                 if (base.EnableOverloadChecks (overload)) {
7654                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7655                                         return true;
7656                                 }
7657
7658                                 return false;
7659                         }                       
7660
7661                         public override Parameters ParameterInfo {
7662                                 get {
7663                                         return ((Indexer)method).parameters;
7664                                 }
7665                         }
7666                 }
7667
7668                 class SetIndexerMethod: SetMethod
7669                 {
7670                         public SetIndexerMethod (PropertyBase method):
7671                                 base (method)
7672                         {
7673                         }
7674
7675                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7676                                 base (method, accessor)
7677                         {
7678                         }
7679
7680                         protected override void DefineParameters ()
7681                         {
7682                                 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7683                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7684                         }
7685                         
7686                         public override bool EnableOverloadChecks (MemberCore overload)
7687                         {
7688                                 if (base.EnableOverloadChecks (overload)) {
7689                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7690                                         return true;
7691                                 }
7692
7693                                 return false;
7694                         }                       
7695                 }
7696
7697                 const int AllowedModifiers =
7698                         Modifiers.NEW |
7699                         Modifiers.PUBLIC |
7700                         Modifiers.PROTECTED |
7701                         Modifiers.INTERNAL |
7702                         Modifiers.PRIVATE |
7703                         Modifiers.VIRTUAL |
7704                         Modifiers.SEALED |
7705                         Modifiers.OVERRIDE |
7706                         Modifiers.UNSAFE |
7707                         Modifiers.EXTERN |
7708                         Modifiers.ABSTRACT;
7709
7710                 const int AllowedInterfaceModifiers =
7711                         Modifiers.NEW;
7712
7713                 public readonly Parameters parameters;
7714
7715                 public Indexer (DeclSpace parent, Expression type, MemberName name, int mod,
7716                                 bool is_iface, Parameters parameters, Attributes attrs,
7717                                 Accessor get_block, Accessor set_block, bool define_set_first)
7718                         : base (parent, type, mod,
7719                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7720                                 is_iface, name, attrs, define_set_first)
7721                 {
7722                         if (type == TypeManager.system_void_expr)
7723                                 Report.Error (620, name.Location, "An indexer return type cannot be `void'");
7724                         
7725                         this.parameters = parameters;
7726
7727                         if (get_block == null)
7728                                 Get = new GetIndexerMethod (this);
7729                         else
7730                                 Get = new GetIndexerMethod (this, get_block);
7731
7732                         if (set_block == null)
7733                                 Set = new SetIndexerMethod (this);
7734                         else
7735                                 Set = new SetIndexerMethod (this, set_block);
7736                 }
7737                 
7738                 public override bool Define ()
7739                 {
7740                         if (!DoDefineBase ())
7741                                 return false;
7742
7743                         if (!base.Define ())
7744                                 return false;
7745
7746                         if (!DefineParameters (parameters))
7747                                 return false;
7748
7749                         if (OptAttributes != null) {
7750                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7751                                 if (indexer_attr != null) {
7752                                         // Remove the attribute from the list because it is not emitted
7753                                         OptAttributes.Attrs.Remove (indexer_attr);
7754
7755                                         string name = indexer_attr.GetIndexerAttributeValue ();
7756                                         if (name == null)
7757                                                 return false;
7758
7759                                         ShortName = name;
7760
7761                                         if (IsExplicitImpl) {
7762                                                 Report.Error (415, indexer_attr.Location,
7763                                                               "The `IndexerName' attribute is valid only on an " +
7764                                                               "indexer that is not an explicit interface member declaration");
7765                                                 return false;
7766                                         }
7767
7768                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7769                                                 Report.Error (609, indexer_attr.Location,
7770                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7771                                                 return false;
7772                                         }
7773                                 }
7774                         }
7775
7776                         if (InterfaceType != null) {
7777                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7778                                 if (base_IndexerName != Name)
7779                                         ShortName = base_IndexerName;
7780                         }
7781
7782                         if (!Parent.PartialContainer.AddMember (this) ||
7783                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7784                                 return false;
7785
7786                         if (!CheckBase ())
7787                                 return false;
7788
7789
7790                         if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
7791                                 if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, parameters))
7792                                         return false;
7793                         }
7794
7795                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7796                         
7797                         if (!DefineAccessors ())
7798                                 return false;
7799
7800                         if (!Get.IsDummy) {
7801                                 // Setup iterator if we are one
7802                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7803                                         Iterator iterator = Iterator.CreateIterator (Get, Parent, null, ModFlags);
7804                                         if (iterator == null)
7805                                                 return false;
7806                                 }
7807                         }
7808
7809                         //
7810                         // Now name the parameters
7811                         //
7812                         Parameter [] p = parameters.FixedParameters;
7813                         if (p != null) {
7814                                 // TODO: should be done in parser and it needs to do cycle
7815                                 if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
7816                                         CSharpParser.Error_ParameterModifierNotValid (Location);
7817                                         return false;
7818                                 }
7819                         }
7820
7821                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7822                                 Name, PropertyAttributes.None, MemberType, parameters.Types);
7823
7824                         if (!Get.IsDummy) {
7825                                 PropertyBuilder.SetGetMethod (GetBuilder);
7826                                 Parent.MemberCache.AddMember (GetBuilder, Get);
7827                         }
7828
7829                         if (!Set.IsDummy) {
7830                                 PropertyBuilder.SetSetMethod (SetBuilder);
7831                                 Parent.MemberCache.AddMember (SetBuilder, Set);
7832                         }
7833                                 
7834                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7835                         Parent.MemberCache.AddMember (PropertyBuilder, this);
7836                         return true;
7837                 }
7838
7839                 public override bool EnableOverloadChecks (MemberCore overload)
7840                 {
7841                         if (overload is Indexer) {
7842                                 caching_flags |= Flags.MethodOverloadsExist;
7843                                 return true;
7844                         }
7845
7846                         return false;
7847                 }
7848
7849                 public override string GetDocCommentName (DeclSpace ds)
7850                 {
7851                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7852                 }
7853
7854                 public override string GetSignatureForError ()
7855                 {
7856                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7857                         if (MemberName.Left != null) {
7858                                 sb.Append ('.');
7859                                 sb.Append (MemberName.Left);
7860                         }
7861
7862                         sb.Append (".this");
7863                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7864                         return sb.ToString ();
7865                 }
7866
7867                 protected override PropertyInfo ResolveBaseProperty ()
7868                 {
7869                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7870                                 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7871                 }
7872
7873                 protected override bool VerifyClsCompliance ()
7874                 {
7875                         if (!base.VerifyClsCompliance ())
7876                                 return false;
7877
7878                         parameters.VerifyClsCompliance ();
7879                         return true;
7880                 }
7881         }
7882
7883         public class Operator : MethodOrOperator, IAnonymousHost {
7884
7885                 const int AllowedModifiers =
7886                         Modifiers.PUBLIC |
7887                         Modifiers.UNSAFE |
7888                         Modifiers.EXTERN |
7889                         Modifiers.STATIC;
7890
7891                 public enum OpType : byte {
7892
7893                         // Unary operators
7894                         LogicalNot,
7895                         OnesComplement,
7896                         Increment,
7897                         Decrement,
7898                         True,
7899                         False,
7900
7901                         // Unary and Binary operators
7902                         Addition,
7903                         Subtraction,
7904
7905                         UnaryPlus,
7906                         UnaryNegation,
7907                         
7908                         // Binary operators
7909                         Multiply,
7910                         Division,
7911                         Modulus,
7912                         BitwiseAnd,
7913                         BitwiseOr,
7914                         ExclusiveOr,
7915                         LeftShift,
7916                         RightShift,
7917                         Equality,
7918                         Inequality,
7919                         GreaterThan,
7920                         LessThan,
7921                         GreaterThanOrEqual,
7922                         LessThanOrEqual,
7923
7924                         // Implicit and Explicit
7925                         Implicit,
7926                         Explicit,
7927
7928                         // Just because of enum
7929                         TOP
7930                 };
7931
7932                 public readonly OpType OperatorType;
7933                 
7934                 public Operator (DeclSpace parent, OpType type, Expression ret_type,
7935                                  int mod_flags, Parameters parameters,
7936                                  ToplevelBlock block, Attributes attrs, Location loc)
7937                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7938                                 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7939                 {
7940                         OperatorType = type;
7941                         Block = block;
7942                 }
7943
7944                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7945                 {
7946                         if (a.Type == TypeManager.conditional_attribute_type) {
7947                                 Error_ConditionalAttributeIsNotValid ();
7948                                 return;
7949                         }
7950
7951                         base.ApplyAttributeBuilder (a, cb);
7952                 }
7953                 
7954                 public override bool Define ()
7955                 {
7956                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7957                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7958                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7959                                 return false;
7960                         }
7961
7962                         if (!base.Define ())
7963                                 return false;
7964
7965                         // imlicit and explicit operator of same types are not allowed
7966                         if (OperatorType == OpType.Explicit)
7967                                 Parent.MemberCache.CheckExistingMembersOverloads (this, "op_Implicit", Parameters);
7968                         else if (OperatorType == OpType.Implicit)
7969                                 Parent.MemberCache.CheckExistingMembersOverloads (this, "op_Explicit", Parameters);
7970
7971                         if (MemberType == TypeManager.void_type) {
7972                                 Report.Error (590, Location, "User-defined operators cannot return void");
7973                                 return false;
7974                         }
7975
7976                         Type declaring_type = MethodData.DeclaringType;
7977                         Type return_type = MemberType;
7978                         Type first_arg_type = ParameterTypes [0];
7979
7980                         // Rules for conversion operators
7981                         
7982                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7983                                 if (first_arg_type == return_type && first_arg_type == declaring_type){
7984                                         Report.Error (555, Location,
7985                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7986                                         return false;
7987                                 }
7988                                 
7989                                 Type conv_type;
7990                                 if (TypeManager.IsEqual (declaring_type, return_type)) {
7991                                         conv_type = first_arg_type;
7992                                 } else if (TypeManager.IsEqual (declaring_type, first_arg_type)) {
7993                                         conv_type = return_type;
7994                                 } else if (TypeManager.IsNullableTypeOf (return_type, declaring_type)) {
7995                                         conv_type = first_arg_type;
7996                                 } else if (TypeManager.IsNullableTypeOf (first_arg_type, declaring_type)) {
7997                                         conv_type = return_type;
7998                                 } else {
7999                                         Report.Error (556, Location, 
8000                                                 "User-defined conversion must convert to or from the enclosing type");
8001                                         return false;
8002                                 }
8003
8004                                 //
8005                                 // Because IsInterface and IsClass are not supported
8006                                 //
8007                                 if (!TypeManager.IsGenericParameter (conv_type)) {
8008                                         if (conv_type.IsInterface) {
8009                                                 Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
8010                                                         GetSignatureForError ());
8011                                                 return false;
8012                                         }
8013
8014                                         if (conv_type.IsClass) {
8015                                                 if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
8016                                                         Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
8017                                                                 GetSignatureForError ());
8018                                                         return false;
8019                                                 }
8020
8021                                                 if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
8022                                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
8023                                                                 GetSignatureForError ());
8024                                                         return false;
8025                                                 }
8026                                         }
8027                                 }
8028                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
8029                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
8030                                         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");
8031                                         return false;
8032                                 }
8033                         } else if (Parameters.Count == 1) {
8034                                 // Checks for Unary operators
8035
8036                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
8037                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
8038                                                 Report.Error (448, Location,
8039                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
8040                                                 return false;
8041                                         }
8042                                         if (first_arg_type != declaring_type) {
8043                                                 Report.Error (
8044                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
8045                                                 return false;
8046                                         }
8047                                 }
8048                                 
8049                                 if (first_arg_type != declaring_type){
8050                                         Report.Error (
8051                                                 562, Location,
8052                                                 "The parameter of a unary operator must be the " +
8053                                                 "containing type");
8054                                         return false;
8055                                 }
8056                                 
8057                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
8058                                         if (return_type != TypeManager.bool_type){
8059                                                 Report.Error (
8060                                                         215, Location,
8061                                                         "The return type of operator True or False " +
8062                                                         "must be bool");
8063                                                 return false;
8064                                         }
8065                                 }
8066                                 
8067                         } else {
8068                                 // Checks for Binary operators
8069                                 
8070                                 if (first_arg_type != declaring_type &&
8071                                     ParameterTypes [1] != declaring_type){
8072                                         Report.Error (
8073                                                 563, Location,
8074                                                 "One of the parameters of a binary operator must " +
8075                                                 "be the containing type");
8076                                         return false;
8077                                 }
8078                         }
8079
8080                         return true;
8081                 }
8082
8083                 protected override bool DoDefine ()
8084                 {
8085                         if (!base.DoDefine ())
8086                                 return false;
8087
8088                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
8089                         return true;
8090                 }
8091                 
8092                 public override void Emit ()
8093                 {
8094                         base.Emit ();
8095
8096                         Parameters.ApplyAttributes (MethodBuilder);
8097
8098                         //
8099                         // abstract or extern methods have no bodies
8100                         //
8101                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
8102                                 return;
8103                         
8104                         EmitContext ec;
8105                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
8106                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
8107                         else
8108                                 ec = CreateEmitContext (Parent, null);
8109                         
8110                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
8111                         ec.EmitTopBlock (this, Block);
8112
8113                         if (source != null)
8114                                 source.CloseMethod ();
8115
8116                         Block = null;
8117                 }
8118
8119                 // Operator cannot be override
8120                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
8121                 {
8122                         return null;
8123                 }
8124
8125                 public static string GetName (OpType ot)
8126                 {
8127                         switch (ot){
8128                         case OpType.LogicalNot:
8129                                 return "!";
8130                         case OpType.OnesComplement:
8131                                 return "~";
8132                         case OpType.Increment:
8133                                 return "++";
8134                         case OpType.Decrement:
8135                                 return "--";
8136                         case OpType.True:
8137                                 return "true";
8138                         case OpType.False:
8139                                 return "false";
8140                         case OpType.Addition:
8141                                 return "+";
8142                         case OpType.Subtraction:
8143                                 return "-";
8144                         case OpType.UnaryPlus:
8145                                 return "+";
8146                         case OpType.UnaryNegation:
8147                                 return "-";
8148                         case OpType.Multiply:
8149                                 return "*";
8150                         case OpType.Division:
8151                                 return "/";
8152                         case OpType.Modulus:
8153                                 return "%";
8154                         case OpType.BitwiseAnd:
8155                                 return "&";
8156                         case OpType.BitwiseOr:
8157                                 return "|";
8158                         case OpType.ExclusiveOr:
8159                                 return "^";
8160                         case OpType.LeftShift:
8161                                 return "<<";
8162                         case OpType.RightShift:
8163                                 return ">>";
8164                         case OpType.Equality:
8165                                 return "==";
8166                         case OpType.Inequality:
8167                                 return "!=";
8168                         case OpType.GreaterThan:
8169                                 return ">";
8170                         case OpType.LessThan:
8171                                 return "<";
8172                         case OpType.GreaterThanOrEqual:
8173                                 return ">=";
8174                         case OpType.LessThanOrEqual:
8175                                 return "<=";
8176                         case OpType.Implicit:
8177                                 return "implicit";
8178                         case OpType.Explicit:
8179                                 return "explicit";
8180                         default: return "";
8181                         }
8182                 }
8183
8184                 public static OpType GetOperatorType (string name)
8185                 {
8186                         if (name.StartsWith ("op_")){
8187                                 for (int i = 0; i < Unary.oper_names.Length; ++i) {
8188                                         if (Unary.oper_names [i] == name)
8189                                                 return (OpType)i;
8190                                 }
8191
8192                                 for (int i = 0; i < Binary.oper_names.Length; ++i) {
8193                                         if (Binary.oper_names [i] == name)
8194                                                 return (OpType)i;
8195                                 }
8196                         }
8197                         return OpType.TOP;
8198                 }
8199
8200                 public override string GetSignatureForError ()
8201                 {
8202                         StringBuilder sb = new StringBuilder ();
8203                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
8204                                 sb.AppendFormat ("{0}.{1} operator {2}", Parent.GetSignatureForError (), GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type));
8205                         }
8206                         else {
8207                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
8208                         }
8209
8210                         sb.Append (Parameters.GetSignatureForError ());
8211                         return sb.ToString ();
8212                 }
8213         }
8214
8215         //
8216         // This is used to compare method signatures
8217         //
8218         struct MethodSignature {
8219                 public string Name;
8220                 public Type RetType;
8221                 public Type [] Parameters;
8222                 
8223                 /// <summary>
8224                 ///    This delegate is used to extract methods which have the
8225                 ///    same signature as the argument
8226                 /// </summary>
8227                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8228                 
8229                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8230                 {
8231                         Name = name;
8232                         RetType = ret_type;
8233
8234                         if (parameters == null)
8235                                 Parameters = Type.EmptyTypes;
8236                         else
8237                                 Parameters = parameters;
8238                 }
8239
8240                 public override string ToString ()
8241                 {
8242                         string pars = "";
8243                         if (Parameters.Length != 0){
8244                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8245                                 for (int i = 0; i < Parameters.Length; i++){
8246                                         sb.Append (Parameters [i]);
8247                                         if (i+1 < Parameters.Length)
8248                                                 sb.Append (", ");
8249                                 }
8250                                 pars = sb.ToString ();
8251                         }
8252
8253                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8254                 }
8255                 
8256                 public override int GetHashCode ()
8257                 {
8258                         return Name.GetHashCode ();
8259                 }
8260
8261                 public override bool Equals (Object o)
8262                 {
8263                         MethodSignature other = (MethodSignature) o;
8264
8265                         if (other.Name != Name)
8266                                 return false;
8267
8268                         if (other.RetType != RetType)
8269                                 return false;
8270                         
8271                         if (Parameters == null){
8272                                 if (other.Parameters == null)
8273                                         return true;
8274                                 return false;
8275                         }
8276
8277                         if (other.Parameters == null)
8278                                 return false;
8279                         
8280                         int c = Parameters.Length;
8281                         if (other.Parameters.Length != c)
8282                                 return false;
8283
8284                         for (int i = 0; i < c; i++)
8285                                 if (other.Parameters [i] != Parameters [i])
8286                                         return false;
8287
8288                         return true;
8289                 }
8290
8291                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8292                 {
8293                         MethodSignature sig = (MethodSignature) filter_criteria;
8294
8295                         if (m.Name != sig.Name)
8296                                 return false;
8297
8298                         Type ReturnType;
8299                         MethodInfo mi = m as MethodInfo;
8300                         PropertyInfo pi = m as PropertyInfo;
8301
8302                         if (mi != null)
8303                                 ReturnType = mi.ReturnType;
8304                         else if (pi != null)
8305                                 ReturnType = pi.PropertyType;
8306                         else
8307                                 return false;
8308                         
8309                         //
8310                         // we use sig.RetType == null to mean `do not check the
8311                         // method return value.  
8312                         //
8313                         if (sig.RetType != null)
8314                                 if (ReturnType != sig.RetType)
8315                                         return false;
8316
8317                         Type [] args;
8318                         if (mi != null)
8319                                 args = TypeManager.GetParameterData (mi).Types;
8320                         else
8321                                 args = TypeManager.GetArgumentTypes (pi);
8322                         Type [] sigp = sig.Parameters;
8323
8324                         if (args.Length != sigp.Length)
8325                                 return false;
8326
8327                         for (int i = args.Length; i > 0; ){
8328                                 i--;
8329                                 if (args [i] != sigp [i])
8330                                         return false;
8331                         }
8332                         return true;
8333                 }
8334         }
8335 }
8336