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