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