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