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