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