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