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