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