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