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