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