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