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