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