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