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