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