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