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