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