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