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