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