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