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