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