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