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