2008-06-16 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 //
10 // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2004-2008 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 using System;
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Reflection;
37 using System.Reflection.Emit;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Security;
41 using System.Security.Permissions;
42 using System.Text;
43
44 #if BOOTSTRAP_WITH_OLDLIB || NET_2_1
45 using XmlElement = System.Object;
46 #else
47 using System.Xml;
48 #endif
49
50 using Mono.CompilerServices.SymbolWriter;
51
52 namespace Mono.CSharp {
53
54         public enum Kind {
55                 Root,
56                 Struct,
57                 Class,
58                 Interface,
59                 Enum,
60                 Delegate
61         }
62
63         /// <summary>
64         ///   This is the base class for structs and classes.  
65         /// </summary>
66         public abstract class TypeContainer : DeclSpace, IMemberContainer {
67
68                 public class MemberCoreArrayList: ArrayList
69                 {
70                         /// <summary>
71                         ///   Defines the MemberCore objects that are in this array
72                         /// </summary>
73                         public virtual void DefineContainerMembers ()
74                         {
75                                 foreach (MemberCore mc in this) {
76                                         try {
77                                                 mc.Define ();
78                                         } catch (Exception e) {
79                                                 throw new InternalErrorException (mc, e);
80                                         }
81                                 }
82                         }
83
84                         public virtual void Emit ()
85                         {
86                                 foreach (MemberCore mc in this)
87                                         mc.Emit ();
88                         }
89                 }
90
91                 public class OperatorArrayList: MemberCoreArrayList
92                 {
93                         TypeContainer container;
94
95                         public OperatorArrayList (TypeContainer container)
96                         {
97                                 this.container = container;
98                         }
99
100                         //
101                         // Checks that some operators come in pairs:
102                         //  == and !=
103                         // > and <
104                         // >= and <=
105                         // true and false
106                         //
107                         // They are matched based on the return type and the argument types
108                         //
109                         void CheckPairedOperators ()
110                         {
111                                 bool has_equality_or_inequality = false;
112                                 Operator[] operators = (Operator[]) ToArray (typeof (Operator));
113                                 bool [] has_pair = new bool [operators.Length];
114
115                                 for (int i = 0; i < Count; ++i) {
116                                         if (operators [i] == null)
117                                                 continue;
118
119                                         Operator o_a = operators [i];
120                                         Operator.OpType o_type = o_a.OperatorType;
121                                         if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
122                                                 has_equality_or_inequality = true;
123
124                                         Operator.OpType matching_type = o_a.GetMatchingOperator ();
125                                         if (matching_type == Operator.OpType.TOP) {
126                                                 operators [i] = null;
127                                                 continue;
128                                         }
129         
130                                         for (int ii = 0; ii < Count; ++ii) {
131                                                 Operator o_b = operators [ii];
132                                                 if (o_b == null || o_b.OperatorType != matching_type)
133                                                         continue;
134
135                                                 if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
136                                                         continue;
137
138                                                 if (!TypeManager.IsEqual (o_a.ParameterTypes, o_b.ParameterTypes))
139                                                         continue;
140
141                                                 operators [i] = null;
142
143                                                 //
144                                                 // Used to ignore duplicate user conversions
145                                                 //
146                                                 has_pair [ii] = true;
147                                         }
148                                 }
149
150                                 for (int i = 0; i < Count; ++i) {
151                                         if (operators [i] == null || has_pair [i])
152                                                 continue;
153
154                                         Operator o = operators [i];
155                                         Report.Error (216, o.Location,
156                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
157                                                 o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ()));
158                                 }
159
160                                 if (has_equality_or_inequality && Report.WarningLevel > 2) {
161                                         if (container.Methods == null || !container.HasEquals)
162                                                 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
163  
164                                         if (container.Methods == null || !container.HasGetHashCode)
165                                                 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
166                                 }
167                         }
168
169                         public override void DefineContainerMembers ()
170                         {
171                                 base.DefineContainerMembers ();
172                                 CheckPairedOperators ();
173                         }
174                 }
175
176                 [Flags]
177                 enum CachedMethods
178                 {
179                         Equals                          = 1,
180                         GetHashCode                     = 1 << 1,
181                         HasStaticFieldInitializer       = 1 << 2
182                 }
183
184
185                 // Whether this is a struct, class or interface
186                 public readonly Kind Kind;
187
188                 // Holds a list of classes and structures
189                 protected ArrayList types;
190
191                 MemberCoreArrayList ordered_explicit_member_list;
192                 MemberCoreArrayList ordered_member_list;
193
194                 // Holds the list of properties
195                 MemberCoreArrayList properties;
196
197                 // Holds the list of delegates
198                 MemberCoreArrayList delegates;
199                 
200                 // Holds the list of constructors
201                 protected MemberCoreArrayList instance_constructors;
202
203                 // Holds the list of fields
204                 MemberCoreArrayList fields;
205
206                 // Holds a list of fields that have initializers
207                 protected ArrayList initialized_fields;
208
209                 // Holds a list of static fields that have initializers
210                 protected ArrayList initialized_static_fields;
211
212                 // Holds the list of constants
213                 protected MemberCoreArrayList constants;
214
215                 // Holds the methods.
216                 MemberCoreArrayList methods;
217
218                 // Holds the events
219                 protected MemberCoreArrayList events;
220
221                 // Holds the indexers
222                 ArrayList indexers;
223
224                 // Holds the operators
225                 MemberCoreArrayList operators;
226
227                 // Holds the compiler generated classes
228                 ArrayList compiler_generated;
229
230                 //
231                 // Pointers to the default constructor and the default static constructor
232                 //
233                 protected Constructor default_constructor;
234                 protected Constructor default_static_constructor;
235
236                 //
237                 // Points to the first non-static field added to the container.
238                 //
239                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
240                 // and the first one's as good as any.
241                 //
242                 FieldBase first_nonstatic_field = null;
243
244                 //
245                 // This one is computed after we can distinguish interfaces
246                 // from classes from the arraylist `type_bases' 
247                 //
248                 TypeExpr base_type;
249                 TypeExpr[] iface_exprs;
250                 Type GenericType;
251
252                 protected ArrayList type_bases;
253
254                 bool members_resolved;
255                 bool members_resolved_ok;
256                 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 (Location, 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 (Location loc, 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, loc, "`{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 (!IsInterface)
4045                                         if ((ModFlags & Modifiers.STATIC) == 0)
4046                                                 cc |= CallingConventions.HasThis;
4047
4048                                 // FIXME: How is `ExplicitThis' used in C#?
4049                         
4050                                 return cc;
4051                         }
4052                 }
4053
4054                 public Type ReturnType {
4055                         get {
4056                                 return MemberType;
4057                         }
4058                 }
4059
4060                 public MemberName MethodName {
4061                         get {
4062                                 return MemberName;
4063                         }
4064                 }
4065
4066                 public Iterator Iterator {
4067                         get { return iterator; }
4068                 }
4069
4070                 protected override bool CheckBase ()
4071                 {
4072                         if (!base.CheckBase ())
4073                                 return false;
4074
4075                         // TODO: Destructor should derive from MethodCore
4076                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
4077                                 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
4078                                 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
4079                                 return false;
4080                         }
4081
4082                         return true;
4083                 }
4084
4085                 /// <summary>
4086                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4087                 /// </summary>
4088                 public bool IsExcluded () {
4089                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
4090                                 return (caching_flags & Flags.Excluded) != 0;
4091
4092                         caching_flags &= ~Flags.Excluded_Undetected;
4093
4094                         if (base_method == null) {
4095                                 if (OptAttributes == null)
4096                                         return false;
4097
4098                                 if (TypeManager.conditional_attribute_type == null)
4099                                         return false;
4100
4101                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
4102
4103                                 if (attrs == null)
4104                                         return false;
4105
4106                                 foreach (Attribute a in attrs) {
4107                                         string condition = a.GetConditionalAttributeValue ();
4108                                         if (condition == null)
4109                                                 return false;
4110
4111                                         if (RootContext.AllDefines.Contains (condition))
4112                                                 return false;
4113                                 }
4114
4115                                 caching_flags |= Flags.Excluded;
4116                                 return true;
4117                         }
4118
4119                         IMethodData md = TypeManager.GetMethod (TypeManager.DropGenericMethodArguments (base_method));
4120                         if (md == null) {
4121                                 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4122                                         caching_flags |= Flags.Excluded;
4123                                         return true;
4124                                 }
4125                                 return false;
4126                         }
4127
4128                         if (md.IsExcluded ()) {
4129                                 caching_flags |= Flags.Excluded;
4130                                 return true;
4131                         }
4132                         return false;
4133                 }
4134
4135                 GenericMethod IMethodData.GenericMethod {
4136                         get {
4137                                 return GenericMethod;
4138                         }
4139                 }
4140
4141                 public virtual void EmitExtraSymbolInfo (SourceMethod source)
4142                 { }
4143
4144                 #endregion
4145
4146         }
4147
4148         public class SourceMethod : IMethodDef
4149         {
4150                 DeclSpace parent;
4151                 MethodBase method;
4152                 SourceMethodBuilder builder;
4153
4154                 protected SourceMethod (DeclSpace parent, MethodBase method, ICompileUnit file)
4155                 {
4156                         this.parent = parent;
4157                         this.method = method;
4158                         
4159                         builder = SymbolWriter.OpenMethod (file, parent.NamespaceEntry.SymbolFileID, this);
4160                 }
4161
4162                 public string Name {
4163                         get { return method.Name; }
4164                 }
4165
4166                 public int Token {
4167                         get {
4168                                 if (method is MethodBuilder)
4169                                         return ((MethodBuilder) method).GetToken ().Token;
4170                                 else if (method is ConstructorBuilder)
4171                                         return ((ConstructorBuilder) method).GetToken ().Token;
4172                                 else
4173                                         throw new NotSupportedException ();
4174                         }
4175                 }
4176
4177                 public void CloseMethod ()
4178                 {
4179                         SymbolWriter.CloseMethod ();
4180                 }
4181
4182                 public void SetCompilerGenerated ()
4183                 {
4184                         if (builder != null)
4185                                 builder.SetCompilerGenerated ();
4186                 }
4187
4188                 public void SetRealMethodName (string name)
4189                 {
4190                         if (builder != null)
4191                                 builder.SetRealMethodName (name);
4192                 }
4193
4194                 public static SourceMethod Create (DeclSpace parent, MethodBase method, Block block)
4195                 {
4196                         if (!SymbolWriter.HasSymbolWriter)
4197                                 return null;
4198                         if (block == null)
4199                                 return null;
4200
4201                         Location start_loc = block.StartLocation;
4202                         if (start_loc.IsNull)
4203                                 return null;
4204
4205                         ICompileUnit compile_unit = start_loc.CompilationUnit;
4206                         if (compile_unit == null)
4207                                 return null;
4208
4209                         return new SourceMethod (parent, method, compile_unit);
4210                 }
4211         }
4212
4213         public class Method : MethodOrOperator, IAnonymousHost {
4214
4215                 /// <summary>
4216                 ///   Modifiers allowed in a class declaration
4217                 /// </summary>
4218                 const int AllowedModifiers =
4219                         Modifiers.NEW |
4220                         Modifiers.PUBLIC |
4221                         Modifiers.PROTECTED |
4222                         Modifiers.INTERNAL |
4223                         Modifiers.PRIVATE |
4224                         Modifiers.STATIC |
4225                         Modifiers.VIRTUAL |
4226                         Modifiers.SEALED |
4227                         Modifiers.OVERRIDE |
4228                         Modifiers.ABSTRACT |
4229                         Modifiers.UNSAFE |
4230                         Modifiers.METHOD_YIELDS | 
4231                         Modifiers.EXTERN;
4232
4233                 const int AllowedInterfaceModifiers =
4234                         Modifiers.NEW | Modifiers.UNSAFE;
4235
4236                 //
4237                 // return_type can be "null" for VOID values.
4238                 //
4239                 public Method (DeclSpace parent, GenericMethod generic,
4240                                FullNamedExpression return_type, int mod, bool is_iface,
4241                                MemberName name, Parameters parameters, Attributes attrs)
4242                         : base (parent, generic, return_type, mod,
4243                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4244                                 is_iface, name, attrs, parameters)
4245                 {
4246                 }
4247                 
4248                 public override string GetSignatureForError()
4249                 {
4250                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4251                 }
4252
4253                 void Error_DuplicateEntryPoint (MethodInfo b, Location location)
4254                 {
4255                         Report.Error (17, location,
4256                                 "Program `{0}' has more than one entry point defined: `{1}'",
4257                                 CodeGen.FileName, TypeManager.CSharpSignature(b));
4258                 }
4259
4260                 bool IsEntryPoint ()
4261                 {
4262                         if (ReturnType != TypeManager.void_type &&
4263                                 ReturnType != TypeManager.int32_type)
4264                                 return false;
4265
4266                         if (Parameters.Count == 0)
4267                                 return true;
4268
4269                         if (Parameters.Count > 1)
4270                                 return false;
4271
4272                         Type t = Parameters.ParameterType (0);
4273                         return t.IsArray && t.GetArrayRank () == 1 &&
4274                                         TypeManager.GetElementType (t) == TypeManager.string_type &&
4275                                         (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
4276                 }
4277
4278                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4279                 {
4280                         if (a.Type == TypeManager.conditional_attribute_type) {
4281                                 if (IsExplicitImpl) {
4282                                         Error_ConditionalAttributeIsNotValid ();
4283                                         return;
4284                                 }
4285
4286                                 if (ReturnType != TypeManager.void_type) {
4287                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4288                                         return;
4289                                 }
4290
4291                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4292                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4293                                         return;
4294                                 }
4295
4296                                 if (IsInterface) {
4297                                         Report.Error (582, Location, "Conditional not valid on interface members");
4298                                         return;
4299                                 }
4300
4301                                 if (MethodData.implementing != null) {
4302                                         Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
4303                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4304                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4305                                         return;
4306                                 }
4307
4308                                 for (int i = 0; i < Parameters.Count; ++i) {
4309                                         if ((Parameters.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4310                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4311                                                 return;
4312                                         }
4313                                 }
4314                         }
4315
4316                         if (a.Type == TypeManager.extension_attribute_type) {
4317                                 a.Error_MisusedExtensionAttribute ();
4318                                 return;
4319                         }
4320
4321                         base.ApplyAttributeBuilder (a, cb);
4322                 }
4323
4324                 public bool CheckForDuplications ()
4325                 {
4326                         ArrayList ar = Parent.PartialContainer.Properties;
4327                         if (ar != null) {
4328                                 for (int i = 0; i < ar.Count; ++i) {
4329                                         PropertyBase pb = (PropertyBase) ar [i];
4330                                         if (pb.AreAccessorsDuplicateImplementation (this))
4331                                                 return false;
4332                                 }
4333                         }
4334
4335                         ar = Parent.PartialContainer.Indexers;
4336                         if (ar != null) {
4337                                 for (int i = 0; i < ar.Count; ++i) {
4338                                         PropertyBase pb = (PropertyBase) ar [i];
4339                                         if (pb.AreAccessorsDuplicateImplementation (this))
4340                                                 return false;
4341                                 }
4342                         }
4343
4344                         return true;
4345                 }
4346
4347                 //
4348                 // Creates the type
4349                 //
4350                 public override bool Define ()
4351                 {
4352                         if (!base.Define ())
4353                                 return false;
4354
4355                         if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4356                                 Error1599 (Location, ReturnType);
4357                                 return false;
4358                         }
4359
4360                         if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 && 
4361                                 Name == "Finalize" && !(this is Destructor)) {
4362                                 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4363                         }
4364
4365                         if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
4366                                 if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
4367                                         Parent.PartialContainer.Mark_HasEquals ();
4368                                 else if (Parameters.Empty && Name == "GetHashCode")
4369                                         Parent.PartialContainer.Mark_HasGetHashCode ();
4370                         }
4371
4372                         if ((ModFlags & Modifiers.STATIC) == 0)
4373                                 return true;
4374
4375                         if (Parameters.HasExtensionMethodType) {
4376                                 if (Parent.IsStaticClass && !Parent.IsGeneric) {
4377                                         if (!Parent.IsTopLevel)
4378                                                 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
4379                                                         GetSignatureForError ());
4380
4381                                         if (TypeManager.extension_attribute_type == null) {
4382                                                 Report.Error (1110, Location,
4383                                                         "`{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",
4384                                                         GetSignatureForError ());
4385                                         } else if (TypeManager.extension_attribute_attr == null) {
4386                                                 ConstructorInfo ci = TypeManager.GetPredefinedConstructor (
4387                                                         TypeManager.extension_attribute_type, Location, System.Type.EmptyTypes);
4388
4389                                                 if (ci != null)
4390                                                         TypeManager.extension_attribute_attr = new CustomAttributeBuilder (ci, new object [0]);
4391                                         }
4392
4393                                         ModFlags |= Modifiers.METHOD_EXTENSION;
4394                                         Parent.ModFlags |= Modifiers.METHOD_EXTENSION;
4395                                         CodeGen.Assembly.HasExtensionMethods = true;
4396                                 } else {
4397                                         Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
4398                                                 GetSignatureForError ());
4399                                 }
4400                         }
4401
4402                         //
4403                         // This is used to track the Entry Point,
4404                         //
4405                         if (RootContext.NeedsEntryPoint &&
4406                                 Name == "Main" &&
4407                                 (RootContext.MainClass == null ||
4408                                 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4409                                 if (IsEntryPoint ()) {
4410
4411                                         if (RootContext.EntryPoint == null) {
4412                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
4413                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
4414                                                                 GetSignatureForError ());
4415                                                 } else {
4416                                                         IMethodData md = TypeManager.GetMethod (MethodBuilder);
4417                                                         md.SetMemberIsUsed ();
4418
4419                                                         RootContext.EntryPoint = MethodBuilder;
4420                                                         RootContext.EntryPointLocation = Location;
4421                                                 }
4422                                         } else {
4423                                                 Error_DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4424                                                 Error_DuplicateEntryPoint (MethodBuilder, Location);
4425                                         }
4426                                 } else {
4427                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
4428                                                 GetSignatureForError ());
4429                                 }
4430                         }
4431
4432                         return true;
4433                 }
4434
4435                 //
4436                 // Emits the code
4437                 // 
4438                 public override void Emit ()
4439                 {
4440                         try {
4441                                 Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4442                                 if (IsPartialDefinition) {
4443                                         //
4444                                         // Do attribute checks only when partial implementation does not exist
4445                                         //
4446                                         if (MethodBuilder == null)
4447                                                 base.Emit ();
4448
4449                                         return;
4450                                 }
4451
4452                                 if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0)
4453                                         Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
4454                                                 GetSignatureForError ());
4455
4456                                 MethodData.Emit (Parent);
4457                                 base.Emit ();
4458                                 
4459 #if GMCS_SOURCE                         
4460                                 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
4461                                         MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
4462 #endif
4463
4464                                 Block = null;
4465                                 MethodData = null;
4466                         } catch {
4467                                 Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
4468                                                    Location, MethodBuilder);
4469                                 throw;
4470                         }
4471                 }
4472
4473                 public override bool EnableOverloadChecks (MemberCore overload)
4474                 {
4475                         // TODO: It can be deleted when members will be defined in correct order
4476                         if (overload is Operator)
4477                                 return overload.EnableOverloadChecks (this);
4478
4479                         if (overload is Indexer)
4480                                 return false;
4481
4482                         return base.EnableOverloadChecks (overload);
4483                 }
4484
4485                 public static void Error1599 (Location loc, Type t)
4486                 {
4487                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4488                 }
4489
4490                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4491                 {
4492                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4493                                 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4494
4495                         if (mi == null)
4496                                 return null;
4497
4498                         if (mi.IsSpecialName)
4499                                 return null;
4500
4501                         base_ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
4502                         return mi;
4503                 }
4504
4505                 public void SetPartialDefinition (Method methodDefinition)
4506                 {
4507                         caching_flags |= Flags.PartialDefinitionExists;
4508                         methodDefinition.MethodBuilder = MethodBuilder;
4509                         if (methodDefinition.attributes == null)
4510                                 return;
4511
4512                         if (attributes == null) {
4513                                 attributes = methodDefinition.attributes;
4514                         } else {
4515                                 attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
4516                         }
4517                 }
4518
4519                 protected override bool VerifyClsCompliance ()
4520                 {
4521                         if (!base.VerifyClsCompliance ())
4522                                 return false;
4523
4524                         if (ParameterInfo.Count > 0) {
4525                                 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4526                                 if (al.Count > 1)
4527                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4528                         }
4529
4530                         return true;
4531                 }
4532         }
4533
4534         public abstract class ConstructorInitializer : ExpressionStatement
4535         {
4536                 ArrayList argument_list;
4537                 MethodGroupExpr base_constructor_group;
4538                 
4539                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4540                 {
4541                         this.argument_list = argument_list;
4542                         this.loc = loc;
4543                 }
4544
4545                 public ArrayList Arguments {
4546                         get {
4547                                 return argument_list;
4548                         }
4549                 }
4550
4551                 public override Expression CreateExpressionTree (EmitContext ec)
4552                 {
4553                         throw new NotSupportedException ("ET");
4554                 }
4555
4556                 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
4557                 {
4558                         if (argument_list != null){
4559                                 foreach (Argument a in argument_list){
4560                                         if (!a.Resolve (ec, loc))
4561                                                 return false;
4562                                 }
4563                         }
4564
4565                         if (this is ConstructorBaseInitializer) {
4566                                 if (ec.ContainerType.BaseType == null)
4567                                         return true;
4568
4569                                 type = ec.ContainerType.BaseType;
4570                                 if (ec.ContainerType.IsValueType) {
4571                                         Report.Error (522, loc,
4572                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4573                                         return false;
4574                                 }
4575                         } else {
4576                                 //
4577                                 // It is legal to have "this" initializers that take no arguments
4578                                 // in structs, they are just no-ops.
4579                                 //
4580                                 // struct D { public D (int a) : this () {}
4581                                 //
4582                                 if (ec.ContainerType.IsValueType && argument_list == null)
4583                                         return true;
4584                                 
4585                                 type = ec.ContainerType;
4586                         }
4587
4588                         base_constructor_group = MemberLookupFinal (
4589                                 ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor,
4590                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4591                                 loc) as MethodGroupExpr;
4592                         
4593                         if (base_constructor_group == null)
4594                                 return false;
4595                         
4596                         base_constructor_group = base_constructor_group.OverloadResolve (
4597                                 ec, ref argument_list, false, loc);
4598                         
4599                         if (base_constructor_group == null)
4600                                 return false;
4601                         
4602                         ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group;
4603                         
4604                         if (base_ctor == caller_builder){
4605                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4606                         }
4607                                                 
4608                         return true;
4609                 }
4610
4611                 public override Expression DoResolve (EmitContext ec)
4612                 {
4613                         throw new NotSupportedException ();
4614                 }
4615
4616                 public override void Emit (EmitContext ec)
4617                 {
4618                         // It can be null for static initializers
4619                         if (base_constructor_group == null)
4620                                 return;
4621                         
4622                         ec.Mark (loc, false);
4623                         if (!ec.IsStatic)
4624                                 base_constructor_group.InstanceExpression = ec.GetThis (loc);
4625                         
4626                         base_constructor_group.EmitCall (ec, argument_list);
4627                 }
4628
4629                 public override void EmitStatement (EmitContext ec)
4630                 {
4631                         Emit (ec);
4632                 }
4633         }
4634
4635         public class ConstructorBaseInitializer : ConstructorInitializer {
4636                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4637                         base (argument_list, l)
4638                 {
4639                 }
4640         }
4641
4642         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4643                 public GeneratedBaseInitializer (Location loc):
4644                         base (null, loc)
4645                 {
4646                 }
4647         }
4648
4649         public class ConstructorThisInitializer : ConstructorInitializer {
4650                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4651                         base (argument_list, l)
4652                 {
4653                 }
4654         }
4655         
4656         public class Constructor : MethodCore, IMethodData, IAnonymousHost {
4657                 public ConstructorBuilder ConstructorBuilder;
4658                 public ConstructorInitializer Initializer;
4659                 ListDictionary declarative_security;
4660                 ArrayList anonymous_methods;
4661                 bool has_compliant_args;
4662
4663                 // <summary>
4664                 //   Modifiers allowed for a constructor.
4665                 // </summary>
4666                 public const int AllowedModifiers =
4667                         Modifiers.PUBLIC |
4668                         Modifiers.PROTECTED |
4669                         Modifiers.INTERNAL |
4670                         Modifiers.STATIC |
4671                         Modifiers.UNSAFE |
4672                         Modifiers.EXTERN |              
4673                         Modifiers.PRIVATE;
4674
4675                 static readonly string[] attribute_targets = new string [] { "method" };
4676
4677                 //
4678                 // The spec claims that static is not permitted, but
4679                 // my very own code has static constructors.
4680                 //
4681                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4682                                     ConstructorInitializer init, Location loc)
4683                         : base (parent, null, null, mod, AllowedModifiers, false,
4684                                 new MemberName (name, loc), null, args)
4685                 {
4686                         Initializer = init;
4687                 }
4688
4689                 public bool HasCompliantArgs {
4690                         get { return has_compliant_args; }
4691                 }
4692
4693                 public override AttributeTargets AttributeTargets {
4694                         get { return AttributeTargets.Constructor; }
4695                 }
4696
4697                 public Iterator Iterator {
4698                         get { return null; }
4699                 }
4700
4701                 //
4702                 // Returns true if this is a default constructor
4703                 //
4704                 public bool IsDefault ()
4705                 {
4706                         if ((ModFlags & Modifiers.STATIC) != 0)
4707                                 return Parameters.Empty;
4708                         
4709                         return Parameters.Empty &&
4710                                         (Initializer is ConstructorBaseInitializer) &&
4711                                         (Initializer.Arguments == null);
4712                 }
4713
4714                 public bool IsCompilerGenerated {
4715                         get { return Initializer is GeneratedBaseInitializer; }
4716                 }
4717
4718                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4719                 {
4720                         if (a.IsValidSecurityAttribute ()) {
4721                                 if (declarative_security == null) {
4722                                         declarative_security = new ListDictionary ();
4723                                 }
4724                                 a.ExtractSecurityPermissionSet (declarative_security);
4725                                 return;
4726                         }
4727
4728                         if (a.IsInternalMethodImplAttribute) {
4729                                 is_external_implementation = true;
4730                         }
4731
4732                         ConstructorBuilder.SetCustomAttribute (cb);
4733                 }
4734
4735                 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
4736                 {
4737                         if (anonymous_methods == null)
4738                                 anonymous_methods = new ArrayList ();
4739                         anonymous_methods.Add (anonymous);
4740                 }
4741
4742                 public bool ResolveMembers ()
4743                 {
4744                         if (anonymous_methods != null) {
4745                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
4746                                         if (!ame.CreateAnonymousHelpers ())
4747                                                 return false;
4748                                 }
4749                         }
4750
4751                         return true;
4752                 }
4753
4754                 protected override bool CheckBase ()
4755                 {
4756                         if ((ModFlags & Modifiers.STATIC) != 0) {
4757                                 if (!Parameters.Empty) {
4758                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4759                                                 GetSignatureForError ());
4760                                         return false;
4761                                 }
4762
4763                                 // the rest can be ignored
4764                                 return true;
4765                         }
4766
4767                         // Check whether arguments were correct.
4768                         if (!DefineParameters (Parameters))
4769                                 return false;
4770
4771                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
4772                                 Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorBuilder.ConstructorName,
4773                                         Parameters);
4774
4775                         if (Parent.PartialContainer.Kind == Kind.Struct) {
4776                                 if (ParameterTypes.Length == 0) {
4777                                         Report.Error (568, Location, 
4778                                                 "Structs cannot contain explicit parameterless constructors");
4779                                         return false;
4780                                 }
4781                         }
4782
4783                         CheckProtectedModifier ();
4784                         
4785                         return true;
4786                 }
4787                 
4788                 //
4789                 // Creates the ConstructorBuilder
4790                 //
4791                 public override bool Define ()
4792                 {
4793                         if (ConstructorBuilder != null)
4794                                 return true;
4795
4796                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4797                                                MethodAttributes.SpecialName);
4798                         
4799                         if ((ModFlags & Modifiers.STATIC) != 0) {
4800                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4801                         } else {
4802                                 ca |= MethodAttributes.HideBySig;
4803
4804                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4805                                         ca |= MethodAttributes.Public;
4806                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4807                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4808                                                 ca |= MethodAttributes.FamORAssem;
4809                                         else 
4810                                                 ca |= MethodAttributes.Family;
4811                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4812                                         ca |= MethodAttributes.Assembly;
4813                                 else
4814                                         ca |= MethodAttributes.Private;
4815                         }
4816
4817                         if (!CheckAbstractAndExtern (block != null))
4818                                 return false;
4819                         
4820                         // Check if arguments were correct.
4821                         if (!CheckBase ())
4822                                 return false;
4823
4824                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4825                                 ca, CallingConventions,
4826                                 ParameterTypes);
4827
4828                         if ((ModFlags & Modifiers.UNSAFE) != 0)
4829                                 ConstructorBuilder.InitLocals = false;
4830
4831                         if (Parent.PartialContainer.IsComImport) {
4832                                 if (!IsDefault ()) {
4833                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4834                                                 Parent.GetSignatureForError ());
4835                                         return false;
4836                                 }
4837                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4838                         }
4839                         
4840                         Parent.MemberCache.AddMember (ConstructorBuilder, this);
4841                         TypeManager.AddMethod (ConstructorBuilder, this);
4842                         
4843                         // It's here only to report an error
4844                         if ((ModFlags & Modifiers.METHOD_YIELDS) != 0) {
4845                                 member_type = TypeManager.void_type;
4846                                 Iterator.CreateIterator (this, Parent, null, ModFlags);
4847                         }
4848
4849                         return true;
4850                 }
4851
4852                 //
4853                 // Emits the code
4854                 //
4855                 public override void Emit ()
4856                 {
4857                         if (OptAttributes != null)
4858                                 OptAttributes.Emit ();
4859
4860                         base.Emit ();
4861
4862                         EmitContext ec = CreateEmitContext (null, null);
4863
4864                         //
4865                         // If we use a "this (...)" constructor initializer, then
4866                         // do not emit field initializers, they are initialized in the other constructor
4867                         //
4868                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
4869                                 !(Initializer is ConstructorThisInitializer);
4870
4871                         if (emit_field_initializers)
4872                                 Parent.PartialContainer.ResolveFieldInitializers (ec);
4873
4874                         if (block != null) {
4875                                 // If this is a non-static `struct' constructor and doesn't have any
4876                                 // initializer, it must initialize all of the struct's fields.
4877                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4878                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4879                                         block.AddThisVariable (Parent, Location);
4880
4881                                 if (!block.ResolveMeta (ec, ParameterInfo))
4882                                         block = null;
4883
4884                                 if (block != null && (ModFlags & Modifiers.STATIC) == 0){
4885                                         if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4886                                                 Initializer = new GeneratedBaseInitializer (Location);
4887
4888                                         //
4889                                         // Spec mandates that Initializers will not have `this' access
4890                                         //
4891                                         if (Initializer != null) {
4892                                                 ec.IsStatic = true;
4893                                                 Initializer.Resolve (ConstructorBuilder, ec);
4894                                                 ec.IsStatic = false;
4895                                                 block.AddScopeStatement (new StatementExpression (Initializer));
4896                                         }
4897                                 }
4898                         }
4899
4900                         Parameters.ApplyAttributes (ConstructorBuilder);
4901                         
4902                         SourceMethod source = null;
4903                         if (block == null)
4904                                 ec.OmitDebuggingInfo = true;
4905                         else
4906                                 source = SourceMethod.Create (Parent, ConstructorBuilder, block);
4907
4908                         bool unreachable = false;
4909                         if (block != null) {
4910                                 if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
4911                                         return;
4912
4913                                 ec.EmitMeta (block);
4914
4915                                 if (Report.Errors > 0)
4916                                         return;
4917
4918                                 if (emit_field_initializers)
4919                                         Parent.PartialContainer.EmitFieldInitializers (ec);
4920
4921                                 if (block.ScopeInfo != null) {
4922                                         ExpressionStatement init = block.ScopeInfo.GetScopeInitializer (ec);
4923                                         init.EmitStatement (ec);
4924                                 }
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 MemberName MethodName {
4998                         get {
4999                                 return MemberName;
5000                         }
5001                 }
5002
5003                 public Type ReturnType {
5004                         get {
5005                                 return MemberType;
5006                         }
5007                 }
5008
5009                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
5010                 {
5011                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
5012                         EmitContext ec = new EmitContext (this, Parent, Location, ig_, TypeManager.void_type, ModFlags, true);
5013                         ec.CurrentBlock = block;
5014                         return ec;
5015                 }
5016
5017                 public bool IsExcluded()
5018                 {
5019                         return false;
5020                 }
5021
5022                 GenericMethod IMethodData.GenericMethod {
5023                         get {
5024                                 return null;
5025                         }
5026                 }
5027
5028                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
5029                 { }
5030
5031                 #endregion
5032         }
5033
5034         /// <summary>
5035         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5036         /// </summary>
5037         public interface IMethodData
5038         {
5039                 CallingConventions CallingConventions { get; }
5040                 Location Location { get; }
5041                 MemberName MethodName { get; }
5042                 Type ReturnType { get; }
5043                 GenericMethod GenericMethod { get; }
5044                 Parameters ParameterInfo { get; }
5045
5046                 Iterator Iterator { get; }
5047
5048                 Attributes OptAttributes { get; }
5049                 ToplevelBlock Block { get; set; }
5050
5051                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
5052                 ObsoleteAttribute GetObsoleteAttribute ();
5053                 string GetSignatureForError ();
5054                 bool IsExcluded ();
5055                 bool IsClsComplianceRequired ();
5056                 void SetMemberIsUsed ();
5057                 void EmitExtraSymbolInfo (SourceMethod source);
5058         }
5059
5060         //
5061         // Encapsulates most of the Method's state
5062         //
5063         public class MethodData {
5064
5065                 static FieldInfo methodbuilder_attrs_field;
5066
5067                 readonly IMethodData method;
5068
5069                 public readonly GenericMethod GenericMethod;
5070
5071                 //
5072                 // Are we implementing an interface ?
5073                 //
5074                 public MethodInfo implementing;
5075
5076                 //
5077                 // Protected data.
5078                 //
5079                 protected InterfaceMemberBase member;
5080                 protected int modifiers;
5081                 protected MethodAttributes flags;
5082                 protected Type declaring_type;
5083                 protected MethodInfo parent_method;
5084
5085                 MethodBuilder builder = null;
5086                 public MethodBuilder MethodBuilder {
5087                         get {
5088                                 return builder;
5089                         }
5090                 }
5091
5092                 public Type DeclaringType {
5093                         get {
5094                                 return declaring_type;
5095                         }
5096                 }
5097
5098                 public MethodData (InterfaceMemberBase member,
5099                                    int modifiers, MethodAttributes flags, IMethodData method)
5100                 {
5101                         this.member = member;
5102                         this.modifiers = modifiers;
5103                         this.flags = flags;
5104
5105                         this.method = method;
5106                 }
5107
5108                 public MethodData (InterfaceMemberBase member, 
5109                                    int modifiers, MethodAttributes flags, 
5110                                    IMethodData method, MethodBuilder builder,
5111                                    GenericMethod generic, MethodInfo parent_method)
5112                         : this (member, modifiers, flags, method)
5113                 {
5114                         this.builder = builder;
5115                         this.GenericMethod = generic;
5116                         this.parent_method = parent_method;
5117                 }
5118
5119                 public bool Define (DeclSpace parent, string method_full_name)
5120                 {
5121                         string name = method.MethodName.Basename;
5122
5123                         TypeContainer container = parent.PartialContainer;
5124
5125                         PendingImplementation pending = container.PendingImplementations;
5126                         if (pending != null){
5127                                 if (member is Indexer) // TODO: test it, but it should work without this IF
5128                                         implementing = pending.IsInterfaceIndexer (
5129                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
5130                                 else
5131                                         implementing = pending.IsInterfaceMethod (
5132                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5133
5134                                 if (member.InterfaceType != null){
5135                                         if (implementing == null){
5136                                                 if (member is PropertyBase) {
5137                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5138                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5139                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5140
5141                                                 } else {
5142                                                         Report.Error (539, method.Location,
5143                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5144                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5145                                                 }
5146                                                 return false;
5147                                         }
5148                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5149                                                 Report.SymbolRelatedToPreviousError (implementing);
5150                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5151                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5152                                                 return false;
5153                                         }
5154                                 } else {
5155                                         if (implementing != null) {
5156                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5157                                                 if (prop_method == null) {
5158                                                         if (TypeManager.IsSpecialMethod (implementing)) {
5159                                                                 Report.SymbolRelatedToPreviousError (implementing);
5160                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5161                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5162                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5163                                                         }
5164                                                 } else if (implementing.DeclaringType.IsInterface) {
5165                                                         if (!implementing.IsSpecialName) {
5166                                                                 Report.SymbolRelatedToPreviousError (implementing);
5167                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5168                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5169                                                                 return false;
5170                                                         }
5171                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5172                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5173                                                                 Report.SymbolRelatedToPreviousError (implementing);
5174                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5175                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5176                                                                 return false;
5177                                                         }
5178                                                 }
5179                                         }
5180                                 }
5181                         }
5182
5183                         //
5184                         // For implicit implementations, make sure we are public, for
5185                         // explicit implementations, make sure we are private.
5186                         //
5187                         if (implementing != null){
5188                                 //
5189                                 // Setting null inside this block will trigger a more
5190                                 // verbose error reporting for missing interface implementations
5191                                 //
5192                                 // The "candidate" function has been flagged already
5193                                 // but it wont get cleared
5194                                 //
5195                                 if (member.IsExplicitImpl){
5196                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5197                                                 Report.SymbolRelatedToPreviousError (implementing);
5198                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5199                                                         method.GetSignatureForError ());
5200                                                 return false;
5201                                         }
5202                                 } else {
5203                                         if (implementing.DeclaringType.IsInterface) {
5204                                                 //
5205                                                 // If this is an interface method implementation,
5206                                                 // check for public accessibility
5207                                                 //
5208                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5209                                                 {
5210                                                         implementing = null;
5211                                                 }
5212                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5213                                                 // We may never be private.
5214                                                 implementing = null;
5215
5216                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5217                                                 //
5218                                                 // We may be protected if we're overriding something.
5219                                                 //
5220                                                 implementing = null;
5221                                         }
5222                                 }
5223                                         
5224                                 //
5225                                 // Static is not allowed
5226                                 //
5227                                 if ((modifiers & Modifiers.STATIC) != 0){
5228                                         implementing = null;
5229                                 }
5230                         }
5231                         
5232                         //
5233                         // If implementing is still valid, set flags
5234                         //
5235                         if (implementing != null){
5236                                 //
5237                                 // When implementing interface methods, set NewSlot
5238                                 // unless, we are overwriting a method.
5239                                 //
5240                                 if (implementing.DeclaringType.IsInterface){
5241                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5242                                                 flags |= MethodAttributes.NewSlot;
5243                                 }
5244                                 flags |=
5245                                         MethodAttributes.Virtual |
5246                                         MethodAttributes.HideBySig;
5247
5248                                 // Set Final unless we're virtual, abstract or already overriding a method.
5249                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5250                                         flags |= MethodAttributes.Final;
5251                         }
5252
5253                         DefineMethodBuilder (container, method_full_name, method.ParameterInfo.Types);
5254
5255                         if (builder == null)
5256                                 return false;
5257
5258                         if (container.CurrentType != null)
5259                                 declaring_type = container.CurrentType;
5260                         else
5261                                 declaring_type = container.TypeBuilder;
5262
5263                         if ((modifiers & Modifiers.UNSAFE) != 0)
5264                                 builder.InitLocals = false;
5265
5266
5267                         if (implementing != null){
5268                                 //
5269                                 // clear the pending implemntation flag
5270                                 //
5271                                 if (member is Indexer) {
5272                                         pending.ImplementIndexer (
5273                                                 member.InterfaceType, builder, method.ReturnType,
5274                                                 method.ParameterInfo, member.IsExplicitImpl);
5275                                 } else
5276                                         pending.ImplementMethod (
5277                                                 member.InterfaceType, name, method.ReturnType,
5278                                                 method.ParameterInfo, member.IsExplicitImpl);
5279
5280                                 if (member.IsExplicitImpl)
5281                                         container.TypeBuilder.DefineMethodOverride (
5282                                                 builder, implementing);
5283                         }
5284
5285                         TypeManager.AddMethod (builder, method);
5286
5287                         if (GenericMethod != null) {
5288                                 bool is_override = member.IsExplicitImpl |
5289                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5290
5291                                 if (implementing != null)
5292                                         parent_method = implementing;
5293
5294                                 EmitContext ec = method.CreateEmitContext (container, null);
5295                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5296                                         return false;
5297                         }
5298
5299                         return true;
5300                 }
5301
5302
5303                 /// <summary>
5304                 /// Create the MethodBuilder for the method 
5305                 /// </summary>
5306                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5307                 {
5308                         if (builder == null) {
5309                                 builder = container.TypeBuilder.DefineMethod (
5310                                         method_name, flags, method.CallingConventions,
5311                                         method.ReturnType, ParameterTypes);
5312                                 return;
5313                         }
5314
5315 #if GMCS_SOURCE
5316                         //
5317                         // Generic method has been already defined to resolve method parameters
5318                         // correctly when they use type parameters
5319                         //
5320                         builder.SetParameters (ParameterTypes);
5321                         builder.SetReturnType (method.ReturnType);
5322
5323                         if (builder.Attributes != flags) {
5324                                 try {
5325                                         if (methodbuilder_attrs_field == null)
5326                                                 methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
5327                                         methodbuilder_attrs_field.SetValue (builder, flags);
5328                                 } catch {
5329                                         Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
5330                                 }
5331                         }
5332 #else
5333                         throw new InternalErrorException ();
5334 #endif
5335                 }
5336
5337                 //
5338                 // Emits the code
5339                 // 
5340                 public void Emit (DeclSpace parent)
5341                 {
5342                         ToplevelBlock block = method.Block;
5343
5344                         EmitContext ec;
5345                         if (block != null)
5346                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5347                         else
5348                                 ec = method.CreateEmitContext (parent, null);
5349
5350                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5351
5352                         if (GenericMethod != null)
5353                                 GenericMethod.EmitAttributes ();
5354
5355                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5356
5357                         //
5358                         // Handle destructors specially
5359                         //
5360                         // FIXME: This code generates buggy code
5361                         //
5362                         if (member is Destructor)
5363                                 EmitDestructor (ec, block);
5364                         else
5365                                 ec.EmitTopBlock (method, block);
5366
5367                         if (source != null) {
5368                                 method.EmitExtraSymbolInfo (source);
5369                                 if (method.Iterator != null)
5370                                         source.SetCompilerGenerated ();
5371                                 source.CloseMethod ();
5372                         }
5373                 }
5374
5375                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5376                 {
5377                         ILGenerator ig = ec.ig;
5378                         
5379                         Label finish = ig.DefineLabel ();
5380
5381                         block.SetDestructor ();
5382                         
5383                         ig.BeginExceptionBlock ();
5384                         ec.ReturnLabel = finish;
5385                         ec.HasReturnLabel = true;
5386                         ec.EmitTopBlock (method, block);
5387                         
5388                         // ig.MarkLabel (finish);
5389                         ig.BeginFinallyBlock ();
5390                         
5391                         if (ec.ContainerType.BaseType != null) {
5392                                 Expression member_lookup = Expression.MemberLookup (
5393                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5394                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5395
5396                                 if (member_lookup != null){
5397                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5398                                 
5399                                         ig.Emit (OpCodes.Ldarg_0);
5400                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5401                                 }
5402                         }
5403                         
5404                         ig.EndExceptionBlock ();
5405                         //ig.MarkLabel (ec.ReturnLabel);
5406                         ig.Emit (OpCodes.Ret);
5407                 }
5408         }
5409
5410         // TODO: Should derive from MethodCore
5411         public class Destructor : Method {
5412
5413                 static string[] attribute_targets = new string [] { "method" };
5414
5415                 public Destructor (DeclSpace parent, FullNamedExpression return_type, int mod,
5416                                    string name, Parameters parameters, Attributes attrs,
5417                                    Location l)
5418                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5419                                 parameters, attrs)
5420                 { }
5421
5422                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5423                 {
5424                         if (a.Type == TypeManager.conditional_attribute_type) {
5425                                 Error_ConditionalAttributeIsNotValid ();
5426                                 return;
5427                         }
5428
5429                         base.ApplyAttributeBuilder (a, cb);
5430                 }
5431
5432                 public override string GetSignatureForError ()
5433                 {
5434                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5435                 }
5436
5437                 public override string[] ValidAttributeTargets {
5438                         get {
5439                                 return attribute_targets;
5440                         }
5441                 }
5442         }
5443         
5444         abstract public class MemberBase : MemberCore {
5445                 protected FullNamedExpression type_name;
5446                 public readonly DeclSpace ds;
5447                 public readonly GenericMethod GenericMethod;
5448
5449                 //
5450                 // The type of this property / indexer / event
5451                 //
5452                 protected Type member_type;
5453                 public Type MemberType {
5454                         get {
5455                                 // TODO: Who wrote this, ResolveAsTypeTerminal can have side effects
5456                                 if (member_type == null && type_name != null) {
5457                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5458                                         type_name = type_name.ResolveAsTypeTerminal (rc, false);
5459                                         if (type_name != null) {
5460                                                 member_type = type_name.Type;
5461                                         }
5462                                 }
5463                                 return member_type;
5464                         }
5465                 }
5466
5467                 //
5468                 // The constructor is only exposed to our children
5469                 //
5470                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5471                                       FullNamedExpression type, int mod, int allowed_mod, int def_mod,
5472                                       MemberName name, Attributes attrs)
5473                         : base (parent, name, attrs)
5474                 {
5475                         this.ds = generic != null ? generic : (DeclSpace) parent;
5476                         this.type_name = type;
5477                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5478                         GenericMethod = generic;
5479                         if (GenericMethod != null)
5480                                 GenericMethod.ModFlags = ModFlags;
5481                 }
5482
5483                 protected virtual bool CheckBase ()
5484                 {
5485                         CheckProtectedModifier ();
5486
5487                         return true;
5488                 }
5489
5490                 protected virtual bool DoDefine ()
5491                 {
5492                         if (MemberType == null)
5493                                 return false;
5494
5495                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5496                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5497                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5498                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5499                                         return false;
5500                         }
5501                         
5502                         // verify accessibility
5503                         if (!IsAccessibleAs (MemberType)) {
5504                                 Report.SymbolRelatedToPreviousError (MemberType);
5505                                 if (this is Property)
5506                                         Report.Error (53, Location,
5507                                                       "Inconsistent accessibility: property type `" +
5508                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5509                                                       "accessible than property `" + GetSignatureForError () + "'");
5510                                 else if (this is Indexer)
5511                                         Report.Error (54, Location,
5512                                                       "Inconsistent accessibility: indexer return type `" +
5513                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5514                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5515                                 else if (this is MethodCore) {
5516                                         if (this is Operator)
5517                                                 Report.Error (56, Location,
5518                                                               "Inconsistent accessibility: return type `" +
5519                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5520                                                               "accessible than operator `" + GetSignatureForError () + "'");
5521                                         else
5522                                                 Report.Error (50, Location,
5523                                                               "Inconsistent accessibility: return type `" +
5524                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5525                                                               "accessible than method `" + GetSignatureForError () + "'");
5526                                 } else {
5527                                         Report.Error (52, Location,
5528                                                       "Inconsistent accessibility: field type `" +
5529                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5530                                                       "accessible than field `" + GetSignatureForError () + "'");
5531                                 }
5532                                 return false;
5533                         }
5534
5535                         return true;
5536                 }
5537
5538                 protected bool IsTypePermitted ()
5539                 {
5540                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5541                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5542                                 return false;
5543                         }
5544                         return true;
5545                 }
5546         }
5547
5548         //
5549         // Abstract class for all fields
5550         //
5551         abstract public class FieldBase : MemberBase {
5552                 public FieldBuilder FieldBuilder;
5553                 public Status status;
5554                 protected Expression initializer;
5555
5556                 [Flags]
5557                 public enum Status : byte {
5558                         HAS_OFFSET = 4          // Used by FieldMember.
5559                 }
5560
5561                 static readonly string[] attribute_targets = new string [] { "field" };
5562
5563                 protected FieldBase (DeclSpace parent, FullNamedExpression type, int mod,
5564                                      int allowed_mod, MemberName name, Attributes attrs)
5565                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5566                                 name, attrs)
5567                 {
5568                         if ((mod & Modifiers.ABSTRACT) != 0)
5569                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5570                 }
5571
5572                 public override AttributeTargets AttributeTargets {
5573                         get {
5574                                 return AttributeTargets.Field;
5575                         }
5576                 }
5577
5578                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5579                 {
5580                         if (a.Type == TypeManager.field_offset_attribute_type) {
5581                                 status |= Status.HAS_OFFSET;
5582
5583                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5584                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5585                                         return;
5586                                 }
5587
5588                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5589                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5590                                         return;
5591                                 }
5592                         }
5593
5594 #if NET_2_0
5595                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5596                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5597                                 return;
5598                         }
5599 #endif
5600
5601                         if (a.Type == TypeManager.marshal_as_attr_type) {
5602                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5603                                 if (marshal != null) {
5604                                         FieldBuilder.SetMarshal (marshal);
5605                                 }
5606                                 return;
5607                         }
5608
5609                         if ((a.HasSecurityAttribute)) {
5610                                 a.Error_InvalidSecurityParent ();
5611                                 return;
5612                         }
5613
5614                         FieldBuilder.SetCustomAttribute (cb);
5615                 }
5616
5617                 protected override bool CheckBase ()
5618                 {
5619                         if (!base.CheckBase ())
5620                                 return false;
5621  
5622                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5623                         if (conflict_symbol == null) {
5624                                 if ((ModFlags & Modifiers.NEW) != 0) {
5625                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5626                                 }
5627                                 return true;
5628                         }
5629  
5630                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5631                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5632                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5633                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5634                         }
5635  
5636                         return true;
5637                 }
5638
5639                 public override bool Define()
5640                 {
5641                         if (MemberType == null || member_type == null)
5642                                 return false;
5643
5644                         if (TypeManager.IsGenericParameter (MemberType))
5645                                 return true;
5646
5647                         if (MemberType == TypeManager.void_type) {
5648                                 // TODO: wrong location
5649                                 Expression.Error_VoidInvalidInTheContext (Location);
5650                                 return false;
5651                         }
5652
5653                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5654                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5655                                 return false;
5656                         }
5657
5658                         if (!CheckBase ())
5659                                 return false;
5660
5661                         if (!DoDefine ())
5662                                 return false;
5663
5664                         if (!IsTypePermitted ())
5665                                 return false;
5666
5667                         return true;
5668                 }
5669
5670                 //
5671                 //   Represents header string for documentation comment.
5672                 //
5673                 public override string DocCommentHeader {
5674                         get { return "F:"; }
5675                 }
5676
5677                 public override void Emit ()
5678                 {
5679 #if GMCS_SOURCE
5680                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0) {
5681                                 FieldBuilder.SetCustomAttribute (TypeManager.GetCompilerGeneratedAttribute (Location));
5682                         }
5683 #endif
5684
5685                         if (OptAttributes != null) {
5686                                 OptAttributes.Emit ();
5687                         }
5688
5689                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5690                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5691                         }
5692
5693                         base.Emit ();
5694                 }
5695
5696                 public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class)
5697                 {
5698                         Report.SymbolRelatedToPreviousError (static_class);
5699                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5700                                 variable_name);
5701                 }
5702
5703                 public Expression Initializer {
5704                         set {
5705                                 if (value != null) {
5706                                         this.initializer = value;
5707                                 }
5708                         }
5709                 }
5710
5711                 protected virtual bool IsFieldClsCompliant {
5712                         get {
5713                                 if (FieldBuilder == null)
5714                                         return true;
5715
5716                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5717                         }
5718                 }
5719
5720                 public override string[] ValidAttributeTargets 
5721                 {
5722                         get {
5723                                 return attribute_targets;
5724                         }
5725                 }
5726
5727                 protected override bool VerifyClsCompliance ()
5728                 {
5729                         if (!base.VerifyClsCompliance ())
5730                                 return false;
5731
5732                         if (!IsFieldClsCompliant) {
5733                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5734                         }
5735                         return true;
5736                 }
5737
5738                 public void SetAssigned ()
5739                 {
5740                         caching_flags |= Flags.IsAssigned;
5741                 }
5742         }
5743
5744         interface IFixedBuffer
5745         {
5746                 FieldInfo Element { get; }
5747                 Type ElementType { get; }
5748         }
5749
5750         public class FixedFieldExternal: IFixedBuffer
5751         {
5752                 FieldInfo element_field;
5753
5754                 public FixedFieldExternal (FieldInfo fi)
5755                 {
5756                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5757                 }
5758
5759                 #region IFixedField Members
5760
5761                 public FieldInfo Element {
5762                         get {
5763                                 return element_field;
5764                         }
5765                 }
5766
5767                 public Type ElementType {
5768                         get {
5769                                 return element_field.FieldType;
5770                         }
5771                 }
5772
5773                 #endregion
5774         }
5775
5776         /// <summary>
5777         /// Fixed buffer implementation
5778         /// </summary>
5779         public class FixedField : FieldBase, IFixedBuffer
5780         {
5781                 public const string FixedElementName = "FixedElementField";
5782                 static int GlobalCounter = 0;
5783                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5784                 static FieldInfo[] fi;
5785
5786                 TypeBuilder fixed_buffer_type;
5787                 FieldBuilder element;
5788                 Expression size_expr;
5789
5790                 const int AllowedModifiers =
5791                         Modifiers.NEW |
5792                         Modifiers.PUBLIC |
5793                         Modifiers.PROTECTED |
5794                         Modifiers.INTERNAL |
5795                         Modifiers.PRIVATE;
5796
5797                 public FixedField (DeclSpace parent, FullNamedExpression type, int mod, string name,
5798                         Expression size_expr, Attributes attrs, Location loc):
5799                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5800                 {
5801                         if (RootContext.Version == LanguageVersion.ISO_1)
5802                                 Report.FeatureIsNotAvailable (loc, "fixed size buffers");
5803
5804                         this.size_expr = size_expr;
5805                 }
5806
5807                 public override bool Define()
5808                 {
5809                         if (!Parent.IsInUnsafeScope)
5810                                 Expression.UnsafeError (Location);
5811
5812                         if (!base.Define ())
5813                                 return false;
5814
5815                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5816                                 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",
5817                                         GetSignatureForError ());
5818                         }                       
5819                         
5820                         // Create nested fixed buffer container
5821                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5822                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5823                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5824                         
5825                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5826                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5827                         
5828                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5829                         Parent.MemberCache.AddMember (FieldBuilder, this);
5830                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5831
5832                         return true;
5833                 }
5834
5835                 public override void Emit()
5836                 {
5837                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5838                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5839                                         GetSignatureForError ());
5840                         }
5841
5842                         EmitContext ec = new EmitContext (this, Parent, Location, null, TypeManager.void_type, ModFlags);
5843                         Constant c = size_expr.ResolveAsConstant (ec, this);
5844                         if (c == null)
5845                                 return;
5846
5847                         IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5848                         if (buffer_size_const == null)
5849                                 return;
5850
5851                         int buffer_size = buffer_size_const.Value;
5852
5853                         if (buffer_size <= 0) {
5854                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5855                                 return;
5856                         }
5857
5858                         int type_size = Expression.GetTypeSize (MemberType);
5859
5860                         if (buffer_size > int.MaxValue / type_size) {
5861                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5862                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5863                                 return;
5864                         }
5865
5866                         buffer_size *= type_size;
5867                         EmitFieldSize (buffer_size);
5868                         base.Emit ();
5869                 }
5870
5871                 void EmitFieldSize (int buffer_size)
5872                 {
5873                         if (TypeManager.struct_layout_attribute_type == null) {
5874                                 TypeManager.struct_layout_attribute_type = TypeManager.CoreLookupType (
5875                                         "System.Runtime.InteropServices", "StructLayoutAttribute", Kind.Class, true);
5876
5877                                 if (TypeManager.struct_layout_attribute_type == null)
5878                                         return;
5879                         }
5880
5881                         if (fi == null)
5882                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5883
5884                         object [] fi_val = new object [] { buffer_size };
5885
5886                         if (TypeManager.struct_layout_attribute_ctor == null) {
5887                                 TypeManager.struct_layout_attribute_ctor = TypeManager.GetPredefinedConstructor (
5888                                         TypeManager.struct_layout_attribute_type, Location, TypeManager.short_type);
5889                                 if (TypeManager.struct_layout_attribute_ctor == null)
5890                                         return;
5891                         }
5892
5893                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor,
5894                                 ctor_args, fi, fi_val);
5895                         fixed_buffer_type.SetCustomAttribute (cab);
5896                         
5897                         //
5898                         // Don't emit FixedBufferAttribute attribute for private types
5899                         //
5900                         if ((ModFlags & Modifiers.PRIVATE) != 0)
5901                                 return; 
5902
5903                         if (TypeManager.fixed_buffer_attr_ctor == null) {
5904                                 if (TypeManager.fixed_buffer_attr_type == null) {
5905                                         TypeManager.fixed_buffer_attr_type = TypeManager.CoreLookupType (
5906                                                 "System.Runtime.CompilerServices", "FixedBufferAttribute", Kind.Class, true);
5907
5908                                         if (TypeManager.fixed_buffer_attr_type == null)
5909                                                 return;
5910                                 }
5911
5912                                 TypeManager.fixed_buffer_attr_ctor = TypeManager.GetPredefinedConstructor (TypeManager.fixed_buffer_attr_type,
5913                                         Location, TypeManager.type_type, TypeManager.int32_type);
5914                                 
5915                                 if (TypeManager.fixed_buffer_attr_ctor == null)
5916                                         return;
5917                         }
5918
5919                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object [] { MemberType, buffer_size });
5920                         FieldBuilder.SetCustomAttribute (cab);
5921                 }
5922
5923                 protected override bool IsFieldClsCompliant {
5924                         get {
5925                                 return false;
5926                         }
5927                 }
5928
5929                 #region IFixedField Members
5930
5931                 public FieldInfo Element {
5932                         get {
5933                                 return element;
5934                         }
5935                 }
5936
5937                 public Type ElementType {
5938                         get {
5939                                 return MemberType;
5940                         }
5941                 }
5942
5943                 #endregion
5944         }
5945
5946         //
5947         // The Field class is used to represents class/struct fields during parsing.
5948         //
5949         public class Field : FieldBase {
5950                 // <summary>
5951                 //   Modifiers allowed in a class declaration
5952                 // </summary>
5953                 const int AllowedModifiers =
5954                         Modifiers.NEW |
5955                         Modifiers.PUBLIC |
5956                         Modifiers.PROTECTED |
5957                         Modifiers.INTERNAL |
5958                         Modifiers.PRIVATE |
5959                         Modifiers.STATIC |
5960                         Modifiers.VOLATILE |
5961                         Modifiers.UNSAFE |
5962                         Modifiers.READONLY;
5963
5964                 public Field (DeclSpace parent, FullNamedExpression type, int mod, string name,
5965                               Attributes attrs, Location loc)
5966                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5967                                 attrs)
5968                 {
5969                 }
5970
5971                 bool CanBeVolatile ()
5972                 {
5973                         if (TypeManager.IsReferenceType (MemberType))
5974                                 return true;
5975
5976                         if (MemberType.IsEnum)
5977                                 return true;
5978
5979                         if (MemberType == TypeManager.bool_type || MemberType == TypeManager.char_type ||
5980                                 MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type ||
5981                                 MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type ||
5982                                 MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type ||
5983                                 MemberType == TypeManager.float_type)
5984                                 return true;
5985
5986                         return false;
5987                 }
5988
5989                 public override bool Define ()
5990                 {
5991                         if (!base.Define ())
5992                                 return false;
5993
5994                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5995                                 if (!CanBeVolatile ()) {
5996                                         Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5997                                                 GetSignatureForError (), TypeManager.CSharpName (MemberType));
5998                                 }
5999
6000                                 if ((ModFlags & Modifiers.READONLY) != 0){
6001                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
6002                                                 GetSignatureForError ());
6003                                 }
6004                         }
6005
6006                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
6007
6008                         try {
6009 #if GMCS_SOURCE
6010                                 Type[] required_modifier = null;
6011                                 if ((ModFlags & Modifiers.VOLATILE) != 0) {
6012                                         if (TypeManager.isvolatile_type == null)
6013                                                 TypeManager.isvolatile_type = TypeManager.CoreLookupType (
6014                                                         "System.Runtime.CompilerServices", "IsVolatile", Kind.Class, true);
6015
6016                                         if (TypeManager.isvolatile_type != null)
6017                                                 required_modifier = new Type [] { TypeManager.isvolatile_type };
6018                                 }
6019
6020                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6021                                         Name, MemberType, required_modifier, null, Modifiers.FieldAttr (ModFlags));
6022 #else
6023                                 FieldBuilder = Parent.TypeBuilder.DefineField (
6024                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
6025 #endif
6026                                 Parent.MemberCache.AddMember (FieldBuilder, this);
6027                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
6028                         }
6029                         catch (ArgumentException) {
6030                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6031                                 return false;
6032                         }
6033
6034                         if (initializer != null)
6035                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
6036                                         new FieldInitializer (FieldBuilder, initializer));
6037
6038                         if (Parent.PartialContainer.Kind == Kind.Struct && (fa & FieldAttributes.Static) == 0 &&
6039                                 MemberType == Parent.TypeBuilder && !TypeManager.IsBuiltinType (MemberType) && initializer == null) {
6040                                 Report.Error (523, Location, "Struct member `{0}' causes a cycle in the structure layout",
6041                                         GetSignatureForError ());
6042                                 return false;
6043                         }
6044
6045                         return true;
6046                 }
6047
6048                 public override string GetSignatureForError ()
6049                 {
6050                         string s = base.GetSignatureForError ();
6051                         if ((ModFlags & Modifiers.BACKING_FIELD) == 0)
6052                                 return s;
6053
6054                         // Undecorate name mangling
6055                         int l = s.LastIndexOf ('>');
6056                         return s.Substring (0, l).Remove (s.LastIndexOf ('<'), 1);
6057                 }
6058
6059                 protected override bool VerifyClsCompliance ()
6060                 {
6061                         if (!base.VerifyClsCompliance ())
6062                                 return false;
6063
6064                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
6065                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6066                         }
6067
6068                         return true;
6069                 }
6070         }
6071
6072         //
6073         // `set' and `get' accessors are represented with an Accessor.
6074         // 
6075         public class Accessor : IAnonymousHost {
6076                 //
6077                 // Null if the accessor is empty, or a Block if not
6078                 //
6079                 public const int AllowedModifiers = 
6080                         Modifiers.PUBLIC |
6081                         Modifiers.PROTECTED |
6082                         Modifiers.INTERNAL |
6083                         Modifiers.PRIVATE;
6084                 
6085                 public ToplevelBlock Block;
6086                 public Attributes Attributes;
6087                 public Location Location;
6088                 public int ModFlags;
6089                 public bool Yields;
6090                 public ArrayList AnonymousMethods;
6091                 
6092                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
6093                 {
6094                         Block = b;
6095                         Attributes = attrs;
6096                         Location = loc;
6097                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
6098                 }
6099
6100                 public void SetYields ()
6101                 {
6102                         Yields = true;
6103                 }
6104
6105                 public void AddAnonymousMethod (AnonymousMethodExpression ame)
6106                 {
6107                         if (AnonymousMethods == null)
6108                                 AnonymousMethods = new ArrayList ();
6109                         AnonymousMethods.Add (ame);
6110                 }
6111         }
6112
6113         // Ooouh Martin, templates are missing here.
6114         // When it will be possible move here a lot of child code and template method type.
6115         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
6116                 protected MethodData method_data;
6117                 protected ToplevelBlock block;
6118                 protected ListDictionary declarative_security;
6119
6120                 // The accessor are created event if they are not wanted.
6121                 // But we need them because their names are reserved.
6122                 // Field says whether accessor will be emited or not
6123                 public readonly bool IsDummy;
6124
6125                 protected readonly string prefix;
6126
6127                 ReturnParameter return_attributes;
6128
6129                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
6130                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
6131                 {
6132                         this.prefix = prefix;
6133                         IsDummy = true;
6134                 }
6135
6136                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
6137                                                     string prefix)
6138                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
6139                                 accessor.Attributes)
6140                 {
6141                         this.prefix = prefix;
6142                         this.block = accessor.Block;
6143                 }
6144
6145                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
6146                 {
6147                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
6148                 }
6149
6150                 public void UpdateName (InterfaceMemberBase member)
6151                 {
6152                         SetMemberName (SetupName (prefix, member, Location));
6153                 }
6154
6155                 #region IMethodData Members
6156
6157                 public abstract Iterator Iterator {
6158                         get;
6159                 }
6160
6161                 public ToplevelBlock Block {
6162                         get {
6163                                 return block;
6164                         }
6165
6166                         set {
6167                                 block = value;
6168                         }
6169                 }
6170
6171                 public CallingConventions CallingConventions {
6172                         get {
6173                                 return CallingConventions.Standard;
6174                         }
6175                 }
6176
6177                 public bool IsExcluded ()
6178                 {
6179                         return false;
6180                 }
6181
6182                 GenericMethod IMethodData.GenericMethod {
6183                         get {
6184                                 return null;
6185                         }
6186                 }
6187
6188                 public MemberName MethodName {
6189                         get {
6190                                 return MemberName;
6191                         }
6192                 }
6193
6194                 public Type[] ParameterTypes { 
6195                         get {
6196                                 return ParameterInfo.Types;
6197                         }
6198                 }
6199
6200                 public abstract Parameters ParameterInfo { get ; }
6201                 public abstract Type ReturnType { get; }
6202                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6203
6204                 #endregion
6205
6206                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6207                 {
6208                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6209                                         a.Type == TypeManager.conditional_attribute_type) {
6210                                 Report.Error (1667, a.Location,
6211                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6212                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6213                                 return;
6214                         }
6215
6216                         if (a.IsValidSecurityAttribute ()) {
6217                                 if (declarative_security == null)
6218                                         declarative_security = new ListDictionary ();
6219                                 a.ExtractSecurityPermissionSet (declarative_security);
6220                                 return;
6221                         }
6222
6223                         if (a.Target == AttributeTargets.Method) {
6224                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6225                                 return;
6226                         }
6227
6228                         if (a.Target == AttributeTargets.ReturnValue) {
6229                                 if (return_attributes == null)
6230                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6231
6232                                 return_attributes.ApplyAttributeBuilder (a, cb);
6233                                 return;
6234                         }
6235
6236                         ApplyToExtraTarget (a, cb);
6237                 }
6238
6239                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6240                 {
6241                         throw new NotSupportedException ("You forgot to define special attribute target handling");
6242                 }
6243
6244                 // It is not supported for the accessors
6245                 public sealed override bool Define()
6246                 {
6247                         throw new NotSupportedException ();
6248                 }
6249
6250                 public void Emit (DeclSpace parent)
6251                 {
6252                         EmitMethod (parent);
6253
6254 #if GMCS_SOURCE                 
6255                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0)
6256                                 method_data.MethodBuilder.SetCustomAttribute (TypeManager.GetCompilerGeneratedAttribute (Location));
6257 #endif                  
6258                         if (OptAttributes != null)
6259                                 OptAttributes.Emit ();
6260
6261                         if (declarative_security != null) {
6262                                 foreach (DictionaryEntry de in declarative_security) {
6263                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6264                                 }
6265                         }
6266
6267                         block = null;
6268                 }
6269
6270                 protected virtual void EmitMethod (DeclSpace parent)
6271                 {
6272                         method_data.Emit (parent);
6273                 }
6274
6275                 public override bool EnableOverloadChecks (MemberCore overload)
6276                 {
6277                         // This can only happen with indexers and it will
6278                         // be catched as indexer difference
6279                         if (overload is AbstractPropertyEventMethod)
6280                                 return true;
6281
6282                         if (overload is MethodCore) {
6283                                 caching_flags |= Flags.MethodOverloadsExist;
6284                                 return true;
6285                         }
6286                         return false;
6287                 }
6288
6289                 public override bool IsClsComplianceRequired()
6290                 {
6291                         return false;
6292                 }
6293
6294                 public bool IsDuplicateImplementation (MethodCore method)
6295                 {
6296                         if (!MemberName.Equals (method.MemberName))
6297                                 return false;
6298
6299                         Type[] param_types = method.ParameterTypes;
6300
6301                         if (param_types == null || param_types.Length != ParameterTypes.Length)
6302                                 return false;
6303
6304                         for (int i = 0; i < param_types.Length; i++)
6305                                 if (param_types [i] != ParameterTypes [i])
6306                                         return false;
6307
6308                         Report.SymbolRelatedToPreviousError (method);
6309                         Report.Error (82, Location, "A member `{0}' is already reserved",
6310                                 method.GetSignatureForError ());
6311                         return true;
6312                 }
6313
6314                 public override bool IsUsed
6315                 {
6316                         get {
6317                                 if (IsDummy)
6318                                         return false;
6319
6320                                 return base.IsUsed;
6321                         }
6322                 }
6323
6324                 public virtual bool ResolveMembers ()
6325                 {
6326                         return true;
6327                 }
6328
6329                 //
6330                 //   Represents header string for documentation comment.
6331                 //
6332                 public override string DocCommentHeader {
6333                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6334                 }
6335
6336                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
6337                 { }
6338         }
6339
6340         //
6341         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6342         // their common bits.
6343         //
6344         abstract public class PropertyBase : PropertyBasedMember {
6345
6346                 public class GetMethod : PropertyMethod
6347                 {
6348                         static string[] attribute_targets = new string [] { "method", "return" };
6349
6350                         public GetMethod (PropertyBase method):
6351                                 base (method, "get_")
6352                         {
6353                         }
6354
6355                         public GetMethod (PropertyBase method, Accessor accessor):
6356                                 base (method, accessor, "get_")
6357                         {
6358                         }
6359
6360                         public override MethodBuilder Define (DeclSpace parent)
6361                         {
6362                                 if (!CheckForDuplications ())
6363                                         return null;
6364
6365                                 if (IsDummy)
6366                                         return null;
6367                                 
6368                                 base.Define (parent);
6369                                 
6370                                 method_data = new MethodData (method, ModFlags, flags, this);
6371
6372                                 if (!method_data.Define (parent, method.GetFullName (MemberName)))
6373                                         return null;
6374
6375                                 return method_data.MethodBuilder;
6376                         }
6377
6378                         public override Type ReturnType {
6379                                 get {
6380                                         return method.MemberType;
6381                                 }
6382                         }
6383
6384                         public override Parameters ParameterInfo {
6385                                 get {
6386                                         return Parameters.EmptyReadOnlyParameters;
6387                                 }
6388                         }
6389
6390                         public override string[] ValidAttributeTargets {
6391                                 get {
6392                                         return attribute_targets;
6393                                 }
6394                         }
6395                 }
6396
6397                 public class SetMethod : PropertyMethod {
6398
6399                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6400                         ImplicitParameter param_attr;
6401                         protected Parameters parameters;
6402
6403                         public SetMethod (PropertyBase method):
6404                                 base (method, "set_")
6405                         {
6406                         }
6407
6408                         public SetMethod (PropertyBase method, Accessor accessor):
6409                                 base (method, accessor, "set_")
6410                         {
6411                         }
6412
6413                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6414                         {
6415                                 if (a.Target == AttributeTargets.Parameter) {
6416                                         if (param_attr == null)
6417                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6418
6419                                         param_attr.ApplyAttributeBuilder (a, cb);
6420                                         return;
6421                                 }
6422
6423                                 base.ApplyAttributeBuilder (a, cb);
6424                         }
6425
6426                         public override Parameters ParameterInfo {
6427                                 get {
6428                                         if (parameters == null)
6429                                                 DefineParameters ();
6430                                         return parameters;
6431                                 }
6432                         }
6433
6434                         protected virtual void DefineParameters ()
6435                         {
6436                                 parameters = Parameters.CreateFullyResolved (
6437                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location));
6438                         }
6439
6440                         public override MethodBuilder Define (DeclSpace parent)
6441                         {
6442                                 if (!CheckForDuplications ())
6443                                         return null;
6444                                 
6445                                 if (IsDummy)
6446                                         return null;
6447
6448                                 base.Define (parent);
6449
6450                                 method_data = new MethodData (method, ModFlags, flags, this);
6451
6452                                 if (!method_data.Define (parent, method.GetFullName (MemberName)))
6453                                         return null;
6454
6455                                 return method_data.MethodBuilder;
6456                         }
6457
6458                         public override Type ReturnType {
6459                                 get {
6460                                         return TypeManager.void_type;
6461                                 }
6462                         }
6463
6464                         public override string[] ValidAttributeTargets {
6465                                 get {
6466                                         return attribute_targets;
6467                                 }
6468                         }
6469                 }
6470
6471                 static string[] attribute_targets = new string [] { "property" };
6472
6473                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6474                 {
6475                         protected readonly PropertyBase method;
6476                         protected MethodAttributes flags;
6477                         Iterator iterator;
6478                         ArrayList anonymous_methods;
6479                         bool yields;
6480
6481                         public PropertyMethod (PropertyBase method, string prefix)
6482                                 : base (method, prefix)
6483                         {
6484                                 this.method = method;
6485                         }
6486
6487                         public PropertyMethod (PropertyBase method, Accessor accessor,
6488                                                string prefix)
6489                                 : base (method, accessor, prefix)
6490                         {
6491                                 this.method = method;
6492                                 this.ModFlags = accessor.ModFlags;
6493                                 yields = accessor.Yields;
6494                                 anonymous_methods = accessor.AnonymousMethods;
6495
6496                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6497                                         Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
6498                                 }
6499                         }
6500
6501                         public override Iterator Iterator {
6502                                 get { return iterator; }
6503                         }
6504
6505                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6506                         {
6507                                 if (a.IsInternalMethodImplAttribute) {
6508                                         method.is_external_implementation = true;
6509                                 }
6510
6511                                 base.ApplyAttributeBuilder (a, cb);
6512                         }
6513
6514                         public override AttributeTargets AttributeTargets {
6515                                 get {
6516                                         return AttributeTargets.Method;
6517                                 }
6518                         }
6519
6520                         public override bool IsClsComplianceRequired ()
6521                         {
6522                                 return method.IsClsComplianceRequired ();
6523                         }
6524
6525                         public override bool ResolveMembers ()
6526                         {
6527                                 if (yields) {
6528                                         iterator = Iterator.CreateIterator (this, Parent, null, ModFlags);
6529                                         if (iterator == null)
6530                                                 return false;
6531                                 }
6532
6533                                 if (anonymous_methods != null) {
6534                                         foreach (AnonymousMethodExpression ame in anonymous_methods) {
6535                                                 if (!ame.CreateAnonymousHelpers ())
6536                                                         return false;
6537                                         }
6538                                 }
6539
6540                                 return true;
6541                         }
6542
6543                         public virtual MethodBuilder Define (DeclSpace parent)
6544                         {
6545                                 TypeContainer container = parent.PartialContainer;
6546
6547                                 //
6548                                 // Check for custom access modifier
6549                                 //
6550                                 if ((ModFlags & Modifiers.Accessibility) == 0) {
6551                                         ModFlags |= method.ModFlags;
6552                                         flags = method.flags;
6553                                 } else {
6554                                         if (container.Kind == Kind.Interface)
6555                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6556                                                         GetSignatureForError ());
6557
6558                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6559                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6560                                         }
6561
6562                                         CheckModifiers (ModFlags);
6563                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6564                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6565                                         flags = Modifiers.MethodAttr (ModFlags);
6566                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6567                                 }
6568
6569                                 CheckAbstractAndExtern (block != null);
6570                                 return null;
6571                         }
6572
6573                         public bool HasCustomAccessModifier
6574                         {
6575                                 get {
6576                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6577                                 }
6578                         }
6579
6580                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6581                         {
6582                                 return new EmitContext (method,
6583                                         ds, method.ds, method.Location, ig, ReturnType,
6584                                         method.ModFlags, false);
6585                         }
6586
6587                         public override ObsoleteAttribute GetObsoleteAttribute ()
6588                         {
6589                                 return method.GetObsoleteAttribute ();
6590                         }
6591
6592                         public override string GetSignatureForError()
6593                         {
6594                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6595                         }
6596                         
6597                         void CheckModifiers (int modflags)
6598                         {
6599                                 modflags &= Modifiers.Accessibility;
6600                                 int flags = 0;
6601                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6602
6603                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6604                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6605                                 }
6606                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6607                                         if ((mflags & Modifiers.INTERNAL) != 0)
6608                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6609
6610                                         flags |= Modifiers.PRIVATE;
6611                                 }
6612                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6613                                         flags |= Modifiers.PRIVATE;
6614
6615                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6616                                         Report.Error (273, Location,
6617                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6618                                                 GetSignatureForError (), method.GetSignatureForError ());
6619                                 }
6620                         }
6621
6622                         protected bool CheckForDuplications () 
6623                         {
6624                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0)
6625                                         return true;
6626
6627                                 return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo);
6628                         }
6629                 }
6630
6631                 public PropertyMethod Get, Set;
6632                 public PropertyBuilder PropertyBuilder;
6633                 public MethodBuilder GetBuilder, SetBuilder;
6634
6635                 protected bool define_set_first = false;
6636
6637                 public PropertyBase (DeclSpace parent, FullNamedExpression type, int mod_flags,
6638                                      int allowed_mod, bool is_iface, MemberName name,
6639                                      Attributes attrs, bool define_set_first)
6640                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,     attrs)
6641                 {
6642                          this.define_set_first = define_set_first;
6643                 }
6644
6645                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6646                 {
6647                         if (a.HasSecurityAttribute) {
6648                                 a.Error_InvalidSecurityParent ();
6649                                 return;
6650                         }
6651
6652                         PropertyBuilder.SetCustomAttribute (cb);
6653                 }
6654
6655                 public override AttributeTargets AttributeTargets {
6656                         get {
6657                                 return AttributeTargets.Property;
6658                         }
6659                 }
6660
6661                 public override bool Define ()
6662                 {
6663                         if (!DoDefine ())
6664                                 return false;
6665
6666                         if (!IsTypePermitted ())
6667                                 return false;
6668
6669                         return true;
6670                 }
6671
6672                 protected override bool DoDefine ()
6673                 {
6674                         if (!base.DoDefine ())
6675                                 return false;
6676
6677                         //
6678                         // Accessors modifiers check
6679                         //
6680                         if ((Get.ModFlags & Modifiers.Accessibility) != 0 &&
6681                                 (Set.ModFlags & Modifiers.Accessibility) != 0) {
6682                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6683                                                 GetSignatureForError ());
6684                                 return false;
6685                         }
6686
6687                         if ((Get.IsDummy || Set.IsDummy)
6688                                         && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6689                                 Report.Error (276, Location, 
6690                                         "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6691                                         GetSignatureForError ());
6692                                 return false;
6693                         }
6694
6695 #if MS_COMPATIBLE
6696                         if (MemberType.IsGenericParameter)
6697                                 return true;
6698 #endif
6699
6700                         if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
6701                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6702                                 return false;
6703                         }
6704
6705                         return true;
6706                 }
6707
6708                 bool DefineGet ()
6709                 {
6710                         GetBuilder = Get.Define (Parent);
6711                         return (Get.IsDummy) ? true : GetBuilder != null;
6712                 }
6713
6714                 bool DefineSet (bool define)
6715                 {
6716                         if (!define)
6717                                 return true;
6718
6719                         SetBuilder = Set.Define (Parent);
6720                         return (Set.IsDummy) ? true : SetBuilder != null;
6721                 }
6722
6723                 protected bool DefineAccessors ()
6724                 {
6725                         return DefineSet (define_set_first) &&
6726                                 DefineGet () &&
6727                                 DefineSet (!define_set_first);
6728                 }
6729
6730                 protected abstract PropertyInfo ResolveBaseProperty ();
6731
6732                 // TODO: rename to Resolve......
6733                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6734                 {
6735                         PropertyInfo base_property = ResolveBaseProperty ();
6736                         if (base_property == null)
6737                                 return null;
6738
6739                         base_ret_type = base_property.PropertyType;
6740                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6741                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6742                         MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
6743
6744                         //
6745                         // Check base property accessors conflict
6746                         //
6747                         if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
6748                                 if (get_accessor == null) {
6749                                         if (Get != null && !Get.IsDummy) {
6750                                                 Report.SymbolRelatedToPreviousError (base_property);
6751                                                 Report.Error (545, Location,
6752                                                         "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
6753                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6754                                         }
6755                                 } else {
6756                                         get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
6757
6758                                         if (!Get.IsDummy && !CheckAccessModifiers (
6759                                                 Modifiers.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6760                                                 Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
6761                                 }
6762
6763                                 if (set_accessor == null) {
6764                                         if (Set != null && !Set.IsDummy) {
6765                                                 Report.SymbolRelatedToPreviousError (base_property);
6766                                                 Report.Error (546, Location,
6767                                                         "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
6768                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6769                                         }
6770                                 } else {
6771                                         set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
6772
6773                                         if (!Set.IsDummy && !CheckAccessModifiers (
6774                                                 Modifiers.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6775                                                 Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
6776                                 }
6777                         }
6778
6779                         // When one accessor does not exist and property hides base one
6780                         // we need to propagate this upwards
6781                         if (set_accessor == null)
6782                                 set_accessor = get_accessor;
6783
6784                         //
6785                         // Get the less restrictive access
6786                         //
6787                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6788                 }
6789
6790                 public override void Emit ()
6791                 {
6792                         //
6793                         // The PropertyBuilder can be null for explicit implementations, in that
6794                         // case, we do not actually emit the ".property", so there is nowhere to
6795                         // put the attribute
6796                         //
6797                         if (PropertyBuilder != null && OptAttributes != null)
6798                                 OptAttributes.Emit ();
6799
6800                         if (!Get.IsDummy)
6801                                 Get.Emit (Parent);
6802
6803                         if (!Set.IsDummy)
6804                                 Set.Emit (Parent);
6805
6806                         base.Emit ();
6807                 }
6808
6809                 /// <summary>
6810                 /// Tests whether accessors are not in collision with some method (CS0111)
6811                 /// </summary>
6812                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6813                 {
6814                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6815                 }
6816
6817                 public override bool IsUsed
6818                 {
6819                         get {
6820                                 if (IsExplicitImpl)
6821                                         return true;
6822
6823                                 return Get.IsUsed | Set.IsUsed;
6824                         }
6825                 }
6826
6827                 protected override void SetMemberName (MemberName new_name)
6828                 {
6829                         base.SetMemberName (new_name);
6830
6831                         Get.UpdateName (this);
6832                         Set.UpdateName (this);
6833                 }
6834
6835                 public override string[] ValidAttributeTargets {
6836                         get {
6837                                 return attribute_targets;
6838                         }
6839                 }
6840
6841                 //
6842                 //   Represents header string for documentation comment.
6843                 //
6844                 public override string DocCommentHeader {
6845                         get { return "P:"; }
6846                 }
6847         }
6848                         
6849         public class Property : PropertyBase {
6850                 const int AllowedModifiers =
6851                         Modifiers.NEW |
6852                         Modifiers.PUBLIC |
6853                         Modifiers.PROTECTED |
6854                         Modifiers.INTERNAL |
6855                         Modifiers.PRIVATE |
6856                         Modifiers.STATIC |
6857                         Modifiers.SEALED |
6858                         Modifiers.OVERRIDE |
6859                         Modifiers.ABSTRACT |
6860                         Modifiers.UNSAFE |
6861                         Modifiers.EXTERN |
6862                         Modifiers.METHOD_YIELDS |
6863                         Modifiers.VIRTUAL;
6864
6865                 const int AllowedInterfaceModifiers =
6866                         Modifiers.NEW;
6867
6868                 void CreateAutomaticProperty (Block block, Accessor get_block, Accessor set_block)
6869                 {
6870                         // Make the field
6871                         Field field = new Field (
6872                                 Parent, type_name,
6873                                 Modifiers.BACKING_FIELD | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
6874                             "<" + Name + ">k__BackingField", null, Location);
6875                         ((TypeContainer)Parent).PartialContainer.AddField (field);
6876
6877                         // Make get block
6878                         get_block.Block = new ToplevelBlock (block, null, Location);
6879                         Return r = new Return (new SimpleName(field.Name, Location), Location);
6880                         get_block.Block.AddStatement (r);
6881                         get_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6882
6883                         // Make set block
6884                         Parameters parameters = new Parameters (new Parameter (type_name, "value", Parameter.Modifier.NONE, null, Location));
6885                         set_block.Block = new ToplevelBlock (block, parameters, Location);
6886                         Assign a = new SimpleAssign (new SimpleName (field.Name, Location), new SimpleName ("value", Location));
6887                         set_block.Block.AddStatement (new StatementExpression(a));
6888                         set_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6889                 }
6890
6891                 public Property (DeclSpace parent, FullNamedExpression type, int mod, bool is_iface,
6892                                  MemberName name, Attributes attrs, Accessor get_block,
6893                                  Accessor set_block, bool define_set_first)
6894                         : this (parent, type, mod, is_iface, name, attrs, get_block, set_block,
6895                                 define_set_first, null)
6896                 {
6897                 }
6898                 
6899                 public Property (DeclSpace parent, FullNamedExpression type, int mod, bool is_iface,
6900                                  MemberName name, Attributes attrs, Accessor get_block,
6901                                  Accessor set_block, bool define_set_first, Block current_block)
6902                         : base (parent, type, mod,
6903                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6904                                 is_iface, name, attrs, define_set_first)
6905                 {
6906                         if (!is_iface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
6907                                 get_block != null && get_block.Block == null &&
6908                                 set_block != null && set_block.Block == null) {
6909                                 if (RootContext.Version <= LanguageVersion.ISO_2)
6910                                         Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
6911                                 
6912                                 CreateAutomaticProperty (current_block, get_block, set_block);
6913                         }
6914
6915                         if (get_block == null)
6916                                 Get = new GetMethod (this);
6917                         else
6918                                 Get = new GetMethod (this, get_block);
6919
6920                         if (set_block == null)
6921                                 Set = new SetMethod (this);
6922                         else
6923                                 Set = new SetMethod (this, set_block);
6924                 }
6925
6926                 public override bool Define ()
6927                 {
6928                         if (!DoDefineBase ())
6929                                 return false;
6930
6931                         if (!base.Define ())
6932                                 return false;
6933
6934                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6935
6936                         if (!DefineAccessors ())
6937                                 return false;
6938
6939                         if (!CheckBase ())
6940                                 return false;
6941
6942                         // FIXME - PropertyAttributes.HasDefault ?
6943
6944                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6945                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, null);
6946
6947                         if (!Get.IsDummy) {
6948                                 PropertyBuilder.SetGetMethod (GetBuilder);
6949                                 Parent.MemberCache.AddMember (GetBuilder, Get);
6950                         }
6951
6952                         if (!Set.IsDummy) {
6953                                 PropertyBuilder.SetSetMethod (SetBuilder);
6954                                 Parent.MemberCache.AddMember (SetBuilder, Set);
6955                         }
6956                         
6957                         TypeManager.RegisterProperty (PropertyBuilder, this);
6958                         Parent.MemberCache.AddMember (PropertyBuilder, this);
6959                         return true;
6960                 }
6961
6962                 protected override PropertyInfo ResolveBaseProperty ()
6963                 {
6964                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6965                                 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
6966                 }
6967         }
6968
6969         /// </summary>
6970         ///  Gigantic workaround  for lameness in SRE follows :
6971         ///  This class derives from EventInfo and attempts to basically
6972         ///  wrap around the EventBuilder so that FindMembers can quickly
6973         ///  return this in it search for members
6974         /// </summary>
6975         public class MyEventBuilder : EventInfo {
6976                 
6977                 //
6978                 // We use this to "point" to our Builder which is
6979                 // not really a MemberInfo
6980                 //
6981                 EventBuilder MyBuilder;
6982                 
6983                 //
6984                 // We "catch" and wrap these methods
6985                 //
6986                 MethodInfo raise, remove, add;
6987
6988                 EventAttributes attributes;
6989                 Type declaring_type, reflected_type, event_type;
6990                 string name;
6991
6992                 Event my_event;
6993
6994                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6995                 {
6996                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6997
6998                         // And now store the values in our own fields.
6999                         
7000                         declaring_type = type_builder;
7001
7002                         reflected_type = type_builder;
7003                         
7004                         attributes = event_attr;
7005                         this.name = name;
7006                         my_event = ev;
7007                         this.event_type = event_type;
7008                 }
7009                 
7010                 //
7011                 // Methods that you have to override.  Note that you only need 
7012                 // to "implement" the variants that take the argument (those are
7013                 // the "abstract" methods, the others (GetAddMethod()) are 
7014                 // regular.
7015                 //
7016                 public override MethodInfo GetAddMethod (bool nonPublic)
7017                 {
7018                         return add;
7019                 }
7020                 
7021                 public override MethodInfo GetRemoveMethod (bool nonPublic)
7022                 {
7023                         return remove;
7024                 }
7025                 
7026                 public override MethodInfo GetRaiseMethod (bool nonPublic)
7027                 {
7028                         return raise;
7029                 }
7030                 
7031                 //
7032                 // These methods make "MyEventInfo" look like a Builder
7033                 //
7034                 public void SetRaiseMethod (MethodBuilder raiseMethod)
7035                 {
7036                         raise = raiseMethod;
7037                         MyBuilder.SetRaiseMethod (raiseMethod);
7038                 }
7039
7040                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
7041                 {
7042                         remove = removeMethod;
7043                         MyBuilder.SetRemoveOnMethod (removeMethod);
7044                 }
7045
7046                 public void SetAddOnMethod (MethodBuilder addMethod)
7047                 {
7048                         add = addMethod;
7049                         MyBuilder.SetAddOnMethod (addMethod);
7050                 }
7051
7052                 public void SetCustomAttribute (CustomAttributeBuilder cb)
7053                 {
7054                         MyBuilder.SetCustomAttribute (cb);
7055                 }
7056                 
7057                 public override object [] GetCustomAttributes (bool inherit)
7058                 {
7059                         // FIXME : There's nothing which can be seemingly done here because
7060                         // we have no way of getting at the custom attribute objects of the
7061                         // EventBuilder !
7062                         return null;
7063                 }
7064
7065                 public override object [] GetCustomAttributes (Type t, bool inherit)
7066                 {
7067                         // FIXME : Same here !
7068                         return null;
7069                 }
7070
7071                 public override bool IsDefined (Type t, bool b)
7072                 {
7073                         return true;
7074                 }
7075
7076                 public override EventAttributes Attributes {
7077                         get {
7078                                 return attributes;
7079                         }
7080                 }
7081
7082                 public override string Name {
7083                         get {
7084                                 return name;
7085                         }
7086                 }
7087
7088                 public override Type DeclaringType {
7089                         get {
7090                                 return declaring_type;
7091                         }
7092                 }
7093
7094                 public override Type ReflectedType {
7095                         get {
7096                                 return reflected_type;
7097                         }
7098                 }
7099
7100                 public Type EventType {
7101                         get {
7102                                 return event_type;
7103                         }
7104                 }
7105                 
7106                 public void SetUsed ()
7107                 {
7108                         if (my_event != null) {
7109 //                              my_event.SetAssigned ();
7110                                 my_event.SetMemberIsUsed ();
7111                         }
7112                 }
7113         }
7114         
7115         /// <summary>
7116         /// For case when event is declared like property (with add and remove accessors).
7117         /// </summary>
7118         public class EventProperty: Event {
7119                 abstract class AEventPropertyAccessor : AEventAccessor
7120                 {
7121                         readonly ArrayList anonymous_methods;
7122
7123                         public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
7124                                 base (method, accessor, prefix)
7125                         {
7126                                 this.anonymous_methods = accessor.AnonymousMethods;
7127                         }
7128
7129                         public override MethodBuilder Define (DeclSpace ds)
7130                         {
7131                                 CheckAbstractAndExtern (block != null);
7132                                 return base.Define (ds);
7133                         }
7134                         
7135                         public override string GetSignatureForError ()
7136                         {
7137                                 return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
7138                         }
7139
7140                         public override bool ResolveMembers ()
7141                         {
7142                                 if (anonymous_methods == null)
7143                                         return true;
7144
7145                                 foreach (AnonymousMethodExpression ame in anonymous_methods) {
7146                                         if (!ame.CreateAnonymousHelpers ())
7147                                                 return false;
7148                                 }
7149
7150                                 return true;
7151                         }
7152
7153                 }
7154
7155                 sealed class AddDelegateMethod: AEventPropertyAccessor
7156                 {
7157                         public AddDelegateMethod (Event method, Accessor accessor):
7158                                 base (method, accessor, "add_")
7159                         {
7160                         }
7161
7162                         protected override MethodInfo DelegateMethodInfo {
7163                                 get {
7164                                         return TypeManager.delegate_combine_delegate_delegate;
7165                                 }
7166                         }
7167                 }
7168
7169                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
7170                 {
7171                         public RemoveDelegateMethod (Event method, Accessor accessor):
7172                                 base (method, accessor, "remove_")
7173                         {
7174                         }
7175
7176                         protected override MethodInfo DelegateMethodInfo {
7177                                 get {
7178                                         return TypeManager.delegate_remove_delegate_delegate;
7179                                 }
7180                         }
7181                 }
7182
7183
7184                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
7185
7186                 public EventProperty (DeclSpace parent, FullNamedExpression type, int mod_flags,
7187                                       bool is_iface, MemberName name,
7188                                       Attributes attrs, Accessor add, Accessor remove)
7189                         : base (parent, type, mod_flags, is_iface, name, attrs)
7190                 {
7191                         Add = new AddDelegateMethod (this, add);
7192                         Remove = new RemoveDelegateMethod (this, remove);
7193                 }
7194
7195                 public override bool Define()
7196                 {
7197                         if (!base.Define ())
7198                                 return false;
7199
7200                         SetMemberIsUsed ();
7201                         return true;
7202                 }
7203
7204                 public override string[] ValidAttributeTargets {
7205                         get {
7206                                 return attribute_targets;
7207                         }
7208                 }
7209         }
7210
7211         /// <summary>
7212         /// Event is declared like field.
7213         /// </summary>
7214         public class EventField : Event {
7215                 abstract class EventFieldAccessor : AEventAccessor
7216                 {
7217                         protected EventFieldAccessor (Event method, string prefix)
7218                                 : base (method, prefix)
7219                         {
7220                         }
7221
7222                         protected override void EmitMethod(DeclSpace parent)
7223                         {
7224                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7225                                         return;
7226
7227                                 MethodBuilder mb = method_data.MethodBuilder;
7228                                 ILGenerator ig = mb.GetILGenerator ();
7229
7230                                 // TODO: because we cannot use generics yet
7231                                 FieldInfo field_info = ((EventField)method).FieldBuilder;
7232
7233                                 if (parent is Class) {
7234                                         mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7235                                 }
7236                                 
7237                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7238                                         ig.Emit (OpCodes.Ldsfld, field_info);
7239                                         ig.Emit (OpCodes.Ldarg_0);
7240                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7241                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7242                                         ig.Emit (OpCodes.Stsfld, field_info);
7243                                 } else {
7244                                         ig.Emit (OpCodes.Ldarg_0);
7245                                         ig.Emit (OpCodes.Ldarg_0);
7246                                         ig.Emit (OpCodes.Ldfld, field_info);
7247                                         ig.Emit (OpCodes.Ldarg_1);
7248                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7249                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7250                                         ig.Emit (OpCodes.Stfld, field_info);
7251                                 }
7252                                 ig.Emit (OpCodes.Ret);
7253                         }
7254                 }
7255
7256                 sealed class AddDelegateMethod: EventFieldAccessor
7257                 {
7258                         public AddDelegateMethod (Event method):
7259                                 base (method, "add_")
7260                         {
7261                         }
7262
7263                         protected override MethodInfo DelegateMethodInfo {
7264                                 get {
7265                                         return TypeManager.delegate_combine_delegate_delegate;
7266                                 }
7267                         }
7268                 }
7269
7270                 sealed class RemoveDelegateMethod: EventFieldAccessor
7271                 {
7272                         public RemoveDelegateMethod (Event method):
7273                                 base (method, "remove_")
7274                         {
7275                         }
7276
7277                         protected override MethodInfo DelegateMethodInfo {
7278                                 get {
7279                                         return TypeManager.delegate_remove_delegate_delegate;
7280                                 }
7281                         }
7282                 }
7283
7284
7285                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7286                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7287
7288                 public FieldBuilder FieldBuilder;
7289                 public Expression Initializer;
7290
7291                 public EventField (DeclSpace parent, FullNamedExpression type, int mod_flags,
7292                                    bool is_iface, MemberName name,
7293                                    Attributes attrs)
7294                         : base (parent, type, mod_flags, is_iface, name, attrs)
7295                 {
7296                         Add = new AddDelegateMethod (this);
7297                         Remove = new RemoveDelegateMethod (this);
7298                 }
7299
7300                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7301                 {
7302                         if (a.Target == AttributeTargets.Field) {
7303                                 FieldBuilder.SetCustomAttribute (cb);
7304                                 return;
7305                         }
7306
7307                         if (a.Target == AttributeTargets.Method) {
7308                                 int errors = Report.Errors;
7309                                 Add.ApplyAttributeBuilder (a, cb);
7310                                 if (errors == Report.Errors)
7311                                         Remove.ApplyAttributeBuilder (a, cb);
7312                                 return;
7313                         }
7314
7315                         base.ApplyAttributeBuilder (a, cb);
7316                 }
7317
7318                 public override bool Define()
7319                 {
7320                         if (!base.Define ())
7321                                 return false;
7322
7323                         if (IsInterface)
7324                                 return true;
7325
7326                         // FIXME: We are unable to detect whether generic event is used because
7327                         // we are using FieldExpr instead of EventExpr for event access in that
7328                         // case.  When this issue will be fixed this hack can be removed.
7329                         if (TypeManager.IsGenericType (MemberType))
7330                                 SetMemberIsUsed();
7331
7332                         if (Add.IsInterfaceImplementation)
7333                                 SetMemberIsUsed ();
7334
7335                         FieldBuilder = Parent.TypeBuilder.DefineField (
7336                                 Name, MemberType,
7337                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7338                         TypeManager.RegisterEventField (EventBuilder, this);
7339
7340                         if (Initializer != null) {
7341                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7342                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7343                                                 GetSignatureForError ());
7344                                         return false;
7345                                 }
7346
7347                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
7348                                         new FieldInitializer (FieldBuilder, Initializer));
7349                         }
7350
7351                         return true;
7352                 }
7353
7354                 public override string[] ValidAttributeTargets 
7355                 {
7356                         get {
7357                                 return IsInterface ? attribute_targets_interface : attribute_targets;
7358                         }
7359                 }
7360         }
7361
7362         public abstract class Event : PropertyBasedMember {
7363                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7364                 {
7365                         protected readonly Event method;
7366                         ImplicitParameter param_attr;
7367
7368                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7369
7370                         protected AEventAccessor (Event method, string prefix)
7371                                 : base (method, prefix)
7372                         {
7373                                 this.method = method;
7374                                 this.ModFlags = method.ModFlags;
7375                         }
7376
7377                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7378                                 : base (method, accessor, prefix)
7379                         {
7380                                 this.method = method;
7381                                 this.ModFlags = method.ModFlags;
7382                         }
7383
7384                         public override Iterator Iterator {
7385                                 get { return null; }
7386                         }
7387
7388                         public bool IsInterfaceImplementation {
7389                                 get { return method_data.implementing != null; }
7390                         }
7391
7392                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7393                         {
7394                                 if (a.IsInternalMethodImplAttribute) {
7395                                         method.is_external_implementation = true;
7396                                 }
7397
7398                                 base.ApplyAttributeBuilder (a, cb);
7399                         }
7400
7401                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7402                         {
7403                                 if (a.Target == AttributeTargets.Parameter) {
7404                                         if (param_attr == null)
7405                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7406
7407                                         param_attr.ApplyAttributeBuilder (a, cb);
7408                                         return;
7409                                 }
7410
7411                                 base.ApplyAttributeBuilder (a, cb);
7412                         }
7413
7414                         public override AttributeTargets AttributeTargets {
7415                                 get {
7416                                         return AttributeTargets.Method;
7417                                 }
7418                         }
7419
7420                         public override bool IsClsComplianceRequired ()
7421                         {
7422                                 return method.IsClsComplianceRequired ();
7423                         }
7424
7425                         public virtual MethodBuilder Define (DeclSpace parent)
7426                         {
7427                                 method_data = new MethodData (method, method.ModFlags,
7428                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7429
7430                                 if (!method_data.Define (parent, method.GetFullName (MemberName)))
7431                                         return null;
7432
7433                                 MethodBuilder mb = method_data.MethodBuilder;
7434                                 ParameterInfo.ApplyAttributes (mb);
7435                                 return mb;
7436                         }
7437
7438                         protected abstract MethodInfo DelegateMethodInfo { get; }
7439
7440                         public override Type ReturnType {
7441                                 get {
7442                                         return TypeManager.void_type;
7443                                 }
7444                         }
7445
7446                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7447                         {
7448                                 return new EmitContext (
7449                                         ds, method.Parent, Location, ig, ReturnType,
7450                                         method.ModFlags, false);
7451                         }
7452
7453                         public override ObsoleteAttribute GetObsoleteAttribute ()
7454                         {
7455                                 return method.GetObsoleteAttribute ();
7456                         }
7457
7458                         public override string[] ValidAttributeTargets {
7459                                 get {
7460                                         return attribute_targets;
7461                                 }
7462                         }
7463
7464                         public override Parameters ParameterInfo {
7465                                 get {
7466                                         return method.parameters;
7467                                 }
7468                         }
7469                 }
7470
7471
7472                 const int AllowedModifiers =
7473                         Modifiers.NEW |
7474                         Modifiers.PUBLIC |
7475                         Modifiers.PROTECTED |
7476                         Modifiers.INTERNAL |
7477                         Modifiers.PRIVATE |
7478                         Modifiers.STATIC |
7479                         Modifiers.VIRTUAL |
7480                         Modifiers.SEALED |
7481                         Modifiers.OVERRIDE |
7482                         Modifiers.UNSAFE |
7483                         Modifiers.ABSTRACT |
7484                         Modifiers.EXTERN;
7485
7486                 const int AllowedInterfaceModifiers =
7487                         Modifiers.NEW;
7488
7489                 public AEventAccessor Add, Remove;
7490                 public MyEventBuilder     EventBuilder;
7491                 public MethodBuilder AddBuilder, RemoveBuilder;
7492
7493                 Parameters parameters;
7494
7495                 protected Event (DeclSpace parent, FullNamedExpression type, int mod_flags,
7496                               bool is_iface, MemberName name, Attributes attrs)
7497                         : base (parent, null, type, mod_flags,
7498                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7499                                 name, attrs)
7500                 {
7501                 }
7502
7503                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7504                 {
7505                         if ((a.HasSecurityAttribute)) {
7506                                 a.Error_InvalidSecurityParent ();
7507                                 return;
7508                         }
7509                         
7510                         EventBuilder.SetCustomAttribute (cb);
7511                 }
7512
7513                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7514                 {
7515                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7516                 }
7517
7518                 public override AttributeTargets AttributeTargets {
7519                         get {
7520                                 return AttributeTargets.Event;
7521                         }
7522                 }
7523
7524                 public override bool Define ()
7525                 {
7526                         if (!DoDefineBase ())
7527                                 return false;
7528
7529                         if (!DoDefine ())
7530                                 return false;
7531
7532                         if (!TypeManager.IsDelegateType (MemberType)) {
7533                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7534                                 return false;
7535                         }
7536
7537                         parameters = Parameters.CreateFullyResolved (
7538                                 new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location));
7539
7540                         if (!CheckBase ())
7541                                 return false;
7542
7543                         if (TypeManager.delegate_combine_delegate_delegate == null) {
7544                                 TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
7545                                         TypeManager.delegate_type, "Combine", Location,
7546                                         TypeManager.delegate_type, TypeManager.delegate_type);
7547                         }
7548                         if (TypeManager.delegate_remove_delegate_delegate == null) {
7549                                 TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
7550                                         TypeManager.delegate_type, "Remove", Location,
7551                                         TypeManager.delegate_type, TypeManager.delegate_type);
7552                         }
7553
7554                         //
7555                         // Now define the accessors
7556                         //
7557
7558                         AddBuilder = Add.Define (Parent);
7559                         if (AddBuilder == null)
7560                                 return false;
7561
7562                         RemoveBuilder = Remove.Define (Parent);
7563                         if (RemoveBuilder == null)
7564                                 return false;
7565
7566                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7567                         EventBuilder.SetAddOnMethod (AddBuilder);
7568                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7569
7570                         Parent.MemberCache.AddMember (EventBuilder, this);
7571                         Parent.MemberCache.AddMember (AddBuilder, Add);
7572                         Parent.MemberCache.AddMember (RemoveBuilder, Remove);
7573                         
7574                         return true;
7575                 }
7576
7577                 public override void Emit ()
7578                 {
7579                         if (OptAttributes != null) {
7580                                 OptAttributes.Emit ();
7581                         }
7582
7583                         Add.Emit (Parent);
7584                         Remove.Emit (Parent);
7585
7586                         base.Emit ();
7587                 }
7588
7589                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7590                 {
7591                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7592                                 Parent.TypeBuilder, Name);
7593
7594                         if (mi == null)
7595                                 return null;
7596
7597                         ParameterData pd = TypeManager.GetParameterData (mi);
7598                         base_ret_type = pd.ParameterType (0);
7599                         return mi;
7600                 }
7601
7602                 //
7603                 //   Represents header string for documentation comment.
7604                 //
7605                 public override string DocCommentHeader {
7606                         get { return "E:"; }
7607                 }
7608         }
7609
7610  
7611         public class Indexer : PropertyBase
7612         {
7613                 class GetIndexerMethod : GetMethod
7614                 {
7615                         public GetIndexerMethod (PropertyBase method):
7616                                 base (method)
7617                         {
7618                         }
7619
7620                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7621                                 base (method, accessor)
7622                         {
7623                         }
7624                         
7625                         public override bool EnableOverloadChecks (MemberCore overload)
7626                         {
7627                                 if (base.EnableOverloadChecks (overload)) {
7628                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7629                                         return true;
7630                                 }
7631
7632                                 return false;
7633                         }                       
7634
7635                         public override Parameters ParameterInfo {
7636                                 get {
7637                                         return ((Indexer)method).parameters;
7638                                 }
7639                         }
7640                 }
7641
7642                 class SetIndexerMethod: SetMethod
7643                 {
7644                         public SetIndexerMethod (PropertyBase method):
7645                                 base (method)
7646                         {
7647                         }
7648
7649                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7650                                 base (method, accessor)
7651                         {
7652                         }
7653
7654                         protected override void DefineParameters ()
7655                         {
7656                                 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7657                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7658                         }
7659                         
7660                         public override bool EnableOverloadChecks (MemberCore overload)
7661                         {
7662                                 if (base.EnableOverloadChecks (overload)) {
7663                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7664                                         return true;
7665                                 }
7666
7667                                 return false;
7668                         }                       
7669                 }
7670
7671                 const int AllowedModifiers =
7672                         Modifiers.NEW |
7673                         Modifiers.PUBLIC |
7674                         Modifiers.PROTECTED |
7675                         Modifiers.INTERNAL |
7676                         Modifiers.PRIVATE |
7677                         Modifiers.VIRTUAL |
7678                         Modifiers.SEALED |
7679                         Modifiers.OVERRIDE |
7680                         Modifiers.UNSAFE |
7681                         Modifiers.EXTERN |
7682                         Modifiers.ABSTRACT;
7683
7684                 const int AllowedInterfaceModifiers =
7685                         Modifiers.NEW;
7686
7687                 public readonly Parameters parameters;
7688
7689                 public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, int mod,
7690                                 bool is_iface, Parameters parameters, Attributes attrs,
7691                                 Accessor get_block, Accessor set_block, bool define_set_first)
7692                         : base (parent, type, mod,
7693                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7694                                 is_iface, name, attrs, define_set_first)
7695                 {
7696                         if (type == TypeManager.system_void_expr)
7697                                 Report.Error (620, name.Location, "An indexer return type cannot be `void'");
7698                         
7699                         this.parameters = parameters;
7700
7701                         if (get_block == null)
7702                                 Get = new GetIndexerMethod (this);
7703                         else
7704                                 Get = new GetIndexerMethod (this, get_block);
7705
7706                         if (set_block == null)
7707                                 Set = new SetIndexerMethod (this);
7708                         else
7709                                 Set = new SetIndexerMethod (this, set_block);
7710                 }
7711                 
7712                 public override bool Define ()
7713                 {
7714                         if (!DoDefineBase ())
7715                                 return false;
7716
7717                         if (!base.Define ())
7718                                 return false;
7719
7720                         if (!DefineParameters (parameters))
7721                                 return false;
7722
7723                         if (OptAttributes != null && TypeManager.indexer_name_type != null) {
7724                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7725                                 if (indexer_attr != null) {
7726                                         // Remove the attribute from the list because it is not emitted
7727                                         OptAttributes.Attrs.Remove (indexer_attr);
7728
7729                                         string name = indexer_attr.GetIndexerAttributeValue ();
7730                                         if (name == null)
7731                                                 return false;
7732
7733                                         ShortName = name;
7734
7735                                         if (IsExplicitImpl) {
7736                                                 Report.Error (415, indexer_attr.Location,
7737                                                               "The `IndexerName' attribute is valid only on an " +
7738                                                               "indexer that is not an explicit interface member declaration");
7739                                                 return false;
7740                                         }
7741
7742                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7743                                                 Report.Error (609, indexer_attr.Location,
7744                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7745                                                 return false;
7746                                         }
7747                                 }
7748                         }
7749
7750                         if (InterfaceType != null) {
7751                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7752                                 if (base_IndexerName != Name)
7753                                         ShortName = base_IndexerName;
7754                         }
7755
7756                         if (!Parent.PartialContainer.AddMember (this) ||
7757                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7758                                 return false;
7759
7760                         if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
7761                                 if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, parameters))
7762                                         return false;
7763                         }
7764
7765                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7766                         
7767                         if (!DefineAccessors ())
7768                                 return false;
7769
7770                         if (!CheckBase ())
7771                                 return false;
7772
7773                         if (!Get.IsDummy) {
7774                                 // Setup iterator if we are one
7775                                 if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
7776                                         Iterator iterator = Iterator.CreateIterator (Get, Parent, null, ModFlags);
7777                                         if (iterator == null)
7778                                                 return false;
7779                                 }
7780                         }
7781
7782                         //
7783                         // Now name the parameters
7784                         //
7785                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7786                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, parameters.Types);
7787
7788                         if (!Get.IsDummy) {
7789                                 PropertyBuilder.SetGetMethod (GetBuilder);
7790                                 Parent.MemberCache.AddMember (GetBuilder, Get);
7791                         }
7792
7793                         if (!Set.IsDummy) {
7794                                 PropertyBuilder.SetSetMethod (SetBuilder);
7795                                 Parent.MemberCache.AddMember (SetBuilder, Set);
7796                         }
7797                                 
7798                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7799                         Parent.MemberCache.AddMember (PropertyBuilder, this);
7800                         return true;
7801                 }
7802
7803                 public override bool EnableOverloadChecks (MemberCore overload)
7804                 {
7805                         if (overload is Indexer) {
7806                                 caching_flags |= Flags.MethodOverloadsExist;
7807                                 return true;
7808                         }
7809
7810                         return false;
7811                 }
7812
7813                 public override string GetDocCommentName (DeclSpace ds)
7814                 {
7815                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7816                 }
7817
7818                 public override string GetSignatureForError ()
7819                 {
7820                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7821                         if (MemberName.Left != null) {
7822                                 sb.Append ('.');
7823                                 sb.Append (MemberName.Left.GetSignatureForError ());
7824                         }
7825
7826                         sb.Append (".this");
7827                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7828                         return sb.ToString ();
7829                 }
7830
7831                 protected override PropertyInfo ResolveBaseProperty ()
7832                 {
7833                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7834                                 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7835                 }
7836
7837                 protected override bool VerifyClsCompliance ()
7838                 {
7839                         if (!base.VerifyClsCompliance ())
7840                                 return false;
7841
7842                         parameters.VerifyClsCompliance ();
7843                         return true;
7844                 }
7845         }
7846
7847         public class Operator : MethodOrOperator, IAnonymousHost {
7848
7849                 const int AllowedModifiers =
7850                         Modifiers.PUBLIC |
7851                         Modifiers.UNSAFE |
7852                         Modifiers.EXTERN |
7853                         Modifiers.STATIC;
7854
7855                 public enum OpType : byte {
7856
7857                         // Unary operators
7858                         LogicalNot,
7859                         OnesComplement,
7860                         Increment,
7861                         Decrement,
7862                         True,
7863                         False,
7864
7865                         // Unary and Binary operators
7866                         Addition,
7867                         Subtraction,
7868
7869                         UnaryPlus,
7870                         UnaryNegation,
7871                         
7872                         // Binary operators
7873                         Multiply,
7874                         Division,
7875                         Modulus,
7876                         BitwiseAnd,
7877                         BitwiseOr,
7878                         ExclusiveOr,
7879                         LeftShift,
7880                         RightShift,
7881                         Equality,
7882                         Inequality,
7883                         GreaterThan,
7884                         LessThan,
7885                         GreaterThanOrEqual,
7886                         LessThanOrEqual,
7887
7888                         // Implicit and Explicit
7889                         Implicit,
7890                         Explicit,
7891
7892                         // Just because of enum
7893                         TOP
7894                 };
7895
7896                 public readonly OpType OperatorType;
7897
7898                 static readonly string [] [] names;
7899
7900                 static Operator ()
7901                 {
7902                         names = new string[(int)OpType.TOP][];
7903                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
7904                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
7905                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
7906                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
7907                         names [(int) OpType.True] = new string [] { "true", "op_True" };
7908                         names [(int) OpType.False] = new string [] { "false", "op_False" };
7909                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
7910                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
7911                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
7912                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
7913                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
7914                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
7915                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
7916                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
7917                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
7918                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
7919                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
7920                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
7921                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
7922                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
7923                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
7924                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
7925                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
7926                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
7927                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
7928                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
7929                 }
7930                 
7931                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
7932                                  int mod_flags, Parameters parameters,
7933                                  ToplevelBlock block, Attributes attrs, Location loc)
7934                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7935                                 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7936                 {
7937                         OperatorType = type;
7938                         Block = block;
7939                 }
7940
7941                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7942                 {
7943                         if (a.Type == TypeManager.conditional_attribute_type) {
7944                                 Error_ConditionalAttributeIsNotValid ();
7945                                 return;
7946                         }
7947
7948                         base.ApplyAttributeBuilder (a, cb);
7949                 }
7950                 
7951                 public override bool Define ()
7952                 {
7953                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7954                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7955                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7956                                 return false;
7957                         }
7958
7959                         if (!base.Define ())
7960                                 return false;
7961
7962                         // imlicit and explicit operator of same types are not allowed
7963                         if (OperatorType == OpType.Explicit)
7964                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), Parameters);
7965                         else if (OperatorType == OpType.Implicit)
7966                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters);
7967
7968                         if (MemberType == TypeManager.void_type) {
7969                                 Report.Error (590, Location, "User-defined operators cannot return void");
7970                                 return false;
7971                         }
7972
7973                         Type declaring_type = MethodData.DeclaringType;
7974                         Type return_type = MemberType;
7975                         Type first_arg_type = ParameterTypes [0];
7976                         
7977                         Type first_arg_type_unwrap = first_arg_type;
7978                         if (TypeManager.IsNullableType (first_arg_type))
7979                                 first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0];
7980                         
7981                         Type return_type_unwrap = return_type;
7982                         if (TypeManager.IsNullableType (return_type))
7983                                 return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];                    
7984
7985                         //
7986                         // Rules for conversion operators
7987                         //
7988                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7989                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type){
7990                                         Report.Error (555, Location,
7991                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7992                                         return false;
7993                                 }
7994                                 
7995                                 Type conv_type;
7996                                 if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
7997                                         conv_type = first_arg_type;
7998                                 } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
7999                                         conv_type = return_type;
8000                                 } else {
8001                                         Report.Error (556, Location, 
8002                                                 "User-defined conversion must convert to or from the enclosing type");
8003                                         return false;
8004                                 }
8005
8006                                 //
8007                                 // Because IsInterface and IsClass are not supported
8008                                 //
8009                                 if (!TypeManager.IsGenericParameter (conv_type)) {
8010                                         if (conv_type.IsInterface) {
8011                                                 Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
8012                                                         GetSignatureForError ());
8013                                                 return false;
8014                                         }
8015
8016                                         if (conv_type.IsClass) {
8017                                                 if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
8018                                                         Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
8019                                                                 GetSignatureForError ());
8020                                                         return false;
8021                                                 }
8022
8023                                                 if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
8024                                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
8025                                                                 GetSignatureForError ());
8026                                                         return false;
8027                                                 }
8028                                         }
8029                                 }
8030                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
8031                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
8032                                         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");
8033                                         return false;
8034                                 }
8035                         } else if (Parameters.Count == 1) {
8036                                 // Checks for Unary operators
8037
8038                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
8039                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
8040                                                 Report.Error (448, Location,
8041                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
8042                                                 return false;
8043                                         }
8044                                         if (first_arg_type != declaring_type) {
8045                                                 Report.Error (
8046                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
8047                                                 return false;
8048                                         }
8049                                 }
8050                                 
8051                                 if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)){
8052                                         Report.Error (562, Location,
8053                                                 "The parameter type of a unary operator must be the containing type");
8054                                         return false;
8055                                 }
8056                                 
8057                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
8058                                         if (return_type != TypeManager.bool_type){
8059                                                 Report.Error (
8060                                                         215, Location,
8061                                                         "The return type of operator True or False " +
8062                                                         "must be bool");
8063                                                 return false;
8064                                         }
8065                                 }
8066                                 
8067                         } else {
8068                                 // Checks for Binary operators
8069                                 
8070                                 if (first_arg_type != declaring_type &&
8071                                     ParameterTypes [1] != declaring_type){
8072                                         Report.Error (
8073                                                 563, Location,
8074                                                 "One of the parameters of a binary operator must " +
8075                                                 "be the containing type");
8076                                         return false;
8077                                 }
8078                         }
8079
8080                         return true;
8081                 }
8082
8083                 protected override bool DoDefine ()
8084                 {
8085                         if (!base.DoDefine ())
8086                                 return false;
8087
8088                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
8089                         return true;
8090                 }
8091                 
8092                 public override void Emit ()
8093                 {
8094                         base.Emit ();
8095
8096                         Parameters.ApplyAttributes (MethodBuilder);
8097
8098                         //
8099                         // abstract or extern methods have no bodies
8100                         //
8101                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
8102                                 return;
8103                         
8104                         EmitContext ec;
8105                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
8106                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
8107                         else
8108                                 ec = CreateEmitContext (Parent, null);
8109                         
8110                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
8111                         ec.EmitTopBlock (this, Block);
8112
8113                         if (source != null)
8114                                 source.CloseMethod ();
8115
8116                         Block = null;
8117                 }
8118
8119                 // Operator cannot be override
8120                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
8121                 {
8122                         return null;
8123                 }
8124
8125                 public static string GetName (OpType ot)
8126                 {
8127                         return names [(int) ot] [0];
8128                 }
8129
8130                 public static string GetName (string metadata_name)
8131                 {
8132                         for (int i = 0; i < names.Length; ++i) {
8133                                 if (names [i] [1] == metadata_name)
8134                                         return names [i] [0];
8135                         }
8136                         return null;
8137                 }
8138
8139                 public static string GetMetadataName (OpType ot)
8140                 {
8141                         return names [(int) ot] [1];
8142                 }
8143
8144                 public static string GetMetadataName (string name)
8145                 {
8146                         for (int i = 0; i < names.Length; ++i) {
8147                                 if (names [i] [0] == name)
8148                                         return names [i] [1];
8149                         }
8150                         return null;
8151                 }
8152
8153                 public OpType GetMatchingOperator ()
8154                 {
8155                         switch (OperatorType) {
8156                                 case OpType.Equality:
8157                                         return OpType.Inequality;
8158                                 case OpType.Inequality:
8159                                         return OpType.Equality;
8160                                 case OpType.True:
8161                                         return OpType.False;
8162                                 case OpType.False:
8163                                         return OpType.True;
8164                                 case OpType.GreaterThan:
8165                                         return OpType.LessThan;
8166                                 case OpType.LessThan:
8167                                         return OpType.GreaterThan;
8168                                 case OpType.GreaterThanOrEqual:
8169                                         return OpType.LessThanOrEqual;
8170                                 case OpType.LessThanOrEqual:
8171                                         return OpType.GreaterThanOrEqual;
8172                                 default:
8173                                         return OpType.TOP;
8174                         }
8175                 }
8176
8177                 public override string GetSignatureForError ()
8178                 {
8179                         StringBuilder sb = new StringBuilder ();
8180                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
8181                                 sb.AppendFormat ("{0}.{1} operator {2}",
8182                                         Parent.GetSignatureForError (), GetName (OperatorType), type_name.GetSignatureForError ());
8183                         }
8184                         else {
8185                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
8186                         }
8187
8188                         sb.Append (Parameters.GetSignatureForError ());
8189                         return sb.ToString ();
8190                 }
8191         }
8192
8193         //
8194         // This is used to compare method signatures
8195         //
8196         struct MethodSignature {
8197                 public string Name;
8198                 public Type RetType;
8199                 public Type [] Parameters;
8200                 
8201                 /// <summary>
8202                 ///    This delegate is used to extract methods which have the
8203                 ///    same signature as the argument
8204                 /// </summary>
8205                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8206                 
8207                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8208                 {
8209                         Name = name;
8210                         RetType = ret_type;
8211
8212                         if (parameters == null)
8213                                 Parameters = Type.EmptyTypes;
8214                         else
8215                                 Parameters = parameters;
8216                 }
8217
8218                 public override string ToString ()
8219                 {
8220                         string pars = "";
8221                         if (Parameters.Length != 0){
8222                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8223                                 for (int i = 0; i < Parameters.Length; i++){
8224                                         sb.Append (Parameters [i]);
8225                                         if (i+1 < Parameters.Length)
8226                                                 sb.Append (", ");
8227                                 }
8228                                 pars = sb.ToString ();
8229                         }
8230
8231                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8232                 }
8233                 
8234                 public override int GetHashCode ()
8235                 {
8236                         return Name.GetHashCode ();
8237                 }
8238
8239                 public override bool Equals (Object o)
8240                 {
8241                         MethodSignature other = (MethodSignature) o;
8242
8243                         if (other.Name != Name)
8244                                 return false;
8245
8246                         if (other.RetType != RetType)
8247                                 return false;
8248                         
8249                         if (Parameters == null){
8250                                 if (other.Parameters == null)
8251                                         return true;
8252                                 return false;
8253                         }
8254
8255                         if (other.Parameters == null)
8256                                 return false;
8257                         
8258                         int c = Parameters.Length;
8259                         if (other.Parameters.Length != c)
8260                                 return false;
8261
8262                         for (int i = 0; i < c; i++)
8263                                 if (other.Parameters [i] != Parameters [i])
8264                                         return false;
8265
8266                         return true;
8267                 }
8268
8269                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8270                 {
8271                         MethodSignature sig = (MethodSignature) filter_criteria;
8272
8273                         if (m.Name != sig.Name)
8274                                 return false;
8275
8276                         Type ReturnType;
8277                         MethodInfo mi = m as MethodInfo;
8278                         PropertyInfo pi = m as PropertyInfo;
8279
8280                         if (mi != null)
8281                                 ReturnType = mi.ReturnType;
8282                         else if (pi != null)
8283                                 ReturnType = pi.PropertyType;
8284                         else
8285                                 return false;
8286
8287                         //
8288                         // we use sig.RetType == null to mean `do not check the
8289                         // method return value.  
8290                         //
8291                         if (sig.RetType != null) {
8292                                 if (!TypeManager.IsEqual (ReturnType, sig.RetType))
8293                                         return false;
8294                         }
8295
8296                         Type [] args;
8297                         if (mi != null)
8298                                 args = TypeManager.GetParameterData (mi).Types;
8299                         else
8300                                 args = TypeManager.GetArgumentTypes (pi);
8301                         Type [] sigp = sig.Parameters;
8302
8303                         if (args.Length != sigp.Length)
8304                                 return false;
8305
8306                         for (int i = args.Length - 1; i >= 0; i--)
8307                                 if (!TypeManager.IsEqual (args [i], sigp [i]))
8308                                         return false;
8309
8310                         return true;
8311                 }
8312         }
8313 }
8314