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