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