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