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