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