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