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