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