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