2008-07-17 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / class.cs
1 //
2 // class.cs: Class and Struct handlers
3 //
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 //          Martin Baulig (martin@ximian.com)
6 //          Marek Safar (marek.safar@seznam.cz)
7 //
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 //
10 // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2004-2008 Novell, Inc
12 //
13 //
14 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
15 //
16 //      * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 //      have fixed a remaining problem: not every AddXXXX was adding a
18 //      fully qualified name.  
19 //
20 //      Now everyone registers a fully qualified name in the DeclSpace as
21 //      being defined instead of the partial name.  
22 //
23 //      Downsides: we are slower than we need to be due to the excess
24 //      copies and the names being registered this way.  
25 //
26 //      The reason for this is that we currently depend (on the corlib
27 //      bootstrap for instance) that types are fully qualified, because
28 //      we dump all the types in the namespace, and we should really have
29 //      types inserted into the proper namespace, so we can only store the
30 //      basenames in the defined_names array.
31 //
32 //
33 using System;
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Reflection;
37 using System.Reflection.Emit;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Security;
41 using System.Security.Permissions;
42 using System.Text;
43
44 #if BOOTSTRAP_WITH_OLDLIB || NET_2_1
45 using XmlElement = System.Object;
46 #else
47 using System.Xml;
48 #endif
49
50 using Mono.CompilerServices.SymbolWriter;
51
52 namespace Mono.CSharp {
53
54         public enum Kind {
55                 Root,
56                 Struct,
57                 Class,
58                 Interface,
59                 Enum,
60                 Delegate
61         }
62
63         /// <summary>
64         ///   This is the base class for structs and classes.  
65         /// </summary>
66         public abstract class TypeContainer : DeclSpace, IMemberContainer {
67
68                 public class MemberCoreArrayList: ArrayList
69                 {
70                         /// <summary>
71                         ///   Defines the MemberCore objects that are in this array
72                         /// </summary>
73                         public virtual void DefineContainerMembers ()
74                         {
75                                 foreach (MemberCore mc in this) {
76                                         try {
77                                                 mc.Define ();
78                                         } catch (Exception e) {
79                                                 throw new InternalErrorException (mc, e);
80                                         }
81                                 }
82                         }
83
84                         public virtual void Emit ()
85                         {
86                                 foreach (MemberCore mc in this)
87                                         mc.Emit ();
88                         }
89                 }
90
91                 public class OperatorArrayList: MemberCoreArrayList
92                 {
93                         TypeContainer container;
94
95                         public OperatorArrayList (TypeContainer container)
96                         {
97                                 this.container = container;
98                         }
99
100                         //
101                         // Checks that some operators come in pairs:
102                         //  == and !=
103                         // > and <
104                         // >= and <=
105                         // true and false
106                         //
107                         // They are matched based on the return type and the argument types
108                         //
109                         void CheckPairedOperators ()
110                         {
111                                 bool has_equality_or_inequality = false;
112                                 Operator[] operators = (Operator[]) ToArray (typeof (Operator));
113                                 bool [] has_pair = new bool [operators.Length];
114
115                                 for (int i = 0; i < Count; ++i) {
116                                         if (operators [i] == null)
117                                                 continue;
118
119                                         Operator o_a = operators [i];
120                                         Operator.OpType o_type = o_a.OperatorType;
121                                         if (o_type == Operator.OpType.Equality || o_type == Operator.OpType.Inequality)
122                                                 has_equality_or_inequality = true;
123
124                                         Operator.OpType matching_type = o_a.GetMatchingOperator ();
125                                         if (matching_type == Operator.OpType.TOP) {
126                                                 operators [i] = null;
127                                                 continue;
128                                         }
129         
130                                         for (int ii = 0; ii < Count; ++ii) {
131                                                 Operator o_b = operators [ii];
132                                                 if (o_b == null || o_b.OperatorType != matching_type)
133                                                         continue;
134
135                                                 if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
136                                                         continue;
137
138                                                 if (!TypeManager.IsEqual (o_a.ParameterTypes, o_b.ParameterTypes))
139                                                         continue;
140
141                                                 operators [i] = null;
142
143                                                 //
144                                                 // Used to ignore duplicate user conversions
145                                                 //
146                                                 has_pair [ii] = true;
147                                         }
148                                 }
149
150                                 for (int i = 0; i < Count; ++i) {
151                                         if (operators [i] == null || has_pair [i])
152                                                 continue;
153
154                                         Operator o = operators [i];
155                                         Report.Error (216, o.Location,
156                                                 "The operator `{0}' requires a matching operator `{1}' to also be defined",
157                                                 o.GetSignatureForError (), Operator.GetName (o.GetMatchingOperator ()));
158                                 }
159
160                                 if (has_equality_or_inequality && Report.WarningLevel > 2) {
161                                         if (container.Methods == null || !container.HasEquals)
162                                                 Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
163  
164                                         if (container.Methods == null || !container.HasGetHashCode)
165                                                 Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
166                                 }
167                         }
168
169                         public override void DefineContainerMembers ()
170                         {
171                                 base.DefineContainerMembers ();
172                                 CheckPairedOperators ();
173                         }
174                 }
175
176                 [Flags]
177                 enum CachedMethods
178                 {
179                         Equals                          = 1,
180                         GetHashCode                     = 1 << 1,
181                         HasStaticFieldInitializer       = 1 << 2
182                 }
183
184
185                 // Whether this is a struct, class or interface
186                 public readonly Kind Kind;
187
188                 // Holds a list of classes and structures
189                 protected ArrayList types;
190
191                 MemberCoreArrayList ordered_explicit_member_list;
192                 MemberCoreArrayList ordered_member_list;
193
194                 // Holds the list of properties
195                 MemberCoreArrayList properties;
196
197                 // Holds the list of delegates
198                 MemberCoreArrayList delegates;
199                 
200                 // Holds the list of constructors
201                 protected MemberCoreArrayList instance_constructors;
202
203                 // Holds the list of fields
204                 MemberCoreArrayList fields;
205
206                 // Holds a list of fields that have initializers
207                 protected ArrayList initialized_fields;
208
209                 // Holds a list of static fields that have initializers
210                 protected ArrayList initialized_static_fields;
211
212                 // Holds the list of constants
213                 protected MemberCoreArrayList constants;
214
215                 // Holds the methods.
216                 MemberCoreArrayList methods;
217
218                 // Holds the events
219                 protected MemberCoreArrayList events;
220
221                 // Holds the indexers
222                 ArrayList indexers;
223
224                 // Holds the operators
225                 MemberCoreArrayList operators;
226
227                 // Holds the compiler generated classes
228                 ArrayList compiler_generated;
229
230                 //
231                 // Pointers to the default constructor and the default static constructor
232                 //
233                 protected Constructor default_constructor;
234                 protected Constructor default_static_constructor;
235
236                 //
237                 // Points to the first non-static field added to the container.
238                 //
239                 // This is an arbitrary choice.  We are interested in looking at _some_ non-static field,
240                 // and the first one's as good as any.
241                 //
242                 FieldBase first_nonstatic_field = null;
243
244                 //
245                 // This one is computed after we can distinguish interfaces
246                 // from classes from the arraylist `type_bases' 
247                 //
248                 TypeExpr base_type;
249                 TypeExpr[] iface_exprs;
250                 Type GenericType;
251
252                 protected ArrayList type_bases;
253
254                 bool members_resolved;
255                 bool members_resolved_ok;
256                 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.Error (3015, 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.Error (3009, 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 #if GMCS_SOURCE
2509                                 Report.Warning (3005, 1, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2510 #else
2511                                 Report.Error (3005, mc.Location, "Identifier `{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
2512 #endif
2513                         }
2514                 }
2515
2516
2517                 /// <summary>
2518                 ///   Performs checks for an explicit interface implementation.  First it
2519                 ///   checks whether the `interface_type' is a base inteface implementation.
2520                 ///   Then it checks whether `name' exists in the interface type.
2521                 /// </summary>
2522                 public bool VerifyImplements (InterfaceMemberBase mb)
2523                 {
2524                         if (ifaces != null) {
2525                                 foreach (Type t in ifaces){
2526                                         if (TypeManager.IsEqual (t, mb.InterfaceType))
2527                                                 return true;
2528                                 }
2529                         }
2530                         
2531                         Report.SymbolRelatedToPreviousError (mb.InterfaceType);
2532                         Report.Error (540, mb.Location, "`{0}': containing type does not implement interface `{1}'",
2533                                 mb.GetSignatureForError (), TypeManager.CSharpName (mb.InterfaceType));
2534                         return false;
2535                 }
2536
2537                 public override Type LookupAnyGeneric (string typeName)
2538                 {
2539                         if (types != null) {
2540                                 foreach (TypeContainer tc in types) {
2541                                         if (!tc.IsGeneric)
2542                                                 continue;
2543
2544                                         int pos = tc.Basename.LastIndexOf ('`');
2545                                         if (pos == typeName.Length && String.Compare (typeName, 0, tc.Basename, 0, pos) == 0)
2546                                                 return tc.TypeBuilder;
2547                                 }
2548                         }
2549
2550                         return base.LookupAnyGeneric (typeName);
2551                 }
2552
2553                 public void Mark_HasEquals ()
2554                 {
2555                         cached_method |= CachedMethods.Equals;
2556                 }
2557
2558                 public void Mark_HasGetHashCode ()
2559                 {
2560                         cached_method |= CachedMethods.GetHashCode;
2561                 }
2562
2563                 /// <summary>
2564                 /// Method container contains Equals method
2565                 /// </summary>
2566                 public bool HasEquals {
2567                         get {
2568                                 return (cached_method & CachedMethods.Equals) != 0;
2569                         }
2570                 }
2571  
2572                 /// <summary>
2573                 /// Method container contains GetHashCode method
2574                 /// </summary>
2575                 public bool HasGetHashCode {
2576                         get {
2577                                 return (cached_method & CachedMethods.GetHashCode) != 0;
2578                         }
2579                 }
2580
2581                 public bool HasStaticFieldInitializer {
2582                         get {
2583                                 return (cached_method & CachedMethods.HasStaticFieldInitializer) != 0;
2584                         }
2585                         set {
2586                                 if (value)
2587                                         cached_method |= CachedMethods.HasStaticFieldInitializer;
2588                                 else
2589                                         cached_method &= ~CachedMethods.HasStaticFieldInitializer;
2590                         }
2591                 }
2592
2593                 //
2594                 // IMemberContainer
2595                 //
2596
2597                 string IMemberContainer.Name {
2598                         get {
2599                                 return Name;
2600                         }
2601                 }
2602
2603                 Type IMemberContainer.Type {
2604                         get {
2605                                 return TypeBuilder;
2606                         }
2607                 }
2608
2609                 bool IMemberContainer.IsInterface {
2610                         get {
2611                                 return Kind == Kind.Interface;
2612                         }
2613                 }
2614
2615                 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
2616                 {
2617                         BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
2618
2619                         if (GenericType != null)
2620                                 return TypeManager.FindMembers (GenericType, mt, new_bf,
2621                                                                 null, null);
2622                         else
2623                                 return FindMembers (mt, new_bf, null, null);
2624                 }
2625
2626                 //
2627                 // Generates xml doc comments (if any), and if required,
2628                 // handle warning report.
2629                 //
2630                 internal override void GenerateDocComment (DeclSpace ds)
2631                 {
2632                         DocUtil.GenerateTypeDocComment (this, ds);
2633                 }
2634
2635                 public override string DocCommentHeader {
2636                         get { return "T:"; }
2637                 }
2638
2639                 public MemberCache BaseCache {
2640                         get {
2641                                 if (base_cache != null)
2642                                         return base_cache;
2643                                 if (TypeBuilder.BaseType != null)
2644                                         base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
2645                                 if (TypeBuilder.IsInterface)
2646                                         base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
2647                                 return base_cache;
2648                         }
2649                 }
2650         }
2651
2652         public abstract class ClassOrStruct : TypeContainer {
2653                 ListDictionary declarative_security;
2654
2655                 public ClassOrStruct (NamespaceEntry ns, DeclSpace parent,
2656                                       MemberName name, Attributes attrs, Kind kind)
2657                         : base (ns, parent, name, attrs, kind)
2658                 {
2659                 }
2660
2661                 protected override bool AddToContainer (MemberCore symbol, string name)
2662                 {
2663                         if (name == MemberName.Name) {
2664                                 if (symbol is TypeParameter) {
2665                                         Report.Error (694, symbol.Location,
2666                                                       "Type parameter `{0}' has same name as " +
2667                                                       "containing type, or method", name);
2668                                         return false;
2669                                 }
2670
2671                                 Report.SymbolRelatedToPreviousError (this);
2672                                 Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type",
2673                                         symbol.GetSignatureForError ());
2674                                 return false;
2675                         }
2676
2677                         return base.AddToContainer (symbol, name);
2678                 }
2679
2680                 public override void VerifyMembers ()
2681                 {
2682                         base.VerifyMembers ();
2683
2684                         if ((events != null) && Report.WarningLevel >= 3) {
2685                                 foreach (Event e in events){
2686                                         // Note: The event can be assigned from same class only, so we can report
2687                                         // this warning for all accessibility modes
2688                                         if ((e.caching_flags & Flags.IsUsed) == 0)
2689                                                 Report.Warning (67, 3, e.Location, "The event `{0}' is never used", e.GetSignatureForError ());
2690                                 }
2691                         }
2692                 }
2693
2694                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
2695                 {
2696                         if (a.IsValidSecurityAttribute ()) {
2697                                 if (declarative_security == null)
2698                                         declarative_security = new ListDictionary ();
2699
2700                                 a.ExtractSecurityPermissionSet (declarative_security);
2701                                 return;
2702                         }
2703
2704                         if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit) {
2705                                 PartialContainer.HasExplicitLayout = true;
2706                         }
2707
2708                         base.ApplyAttributeBuilder (a, cb);
2709                 }
2710
2711                 /// <summary>
2712                 /// Defines the default constructors 
2713                 /// </summary>
2714                 protected void DefineDefaultConstructor (bool is_static)
2715                 {
2716                         // The default instance constructor is public
2717                         // If the class is abstract, the default constructor is protected
2718                         // The default static constructor is private
2719
2720                         int mods;
2721                         if (is_static) {
2722                                 mods = Modifiers.STATIC | Modifiers.PRIVATE;
2723                         } else {
2724                                 mods = ((ModFlags & Modifiers.ABSTRACT) != 0) ? Modifiers.PROTECTED : Modifiers.PUBLIC;
2725                         }
2726
2727                         Constructor c = new Constructor (this, MemberName.Name, mods,
2728                                 Parameters.EmptyReadOnlyParameters,
2729                                 new GeneratedBaseInitializer (Location),
2730                                 Location);
2731                         
2732                         AddConstructor (c);
2733                         c.Block = new ToplevelBlock (null, Location);
2734                 }
2735
2736                 public override bool Define ()
2737                 {
2738                         if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer)
2739                                 DefineDefaultConstructor (true);
2740
2741                         if (default_static_constructor != null)
2742                                 default_static_constructor.Define ();
2743
2744                         return base.Define ();
2745                 }
2746
2747                 public override void Emit ()
2748                 {
2749                         base.Emit ();
2750
2751                         if (declarative_security != null) {
2752                                 foreach (DictionaryEntry de in declarative_security) {
2753                                         TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
2754                                 }
2755                         }
2756                 }
2757
2758                 public override ExtensionMethodGroupExpr LookupExtensionMethod (Type extensionType, string name, Location loc)
2759                 {
2760                         return NamespaceEntry.LookupExtensionMethod (extensionType, this, name, loc);
2761                 }
2762
2763                 protected override TypeAttributes TypeAttr {
2764                         get {
2765                                 if (default_static_constructor == null)
2766                                         return base.TypeAttr | TypeAttributes.BeforeFieldInit;
2767
2768                                 return base.TypeAttr;
2769                         }
2770                 }
2771         }
2772
2773
2774         // TODO: should be sealed
2775         public class Class : ClassOrStruct {
2776                 const int AllowedModifiers =
2777                         Modifiers.NEW |
2778                         Modifiers.PUBLIC |
2779                         Modifiers.PROTECTED |
2780                         Modifiers.INTERNAL |
2781                         Modifiers.PRIVATE |
2782                         Modifiers.ABSTRACT |
2783                         Modifiers.SEALED |
2784                         Modifiers.STATIC |
2785                         Modifiers.UNSAFE;
2786
2787                 public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
2788
2789                 public Class (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
2790                               Attributes attrs)
2791                         : base (ns, parent, name, attrs, Kind.Class)
2792                 {
2793                         int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
2794                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
2795
2796                         if (IsStatic && RootContext.Version == LanguageVersion.ISO_1) {
2797                                 Report.FeatureIsNotAvailable (Location, "static classes");
2798                         }
2799                 }
2800
2801                 public override void AddBasesForPart (DeclSpace part, ArrayList bases)
2802                 {
2803                         if (part.Name == "System.Object")
2804                                 Report.Error (537, part.Location,
2805                                         "The class System.Object cannot have a base class or implement an interface.");
2806                         base.AddBasesForPart (part, bases);
2807                 }
2808
2809                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
2810                 {
2811                         if (a.Type == TypeManager.attribute_usage_type) {
2812                                 if (!TypeManager.IsAttributeType (BaseType) &&
2813                                         TypeBuilder.FullName != "System.Attribute") {
2814                                         Report.Error (641, a.Location, "Attribute `{0}' is only valid on classes derived from System.Attribute", a.GetSignatureForError ());
2815                                 }
2816                         }
2817
2818                         if (a.Type == TypeManager.conditional_attribute_type && !TypeManager.IsAttributeType (BaseType)) {
2819                                 Report.Error (1689, a.Location, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2820                                 return;
2821                         }
2822
2823                         if (a.Type == TypeManager.comimport_attr_type && TypeManager.guid_attr_type != null &&
2824                                 !attributes.Contains (TypeManager.guid_attr_type)) {
2825                                         a.Error_MissingGuidAttribute ();
2826                                         return;
2827                         }
2828
2829                         if (a.Type == TypeManager.extension_attribute_type) {
2830                                 a.Error_MisusedExtensionAttribute ();
2831                                 return;
2832                         }
2833
2834                         if (AttributeTester.IsAttributeExcluded (a.Type))
2835                                 return;
2836
2837                         base.ApplyAttributeBuilder (a, cb);
2838                 }
2839
2840                 public override AttributeTargets AttributeTargets {
2841                         get {
2842                                 return AttributeTargets.Class;
2843                         }
2844                 }
2845
2846                 protected override void DefineContainerMembers (MemberCoreArrayList list)
2847                 {
2848                         if (list == null)
2849                                 return;
2850
2851                         if (!IsStatic) {
2852                                 base.DefineContainerMembers (list);
2853                                 return;
2854                         }
2855
2856                         foreach (MemberCore m in list) {
2857                                 if (m is Operator) {
2858                                         Report.Error (715, m.Location, "`{0}': Static classes cannot contain user-defined operators", m.GetSignatureForError ());
2859                                         continue;
2860                                 }
2861
2862                                 if (m is Destructor) {
2863                                         Report.Error (711, m.Location, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2864                                         continue;
2865                                 }
2866
2867                                 if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
2868                                         m.CheckProtectedModifier ();
2869                                         continue;
2870                                 }
2871
2872                                 if (m is Indexer) {
2873                                         Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
2874                                         continue;
2875                                 }
2876
2877                                 if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
2878                                         continue;
2879
2880                                 if (m is Constructor) {
2881                                         Report.Error (710, m.Location, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2882                                         continue;
2883                                 }
2884
2885                                 Method method = m as Method;
2886                                 if (method != null && method.Parameters.HasExtensionMethodType) {
2887                                         Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static", m.GetSignatureForError ());
2888                                         continue;
2889                                 }
2890
2891                                 Report.Error (708, m.Location, "`{0}': cannot declare instance members in a static class", m.GetSignatureForError ());
2892                         }
2893
2894                         base.DefineContainerMembers (list);
2895                 }
2896
2897                 public override TypeBuilder DefineType ()
2898                 {
2899                         if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
2900                                 Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2901                                 return null;
2902                         }
2903
2904                         if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
2905                                 Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2906                                 return null;
2907                         }
2908
2909                         return base.DefineType ();
2910                 }
2911
2912                 protected override bool DoDefineMembers ()
2913                 {
2914                         if (InstanceConstructors == null && !IsStatic)
2915                                 DefineDefaultConstructor (false);
2916
2917                         return base.DoDefineMembers ();
2918                 }
2919
2920                 public override void Emit ()
2921                 {
2922                         base.Emit ();
2923
2924 #if GMCS_SOURCE
2925                         if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
2926                                 TypeBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
2927 #endif                  
2928                 }
2929
2930                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
2931                 {
2932                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
2933
2934                         if (base_class == null) {
2935                                 if (RootContext.StdLib)
2936                                         base_class = TypeManager.system_object_expr;
2937                                 else if (Name != "System.Object")
2938                                         base_class = TypeManager.system_object_expr;
2939                         } else {
2940                                 if (Kind == Kind.Class && base_class is TypeParameterExpr){
2941                                         Report.Error (
2942                                                 689, base_class.Location,
2943                                                 "Cannot derive from `{0}' because it is a type parameter",
2944                                                 base_class.GetSignatureForError ());
2945                                         return ifaces;
2946                                 }
2947
2948                                 if (base_class.IsSealed){
2949                                         Report.SymbolRelatedToPreviousError (base_class.Type);
2950                                         if (base_class.Type.IsAbstract) {
2951                                                 Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'",
2952                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
2953                                         } else {
2954                                                 Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'",
2955                                                         GetSignatureForError (), TypeManager.CSharpName (base_class.Type));
2956                                         }
2957                                         return ifaces;
2958                                 }
2959
2960                                 if (!base_class.CanInheritFrom ()){
2961                                         Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'",
2962                                                 GetSignatureForError (), base_class.GetSignatureForError ());
2963                                         return ifaces;
2964                                 }
2965
2966                                 if (!base_class.AsAccessible (this)) {
2967                                         Report.SymbolRelatedToPreviousError (base_class.Type);
2968                                         Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", 
2969                                                 TypeManager.CSharpName (base_class.Type), GetSignatureForError ());
2970                                 }
2971                         }
2972
2973                         if (PartialContainer.IsStaticClass) {
2974                                 if (base_class.Type != TypeManager.object_type) {
2975                                         Report.Error (713, Location, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2976                                                 GetSignatureForError (), base_class.GetSignatureForError ());
2977                                         return ifaces;
2978                                 }
2979
2980                                 if (ifaces != null) {
2981                                         foreach (TypeExpr t in ifaces)
2982                                                 Report.SymbolRelatedToPreviousError (t.Type);
2983                                         Report.Error (714, Location, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2984                                 }
2985                         }
2986
2987                         return ifaces;
2988                 }
2989
2990                 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2991                 /// Valid only for attribute classes.
2992                 public bool IsExcluded ()
2993                 {
2994                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
2995                                 return (caching_flags & Flags.Excluded) != 0;
2996
2997                         caching_flags &= ~Flags.Excluded_Undetected;
2998
2999                         if (OptAttributes == null)
3000                                 return false;
3001
3002                         if (TypeManager.conditional_attribute_type == null)
3003                                 return false;
3004
3005                         Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
3006
3007                         if (attrs == null)
3008                                 return false;
3009
3010                         foreach (Attribute a in attrs) {
3011                                 string condition = a.GetConditionalAttributeValue ();
3012                                 if (RootContext.AllDefines.Contains (condition))
3013                                         return false;
3014                         }
3015
3016                         caching_flags |= Flags.Excluded;
3017                         return true;
3018                 }
3019
3020                 bool IsStatic {
3021                         get {
3022                                 return (ModFlags & Modifiers.STATIC) != 0;
3023                         }
3024                 }
3025
3026                 //
3027                 // FIXME: How do we deal with the user specifying a different
3028                 // layout?
3029                 //
3030                 protected override TypeAttributes TypeAttr {
3031                         get {
3032                                 TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
3033                                 if (IsStatic)
3034                                         ta |= StaticClassAttribute;
3035                                 return ta;
3036                         }
3037                 }
3038         }
3039
3040         public sealed class Struct : ClassOrStruct {
3041                 // <summary>
3042                 //   Modifiers allowed in a struct declaration
3043                 // </summary>
3044                 const int AllowedModifiers =
3045                         Modifiers.NEW       |
3046                         Modifiers.PUBLIC    |
3047                         Modifiers.PROTECTED |
3048                         Modifiers.INTERNAL  |
3049                         Modifiers.UNSAFE    |
3050                         Modifiers.PRIVATE;
3051
3052                 public Struct (NamespaceEntry ns, DeclSpace parent, MemberName name,
3053                                int mod, Attributes attrs)
3054                         : base (ns, parent, name, attrs, Kind.Struct)
3055                 {
3056                         int accmods;
3057                         
3058                         if (parent.Parent == null)
3059                                 accmods = Modifiers.INTERNAL;
3060                         else
3061                                 accmods = Modifiers.PRIVATE;
3062                         
3063                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, Location);
3064
3065                         this.ModFlags |= Modifiers.SEALED;
3066                 }
3067
3068                 public override AttributeTargets AttributeTargets {
3069                         get {
3070                                 return AttributeTargets.Struct;
3071                         }
3072                 }
3073
3074                 const TypeAttributes DefaultTypeAttributes =
3075                         TypeAttributes.SequentialLayout |
3076                         TypeAttributes.Sealed |
3077                         TypeAttributes.BeforeFieldInit;
3078
3079
3080                 public override TypeExpr[] GetClassBases (out TypeExpr base_class)
3081                 {
3082                         TypeExpr[] ifaces = base.GetClassBases (out base_class);
3083                         //
3084                         // If we are compiling our runtime,
3085                         // and we are defining ValueType, then our
3086                         // base is `System.Object'.
3087                         //
3088                         if (base_class == null) {
3089                                 if (!RootContext.StdLib && Name == "System.ValueType")
3090                                         base_class = TypeManager.system_object_expr;
3091                                 else
3092                                         base_class = TypeManager.system_valuetype_expr;
3093                         }
3094
3095                         return ifaces;
3096                 }
3097
3098                 //
3099                 // FIXME: Allow the user to specify a different set of attributes
3100                 // in some cases (Sealed for example is mandatory for a class,
3101                 // but what SequentialLayout can be changed
3102                 //
3103                 protected override TypeAttributes TypeAttr {
3104                         get {
3105                                 return base.TypeAttr | DefaultTypeAttributes;
3106                         }
3107                 }
3108
3109                 public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
3110                 {
3111                         if ((field.ModFlags & Modifiers.STATIC) == 0) {
3112                                 Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers",
3113                                         field.GetSignatureForError ());
3114                                 return;
3115                         }
3116                         base.RegisterFieldForInitialization (field, expression);
3117                 }
3118
3119         }
3120
3121         /// <summary>
3122         ///   Interfaces
3123         /// </summary>
3124         public sealed class Interface : TypeContainer, IMemberContainer {
3125
3126                 /// <summary>
3127                 ///   Modifiers allowed in a class declaration
3128                 /// </summary>
3129                 public const int AllowedModifiers =
3130                         Modifiers.NEW       |
3131                         Modifiers.PUBLIC    |
3132                         Modifiers.PROTECTED |
3133                         Modifiers.INTERNAL  |
3134                         Modifiers.UNSAFE    |
3135                         Modifiers.PRIVATE;
3136
3137                 public Interface (NamespaceEntry ns, DeclSpace parent, MemberName name, int mod,
3138                                   Attributes attrs)
3139                         : base (ns, parent, name, attrs, Kind.Interface)
3140                 {
3141                         int accmods;
3142
3143                         if (parent.Parent == null)
3144                                 accmods = Modifiers.INTERNAL;
3145                         else
3146                                 accmods = Modifiers.PRIVATE;
3147
3148                         this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, name.Location);
3149                 }
3150
3151                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3152                 {
3153                         if (a.Type == TypeManager.comimport_attr_type && TypeManager.guid_attr_type != null &&
3154                                 !attributes.Contains (TypeManager.guid_attr_type)) {
3155                                         a.Error_MissingGuidAttribute ();
3156                                         return;
3157                         }
3158                         base.ApplyAttributeBuilder (a, cb);
3159                 }
3160
3161
3162                 public override AttributeTargets AttributeTargets {
3163                         get {
3164                                 return AttributeTargets.Interface;
3165                         }
3166                 }
3167
3168                 const TypeAttributes DefaultTypeAttributes =
3169                         TypeAttributes.AutoLayout |
3170                         TypeAttributes.Abstract |
3171                         TypeAttributes.Interface;
3172
3173                 protected override TypeAttributes TypeAttr {
3174                         get {
3175                                 return base.TypeAttr | DefaultTypeAttributes;
3176                         }
3177                 }
3178
3179                 protected override bool VerifyClsCompliance ()
3180                 {
3181                         if (!base.VerifyClsCompliance ())
3182                                 return false;
3183
3184                         if (ifaces != null) {
3185                                 foreach (Type t in ifaces) {
3186                                         if (AttributeTester.IsClsCompliant (t))
3187                                                 continue;
3188
3189                                         Report.SymbolRelatedToPreviousError (t);
3190                                         Report.Warning (3027, 1, Location, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3191                                                 GetSignatureForError (), TypeManager.CSharpName (t));
3192                                 }
3193                         }
3194
3195                         return true;
3196                 }
3197         }
3198
3199         // It is used as a base class for all property based members
3200         // This includes properties, indexers, and events
3201         public abstract class PropertyBasedMember : InterfaceMemberBase
3202         {
3203                 public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
3204                         FullNamedExpression type, int mod, int allowed_mod, bool is_iface,
3205                         MemberName name, Attributes attrs)
3206                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3207                 {
3208                 }
3209
3210                 protected override bool VerifyClsCompliance ()
3211                 {
3212                         if (!base.VerifyClsCompliance ())
3213                                 return false;
3214
3215                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3216                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
3217                                         GetSignatureForError ());
3218                         }
3219                         return true;
3220                 }
3221
3222         }
3223
3224
3225         public abstract class MethodCore : InterfaceMemberBase
3226         {
3227                 public readonly Parameters Parameters;
3228                 protected ToplevelBlock block;
3229
3230                 public MethodCore (DeclSpace parent, GenericMethod generic,
3231                         FullNamedExpression type, int mod, int allowed_mod, bool is_iface,
3232                         MemberName name, Attributes attrs, Parameters parameters)
3233                         : base (parent, generic, type, mod, allowed_mod, is_iface, name, attrs)
3234                 {
3235                         Parameters = parameters;
3236                 }
3237
3238                 //
3239                 //  Returns the System.Type array for the parameters of this method
3240                 //
3241                 public Type [] ParameterTypes {
3242                         get {
3243                                 return Parameters.Types;
3244                         }
3245                 }
3246
3247                 public Parameters ParameterInfo
3248                 {
3249                         get {
3250                                 return Parameters;
3251                         }
3252                 }
3253                 
3254                 public ToplevelBlock Block {
3255                         get {
3256                                 return block;
3257                         }
3258
3259                         set {
3260                                 block = value;
3261                         }
3262                 }
3263
3264                 protected override bool CheckBase ()
3265                 {
3266                         // Check whether arguments were correct.
3267                         if (!DefineParameters (Parameters))
3268                                 return false;
3269
3270                         if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
3271                                 if (!Parent.MemberCache.CheckExistingMembersOverloads (this,
3272                                         MemberName.IsGeneric ? MemberName.Basename : MemberName.MethodName, Parameters))
3273                                         return false;
3274
3275                                 // TODO: Find a better way how to check reserved accessors collision
3276                                 Method m = this as Method;
3277                                 if (m != null) {
3278                                         if (!m.CheckForDuplications ())
3279                                                 return false;
3280                                 }
3281                         }
3282
3283                         if (!base.CheckBase ())
3284                                 return false;
3285
3286                         return true;
3287                 }
3288
3289                 //
3290                 // Returns a string that represents the signature for this 
3291                 // member which should be used in XML documentation.
3292                 //
3293                 public override string GetDocCommentName (DeclSpace ds)
3294                 {
3295                         return DocUtil.GetMethodDocCommentName (this, Parameters, ds);
3296                 }
3297
3298                 //
3299                 // Raised (and passed an XmlElement that contains the comment)
3300                 // when GenerateDocComment is writing documentation expectedly.
3301                 //
3302                 // FIXME: with a few effort, it could be done with XmlReader,
3303                 // that means removal of DOM use.
3304                 //
3305                 internal override void OnGenerateDocComment (XmlElement el)
3306                 {
3307                         DocUtil.OnMethodGenerateDocComment (this, el);
3308                 }
3309
3310                 //
3311                 //   Represents header string for documentation comment.
3312                 //
3313                 public override string DocCommentHeader 
3314                 {
3315                         get { return "M:"; }
3316                 }
3317
3318                 public override bool EnableOverloadChecks (MemberCore overload)
3319                 {
3320                         if (overload is MethodCore || overload is AbstractPropertyEventMethod) {
3321                                 caching_flags |= Flags.MethodOverloadsExist;
3322                                 return true;
3323                         }
3324
3325                         return false;
3326                 }
3327
3328                 protected override bool VerifyClsCompliance ()
3329                 {
3330                         if (!base.VerifyClsCompliance ())
3331                                 return false;
3332
3333                         if (Parameters.HasArglist) {
3334                                 Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
3335                         }
3336
3337                         if (!AttributeTester.IsClsCompliant (MemberType)) {
3338                                 Report.Error (3002, Location, "Return type of `{0}' is not CLS-compliant",
3339                                         GetSignatureForError ());
3340                         }
3341
3342                         Parameters.VerifyClsCompliance ();
3343                         return true;
3344                 }
3345
3346         }
3347
3348         public abstract class InterfaceMemberBase : MemberBase {
3349                 //
3350                 // Whether this is an interface member.
3351                 //
3352                 public bool IsInterface;
3353
3354                 //
3355                 // If true, this is an explicit interface implementation
3356                 //
3357                 public bool IsExplicitImpl;
3358
3359                 protected bool is_external_implementation;
3360
3361                 //
3362                 // The interface type we are explicitly implementing
3363                 //
3364                 public Type InterfaceType;
3365
3366                 //
3367                 // The method we're overriding if this is an override method.
3368                 //
3369                 protected MethodInfo base_method;
3370
3371                 readonly int explicit_mod_flags;
3372                 public MethodAttributes flags;
3373
3374                 public InterfaceMemberBase (DeclSpace parent, GenericMethod generic,
3375                                    FullNamedExpression type, int mod, int allowed_mod, bool is_iface,
3376                                    MemberName name, Attributes attrs)
3377                         : base (parent, generic, type, mod, allowed_mod, Modifiers.PRIVATE,
3378                                 name, attrs)
3379                 {
3380                         IsInterface = is_iface;
3381                         IsExplicitImpl = (MemberName.Left != null);
3382                         explicit_mod_flags = mod;
3383                 }
3384                 
3385                 protected override bool CheckBase ()
3386                 {
3387                         if (!base.CheckBase ())
3388                                 return false;
3389                         
3390                         if (IsExplicitImpl)
3391                                 return true;
3392
3393                         // Is null for System.Object while compiling corlib and base interfaces
3394                         if (Parent.PartialContainer.BaseCache == null) {
3395                                 if ((ModFlags & Modifiers.NEW) != 0) {
3396                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3397                                 }
3398                                 return true;
3399                         }
3400
3401                         Type base_ret_type = null;
3402                         base_method = FindOutBaseMethod (ref base_ret_type);
3403
3404                         // method is override
3405                         if (base_method != null) {
3406                                 if (!CheckMethodAgainstBase (base_ret_type))
3407                                         return false;
3408
3409                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3410                                         ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method);
3411                                         if (oa != null) {
3412                                                 if (OptAttributes == null || TypeManager.obsolete_attribute_type == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3413                                                         Report.SymbolRelatedToPreviousError (base_method);
3414                                                                 Report.Warning (672, 1, Location, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3415                                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3416                                                 }
3417                                         } else {
3418                                                 if (OptAttributes != null && TypeManager.obsolete_attribute_type != null && OptAttributes.Contains (TypeManager.obsolete_attribute_type)) {
3419                                                         Report.SymbolRelatedToPreviousError (base_method);
3420                                                         Report.Warning (809, 1, Location, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3421                                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3422                                                 }
3423                                         }
3424                                 }
3425                                 return true;
3426                         }
3427
3428                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, !((this is Event) || (this is Property)));
3429                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
3430                                 if (conflict_symbol != null) {
3431                                         Report.SymbolRelatedToPreviousError (conflict_symbol);
3432                                         if (this is Event)
3433                                                 Report.Error (72, Location, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3434                                         else if (this is PropertyBase)
3435                                                 Report.Error (544, Location, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3436                                         else
3437                                                 Report.Error (505, Location, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3438                                 } else {
3439                                         Report.Error (115, Location, "`{0}' is marked as an override but no suitable {1} found to override",
3440                                                 GetSignatureForError (), SimpleName.GetMemberType (this));
3441                                 }
3442                                 return false;
3443                         }
3444
3445                         if (conflict_symbol == null) {
3446                                 if ((ModFlags & Modifiers.NEW) != 0) {
3447                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3448                                 }
3449                                 return true;
3450                         }
3451
3452                         if ((ModFlags & Modifiers.NEW) == 0) {
3453                                 if (this is Method && conflict_symbol is MethodBase)
3454                                         return true;
3455
3456                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
3457                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3458                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
3459                         }
3460
3461                         return true;
3462                 }
3463
3464                 //
3465                 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3466                 // that have been defined.
3467                 //
3468                 // `name' is the user visible name for reporting errors (this is used to
3469                 // provide the right name regarding method names and properties)
3470                 //
3471                 bool CheckMethodAgainstBase (Type base_method_type)
3472                 {
3473                         bool ok = true;
3474
3475                         if ((ModFlags & Modifiers.OVERRIDE) != 0){
3476                                 if (!(base_method.IsAbstract || base_method.IsVirtual)){
3477                                         Report.Error (506, Location,
3478                                                 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3479                                                  GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3480                                         ok = false;
3481                                 }
3482                                 
3483                                 // Now we check that the overriden method is not final
3484                                 
3485                                 if (base_method.IsFinal) {
3486                                         Report.SymbolRelatedToPreviousError (base_method);
3487                                         Report.Error (239, Location, "`{0}': cannot override inherited member `{1}' because it is sealed",
3488                                                               GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3489                                         ok = false;
3490                                 }
3491                                 //
3492                                 // Check that the permissions are not being changed
3493                                 //
3494                                 MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
3495                                 MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
3496
3497                                 if (!CheckAccessModifiers (thisp, base_classp, base_method)) {
3498                                         Error_CannotChangeAccessModifiers (Location, base_method, base_classp, null);
3499                                         ok = false;
3500                                 }
3501
3502                                 if (!TypeManager.IsEqual (MemberType, TypeManager.TypeToCoreType (base_method_type))) {
3503                                         Report.SymbolRelatedToPreviousError (base_method);
3504                                         if (this is PropertyBasedMember) {
3505                                                 Report.Error (1715, Location, "`{0}': type must be `{1}' to match overridden member `{2}'", 
3506                                                         GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
3507                                         }
3508                                         else {
3509                                                 Report.Error (508, Location, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3510                                                         GetSignatureForError (), TypeManager.CSharpName (base_method_type), TypeManager.CSharpSignature (base_method));
3511                                         }
3512                                         ok = false;
3513                                 }
3514                         }
3515
3516                         if ((ModFlags & Modifiers.NEW) == 0) {
3517                                 if ((ModFlags & Modifiers.OVERRIDE) == 0 && Name != "Finalize") {
3518                                         ModFlags |= Modifiers.NEW;
3519                                         Report.SymbolRelatedToPreviousError (base_method);
3520                                         if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) {
3521                                                 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",
3522                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3523                                         } else {
3524                                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3525                                                         GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3526                                         }
3527                                 }
3528                         } else {
3529                                 if (base_method.IsAbstract && !IsInterface) {
3530                                         Report.SymbolRelatedToPreviousError (base_method);
3531                                         Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
3532                                                 GetSignatureForError (), TypeManager.CSharpSignature (base_method));
3533                                         return ok = false;
3534                                 }
3535                         }
3536
3537                         return ok;
3538                 }
3539                 
3540                 protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
3541                 {
3542                         if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3543                                 //
3544                                 // when overriding protected internal, the method can be declared
3545                                 // protected internal only within the same assembly or assembly
3546                                 // which has InternalsVisibleTo
3547                                 //
3548                                 if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
3549                                         return TypeManager.IsThisOrFriendAssembly (base_method.DeclaringType.Assembly);
3550                                 } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
3551                                         //
3552                                         // if it's not "protected internal", it must be "protected"
3553                                         //
3554
3555                                         return false;
3556                                 } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
3557                                         //
3558                                         // protected within the same assembly - an error
3559                                         //
3560                                         return false;
3561                                 } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
3562                                            (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
3563                                         //
3564                                         // protected ok, but other attributes differ - report an error
3565                                         //
3566                                         return false;
3567                                 }
3568                                 return true;
3569                         } else {
3570                                 return (thisp == base_classp);
3571                         }
3572                 }
3573
3574                 protected bool DefineParameters (Parameters parameters)
3575                 {
3576                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
3577
3578                         if (!parameters.Resolve (rc))
3579                                 return false;
3580
3581                         bool error = false;
3582                         foreach (Parameter p in parameters.FixedParameters) {
3583                                 if (p.CheckAccessibility (this))
3584                                         continue;
3585
3586                                 Report.SymbolRelatedToPreviousError (p.ParameterType);
3587                                 if (this is Indexer)
3588                                         Report.Error (55, Location,
3589                                                 "Inconsistent accessibility: parameter type `" +
3590                                                 TypeManager.CSharpName (p.ParameterType) + "' is less " +
3591                                                 "accessible than indexer `" + GetSignatureForError () + "'");
3592                                 else if (this is Operator)
3593                                         Report.Error (57, Location,
3594                                                 "Inconsistent accessibility: parameter type `" +
3595                                                 TypeManager.CSharpName (p.ParameterType) + "' is less " +
3596                                                 "accessible than operator `" + GetSignatureForError () + "'");
3597                                 else
3598                                         Report.Error (51, Location,
3599                                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3600                                                 TypeManager.CSharpName (p.ParameterType), GetSignatureForError ());
3601                                 error = true;
3602                         }
3603                         return !error;
3604                 }
3605
3606                 protected override bool DoDefine()
3607                 {
3608                         if (!base.DoDefine ())
3609                                 return false;
3610
3611                         if (IsExplicitImpl) {
3612                                 TypeExpr texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
3613                                 if (texpr == null)
3614                                         return false;
3615
3616                                 InterfaceType = texpr.Type;
3617
3618                                 if (!InterfaceType.IsInterface) {
3619                                         Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3620                                         return false;
3621                                 }
3622                                 
3623                                 if (!Parent.PartialContainer.VerifyImplements (this))
3624                                         return false;
3625                                 
3626                         }
3627                         return true;
3628                 }
3629
3630                 protected bool DoDefineBase ()
3631                 {
3632                         if (Name == null)
3633                                 throw new InternalErrorException ();
3634
3635                         if (IsInterface) {
3636                                 ModFlags = Modifiers.PUBLIC |
3637                                         Modifiers.ABSTRACT |
3638                                         Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
3639
3640                                 flags = MethodAttributes.Public |
3641                                         MethodAttributes.Abstract |
3642                                         MethodAttributes.HideBySig |
3643                                         MethodAttributes.NewSlot |
3644                                         MethodAttributes.Virtual;
3645                         } else {
3646                                 if (!Parent.PartialContainer.MethodModifiersValid (this))
3647                                         return false;
3648
3649                                 flags = Modifiers.MethodAttr (ModFlags);
3650                         }
3651
3652                         if (IsExplicitImpl) {
3653                                 TypeExpr iface_texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
3654                                 if (iface_texpr == null)
3655                                         return false;
3656
3657                                 if ((ModFlags & Modifiers.PARTIAL) != 0) {
3658                                         Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
3659                                                 GetSignatureForError ());
3660                                         return false;
3661                                 }
3662
3663                                 InterfaceType = iface_texpr.Type;
3664
3665                                 if (!InterfaceType.IsInterface) {
3666                                         Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
3667                                         return false;
3668                                 }
3669
3670                                 if (!Parent.PartialContainer.VerifyImplements (this))
3671                                         return false;
3672                                 
3673                                 Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
3674                         }
3675
3676                         return true;
3677                 }
3678
3679                 public override void Emit()
3680                 {
3681                         // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3682                         // We are more strict than Microsoft and report CS0626 as error
3683                         if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
3684                                 Report.Error (626, Location,
3685                                         "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3686                                         GetSignatureForError ());
3687                         }
3688
3689                         base.Emit ();
3690                 }
3691
3692                 protected void Error_CannotChangeAccessModifiers (Location loc, MemberInfo base_method, MethodAttributes ma, string suffix)
3693                 {
3694                         Report.SymbolRelatedToPreviousError (base_method);
3695                         string base_name = TypeManager.GetFullNameSignature (base_method);
3696                         string this_name = GetSignatureForError ();
3697                         if (suffix != null) {
3698                                 base_name += suffix;
3699                                 this_name += suffix;
3700                         }
3701
3702                         Report.Error (507, loc, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3703                                 this_name, Modifiers.GetDescription (ma), base_name);
3704                 }
3705
3706                 protected static string Error722 {
3707                         get {
3708                                 return "`{0}': static types cannot be used as return types";
3709                         }
3710                 }
3711
3712                 /// <summary>
3713                 /// Gets base method and its return type
3714                 /// </summary>
3715                 protected abstract MethodInfo FindOutBaseMethod (ref Type base_ret_type);
3716
3717                 //
3718                 // The "short" name of this property / indexer / event.  This is the
3719                 // name without the explicit interface.
3720                 //
3721                 public string ShortName 
3722                 {
3723                         get { return MemberName.Name; }
3724                         set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3725                 }
3726                 
3727                 public string GetFullName (MemberName name)
3728                 {
3729                         if (!IsExplicitImpl)
3730                                 return name.Name;
3731
3732                         return InterfaceType.FullName.Replace ('+', '.') + "." + name.Name;
3733                 }
3734
3735                 protected override bool VerifyClsCompliance ()
3736                 {
3737                         if (!base.VerifyClsCompliance ()) {
3738                                 if (IsInterface && HasClsCompliantAttribute && Parent.IsClsComplianceRequired ()) {
3739                                         Report.Error (3010, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3740                                 }
3741
3742                                 if ((ModFlags & Modifiers.ABSTRACT) != 0 && Parent.TypeBuilder.IsClass && IsExposedFromAssembly () && Parent.IsClsComplianceRequired ()) {
3743                                         Report.Error (3011, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3744                                 }
3745                                 return false;
3746                         }
3747
3748                         if (GenericMethod != null)
3749                                 GenericMethod.VerifyClsCompliance ();
3750
3751                         return true;
3752                 }
3753
3754                 public override bool IsUsed 
3755                 {
3756                         get { return IsExplicitImpl || base.IsUsed; }
3757                 }
3758
3759         }
3760
3761         public abstract class MethodOrOperator : MethodCore, IMethodData
3762         {
3763                 public MethodBuilder MethodBuilder;
3764                 ReturnParameter return_attributes;
3765                 ListDictionary declarative_security;
3766                 protected MethodData MethodData;
3767
3768                 static string[] attribute_targets = new string [] { "method", "return" };
3769
3770                 protected MethodOrOperator (DeclSpace parent, GenericMethod generic, FullNamedExpression type, int mod,
3771                                 int allowed_mod, bool is_interface, MemberName name,
3772                                 Attributes attrs, Parameters parameters)
3773                         : base (parent, generic, type, mod, allowed_mod, is_interface, name,
3774                                         attrs, parameters)
3775                 {
3776                 }
3777
3778                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
3779                 {
3780                         if (a.Target == AttributeTargets.ReturnValue) {
3781                                 if (return_attributes == null)
3782                                         return_attributes = new ReturnParameter (MethodBuilder, Location);
3783
3784                                 return_attributes.ApplyAttributeBuilder (a, cb);
3785                                 return;
3786                         }
3787
3788                         if (a.IsInternalMethodImplAttribute) {
3789                                 is_external_implementation = true;
3790                         }
3791
3792                         if (a.Type == TypeManager.dllimport_type) {
3793                                 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
3794                                 if ((ModFlags & extern_static) != extern_static) {
3795                                         Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3796                                 }
3797                                 is_external_implementation = true;
3798                         }
3799
3800                         if (a.IsValidSecurityAttribute ()) {
3801                                 if (declarative_security == null)
3802                                         declarative_security = new ListDictionary ();
3803                                 a.ExtractSecurityPermissionSet (declarative_security);
3804                                 return;
3805                         }
3806
3807                         if (MethodBuilder != null)
3808                                 MethodBuilder.SetCustomAttribute (cb);
3809                 }
3810
3811                 public override AttributeTargets AttributeTargets {
3812                         get {
3813                                 return AttributeTargets.Method; 
3814                         }
3815                 }
3816
3817                 public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
3818                 {
3819                         return new EmitContext (
3820                                 this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
3821                 }
3822
3823                 protected bool DefineGenericMethod ()
3824                 {
3825                         if (!DoDefineBase ())
3826                                 return false;
3827
3828 #if GMCS_SOURCE
3829                         if (GenericMethod != null) {
3830                                 MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
3831                                 if (!GenericMethod.Define (MethodBuilder, block))
3832                                         return false;
3833                         }
3834 #endif
3835
3836                         return true;
3837                 }
3838
3839                 public bool ResolveMembers ()
3840                 {
3841                         if (!DefineGenericMethod ())
3842                                 return false;
3843
3844                         return true;
3845                 }
3846
3847                 public override bool Define ()
3848                 {
3849                         if (!DoDefine ())
3850                                 return false;
3851
3852                         if (!CheckAbstractAndExtern (block != null))
3853                                 return false;
3854
3855                         if ((ModFlags & Modifiers.PARTIAL) != 0) {
3856                                 for (int i = 0; i < Parameters.Count; ++i ) {
3857                                         if (Parameters.ParameterModifier (i) == Parameter.Modifier.OUT) {
3858                                                 Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
3859                                                         GetSignatureForError ());
3860                                                 return false;
3861                                         }
3862                                 }
3863                         }
3864
3865                         if (!CheckBase ())
3866                                 return false;
3867
3868                         if (block != null && block.IsIterator && !(Parent is IteratorStorey))
3869                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
3870
3871                         if (IsPartialDefinition) {
3872                                 caching_flags &= ~Flags.Excluded_Undetected;
3873                                 caching_flags |= Flags.Excluded;
3874                                 // Add to member cache only when a partial method implementation is not there
3875                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0) {
3876                                         MethodBase mb = new PartialMethodDefinitionInfo (this);
3877                                         Parent.MemberCache.AddMember (mb, this);
3878                                         TypeManager.AddMethod (mb, this);
3879                                 }
3880
3881                                 return true;
3882                         }
3883
3884                         MethodData = new MethodData (
3885                                 this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method);
3886
3887                         if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
3888                                 return false;
3889                                         
3890                         MethodBuilder = MethodData.MethodBuilder;
3891
3892 #if GMCS_SOURCE                                         
3893                         if (MethodBuilder.IsGenericMethod)
3894                                 Parent.MemberCache.AddGenericMember (MethodBuilder, this);
3895 #endif                  
3896                         
3897                         Parent.MemberCache.AddMember (MethodBuilder, this);
3898
3899                         if (!TypeManager.IsGenericParameter (MemberType)) {
3900                                 if (MemberType.IsAbstract && MemberType.IsSealed) {
3901                                         Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
3902                                         return false;
3903                                 }
3904                         }
3905
3906                         return true;
3907                 }
3908
3909                 public override void Emit ()
3910                 {
3911 #if GMCS_SOURCE                 
3912                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
3913                                 MethodBuilder.SetCustomAttribute (TypeManager.GetCompilerGeneratedAttribute (Location));
3914                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
3915                                 MethodBuilder.SetCustomAttribute (TypeManager.GetDebuggerHiddenAttribute (Location));
3916 #endif
3917                         if (OptAttributes != null)
3918                                 OptAttributes.Emit ();
3919
3920                         if (declarative_security != null) {
3921                                 foreach (DictionaryEntry de in declarative_security) {
3922                                         MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
3923                                 }
3924                         }
3925
3926                         base.Emit ();
3927                 }
3928
3929                 protected void Error_ConditionalAttributeIsNotValid ()
3930                 {
3931                         Report.Error (577, Location,
3932                                 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
3933                                 GetSignatureForError ());
3934                 }
3935
3936                 public bool IsPartialDefinition {
3937                         get {
3938                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
3939                         }
3940                 }
3941
3942                 public bool IsPartialImplementation {
3943                         get {
3944                                 return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
3945                         }
3946                 }
3947
3948                 public override string[] ValidAttributeTargets {
3949                         get {
3950                                 return attribute_targets;
3951                         }
3952                 }
3953
3954                 #region IMethodData Members
3955
3956                 public CallingConventions CallingConventions {
3957                         get {
3958                                 CallingConventions cc = Parameters.CallingConvention;
3959                                 if (!IsInterface)
3960                                         if ((ModFlags & Modifiers.STATIC) == 0)
3961                                                 cc |= CallingConventions.HasThis;
3962
3963                                 // FIXME: How is `ExplicitThis' used in C#?
3964                         
3965                                 return cc;
3966                         }
3967                 }
3968
3969                 public Type ReturnType {
3970                         get {
3971                                 return MemberType;
3972                         }
3973                 }
3974
3975                 public MemberName MethodName {
3976                         get {
3977                                 return MemberName;
3978                         }
3979                 }
3980
3981                 protected override bool CheckBase ()
3982                 {
3983                         if (!base.CheckBase ())
3984                                 return false;
3985
3986                         // TODO: Destructor should derive from MethodCore
3987                         if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
3988                                 base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
3989                                 Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
3990                                 return false;
3991                         }
3992
3993                         return true;
3994                 }
3995
3996                 /// <summary>
3997                 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3998                 /// </summary>
3999                 public bool IsExcluded () {
4000                         if ((caching_flags & Flags.Excluded_Undetected) == 0)
4001                                 return (caching_flags & Flags.Excluded) != 0;
4002
4003                         caching_flags &= ~Flags.Excluded_Undetected;
4004
4005                         if (base_method == null) {
4006                                 if (OptAttributes == null)
4007                                         return false;
4008
4009                                 if (TypeManager.conditional_attribute_type == null)
4010                                         return false;
4011
4012                                 Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type);
4013
4014                                 if (attrs == null)
4015                                         return false;
4016
4017                                 foreach (Attribute a in attrs) {
4018                                         string condition = a.GetConditionalAttributeValue ();
4019                                         if (condition == null)
4020                                                 return false;
4021
4022                                         if (RootContext.AllDefines.Contains (condition))
4023                                                 return false;
4024                                 }
4025
4026                                 caching_flags |= Flags.Excluded;
4027                                 return true;
4028                         }
4029
4030                         IMethodData md = TypeManager.GetMethod (TypeManager.DropGenericMethodArguments (base_method));
4031                         if (md == null) {
4032                                 if (AttributeTester.IsConditionalMethodExcluded (base_method)) {
4033                                         caching_flags |= Flags.Excluded;
4034                                         return true;
4035                                 }
4036                                 return false;
4037                         }
4038
4039                         if (md.IsExcluded ()) {
4040                                 caching_flags |= Flags.Excluded;
4041                                 return true;
4042                         }
4043                         return false;
4044                 }
4045
4046                 GenericMethod IMethodData.GenericMethod {
4047                         get {
4048                                 return GenericMethod;
4049                         }
4050                 }
4051
4052                 public virtual void EmitExtraSymbolInfo (SourceMethod source)
4053                 { }
4054
4055                 #endregion
4056
4057         }
4058
4059         public class SourceMethod : IMethodDef
4060         {
4061                 MethodBase method;
4062                 SourceMethodBuilder builder;
4063
4064                 protected SourceMethod (DeclSpace parent, MethodBase method, ICompileUnit file)
4065                 {
4066                         this.method = method;
4067                         
4068                         builder = SymbolWriter.OpenMethod (file, parent.NamespaceEntry.SymbolFileID, this);
4069                 }
4070
4071                 public string Name {
4072                         get { return method.Name; }
4073                 }
4074
4075                 public int Token {
4076                         get {
4077                                 if (method is MethodBuilder)
4078                                         return ((MethodBuilder) method).GetToken ().Token;
4079                                 else if (method is ConstructorBuilder)
4080                                         return ((ConstructorBuilder) method).GetToken ().Token;
4081                                 else
4082                                         throw new NotSupportedException ();
4083                         }
4084                 }
4085
4086                 public void CloseMethod ()
4087                 {
4088                         SymbolWriter.CloseMethod ();
4089                 }
4090
4091                 public void SetRealMethodName (string name)
4092                 {
4093                         if (builder != null)
4094                                 builder.SetRealMethodName (name);
4095                 }
4096
4097                 public static SourceMethod Create (DeclSpace parent, MethodBase method, Block block)
4098                 {
4099                         if (!SymbolWriter.HasSymbolWriter)
4100                                 return null;
4101                         if (block == null)
4102                                 return null;
4103
4104                         Location start_loc = block.StartLocation;
4105                         if (start_loc.IsNull)
4106                                 return null;
4107
4108                         ICompileUnit compile_unit = start_loc.CompilationUnit;
4109                         if (compile_unit == null)
4110                                 return null;
4111
4112                         return new SourceMethod (parent, method, compile_unit);
4113                 }
4114         }
4115
4116         public class Method : MethodOrOperator {
4117
4118                 /// <summary>
4119                 ///   Modifiers allowed in a class declaration
4120                 /// </summary>
4121                 const int AllowedModifiers =
4122                         Modifiers.NEW |
4123                         Modifiers.PUBLIC |
4124                         Modifiers.PROTECTED |
4125                         Modifiers.INTERNAL |
4126                         Modifiers.PRIVATE |
4127                         Modifiers.STATIC |
4128                         Modifiers.VIRTUAL |
4129                         Modifiers.SEALED |
4130                         Modifiers.OVERRIDE |
4131                         Modifiers.ABSTRACT |
4132                         Modifiers.UNSAFE |
4133                         Modifiers.EXTERN;
4134
4135                 const int AllowedInterfaceModifiers =
4136                         Modifiers.NEW | Modifiers.UNSAFE;
4137
4138                 //
4139                 // return_type can be "null" for VOID values.
4140                 //
4141                 public Method (DeclSpace parent, GenericMethod generic,
4142                                FullNamedExpression return_type, int mod, bool is_iface,
4143                                MemberName name, Parameters parameters, Attributes attrs)
4144                         : base (parent, generic, return_type, mod,
4145                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
4146                                 is_iface, name, attrs, parameters)
4147                 {
4148                 }
4149                 
4150                 public override string GetSignatureForError()
4151                 {
4152                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4153                 }
4154
4155                 void Error_DuplicateEntryPoint (MethodInfo b, Location location)
4156                 {
4157                         Report.Error (17, location,
4158                                 "Program `{0}' has more than one entry point defined: `{1}'",
4159                                 CodeGen.FileName, TypeManager.CSharpSignature(b));
4160                 }
4161
4162                 bool IsEntryPoint ()
4163                 {
4164                         if (ReturnType != TypeManager.void_type &&
4165                                 ReturnType != TypeManager.int32_type)
4166                                 return false;
4167
4168                         if (Parameters.Count == 0)
4169                                 return true;
4170
4171                         if (Parameters.Count > 1)
4172                                 return false;
4173
4174                         Type t = Parameters.ParameterType (0);
4175                         return t.IsArray && t.GetArrayRank () == 1 &&
4176                                         TypeManager.GetElementType (t) == TypeManager.string_type &&
4177                                         (Parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
4178                 }
4179
4180                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4181                 {
4182                         if (a.Type == TypeManager.conditional_attribute_type) {
4183                                 if (IsExplicitImpl) {
4184                                         Error_ConditionalAttributeIsNotValid ();
4185                                         return;
4186                                 }
4187
4188                                 if (ReturnType != TypeManager.void_type) {
4189                                         Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4190                                         return;
4191                                 }
4192
4193                                 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4194                                         Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4195                                         return;
4196                                 }
4197
4198                                 if (IsInterface) {
4199                                         Report.Error (582, Location, "Conditional not valid on interface members");
4200                                         return;
4201                                 }
4202
4203                                 if (MethodData.implementing != null) {
4204                                         Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
4205                                         Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
4206                                                 GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
4207                                         return;
4208                                 }
4209
4210                                 for (int i = 0; i < Parameters.Count; ++i) {
4211                                         if ((Parameters.ParameterModifier (i) & Parameter.Modifier.OUTMASK) != 0) {
4212                                                 Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4213                                                 return;
4214                                         }
4215                                 }
4216                         }
4217
4218                         if (a.Type == TypeManager.extension_attribute_type) {
4219                                 a.Error_MisusedExtensionAttribute ();
4220                                 return;
4221                         }
4222
4223                         base.ApplyAttributeBuilder (a, cb);
4224                 }
4225
4226                 public bool CheckForDuplications ()
4227                 {
4228                         ArrayList ar = Parent.PartialContainer.Properties;
4229                         if (ar != null) {
4230                                 for (int i = 0; i < ar.Count; ++i) {
4231                                         PropertyBase pb = (PropertyBase) ar [i];
4232                                         if (pb.AreAccessorsDuplicateImplementation (this))
4233                                                 return false;
4234                                 }
4235                         }
4236
4237                         ar = Parent.PartialContainer.Indexers;
4238                         if (ar != null) {
4239                                 for (int i = 0; i < ar.Count; ++i) {
4240                                         PropertyBase pb = (PropertyBase) ar [i];
4241                                         if (pb.AreAccessorsDuplicateImplementation (this))
4242                                                 return false;
4243                                 }
4244                         }
4245
4246                         return true;
4247                 }
4248
4249                 //
4250                 // Creates the type
4251                 //
4252                 public override bool Define ()
4253                 {
4254                         if (!base.Define ())
4255                                 return false;
4256
4257                         if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
4258                                 Error1599 (Location, ReturnType);
4259                                 return false;
4260                         }
4261
4262                         if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 && 
4263                                 Name == "Finalize" && !(this is Destructor)) {
4264                                 Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4265                         }
4266
4267                         if (base_method != null && (ModFlags & Modifiers.NEW) == 0) {
4268                                 if (Parameters.Count == 1 && ParameterTypes [0] == TypeManager.object_type && Name == "Equals")
4269                                         Parent.PartialContainer.Mark_HasEquals ();
4270                                 else if (Parameters.Empty && Name == "GetHashCode")
4271                                         Parent.PartialContainer.Mark_HasGetHashCode ();
4272                         }
4273
4274                         if ((ModFlags & Modifiers.STATIC) == 0)
4275                                 return true;
4276
4277                         if (Parameters.HasExtensionMethodType) {
4278                                 if (Parent.IsStaticClass && !Parent.IsGeneric) {
4279                                         if (!Parent.IsTopLevel)
4280                                                 Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
4281                                                         GetSignatureForError ());
4282
4283                                         if (TypeManager.extension_attribute_type == null) {
4284                                                 Report.Error (1110, Location,
4285                                                         "`{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",
4286                                                         GetSignatureForError ());
4287                                         } else if (TypeManager.extension_attribute_attr == null) {
4288                                                 ConstructorInfo ci = TypeManager.GetPredefinedConstructor (
4289                                                         TypeManager.extension_attribute_type, Location, System.Type.EmptyTypes);
4290
4291                                                 if (ci != null)
4292                                                         TypeManager.extension_attribute_attr = new CustomAttributeBuilder (ci, new object [0]);
4293                                         }
4294
4295                                         ModFlags |= Modifiers.METHOD_EXTENSION;
4296                                         Parent.ModFlags |= Modifiers.METHOD_EXTENSION;
4297                                         CodeGen.Assembly.HasExtensionMethods = true;
4298                                 } else {
4299                                         Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
4300                                                 GetSignatureForError ());
4301                                 }
4302                         }
4303
4304                         //
4305                         // This is used to track the Entry Point,
4306                         //
4307                         if (RootContext.NeedsEntryPoint &&
4308                                 Name == "Main" &&
4309                                 (RootContext.MainClass == null ||
4310                                 RootContext.MainClass == Parent.TypeBuilder.FullName)){
4311                                 if (IsEntryPoint ()) {
4312
4313                                         if (RootContext.EntryPoint == null) {
4314                                                 if (Parent.IsGeneric || MemberName.IsGeneric) {
4315                                                         Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
4316                                                                 GetSignatureForError ());
4317                                                 } else {
4318                                                         IMethodData md = TypeManager.GetMethod (MethodBuilder);
4319                                                         md.SetMemberIsUsed ();
4320
4321                                                         RootContext.EntryPoint = MethodBuilder;
4322                                                         RootContext.EntryPointLocation = Location;
4323                                                 }
4324                                         } else {
4325                                                 Error_DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
4326                                                 Error_DuplicateEntryPoint (MethodBuilder, Location);
4327                                         }
4328                                 } else {
4329                                         Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
4330                                                 GetSignatureForError ());
4331                                 }
4332                         }
4333
4334                         return true;
4335                 }
4336
4337                 //
4338                 // Emits the code
4339                 // 
4340                 public override void Emit ()
4341                 {
4342                         try {
4343                                 Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData);
4344                                 if (IsPartialDefinition) {
4345                                         //
4346                                         // Do attribute checks only when partial implementation does not exist
4347                                         //
4348                                         if (MethodBuilder == null)
4349                                                 base.Emit ();
4350
4351                                         return;
4352                                 }
4353
4354                                 if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0)
4355                                         Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
4356                                                 GetSignatureForError ());
4357
4358                                 MethodData.Emit (Parent);
4359                                 base.Emit ();
4360                                 
4361 #if GMCS_SOURCE                         
4362                                 if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
4363                                         MethodBuilder.SetCustomAttribute (TypeManager.extension_attribute_attr);
4364 #endif
4365
4366                                 Block = null;
4367                                 MethodData = null;
4368                         } catch {
4369                                 Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
4370                                                    Location, MethodBuilder);
4371                                 throw;
4372                         }
4373                 }
4374
4375                 public override bool EnableOverloadChecks (MemberCore overload)
4376                 {
4377                         // TODO: It can be deleted when members will be defined in correct order
4378                         if (overload is Operator)
4379                                 return overload.EnableOverloadChecks (this);
4380
4381                         if (overload is Indexer)
4382                                 return false;
4383
4384                         return base.EnableOverloadChecks (overload);
4385                 }
4386
4387                 public static void Error1599 (Location loc, Type t)
4388                 {
4389                         Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
4390                 }
4391
4392                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4393                 {
4394                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindMemberToOverride (
4395                                 Parent.TypeBuilder, Name, ParameterTypes, GenericMethod, false);
4396
4397                         if (mi == null)
4398                                 return null;
4399
4400                         if (mi.IsSpecialName)
4401                                 return null;
4402
4403                         base_ret_type = TypeManager.TypeToCoreType (mi.ReturnType);
4404                         return mi;
4405                 }
4406
4407                 public void SetPartialDefinition (Method methodDefinition)
4408                 {
4409                         caching_flags |= Flags.PartialDefinitionExists;
4410                         methodDefinition.MethodBuilder = MethodBuilder;
4411                         if (methodDefinition.attributes == null)
4412                                 return;
4413
4414                         if (attributes == null) {
4415                                 attributes = methodDefinition.attributes;
4416                         } else {
4417                                 attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
4418                         }
4419                 }
4420
4421                 protected override bool VerifyClsCompliance ()
4422                 {
4423                         if (!base.VerifyClsCompliance ())
4424                                 return false;
4425
4426                         if (ParameterInfo.Count > 0) {
4427                                 ArrayList al = (ArrayList)Parent.PartialContainer.MemberCache.Members [Name];
4428                                 if (al.Count > 1)
4429                                         MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
4430                         }
4431
4432                         return true;
4433                 }
4434         }
4435
4436         public abstract class ConstructorInitializer : ExpressionStatement
4437         {
4438                 ArrayList argument_list;
4439                 MethodGroupExpr base_constructor_group;
4440                 
4441                 public ConstructorInitializer (ArrayList argument_list, Location loc)
4442                 {
4443                         this.argument_list = argument_list;
4444                         this.loc = loc;
4445                 }
4446
4447                 public ArrayList Arguments {
4448                         get {
4449                                 return argument_list;
4450                         }
4451                 }
4452
4453                 public override Expression CreateExpressionTree (EmitContext ec)
4454                 {
4455                         throw new NotSupportedException ("ET");
4456                 }
4457
4458                 public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
4459                 {
4460                         if (argument_list != null){
4461                                 foreach (Argument a in argument_list){
4462                                         if (!a.Resolve (ec, loc))
4463                                                 return false;
4464                                 }
4465                         }
4466
4467                         if (this is ConstructorBaseInitializer) {
4468                                 if (ec.ContainerType.BaseType == null)
4469                                         return true;
4470
4471                                 type = ec.ContainerType.BaseType;
4472                                 if (ec.ContainerType.IsValueType) {
4473                                         Report.Error (522, loc,
4474                                                 "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder));
4475                                         return false;
4476                                 }
4477                         } else {
4478                                 //
4479                                 // It is legal to have "this" initializers that take no arguments
4480                                 // in structs, they are just no-ops.
4481                                 //
4482                                 // struct D { public D (int a) : this () {}
4483                                 //
4484                                 if (ec.ContainerType.IsValueType && argument_list == null)
4485                                         return true;
4486                                 
4487                                 type = ec.ContainerType;
4488                         }
4489
4490                         base_constructor_group = MemberLookupFinal (
4491                                 ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor,
4492                                 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
4493                                 loc) as MethodGroupExpr;
4494                         
4495                         if (base_constructor_group == null)
4496                                 return false;
4497                         
4498                         base_constructor_group = base_constructor_group.OverloadResolve (
4499                                 ec, ref argument_list, false, loc);
4500                         
4501                         if (base_constructor_group == null)
4502                                 return false;
4503                         
4504                         ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group;
4505                         
4506                         if (base_ctor == caller_builder){
4507                                 Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder));
4508                         }
4509                                                 
4510                         return true;
4511                 }
4512
4513                 public override Expression DoResolve (EmitContext ec)
4514                 {
4515                         throw new NotSupportedException ();
4516                 }
4517
4518                 public override void Emit (EmitContext ec)
4519                 {
4520                         // It can be null for static initializers
4521                         if (base_constructor_group == null)
4522                                 return;
4523                         
4524                         ec.Mark (loc, false);
4525                         if (!ec.IsStatic)
4526                                 base_constructor_group.InstanceExpression = ec.GetThis (loc);
4527                         
4528                         base_constructor_group.EmitCall (ec, argument_list);
4529                 }
4530
4531                 public override void EmitStatement (EmitContext ec)
4532                 {
4533                         Emit (ec);
4534                 }
4535         }
4536
4537         public class ConstructorBaseInitializer : ConstructorInitializer {
4538                 public ConstructorBaseInitializer (ArrayList argument_list, Location l) :
4539                         base (argument_list, l)
4540                 {
4541                 }
4542         }
4543
4544         class GeneratedBaseInitializer: ConstructorBaseInitializer {
4545                 public GeneratedBaseInitializer (Location loc):
4546                         base (null, loc)
4547                 {
4548                 }
4549         }
4550
4551         public class ConstructorThisInitializer : ConstructorInitializer {
4552                 public ConstructorThisInitializer (ArrayList argument_list, Location l) :
4553                         base (argument_list, l)
4554                 {
4555                 }
4556         }
4557         
4558         public class Constructor : MethodCore, IMethodData {
4559                 public ConstructorBuilder ConstructorBuilder;
4560                 public ConstructorInitializer Initializer;
4561                 ListDictionary declarative_security;
4562                 bool has_compliant_args;
4563
4564                 // <summary>
4565                 //   Modifiers allowed for a constructor.
4566                 // </summary>
4567                 public const int AllowedModifiers =
4568                         Modifiers.PUBLIC |
4569                         Modifiers.PROTECTED |
4570                         Modifiers.INTERNAL |
4571                         Modifiers.STATIC |
4572                         Modifiers.UNSAFE |
4573                         Modifiers.EXTERN |              
4574                         Modifiers.PRIVATE;
4575
4576                 static readonly string[] attribute_targets = new string [] { "method" };
4577
4578                 //
4579                 // The spec claims that static is not permitted, but
4580                 // my very own code has static constructors.
4581                 //
4582                 public Constructor (DeclSpace parent, string name, int mod, Parameters args,
4583                                     ConstructorInitializer init, Location loc)
4584                         : base (parent, null, null, mod, AllowedModifiers, false,
4585                                 new MemberName (name, loc), null, args)
4586                 {
4587                         Initializer = init;
4588                 }
4589
4590                 public bool HasCompliantArgs {
4591                         get { return has_compliant_args; }
4592                 }
4593
4594                 public override AttributeTargets AttributeTargets {
4595                         get { return AttributeTargets.Constructor; }
4596                 }
4597
4598                 //
4599                 // Returns true if this is a default constructor
4600                 //
4601                 public bool IsDefault ()
4602                 {
4603                         if ((ModFlags & Modifiers.STATIC) != 0)
4604                                 return Parameters.Empty;
4605                         
4606                         return Parameters.Empty &&
4607                                         (Initializer is ConstructorBaseInitializer) &&
4608                                         (Initializer.Arguments == null);
4609                 }
4610
4611                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
4612                 {
4613                         if (a.IsValidSecurityAttribute ()) {
4614                                 if (declarative_security == null) {
4615                                         declarative_security = new ListDictionary ();
4616                                 }
4617                                 a.ExtractSecurityPermissionSet (declarative_security);
4618                                 return;
4619                         }
4620
4621                         if (a.IsInternalMethodImplAttribute) {
4622                                 is_external_implementation = true;
4623                         }
4624
4625                         ConstructorBuilder.SetCustomAttribute (cb);
4626                 }
4627
4628                 protected override bool CheckBase ()
4629                 {
4630                         if ((ModFlags & Modifiers.STATIC) != 0) {
4631                                 if (!Parameters.Empty) {
4632                                         Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
4633                                                 GetSignatureForError ());
4634                                         return false;
4635                                 }
4636
4637                                 // the rest can be ignored
4638                                 return true;
4639                         }
4640
4641                         // Check whether arguments were correct.
4642                         if (!DefineParameters (Parameters))
4643                                 return false;
4644
4645                         if ((caching_flags & Flags.MethodOverloadsExist) != 0)
4646                                 Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorBuilder.ConstructorName,
4647                                         Parameters);
4648
4649                         if (Parent.PartialContainer.Kind == Kind.Struct) {
4650                                 if (ParameterTypes.Length == 0) {
4651                                         Report.Error (568, Location, 
4652                                                 "Structs cannot contain explicit parameterless constructors");
4653                                         return false;
4654                                 }
4655                         }
4656
4657                         CheckProtectedModifier ();
4658                         
4659                         return true;
4660                 }
4661                 
4662                 //
4663                 // Creates the ConstructorBuilder
4664                 //
4665                 public override bool Define ()
4666                 {
4667                         if (ConstructorBuilder != null)
4668                                 return true;
4669
4670                         MethodAttributes ca = (MethodAttributes.RTSpecialName |
4671                                                MethodAttributes.SpecialName);
4672                         
4673                         if ((ModFlags & Modifiers.STATIC) != 0) {
4674                                 ca |= MethodAttributes.Static | MethodAttributes.Private;
4675                         } else {
4676                                 ca |= MethodAttributes.HideBySig;
4677
4678                                 if ((ModFlags & Modifiers.PUBLIC) != 0)
4679                                         ca |= MethodAttributes.Public;
4680                                 else if ((ModFlags & Modifiers.PROTECTED) != 0){
4681                                         if ((ModFlags & Modifiers.INTERNAL) != 0)
4682                                                 ca |= MethodAttributes.FamORAssem;
4683                                         else 
4684                                                 ca |= MethodAttributes.Family;
4685                                 } else if ((ModFlags & Modifiers.INTERNAL) != 0)
4686                                         ca |= MethodAttributes.Assembly;
4687                                 else
4688                                         ca |= MethodAttributes.Private;
4689                         }
4690
4691                         if (!CheckAbstractAndExtern (block != null))
4692                                 return false;
4693                         
4694                         // Check if arguments were correct.
4695                         if (!CheckBase ())
4696                                 return false;
4697
4698                         ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
4699                                 ca, CallingConventions,
4700                                 ParameterTypes);
4701
4702                         if (Parent.PartialContainer.IsComImport) {
4703                                 if (!IsDefault ()) {
4704                                         Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4705                                                 Parent.GetSignatureForError ());
4706                                         return false;
4707                                 }
4708                                 ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
4709                         }
4710                         
4711                         Parent.MemberCache.AddMember (ConstructorBuilder, this);
4712                         TypeManager.AddMethod (ConstructorBuilder, this);
4713                         
4714                         // It's here only to report an error
4715                         if (block != null && block.IsIterator) {
4716                                 member_type = TypeManager.void_type;
4717                                 Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
4718                         }
4719
4720                         return true;
4721                 }
4722
4723                 //
4724                 // Emits the code
4725                 //
4726                 public override void Emit ()
4727                 {
4728                         if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
4729                                 ConstructorBuilder.SetCustomAttribute (TypeManager.GetDebuggerHiddenAttribute (Location));
4730
4731                         if (OptAttributes != null)
4732                                 OptAttributes.Emit ();
4733
4734                         base.Emit ();
4735
4736                         EmitContext ec = CreateEmitContext (null, null);
4737
4738                         //
4739                         // If we use a "this (...)" constructor initializer, then
4740                         // do not emit field initializers, they are initialized in the other constructor
4741                         //
4742                         bool emit_field_initializers = ((ModFlags & Modifiers.STATIC) != 0) ||
4743                                 !(Initializer is ConstructorThisInitializer);
4744
4745                         if (emit_field_initializers)
4746                                 Parent.PartialContainer.ResolveFieldInitializers (ec);
4747
4748                         if (block != null) {
4749                                 // If this is a non-static `struct' constructor and doesn't have any
4750                                 // initializer, it must initialize all of the struct's fields.
4751                                 if ((Parent.PartialContainer.Kind == Kind.Struct) &&
4752                                         ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
4753                                         block.AddThisVariable (Parent, Location);
4754
4755                                 if (!block.ResolveMeta (ec, ParameterInfo))
4756                                         block = null;
4757
4758                                 if (block != null && (ModFlags & Modifiers.STATIC) == 0){
4759                                         if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null)
4760                                                 Initializer = new GeneratedBaseInitializer (Location);
4761
4762                                         //
4763                                         // Spec mandates that Initializers will not have `this' access
4764                                         //
4765                                         if (Initializer != null) {
4766                                                 ec.IsStatic = true;
4767                                                 Initializer.Resolve (ConstructorBuilder, ec);
4768                                                 ec.IsStatic = false;
4769                                                 block.AddScopeStatement (new StatementExpression (Initializer));
4770                                         }
4771                                 }
4772                         }
4773
4774                         Parameters.ApplyAttributes (ConstructorBuilder);
4775                         
4776                         SourceMethod source = null;
4777                         if (block == null)
4778                                 ec.OmitDebuggingInfo = true;
4779                         else
4780                                 source = SourceMethod.Create (Parent, ConstructorBuilder, block);
4781
4782                         bool unreachable = false;
4783                         if (block != null) {
4784                                 if (!ec.ResolveTopBlock (null, block, ParameterInfo, this, out unreachable))
4785                                         return;
4786
4787                                 ec.EmitMeta (block);
4788
4789                                 if (Report.Errors > 0)
4790                                         return;
4791
4792                                 if (emit_field_initializers)
4793                                         Parent.PartialContainer.EmitFieldInitializers (ec);
4794
4795                                 ec.EmitResolvedTopBlock (block, unreachable);
4796                         }
4797
4798                         if (source != null)
4799                                 source.CloseMethod ();
4800
4801                         if (declarative_security != null) {
4802                                 foreach (DictionaryEntry de in declarative_security) {
4803                                         ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
4804                                 }
4805                         }
4806
4807                         block = null;
4808                 }
4809
4810                 // Is never override
4811                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
4812                 {
4813                         return null;
4814                 }
4815
4816                 public override string GetSignatureForError()
4817                 {
4818                         return base.GetSignatureForError () + Parameters.GetSignatureForError ();
4819                 }
4820
4821                 public override string[] ValidAttributeTargets {
4822                         get {
4823                                 return attribute_targets;
4824                         }
4825                 }
4826
4827                 protected override bool VerifyClsCompliance ()
4828                 {
4829                         if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4830                                 return false;
4831                         }
4832                         
4833                         if (ParameterInfo.Count > 0) {
4834                                 ArrayList al = (ArrayList)Parent.MemberCache.Members [".ctor"];
4835                                 if (al.Count > 2)
4836                                         MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
4837  
4838                                 if (TypeManager.IsSubclassOf (Parent.TypeBuilder, TypeManager.attribute_type)) {
4839                                         foreach (Type param in ParameterTypes) {
4840                                                 if (param.IsArray) {
4841                                                         return true;
4842                                                 }
4843                                         }
4844                                 }
4845                         }
4846                         has_compliant_args = true;
4847                         return true;
4848                 }
4849
4850                 #region IMethodData Members
4851
4852                 public System.Reflection.CallingConventions CallingConventions {
4853                         get {
4854                                 CallingConventions cc = Parameters.CallingConvention;
4855
4856                                 if (Parent.PartialContainer.Kind == Kind.Class)
4857                                         if ((ModFlags & Modifiers.STATIC) == 0)
4858                                                 cc |= CallingConventions.HasThis;
4859
4860                                 // FIXME: How is `ExplicitThis' used in C#?
4861                         
4862                                 return cc;
4863                         }
4864                 }
4865
4866                 public MemberName MethodName {
4867                         get {
4868                                 return MemberName;
4869                         }
4870                 }
4871
4872                 public Type ReturnType {
4873                         get {
4874                                 return MemberType;
4875                         }
4876                 }
4877
4878                 public EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
4879                 {
4880                         ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
4881                         EmitContext ec = new EmitContext (this, Parent, Location, ig_, TypeManager.void_type, ModFlags, true);
4882                         ec.CurrentBlock = block;
4883                         return ec;
4884                 }
4885
4886                 public bool IsExcluded()
4887                 {
4888                         return false;
4889                 }
4890
4891                 GenericMethod IMethodData.GenericMethod {
4892                         get {
4893                                 return null;
4894                         }
4895                 }
4896
4897                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
4898                 { }
4899
4900                 #endregion
4901         }
4902
4903         /// <summary>
4904         /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4905         /// </summary>
4906         public interface IMethodData
4907         {
4908                 CallingConventions CallingConventions { get; }
4909                 Location Location { get; }
4910                 MemberName MethodName { get; }
4911                 Type ReturnType { get; }
4912                 GenericMethod GenericMethod { get; }
4913                 Parameters ParameterInfo { get; }
4914
4915                 Attributes OptAttributes { get; }
4916                 ToplevelBlock Block { get; set; }
4917
4918                 EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
4919                 ObsoleteAttribute GetObsoleteAttribute ();
4920                 string GetSignatureForError ();
4921                 bool IsExcluded ();
4922                 bool IsClsComplianceRequired ();
4923                 void SetMemberIsUsed ();
4924                 void EmitExtraSymbolInfo (SourceMethod source);
4925         }
4926
4927         //
4928         // Encapsulates most of the Method's state
4929         //
4930         public class MethodData {
4931 #if GMCS_SOURCE
4932                 static FieldInfo methodbuilder_attrs_field;
4933 #endif
4934                 readonly IMethodData method;
4935
4936                 public readonly GenericMethod GenericMethod;
4937
4938                 //
4939                 // Are we implementing an interface ?
4940                 //
4941                 public MethodInfo implementing;
4942
4943                 //
4944                 // Protected data.
4945                 //
4946                 protected InterfaceMemberBase member;
4947                 protected int modifiers;
4948                 protected MethodAttributes flags;
4949                 protected Type declaring_type;
4950                 protected MethodInfo parent_method;
4951
4952                 MethodBuilder builder = null;
4953                 public MethodBuilder MethodBuilder {
4954                         get {
4955                                 return builder;
4956                         }
4957                 }
4958
4959                 public Type DeclaringType {
4960                         get {
4961                                 return declaring_type;
4962                         }
4963                 }
4964
4965                 public MethodData (InterfaceMemberBase member,
4966                                    int modifiers, MethodAttributes flags, IMethodData method)
4967                 {
4968                         this.member = member;
4969                         this.modifiers = modifiers;
4970                         this.flags = flags;
4971
4972                         this.method = method;
4973                 }
4974
4975                 public MethodData (InterfaceMemberBase member, 
4976                                    int modifiers, MethodAttributes flags, 
4977                                    IMethodData method, MethodBuilder builder,
4978                                    GenericMethod generic, MethodInfo parent_method)
4979                         : this (member, modifiers, flags, method)
4980                 {
4981                         this.builder = builder;
4982                         this.GenericMethod = generic;
4983                         this.parent_method = parent_method;
4984                 }
4985
4986                 public bool Define (DeclSpace parent, string method_full_name)
4987                 {
4988                         string name = method.MethodName.Basename;
4989
4990                         TypeContainer container = parent.PartialContainer;
4991
4992                         PendingImplementation pending = container.PendingImplementations;
4993                         if (pending != null){
4994                                 if (member is Indexer) // TODO: test it, but it should work without this IF
4995                                         implementing = pending.IsInterfaceIndexer (
4996                                                 member.InterfaceType, method.ReturnType, method.ParameterInfo);
4997                                 else
4998                                         implementing = pending.IsInterfaceMethod (
4999                                                 member.InterfaceType, name, method.ReturnType, method.ParameterInfo);
5000
5001                                 if (member.InterfaceType != null){
5002                                         if (implementing == null){
5003                                                 if (member is PropertyBase) {
5004                                                         Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'",
5005                                                                       method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
5006                                                                       member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
5007
5008                                                 } else {
5009                                                         Report.Error (539, method.Location,
5010                                                                       "`{0}.{1}' in explicit interface declaration is not a member of interface",
5011                                                                       TypeManager.CSharpName (member.InterfaceType), member.ShortName);
5012                                                 }
5013                                                 return false;
5014                                         }
5015                                         if (implementing.IsSpecialName && !(method is AbstractPropertyEventMethod)) {
5016                                                 Report.SymbolRelatedToPreviousError (implementing);
5017                                                 Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5018                                                         member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
5019                                                 return false;
5020                                         }
5021                                 } else {
5022                                         if (implementing != null) {
5023                                                 AbstractPropertyEventMethod prop_method = method as AbstractPropertyEventMethod;
5024                                                 if (prop_method == null) {
5025                                                         if (TypeManager.IsSpecialMethod (implementing)) {
5026                                                                 Report.SymbolRelatedToPreviousError (implementing);
5027                                                                 Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5028                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing),
5029                                                                         implementing.Name.StartsWith ("get_") ? "get" : "set");
5030                                                         }
5031                                                 } else if (implementing.DeclaringType.IsInterface) {
5032                                                         if (!implementing.IsSpecialName) {
5033                                                                 Report.SymbolRelatedToPreviousError (implementing);
5034                                                                 Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5035                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
5036                                                                 return false;
5037                                                         }
5038                                                         PropertyBase.PropertyMethod pm = prop_method as PropertyBase.PropertyMethod;
5039                                                         if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
5040                                                                 Report.SymbolRelatedToPreviousError (implementing);
5041                                                                 Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5042                                                                         method.GetSignatureForError (), TypeManager.CSharpSignature (implementing, true));
5043                                                                 return false;
5044                                                         }
5045                                                 }
5046                                         }
5047                                 }
5048                         }
5049
5050                         //
5051                         // For implicit implementations, make sure we are public, for
5052                         // explicit implementations, make sure we are private.
5053                         //
5054                         if (implementing != null){
5055                                 //
5056                                 // Setting null inside this block will trigger a more
5057                                 // verbose error reporting for missing interface implementations
5058                                 //
5059                                 // The "candidate" function has been flagged already
5060                                 // but it wont get cleared
5061                                 //
5062                                 if (member.IsExplicitImpl){
5063                                         if (method.ParameterInfo.HasParams && !TypeManager.GetParameterData (implementing).HasParams) {
5064                                                 Report.SymbolRelatedToPreviousError (implementing);
5065                                                 Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5066                                                         method.GetSignatureForError ());
5067                                                 return false;
5068                                         }
5069                                 } else {
5070                                         if (implementing.DeclaringType.IsInterface) {
5071                                                 //
5072                                                 // If this is an interface method implementation,
5073                                                 // check for public accessibility
5074                                                 //
5075                                                 if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5076                                                 {
5077                                                         implementing = null;
5078                                                 }
5079                                         } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
5080                                                 // We may never be private.
5081                                                 implementing = null;
5082
5083                                         } else if ((modifiers & Modifiers.OVERRIDE) == 0){
5084                                                 //
5085                                                 // We may be protected if we're overriding something.
5086                                                 //
5087                                                 implementing = null;
5088                                         }
5089                                 }
5090                                         
5091                                 //
5092                                 // Static is not allowed
5093                                 //
5094                                 if ((modifiers & Modifiers.STATIC) != 0){
5095                                         implementing = null;
5096                                 }
5097                         }
5098                         
5099                         //
5100                         // If implementing is still valid, set flags
5101                         //
5102                         if (implementing != null){
5103                                 //
5104                                 // When implementing interface methods, set NewSlot
5105                                 // unless, we are overwriting a method.
5106                                 //
5107                                 if (implementing.DeclaringType.IsInterface){
5108                                         if ((modifiers & Modifiers.OVERRIDE) == 0)
5109                                                 flags |= MethodAttributes.NewSlot;
5110                                 }
5111                                 flags |=
5112                                         MethodAttributes.Virtual |
5113                                         MethodAttributes.HideBySig;
5114
5115                                 // Set Final unless we're virtual, abstract or already overriding a method.
5116                                 if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
5117                                         flags |= MethodAttributes.Final;
5118                         }
5119
5120                         DefineMethodBuilder (container, method_full_name, method.ParameterInfo.Types);
5121
5122                         if (builder == null)
5123                                 return false;
5124
5125                         if (container.CurrentType != null)
5126                                 declaring_type = container.CurrentType;
5127                         else
5128                                 declaring_type = container.TypeBuilder;
5129
5130                         if (implementing != null){
5131                                 //
5132                                 // clear the pending implemntation flag
5133                                 //
5134                                 if (member is Indexer) {
5135                                         pending.ImplementIndexer (
5136                                                 member.InterfaceType, builder, method.ReturnType,
5137                                                 method.ParameterInfo, member.IsExplicitImpl);
5138                                 } else
5139                                         pending.ImplementMethod (
5140                                                 member.InterfaceType, name, method.ReturnType,
5141                                                 method.ParameterInfo, member.IsExplicitImpl);
5142
5143                                 if (member.IsExplicitImpl)
5144                                         container.TypeBuilder.DefineMethodOverride (
5145                                                 builder, implementing);
5146                         }
5147
5148                         TypeManager.AddMethod (builder, method);
5149
5150                         if (GenericMethod != null) {
5151                                 bool is_override = member.IsExplicitImpl |
5152                                         ((modifiers & Modifiers.OVERRIDE) != 0);
5153
5154                                 if (implementing != null)
5155                                         parent_method = implementing;
5156
5157                                 EmitContext ec = method.CreateEmitContext (container, null);
5158                                 if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
5159                                         return false;
5160                         }
5161
5162                         return true;
5163                 }
5164
5165
5166                 /// <summary>
5167                 /// Create the MethodBuilder for the method 
5168                 /// </summary>
5169                 void DefineMethodBuilder (TypeContainer container, string method_name, Type[] ParameterTypes)
5170                 {
5171                         if (builder == null) {
5172                                 builder = container.TypeBuilder.DefineMethod (
5173                                         method_name, flags, method.CallingConventions,
5174                                         method.ReturnType, ParameterTypes);
5175                                 return;
5176                         }
5177
5178 #if GMCS_SOURCE
5179                         //
5180                         // Generic method has been already defined to resolve method parameters
5181                         // correctly when they use type parameters
5182                         //
5183                         builder.SetParameters (ParameterTypes);
5184                         builder.SetReturnType (method.ReturnType);
5185
5186                         if (builder.Attributes != flags) {
5187                                 try {
5188                                         if (methodbuilder_attrs_field == null)
5189                                                 methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
5190                                         methodbuilder_attrs_field.SetValue (builder, flags);
5191                                 } catch {
5192                                         Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
5193                                 }
5194                         }
5195 #else
5196                         throw new InternalErrorException ();
5197 #endif
5198                 }
5199
5200                 //
5201                 // Emits the code
5202                 // 
5203                 public void Emit (DeclSpace parent)
5204                 {
5205                         ToplevelBlock block = method.Block;
5206
5207                         EmitContext ec;
5208                         if (block != null)
5209                                 ec = method.CreateEmitContext (parent, builder.GetILGenerator ());
5210                         else
5211                                 ec = method.CreateEmitContext (parent, null);
5212
5213                         method.ParameterInfo.ApplyAttributes (MethodBuilder);
5214
5215                         if (GenericMethod != null)
5216                                 GenericMethod.EmitAttributes ();
5217
5218                         SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
5219
5220                         //
5221                         // Handle destructors specially
5222                         //
5223                         // FIXME: This code generates buggy code
5224                         //
5225                         if (member is Destructor)
5226                                 EmitDestructor (ec, block);
5227                         else
5228                                 ec.EmitTopBlock (method, block);
5229
5230                         if (source != null) {
5231                                 method.EmitExtraSymbolInfo (source);
5232                                 source.CloseMethod ();
5233                         }
5234                 }
5235
5236                 void EmitDestructor (EmitContext ec, ToplevelBlock block)
5237                 {
5238                         ILGenerator ig = ec.ig;
5239                         
5240                         Label finish = ig.DefineLabel ();
5241
5242                         block.SetDestructor ();
5243                         
5244                         ig.BeginExceptionBlock ();
5245                         ec.ReturnLabel = finish;
5246                         ec.HasReturnLabel = true;
5247                         ec.EmitTopBlock (method, block);
5248                         
5249                         // ig.MarkLabel (finish);
5250                         ig.BeginFinallyBlock ();
5251                         
5252                         if (ec.ContainerType.BaseType != null) {
5253                                 Expression member_lookup = Expression.MemberLookup (
5254                                         ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
5255                                         "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
5256
5257                                 if (member_lookup != null){
5258                                         MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup);
5259                                 
5260                                         ig.Emit (OpCodes.Ldarg_0);
5261                                         ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]);
5262                                 }
5263                         }
5264                         
5265                         ig.EndExceptionBlock ();
5266                         //ig.MarkLabel (ec.ReturnLabel);
5267                         ig.Emit (OpCodes.Ret);
5268                 }
5269         }
5270
5271         // TODO: Should derive from MethodCore
5272         public class Destructor : Method {
5273
5274                 static string[] attribute_targets = new string [] { "method" };
5275
5276                 public Destructor (DeclSpace parent, FullNamedExpression return_type, int mod,
5277                                    string name, Parameters parameters, Attributes attrs,
5278                                    Location l)
5279                         : base (parent, null, return_type, mod, false, new MemberName (name, l),
5280                                 parameters, attrs)
5281                 { }
5282
5283                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
5284                 {
5285                         if (a.Type == TypeManager.conditional_attribute_type) {
5286                                 Error_ConditionalAttributeIsNotValid ();
5287                                 return;
5288                         }
5289
5290                         base.ApplyAttributeBuilder (a, cb);
5291                 }
5292
5293                 public override string GetSignatureForError ()
5294                 {
5295                         return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
5296                 }
5297
5298                 public override string[] ValidAttributeTargets {
5299                         get {
5300                                 return attribute_targets;
5301                         }
5302                 }
5303         }
5304         
5305         abstract public class MemberBase : MemberCore {
5306                 protected FullNamedExpression type_name;
5307                 public readonly DeclSpace ds;
5308                 public readonly GenericMethod GenericMethod;
5309
5310                 //
5311                 // The type of this property / indexer / event
5312                 //
5313                 protected Type member_type;
5314                 public Type MemberType {
5315                         get {
5316                                 // TODO: Who wrote this, ResolveAsTypeTerminal can have side effects
5317                                 if (member_type == null && type_name != null) {
5318                                         IResolveContext rc = GenericMethod == null ? this : (IResolveContext)ds;
5319                                         type_name = type_name.ResolveAsTypeTerminal (rc, false);
5320                                         if (type_name != null) {
5321                                                 member_type = type_name.Type;
5322                                         }
5323                                 }
5324                                 return member_type;
5325                         }
5326                 }
5327
5328                 //
5329                 // The constructor is only exposed to our children
5330                 //
5331                 protected MemberBase (DeclSpace parent, GenericMethod generic,
5332                                       FullNamedExpression type, int mod, int allowed_mod, int def_mod,
5333                                       MemberName name, Attributes attrs)
5334                         : base (parent, name, attrs)
5335                 {
5336                         this.ds = generic != null ? generic : (DeclSpace) parent;
5337                         this.type_name = type;
5338                         ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, Location);
5339                         GenericMethod = generic;
5340                         if (GenericMethod != null)
5341                                 GenericMethod.ModFlags = ModFlags;
5342                 }
5343
5344                 protected virtual bool CheckBase ()
5345                 {
5346                         CheckProtectedModifier ();
5347
5348                         return true;
5349                 }
5350
5351                 protected virtual bool DoDefine ()
5352                 {
5353                         if (MemberType == null)
5354                                 return false;
5355
5356                         if ((Parent.ModFlags & Modifiers.SEALED) != 0 && 
5357                                 (ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0) {
5358                                         Report.Error (549, Location, "New virtual member `{0}' is declared in a sealed class `{1}'",
5359                                                 GetSignatureForError (), Parent.GetSignatureForError ());
5360                                         return false;
5361                         }
5362                         
5363                         // verify accessibility
5364                         if (!IsAccessibleAs (MemberType)) {
5365                                 Report.SymbolRelatedToPreviousError (MemberType);
5366                                 if (this is Property)
5367                                         Report.Error (53, Location,
5368                                                       "Inconsistent accessibility: property type `" +
5369                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5370                                                       "accessible than property `" + GetSignatureForError () + "'");
5371                                 else if (this is Indexer)
5372                                         Report.Error (54, Location,
5373                                                       "Inconsistent accessibility: indexer return type `" +
5374                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5375                                                       "accessible than indexer `" + GetSignatureForError () + "'");
5376                                 else if (this is MethodCore) {
5377                                         if (this is Operator)
5378                                                 Report.Error (56, Location,
5379                                                               "Inconsistent accessibility: return type `" +
5380                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5381                                                               "accessible than operator `" + GetSignatureForError () + "'");
5382                                         else
5383                                                 Report.Error (50, Location,
5384                                                               "Inconsistent accessibility: return type `" +
5385                                                               TypeManager.CSharpName (MemberType) + "' is less " +
5386                                                               "accessible than method `" + GetSignatureForError () + "'");
5387                                 } else {
5388                                         Report.Error (52, Location,
5389                                                       "Inconsistent accessibility: field type `" +
5390                                                       TypeManager.CSharpName (MemberType) + "' is less " +
5391                                                       "accessible than field `" + GetSignatureForError () + "'");
5392                                 }
5393                                 return false;
5394                         }
5395
5396                         return true;
5397                 }
5398
5399                 protected bool IsTypePermitted ()
5400                 {
5401                         if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
5402                                 Report.Error (610, Location, "Field or property cannot be of type `{0}'", TypeManager.CSharpName (MemberType));
5403                                 return false;
5404                         }
5405                         return true;
5406                 }
5407         }
5408
5409         //
5410         // Abstract class for all fields
5411         //
5412         abstract public class FieldBase : MemberBase {
5413                 public FieldBuilder FieldBuilder;
5414                 public Status status;
5415                 protected Expression initializer;
5416
5417                 [Flags]
5418                 public enum Status : byte {
5419                         HAS_OFFSET = 4          // Used by FieldMember.
5420                 }
5421
5422                 static readonly string[] attribute_targets = new string [] { "field" };
5423
5424                 protected FieldBase (DeclSpace parent, FullNamedExpression type, int mod,
5425                                      int allowed_mod, MemberName name, Attributes attrs)
5426                         : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE,
5427                                 name, attrs)
5428                 {
5429                         if ((mod & Modifiers.ABSTRACT) != 0)
5430                                 Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5431                 }
5432
5433                 public override AttributeTargets AttributeTargets {
5434                         get {
5435                                 return AttributeTargets.Field;
5436                         }
5437                 }
5438
5439                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
5440                 {
5441                         if (a.Type == TypeManager.field_offset_attribute_type) {
5442                                 status |= Status.HAS_OFFSET;
5443
5444                                 if (!Parent.PartialContainer.HasExplicitLayout) {
5445                                         Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5446                                         return;
5447                                 }
5448
5449                                 if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
5450                                         Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
5451                                         return;
5452                                 }
5453                         }
5454
5455 #if NET_2_0
5456                         if (a.Type == TypeManager.fixed_buffer_attr_type) {
5457                                 Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5458                                 return;
5459                         }
5460 #endif
5461
5462                         if (a.Type == TypeManager.marshal_as_attr_type) {
5463                                 UnmanagedMarshal marshal = a.GetMarshal (this);
5464                                 if (marshal != null) {
5465                                         FieldBuilder.SetMarshal (marshal);
5466                                 }
5467                                 return;
5468                         }
5469
5470                         if ((a.HasSecurityAttribute)) {
5471                                 a.Error_InvalidSecurityParent ();
5472                                 return;
5473                         }
5474
5475                         FieldBuilder.SetCustomAttribute (cb);
5476                 }
5477
5478                 protected override bool CheckBase ()
5479                 {
5480                         if (!base.CheckBase ())
5481                                 return false;
5482  
5483                         MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Name, false);
5484                         if (conflict_symbol == null) {
5485                                 if ((ModFlags & Modifiers.NEW) != 0) {
5486                                         Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5487                                 }
5488                                 return true;
5489                         }
5490  
5491                         if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
5492                                 Report.SymbolRelatedToPreviousError (conflict_symbol);
5493                                 Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5494                                         GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol));
5495                         }
5496  
5497                         return true;
5498                 }
5499
5500                 public override bool Define()
5501                 {
5502                         if (MemberType == null || member_type == null)
5503                                 return false;
5504
5505                         if (TypeManager.IsGenericParameter (MemberType))
5506                                 return true;
5507
5508                         if (MemberType == TypeManager.void_type) {
5509                                 // TODO: wrong location
5510                                 Expression.Error_VoidInvalidInTheContext (Location);
5511                                 return false;
5512                         }
5513
5514                         if (MemberType.IsSealed && MemberType.IsAbstract) {
5515                                 Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
5516                                 return false;
5517                         }
5518
5519                         if (!CheckBase ())
5520                                 return false;
5521
5522                         if (!DoDefine ())
5523                                 return false;
5524
5525                         if (!IsTypePermitted ())
5526                                 return false;
5527
5528                         return true;
5529                 }
5530
5531                 //
5532                 //   Represents header string for documentation comment.
5533                 //
5534                 public override string DocCommentHeader {
5535                         get { return "F:"; }
5536                 }
5537
5538                 public override void Emit ()
5539                 {
5540 #if GMCS_SOURCE
5541                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
5542                                 FieldBuilder.SetCustomAttribute (TypeManager.GetCompilerGeneratedAttribute (Location));
5543 #endif
5544
5545                         if (OptAttributes != null) {
5546                                 OptAttributes.Emit ();
5547                         }
5548
5549                         if (((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0 && Parent.PartialContainer.HasExplicitLayout) {
5550                                 Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5551                         }
5552
5553                         base.Emit ();
5554                 }
5555
5556                 public static void Error_VariableOfStaticClass (Location loc, string variable_name, Type static_class)
5557                 {
5558                         Report.SymbolRelatedToPreviousError (static_class);
5559                         Report.Error (723, loc, "`{0}': cannot declare variables of static types",
5560                                 variable_name);
5561                 }
5562
5563                 public Expression Initializer {
5564                         set {
5565                                 if (value != null) {
5566                                         this.initializer = value;
5567                                 }
5568                         }
5569                 }
5570
5571                 protected virtual bool IsFieldClsCompliant {
5572                         get {
5573                                 if (FieldBuilder == null)
5574                                         return true;
5575
5576                                 return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
5577                         }
5578                 }
5579
5580                 public override string[] ValidAttributeTargets 
5581                 {
5582                         get {
5583                                 return attribute_targets;
5584                         }
5585                 }
5586
5587                 protected override bool VerifyClsCompliance ()
5588                 {
5589                         if (!base.VerifyClsCompliance ())
5590                                 return false;
5591
5592                         if (!IsFieldClsCompliant) {
5593                                 Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5594                         }
5595                         return true;
5596                 }
5597
5598                 public void SetAssigned ()
5599                 {
5600                         caching_flags |= Flags.IsAssigned;
5601                 }
5602         }
5603
5604         interface IFixedBuffer
5605         {
5606                 FieldInfo Element { get; }
5607                 Type ElementType { get; }
5608         }
5609
5610         public class FixedFieldExternal: IFixedBuffer
5611         {
5612                 FieldInfo element_field;
5613
5614                 public FixedFieldExternal (FieldInfo fi)
5615                 {
5616                         element_field = fi.FieldType.GetField (FixedField.FixedElementName);
5617                 }
5618
5619                 #region IFixedField Members
5620
5621                 public FieldInfo Element {
5622                         get {
5623                                 return element_field;
5624                         }
5625                 }
5626
5627                 public Type ElementType {
5628                         get {
5629                                 return element_field.FieldType;
5630                         }
5631                 }
5632
5633                 #endregion
5634         }
5635
5636         /// <summary>
5637         /// Fixed buffer implementation
5638         /// </summary>
5639         public class FixedField : FieldBase, IFixedBuffer
5640         {
5641                 public const string FixedElementName = "FixedElementField";
5642                 static int GlobalCounter = 0;
5643                 static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
5644                 static FieldInfo[] fi;
5645
5646                 TypeBuilder fixed_buffer_type;
5647                 FieldBuilder element;
5648                 Expression size_expr;
5649
5650                 const int AllowedModifiers =
5651                         Modifiers.NEW |
5652                         Modifiers.PUBLIC |
5653                         Modifiers.PROTECTED |
5654                         Modifiers.INTERNAL |
5655                         Modifiers.PRIVATE;
5656
5657                 public FixedField (DeclSpace parent, FullNamedExpression type, int mod, string name,
5658                         Expression size_expr, Attributes attrs, Location loc):
5659                         base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
5660                 {
5661                         if (RootContext.Version == LanguageVersion.ISO_1)
5662                                 Report.FeatureIsNotAvailable (loc, "fixed size buffers");
5663
5664                         this.size_expr = size_expr;
5665                 }
5666
5667                 public override bool Define()
5668                 {
5669                         if (!Parent.IsInUnsafeScope)
5670                                 Expression.UnsafeError (Location);
5671
5672                         if (!base.Define ())
5673                                 return false;
5674
5675                         if (!TypeManager.IsPrimitiveType (MemberType)) {
5676                                 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",
5677                                         GetSignatureForError ());
5678                         }                       
5679                         
5680                         // Create nested fixed buffer container
5681                         string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
5682                         fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
5683                                 TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
5684                         
5685                         element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
5686                         RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
5687                         
5688                         FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
5689                         Parent.MemberCache.AddMember (FieldBuilder, this);
5690                         TypeManager.RegisterFieldBase (FieldBuilder, this);
5691
5692                         return true;
5693                 }
5694
5695                 public override void Emit()
5696                 {
5697                         if (Parent.PartialContainer.Kind != Kind.Struct) {
5698                                 Report.Error (1642, Location, "`{0}': Fixed size buffer fields may only be members of structs",
5699                                         GetSignatureForError ());
5700                         }
5701
5702                         EmitContext ec = new EmitContext (this, Parent, Location, null, TypeManager.void_type, ModFlags);
5703                         Constant c = size_expr.ResolveAsConstant (ec, this);
5704                         if (c == null)
5705                                 return;
5706
5707                         IntConstant buffer_size_const = c.ImplicitConversionRequired (TypeManager.int32_type, Location) as IntConstant;
5708                         if (buffer_size_const == null)
5709                                 return;
5710
5711                         int buffer_size = buffer_size_const.Value;
5712
5713                         if (buffer_size <= 0) {
5714                                 Report.Error (1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5715                                 return;
5716                         }
5717
5718                         int type_size = Expression.GetTypeSize (MemberType);
5719
5720                         if (buffer_size > int.MaxValue / type_size) {
5721                                 Report.Error (1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5722                                         GetSignatureForError (), buffer_size.ToString (), TypeManager.CSharpName (MemberType));
5723                                 return;
5724                         }
5725
5726                         buffer_size *= type_size;
5727                         EmitFieldSize (buffer_size);
5728                         base.Emit ();
5729                 }
5730
5731                 void EmitFieldSize (int buffer_size)
5732                 {
5733                         if (TypeManager.struct_layout_attribute_type == null) {
5734                                 TypeManager.struct_layout_attribute_type = TypeManager.CoreLookupType (
5735                                         "System.Runtime.InteropServices", "StructLayoutAttribute", Kind.Class, true);
5736
5737                                 if (TypeManager.struct_layout_attribute_type == null)
5738                                         return;
5739                         }
5740
5741                         if (fi == null)
5742                                 fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
5743
5744                         object [] fi_val = new object [] { buffer_size };
5745
5746                         if (TypeManager.struct_layout_attribute_ctor == null) {
5747                                 TypeManager.struct_layout_attribute_ctor = TypeManager.GetPredefinedConstructor (
5748                                         TypeManager.struct_layout_attribute_type, Location, TypeManager.short_type);
5749                                 if (TypeManager.struct_layout_attribute_ctor == null)
5750                                         return;
5751                         }
5752
5753                         CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor,
5754                                 ctor_args, fi, fi_val);
5755                         fixed_buffer_type.SetCustomAttribute (cab);
5756                         
5757                         //
5758                         // Don't emit FixedBufferAttribute attribute for private types
5759                         //
5760                         if ((ModFlags & Modifiers.PRIVATE) != 0)
5761                                 return; 
5762
5763                         if (TypeManager.fixed_buffer_attr_ctor == null) {
5764                                 if (TypeManager.fixed_buffer_attr_type == null) {
5765                                         TypeManager.fixed_buffer_attr_type = TypeManager.CoreLookupType (
5766                                                 "System.Runtime.CompilerServices", "FixedBufferAttribute", Kind.Class, true);
5767
5768                                         if (TypeManager.fixed_buffer_attr_type == null)
5769                                                 return;
5770                                 }
5771
5772                                 TypeManager.fixed_buffer_attr_ctor = TypeManager.GetPredefinedConstructor (TypeManager.fixed_buffer_attr_type,
5773                                         Location, TypeManager.type_type, TypeManager.int32_type);
5774                                 
5775                                 if (TypeManager.fixed_buffer_attr_ctor == null)
5776                                         return;
5777                         }
5778
5779                         cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object [] { MemberType, buffer_size });
5780                         FieldBuilder.SetCustomAttribute (cab);
5781                 }
5782
5783                 protected override bool IsFieldClsCompliant {
5784                         get {
5785                                 return false;
5786                         }
5787                 }
5788
5789                 #region IFixedField Members
5790
5791                 public FieldInfo Element {
5792                         get {
5793                                 return element;
5794                         }
5795                 }
5796
5797                 public Type ElementType {
5798                         get {
5799                                 return MemberType;
5800                         }
5801                 }
5802
5803                 #endregion
5804         }
5805
5806         //
5807         // The Field class is used to represents class/struct fields during parsing.
5808         //
5809         public class Field : FieldBase {
5810                 // <summary>
5811                 //   Modifiers allowed in a class declaration
5812                 // </summary>
5813                 const int AllowedModifiers =
5814                         Modifiers.NEW |
5815                         Modifiers.PUBLIC |
5816                         Modifiers.PROTECTED |
5817                         Modifiers.INTERNAL |
5818                         Modifiers.PRIVATE |
5819                         Modifiers.STATIC |
5820                         Modifiers.VOLATILE |
5821                         Modifiers.UNSAFE |
5822                         Modifiers.READONLY;
5823
5824                 public Field (DeclSpace parent, FullNamedExpression type, int mod, string name,
5825                               Attributes attrs, Location loc)
5826                         : base (parent, type, mod, AllowedModifiers, new MemberName (name, loc),
5827                                 attrs)
5828                 {
5829                 }
5830
5831                 bool CanBeVolatile ()
5832                 {
5833                         if (TypeManager.IsReferenceType (MemberType))
5834                                 return true;
5835
5836                         if (MemberType.IsEnum)
5837                                 return true;
5838
5839                         if (MemberType == TypeManager.bool_type || MemberType == TypeManager.char_type ||
5840                                 MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type ||
5841                                 MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type ||
5842                                 MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type ||
5843                                 MemberType == TypeManager.float_type)
5844                                 return true;
5845
5846                         return false;
5847                 }
5848
5849                 public override bool Define ()
5850                 {
5851                         if (!base.Define ())
5852                                 return false;
5853
5854                         if ((ModFlags & Modifiers.VOLATILE) != 0){
5855                                 if (!CanBeVolatile ()) {
5856                                         Report.Error (677, Location, "`{0}': A volatile field cannot be of the type `{1}'",
5857                                                 GetSignatureForError (), TypeManager.CSharpName (MemberType));
5858                                 }
5859
5860                                 if ((ModFlags & Modifiers.READONLY) != 0){
5861                                         Report.Error (678, Location, "`{0}': A field cannot be both volatile and readonly",
5862                                                 GetSignatureForError ());
5863                                 }
5864                         }
5865
5866                         FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
5867
5868                         try {
5869 #if GMCS_SOURCE
5870                                 Type[] required_modifier = null;
5871                                 if ((ModFlags & Modifiers.VOLATILE) != 0) {
5872                                         if (TypeManager.isvolatile_type == null)
5873                                                 TypeManager.isvolatile_type = TypeManager.CoreLookupType (
5874                                                         "System.Runtime.CompilerServices", "IsVolatile", Kind.Class, true);
5875
5876                                         if (TypeManager.isvolatile_type != null)
5877                                                 required_modifier = new Type [] { TypeManager.isvolatile_type };
5878                                 }
5879
5880                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5881                                         Name, MemberType, required_modifier, null, Modifiers.FieldAttr (ModFlags));
5882 #else
5883                                 FieldBuilder = Parent.TypeBuilder.DefineField (
5884                                         Name, MemberType, Modifiers.FieldAttr (ModFlags));
5885 #endif
5886                                 Parent.MemberCache.AddMember (FieldBuilder, this);
5887                                 TypeManager.RegisterFieldBase (FieldBuilder, this);
5888                         }
5889                         catch (ArgumentException) {
5890                                 Report.Warning (-24, 1, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5891                                 return false;
5892                         }
5893
5894                         if (initializer != null)
5895                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
5896                                         new FieldInitializer (FieldBuilder, initializer));
5897
5898                         if (Parent.PartialContainer.Kind == Kind.Struct && (fa & FieldAttributes.Static) == 0 &&
5899                                 MemberType == Parent.TypeBuilder && !TypeManager.IsBuiltinType (MemberType) && initializer == null) {
5900                                 Report.Error (523, Location, "Struct member `{0}' causes a cycle in the structure layout",
5901                                         GetSignatureForError ());
5902                                 return false;
5903                         }
5904
5905                         return true;
5906                 }
5907
5908                 public override string GetSignatureForError ()
5909                 {
5910                         string s = base.GetSignatureForError ();
5911                         if ((ModFlags & Modifiers.BACKING_FIELD) == 0)
5912                                 return s;
5913
5914                         // Undecorate name mangling
5915                         int l = s.LastIndexOf ('>');
5916                         return s.Substring (0, l).Remove (s.LastIndexOf ('<'), 1);
5917                 }
5918
5919                 protected override bool VerifyClsCompliance ()
5920                 {
5921                         if (!base.VerifyClsCompliance ())
5922                                 return false;
5923
5924                         if ((ModFlags & Modifiers.VOLATILE) != 0) {
5925                                 Report.Warning (3026, 1, Location, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5926                         }
5927
5928                         return true;
5929                 }
5930         }
5931
5932         //
5933         // `set' and `get' accessors are represented with an Accessor.
5934         // 
5935         public class Accessor {
5936                 //
5937                 // Null if the accessor is empty, or a Block if not
5938                 //
5939                 public const int AllowedModifiers = 
5940                         Modifiers.PUBLIC |
5941                         Modifiers.PROTECTED |
5942                         Modifiers.INTERNAL |
5943                         Modifiers.PRIVATE;
5944                 
5945                 public ToplevelBlock Block;
5946                 public Attributes Attributes;
5947                 public Location Location;
5948                 public int ModFlags;
5949                 
5950                 public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
5951                 {
5952                         Block = b;
5953                         Attributes = attrs;
5954                         Location = loc;
5955                         ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
5956                 }
5957         }
5958
5959         // Ooouh Martin, templates are missing here.
5960         // When it will be possible move here a lot of child code and template method type.
5961         public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
5962                 protected MethodData method_data;
5963                 protected ToplevelBlock block;
5964                 protected ListDictionary declarative_security;
5965
5966                 // The accessor are created event if they are not wanted.
5967                 // But we need them because their names are reserved.
5968                 // Field says whether accessor will be emited or not
5969                 public readonly bool IsDummy;
5970
5971                 protected readonly string prefix;
5972
5973                 ReturnParameter return_attributes;
5974
5975                 public AbstractPropertyEventMethod (PropertyBasedMember member, string prefix)
5976                         : base (member.Parent, SetupName (prefix, member, member.Location), null)
5977                 {
5978                         this.prefix = prefix;
5979                         IsDummy = true;
5980                 }
5981
5982                 public AbstractPropertyEventMethod (InterfaceMemberBase member, Accessor accessor,
5983                                                     string prefix)
5984                         : base (member.Parent, SetupName (prefix, member, accessor.Location),
5985                                 accessor.Attributes)
5986                 {
5987                         this.prefix = prefix;
5988                         this.block = accessor.Block;
5989                 }
5990
5991                 static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
5992                 {
5993                         return new MemberName (member.MemberName.Left, prefix + member.ShortName, loc);
5994                 }
5995
5996                 public void UpdateName (InterfaceMemberBase member)
5997                 {
5998                         SetMemberName (SetupName (prefix, member, Location));
5999                 }
6000
6001                 #region IMethodData Members
6002
6003                 public ToplevelBlock Block {
6004                         get {
6005                                 return block;
6006                         }
6007
6008                         set {
6009                                 block = value;
6010                         }
6011                 }
6012
6013                 public CallingConventions CallingConventions {
6014                         get {
6015                                 return CallingConventions.Standard;
6016                         }
6017                 }
6018
6019                 public bool IsExcluded ()
6020                 {
6021                         return false;
6022                 }
6023
6024                 GenericMethod IMethodData.GenericMethod {
6025                         get {
6026                                 return null;
6027                         }
6028                 }
6029
6030                 public MemberName MethodName {
6031                         get {
6032                                 return MemberName;
6033                         }
6034                 }
6035
6036                 public Type[] ParameterTypes { 
6037                         get {
6038                                 return ParameterInfo.Types;
6039                         }
6040                 }
6041
6042                 public abstract Parameters ParameterInfo { get ; }
6043                 public abstract Type ReturnType { get; }
6044                 public abstract EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig);
6045
6046                 #endregion
6047
6048                 public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
6049                 {
6050                         if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
6051                                         a.Type == TypeManager.conditional_attribute_type) {
6052                                 Report.Error (1667, a.Location,
6053                                         "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6054                                         TypeManager.CSharpName (a.Type), a.GetValidTargets ());
6055                                 return;
6056                         }
6057
6058                         if (a.IsValidSecurityAttribute ()) {
6059                                 if (declarative_security == null)
6060                                         declarative_security = new ListDictionary ();
6061                                 a.ExtractSecurityPermissionSet (declarative_security);
6062                                 return;
6063                         }
6064
6065                         if (a.Target == AttributeTargets.Method) {
6066                                 method_data.MethodBuilder.SetCustomAttribute (cb);
6067                                 return;
6068                         }
6069
6070                         if (a.Target == AttributeTargets.ReturnValue) {
6071                                 if (return_attributes == null)
6072                                         return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
6073
6074                                 return_attributes.ApplyAttributeBuilder (a, cb);
6075                                 return;
6076                         }
6077
6078                         ApplyToExtraTarget (a, cb);
6079                 }
6080
6081                 virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
6082                 {
6083                         throw new NotSupportedException ("You forgot to define special attribute target handling");
6084                 }
6085
6086                 // It is not supported for the accessors
6087                 public sealed override bool Define()
6088                 {
6089                         throw new NotSupportedException ();
6090                 }
6091
6092                 public void Emit (DeclSpace parent)
6093                 {
6094                         EmitMethod (parent);
6095
6096 #if GMCS_SOURCE                 
6097                         if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
6098                                 method_data.MethodBuilder.SetCustomAttribute (TypeManager.GetCompilerGeneratedAttribute (Location));
6099                         if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
6100                                 method_data.MethodBuilder.SetCustomAttribute (TypeManager.GetDebuggerHiddenAttribute (Location));
6101 #endif                  
6102                         if (OptAttributes != null)
6103                                 OptAttributes.Emit ();
6104
6105                         if (declarative_security != null) {
6106                                 foreach (DictionaryEntry de in declarative_security) {
6107                                         method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
6108                                 }
6109                         }
6110
6111                         block = null;
6112                 }
6113
6114                 protected virtual void EmitMethod (DeclSpace parent)
6115                 {
6116                         method_data.Emit (parent);
6117                 }
6118
6119                 public override bool EnableOverloadChecks (MemberCore overload)
6120                 {
6121                         // This can only happen with indexers and it will
6122                         // be catched as indexer difference
6123                         if (overload is AbstractPropertyEventMethod)
6124                                 return true;
6125
6126                         if (overload is MethodCore) {
6127                                 caching_flags |= Flags.MethodOverloadsExist;
6128                                 return true;
6129                         }
6130                         return false;
6131                 }
6132
6133                 public override bool IsClsComplianceRequired()
6134                 {
6135                         return false;
6136                 }
6137
6138                 public bool IsDuplicateImplementation (MethodCore method)
6139                 {
6140                         if (!MemberName.Equals (method.MemberName))
6141                                 return false;
6142
6143                         Type[] param_types = method.ParameterTypes;
6144
6145                         if (param_types == null || param_types.Length != ParameterTypes.Length)
6146                                 return false;
6147
6148                         for (int i = 0; i < param_types.Length; i++)
6149                                 if (param_types [i] != ParameterTypes [i])
6150                                         return false;
6151
6152                         Report.SymbolRelatedToPreviousError (method);
6153                         Report.Error (82, Location, "A member `{0}' is already reserved",
6154                                 method.GetSignatureForError ());
6155                         return true;
6156                 }
6157
6158                 public override bool IsUsed
6159                 {
6160                         get {
6161                                 if (IsDummy)
6162                                         return false;
6163
6164                                 return base.IsUsed;
6165                         }
6166                 }
6167
6168                 //
6169                 //   Represents header string for documentation comment.
6170                 //
6171                 public override string DocCommentHeader {
6172                         get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6173                 }
6174
6175                 void IMethodData.EmitExtraSymbolInfo (SourceMethod source)
6176                 { }
6177         }
6178
6179         //
6180         // Properties and Indexers both generate PropertyBuilders, we use this to share 
6181         // their common bits.
6182         //
6183         abstract public class PropertyBase : PropertyBasedMember {
6184
6185                 public class GetMethod : PropertyMethod
6186                 {
6187                         static string[] attribute_targets = new string [] { "method", "return" };
6188
6189                         public GetMethod (PropertyBase method):
6190                                 base (method, "get_")
6191                         {
6192                         }
6193
6194                         public GetMethod (PropertyBase method, Accessor accessor):
6195                                 base (method, accessor, "get_")
6196                         {
6197                         }
6198
6199                         public override MethodBuilder Define (DeclSpace parent)
6200                         {
6201                                 if (!CheckForDuplications ())
6202                                         return null;
6203
6204                                 if (IsDummy)
6205                                         return null;
6206                                 
6207                                 base.Define (parent);
6208                                 
6209                                 method_data = new MethodData (method, ModFlags, flags, this);
6210
6211                                 if (!method_data.Define (parent, method.GetFullName (MemberName)))
6212                                         return null;
6213
6214                                 return method_data.MethodBuilder;
6215                         }
6216
6217                         public override Type ReturnType {
6218                                 get {
6219                                         return method.MemberType;
6220                                 }
6221                         }
6222
6223                         public override Parameters ParameterInfo {
6224                                 get {
6225                                         return Parameters.EmptyReadOnlyParameters;
6226                                 }
6227                         }
6228
6229                         public override string[] ValidAttributeTargets {
6230                                 get {
6231                                         return attribute_targets;
6232                                 }
6233                         }
6234                 }
6235
6236                 public class SetMethod : PropertyMethod {
6237
6238                         static string[] attribute_targets = new string [] { "method", "param", "return" };
6239                         ImplicitParameter param_attr;
6240                         protected Parameters parameters;
6241
6242                         public SetMethod (PropertyBase method):
6243                                 base (method, "set_")
6244                         {
6245                         }
6246
6247                         public SetMethod (PropertyBase method, Accessor accessor):
6248                                 base (method, accessor, "set_")
6249                         {
6250                         }
6251
6252                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
6253                         {
6254                                 if (a.Target == AttributeTargets.Parameter) {
6255                                         if (param_attr == null)
6256                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
6257
6258                                         param_attr.ApplyAttributeBuilder (a, cb);
6259                                         return;
6260                                 }
6261
6262                                 base.ApplyAttributeBuilder (a, cb);
6263                         }
6264
6265                         public override Parameters ParameterInfo {
6266                                 get {
6267                                         if (parameters == null)
6268                                                 DefineParameters ();
6269                                         return parameters;
6270                                 }
6271                         }
6272
6273                         protected virtual void DefineParameters ()
6274                         {
6275                                 parameters = Parameters.CreateFullyResolved (
6276                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location));
6277                         }
6278
6279                         public override MethodBuilder Define (DeclSpace parent)
6280                         {
6281                                 if (!CheckForDuplications ())
6282                                         return null;
6283                                 
6284                                 if (IsDummy)
6285                                         return null;
6286
6287                                 base.Define (parent);
6288
6289                                 method_data = new MethodData (method, ModFlags, flags, this);
6290
6291                                 if (!method_data.Define (parent, method.GetFullName (MemberName)))
6292                                         return null;
6293
6294                                 return method_data.MethodBuilder;
6295                         }
6296
6297                         public override Type ReturnType {
6298                                 get {
6299                                         return TypeManager.void_type;
6300                                 }
6301                         }
6302
6303                         public override string[] ValidAttributeTargets {
6304                                 get {
6305                                         return attribute_targets;
6306                                 }
6307                         }
6308                 }
6309
6310                 static string[] attribute_targets = new string [] { "property" };
6311
6312                 public abstract class PropertyMethod : AbstractPropertyEventMethod
6313                 {
6314                         protected readonly PropertyBase method;
6315                         protected MethodAttributes flags;
6316
6317                         public PropertyMethod (PropertyBase method, string prefix)
6318                                 : base (method, prefix)
6319                         {
6320                                 this.method = method;
6321                         }
6322
6323                         public PropertyMethod (PropertyBase method, Accessor accessor,
6324                                                string prefix)
6325                                 : base (method, accessor, prefix)
6326                         {
6327                                 this.method = method;
6328                                 this.ModFlags = accessor.ModFlags;
6329
6330                                 if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
6331                                         Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
6332                                 }
6333                         }
6334
6335                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6336                         {
6337                                 if (a.IsInternalMethodImplAttribute) {
6338                                         method.is_external_implementation = true;
6339                                 }
6340
6341                                 base.ApplyAttributeBuilder (a, cb);
6342                         }
6343
6344                         public override AttributeTargets AttributeTargets {
6345                                 get {
6346                                         return AttributeTargets.Method;
6347                                 }
6348                         }
6349
6350                         public override bool IsClsComplianceRequired ()
6351                         {
6352                                 return method.IsClsComplianceRequired ();
6353                         }
6354
6355                         public virtual MethodBuilder Define (DeclSpace parent)
6356                         {
6357                                 TypeContainer container = parent.PartialContainer;
6358
6359                                 //
6360                                 // Check for custom access modifier
6361                                 //
6362                                 if ((ModFlags & Modifiers.Accessibility) == 0) {
6363                                         ModFlags |= method.ModFlags;
6364                                         flags = method.flags;
6365                                 } else {
6366                                         if (container.Kind == Kind.Interface)
6367                                                 Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6368                                                         GetSignatureForError ());
6369
6370                                         if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
6371                                                 Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6372                                         }
6373
6374                                         CheckModifiers (ModFlags);
6375                                         ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
6376                                         ModFlags |= Modifiers.PROPERTY_CUSTOM;
6377                                         flags = Modifiers.MethodAttr (ModFlags);
6378                                         flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
6379                                 }
6380
6381                                 CheckAbstractAndExtern (block != null);
6382
6383                                 if (block != null && block.IsIterator)
6384                                         Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
6385
6386                                 return null;
6387                         }
6388
6389                         public bool HasCustomAccessModifier
6390                         {
6391                                 get {
6392                                         return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
6393                                 }
6394                         }
6395
6396                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
6397                         {
6398                                 return new EmitContext (method,
6399                                         ds, method.ds, method.Location, ig, ReturnType,
6400                                         method.ModFlags, false);
6401                         }
6402
6403                         public override ObsoleteAttribute GetObsoleteAttribute ()
6404                         {
6405                                 return method.GetObsoleteAttribute ();
6406                         }
6407
6408                         public override string GetSignatureForError()
6409                         {
6410                                 return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
6411                         }
6412                         
6413                         void CheckModifiers (int modflags)
6414                         {
6415                                 modflags &= Modifiers.Accessibility;
6416                                 int flags = 0;
6417                                 int mflags = method.ModFlags & Modifiers.Accessibility;
6418
6419                                 if ((mflags & Modifiers.PUBLIC) != 0) {
6420                                         flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
6421                                 }
6422                                 else if ((mflags & Modifiers.PROTECTED) != 0) {
6423                                         if ((mflags & Modifiers.INTERNAL) != 0)
6424                                                 flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
6425
6426                                         flags |= Modifiers.PRIVATE;
6427                                 }
6428                                 else if ((mflags & Modifiers.INTERNAL) != 0)
6429                                         flags |= Modifiers.PRIVATE;
6430
6431                                 if ((mflags == modflags) || (modflags & (~flags)) != 0) {
6432                                         Report.Error (273, Location,
6433                                                 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6434                                                 GetSignatureForError (), method.GetSignatureForError ());
6435                                 }
6436                         }
6437
6438                         protected bool CheckForDuplications () 
6439                         {
6440                                 if ((caching_flags & Flags.MethodOverloadsExist) == 0)
6441                                         return true;
6442
6443                                 return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo);
6444                         }
6445                 }
6446
6447                 public PropertyMethod Get, Set;
6448                 public PropertyBuilder PropertyBuilder;
6449                 public MethodBuilder GetBuilder, SetBuilder;
6450
6451                 protected bool define_set_first = false;
6452
6453                 public PropertyBase (DeclSpace parent, FullNamedExpression type, int mod_flags,
6454                                      int allowed_mod, bool is_iface, MemberName name,
6455                                      Attributes attrs, bool define_set_first)
6456                         : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,     attrs)
6457                 {
6458                          this.define_set_first = define_set_first;
6459                 }
6460
6461                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
6462                 {
6463                         if (a.HasSecurityAttribute) {
6464                                 a.Error_InvalidSecurityParent ();
6465                                 return;
6466                         }
6467
6468                         PropertyBuilder.SetCustomAttribute (cb);
6469                 }
6470
6471                 public override AttributeTargets AttributeTargets {
6472                         get {
6473                                 return AttributeTargets.Property;
6474                         }
6475                 }
6476
6477                 public override bool Define ()
6478                 {
6479                         if (!DoDefine ())
6480                                 return false;
6481
6482                         if (!IsTypePermitted ())
6483                                 return false;
6484
6485                         return true;
6486                 }
6487
6488                 protected override bool DoDefine ()
6489                 {
6490                         if (!base.DoDefine ())
6491                                 return false;
6492
6493                         //
6494                         // Accessors modifiers check
6495                         //
6496                         if ((Get.ModFlags & Modifiers.Accessibility) != 0 &&
6497                                 (Set.ModFlags & Modifiers.Accessibility) != 0) {
6498                                 Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6499                                                 GetSignatureForError ());
6500                                 return false;
6501                         }
6502
6503                         if ((Get.IsDummy || Set.IsDummy)
6504                             && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
6505                                 Report.Error (276, Location, 
6506                                               "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6507                                               GetSignatureForError ());
6508                                 return false;
6509                         }
6510
6511 #if MS_COMPATIBLE
6512                         if (MemberType.IsGenericParameter)
6513                                 return true;
6514 #endif
6515
6516                         if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
6517                                 Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
6518                                 return false;
6519                         }
6520
6521                         return true;
6522                 }
6523
6524                 bool DefineGet ()
6525                 {
6526                         GetBuilder = Get.Define (Parent);
6527                         return (Get.IsDummy) ? true : GetBuilder != null;
6528                 }
6529
6530                 bool DefineSet (bool define)
6531                 {
6532                         if (!define)
6533                                 return true;
6534
6535                         SetBuilder = Set.Define (Parent);
6536                         return (Set.IsDummy) ? true : SetBuilder != null;
6537                 }
6538
6539                 protected bool DefineAccessors ()
6540                 {
6541                         return DefineSet (define_set_first) &&
6542                                 DefineGet () &&
6543                                 DefineSet (!define_set_first);
6544                 }
6545
6546                 protected abstract PropertyInfo ResolveBaseProperty ();
6547
6548                 // TODO: rename to Resolve......
6549                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
6550                 {
6551                         PropertyInfo base_property = ResolveBaseProperty ();
6552                         if (base_property == null)
6553                                 return null;
6554
6555                         base_ret_type = base_property.PropertyType;
6556                         MethodInfo get_accessor = base_property.GetGetMethod (true);
6557                         MethodInfo set_accessor = base_property.GetSetMethod (true);
6558                         MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
6559
6560                         //
6561                         // Check base property accessors conflict
6562                         //
6563                         if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
6564                                 if (get_accessor == null) {
6565                                         if (Get != null && !Get.IsDummy) {
6566                                                 Report.SymbolRelatedToPreviousError (base_property);
6567                                                 Report.Error (545, Location,
6568                                                         "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
6569                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6570                                         }
6571                                 } else {
6572                                         get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
6573
6574                                         if (!Get.IsDummy && !CheckAccessModifiers (
6575                                                 Modifiers.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
6576                                                 Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
6577                                 }
6578
6579                                 if (set_accessor == null) {
6580                                         if (Set != null && !Set.IsDummy) {
6581                                                 Report.SymbolRelatedToPreviousError (base_property);
6582                                                 Report.Error (546, Location,
6583                                                         "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
6584                                                         GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
6585                                         }
6586                                 } else {
6587                                         set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
6588
6589                                         if (!Set.IsDummy && !CheckAccessModifiers (
6590                                                 Modifiers.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
6591                                                 Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
6592                                 }
6593                         }
6594
6595                         // When one accessor does not exist and property hides base one
6596                         // we need to propagate this upwards
6597                         if (set_accessor == null)
6598                                 set_accessor = get_accessor;
6599
6600                         //
6601                         // Get the less restrictive access
6602                         //
6603                         return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
6604                 }
6605
6606                 public override void Emit ()
6607                 {
6608                         //
6609                         // The PropertyBuilder can be null for explicit implementations, in that
6610                         // case, we do not actually emit the ".property", so there is nowhere to
6611                         // put the attribute
6612                         //
6613                         if (PropertyBuilder != null && OptAttributes != null)
6614                                 OptAttributes.Emit ();
6615
6616                         if (!Get.IsDummy)
6617                                 Get.Emit (Parent);
6618
6619                         if (!Set.IsDummy)
6620                                 Set.Emit (Parent);
6621
6622                         base.Emit ();
6623                 }
6624
6625                 /// <summary>
6626                 /// Tests whether accessors are not in collision with some method (CS0111)
6627                 /// </summary>
6628                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
6629                 {
6630                         return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
6631                 }
6632
6633                 public override bool IsUsed
6634                 {
6635                         get {
6636                                 if (IsExplicitImpl)
6637                                         return true;
6638
6639                                 return Get.IsUsed | Set.IsUsed;
6640                         }
6641                 }
6642
6643                 protected override void SetMemberName (MemberName new_name)
6644                 {
6645                         base.SetMemberName (new_name);
6646
6647                         Get.UpdateName (this);
6648                         Set.UpdateName (this);
6649                 }
6650
6651                 public override string[] ValidAttributeTargets {
6652                         get {
6653                                 return attribute_targets;
6654                         }
6655                 }
6656
6657                 //
6658                 //   Represents header string for documentation comment.
6659                 //
6660                 public override string DocCommentHeader {
6661                         get { return "P:"; }
6662                 }
6663         }
6664                         
6665         public class Property : PropertyBase {
6666                 const int AllowedModifiers =
6667                         Modifiers.NEW |
6668                         Modifiers.PUBLIC |
6669                         Modifiers.PROTECTED |
6670                         Modifiers.INTERNAL |
6671                         Modifiers.PRIVATE |
6672                         Modifiers.STATIC |
6673                         Modifiers.SEALED |
6674                         Modifiers.OVERRIDE |
6675                         Modifiers.ABSTRACT |
6676                         Modifiers.UNSAFE |
6677                         Modifiers.EXTERN |
6678                         Modifiers.VIRTUAL;
6679
6680                 const int AllowedInterfaceModifiers =
6681                         Modifiers.NEW;
6682
6683                 void CreateAutomaticProperty (Block block, Accessor get_block, Accessor set_block)
6684                 {
6685                         // Make the field
6686                         Field field = new Field (
6687                                 Parent, type_name,
6688                                 Modifiers.BACKING_FIELD | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
6689                             "<" + Name + ">k__BackingField", null, Location);
6690                         ((TypeContainer)Parent).PartialContainer.AddField (field);
6691
6692                         // Make get block
6693                         get_block.Block = new ToplevelBlock (block, null, Location);
6694                         Return r = new Return (new SimpleName(field.Name, Location), Location);
6695                         get_block.Block.AddStatement (r);
6696                         get_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6697
6698                         // Make set block
6699                         Parameters parameters = new Parameters (new Parameter (type_name, "value", Parameter.Modifier.NONE, null, Location));
6700                         set_block.Block = new ToplevelBlock (block, parameters, Location);
6701                         Assign a = new SimpleAssign (new SimpleName (field.Name, Location), new SimpleName ("value", Location));
6702                         set_block.Block.AddStatement (new StatementExpression(a));
6703                         set_block.ModFlags |= Modifiers.COMPILER_GENERATED;
6704                 }
6705
6706                 public Property (DeclSpace parent, FullNamedExpression type, int mod, bool is_iface,
6707                                  MemberName name, Attributes attrs, Accessor get_block,
6708                                  Accessor set_block, bool define_set_first)
6709                         : this (parent, type, mod, is_iface, name, attrs, get_block, set_block,
6710                                 define_set_first, null)
6711                 {
6712                 }
6713                 
6714                 public Property (DeclSpace parent, FullNamedExpression type, int mod, bool is_iface,
6715                                  MemberName name, Attributes attrs, Accessor get_block,
6716                                  Accessor set_block, bool define_set_first, Block current_block)
6717                         : base (parent, type, mod,
6718                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
6719                                 is_iface, name, attrs, define_set_first)
6720                 {
6721                         if (!is_iface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
6722                                 get_block != null && get_block.Block == null &&
6723                                 set_block != null && set_block.Block == null) {
6724                                 if (RootContext.Version <= LanguageVersion.ISO_2)
6725                                         Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
6726                                 
6727                                 CreateAutomaticProperty (current_block, get_block, set_block);
6728                         }
6729
6730                         if (get_block == null)
6731                                 Get = new GetMethod (this);
6732                         else
6733                                 Get = new GetMethod (this, get_block);
6734
6735                         if (set_block == null)
6736                                 Set = new SetMethod (this);
6737                         else
6738                                 Set = new SetMethod (this, set_block);
6739                 }
6740
6741                 public override bool Define ()
6742                 {
6743                         if (!DoDefineBase ())
6744                                 return false;
6745
6746                         if (!base.Define ())
6747                                 return false;
6748
6749                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
6750
6751                         if (!DefineAccessors ())
6752                                 return false;
6753
6754                         if (!CheckBase ())
6755                                 return false;
6756
6757                         // FIXME - PropertyAttributes.HasDefault ?
6758
6759                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
6760                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, null);
6761
6762                         if (!Get.IsDummy) {
6763                                 PropertyBuilder.SetGetMethod (GetBuilder);
6764                                 Parent.MemberCache.AddMember (GetBuilder, Get);
6765                         }
6766
6767                         if (!Set.IsDummy) {
6768                                 PropertyBuilder.SetSetMethod (SetBuilder);
6769                                 Parent.MemberCache.AddMember (SetBuilder, Set);
6770                         }
6771                         
6772                         TypeManager.RegisterProperty (PropertyBuilder, this);
6773                         Parent.MemberCache.AddMember (PropertyBuilder, this);
6774                         return true;
6775                 }
6776
6777                 protected override PropertyInfo ResolveBaseProperty ()
6778                 {
6779                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
6780                                 Parent.TypeBuilder, Name, Parameters.EmptyReadOnlyParameters.Types, null, true) as PropertyInfo;
6781                 }
6782         }
6783
6784         /// </summary>
6785         ///  Gigantic workaround  for lameness in SRE follows :
6786         ///  This class derives from EventInfo and attempts to basically
6787         ///  wrap around the EventBuilder so that FindMembers can quickly
6788         ///  return this in it search for members
6789         /// </summary>
6790         public class MyEventBuilder : EventInfo {
6791                 
6792                 //
6793                 // We use this to "point" to our Builder which is
6794                 // not really a MemberInfo
6795                 //
6796                 EventBuilder MyBuilder;
6797                 
6798                 //
6799                 // We "catch" and wrap these methods
6800                 //
6801                 MethodInfo raise, remove, add;
6802
6803                 EventAttributes attributes;
6804                 Type declaring_type, reflected_type, event_type;
6805                 string name;
6806
6807                 Event my_event;
6808
6809                 public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
6810                 {
6811                         MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
6812
6813                         // And now store the values in our own fields.
6814                         
6815                         declaring_type = type_builder;
6816
6817                         reflected_type = type_builder;
6818                         
6819                         attributes = event_attr;
6820                         this.name = name;
6821                         my_event = ev;
6822                         this.event_type = event_type;
6823                 }
6824                 
6825                 //
6826                 // Methods that you have to override.  Note that you only need 
6827                 // to "implement" the variants that take the argument (those are
6828                 // the "abstract" methods, the others (GetAddMethod()) are 
6829                 // regular.
6830                 //
6831                 public override MethodInfo GetAddMethod (bool nonPublic)
6832                 {
6833                         return add;
6834                 }
6835                 
6836                 public override MethodInfo GetRemoveMethod (bool nonPublic)
6837                 {
6838                         return remove;
6839                 }
6840                 
6841                 public override MethodInfo GetRaiseMethod (bool nonPublic)
6842                 {
6843                         return raise;
6844                 }
6845                 
6846                 //
6847                 // These methods make "MyEventInfo" look like a Builder
6848                 //
6849                 public void SetRaiseMethod (MethodBuilder raiseMethod)
6850                 {
6851                         raise = raiseMethod;
6852                         MyBuilder.SetRaiseMethod (raiseMethod);
6853                 }
6854
6855                 public void SetRemoveOnMethod (MethodBuilder removeMethod)
6856                 {
6857                         remove = removeMethod;
6858                         MyBuilder.SetRemoveOnMethod (removeMethod);
6859                 }
6860
6861                 public void SetAddOnMethod (MethodBuilder addMethod)
6862                 {
6863                         add = addMethod;
6864                         MyBuilder.SetAddOnMethod (addMethod);
6865                 }
6866
6867                 public void SetCustomAttribute (CustomAttributeBuilder cb)
6868                 {
6869                         MyBuilder.SetCustomAttribute (cb);
6870                 }
6871                 
6872                 public override object [] GetCustomAttributes (bool inherit)
6873                 {
6874                         // FIXME : There's nothing which can be seemingly done here because
6875                         // we have no way of getting at the custom attribute objects of the
6876                         // EventBuilder !
6877                         return null;
6878                 }
6879
6880                 public override object [] GetCustomAttributes (Type t, bool inherit)
6881                 {
6882                         // FIXME : Same here !
6883                         return null;
6884                 }
6885
6886                 public override bool IsDefined (Type t, bool b)
6887                 {
6888                         return true;
6889                 }
6890
6891                 public override EventAttributes Attributes {
6892                         get {
6893                                 return attributes;
6894                         }
6895                 }
6896
6897                 public override string Name {
6898                         get {
6899                                 return name;
6900                         }
6901                 }
6902
6903                 public override Type DeclaringType {
6904                         get {
6905                                 return declaring_type;
6906                         }
6907                 }
6908
6909                 public override Type ReflectedType {
6910                         get {
6911                                 return reflected_type;
6912                         }
6913                 }
6914
6915                 public Type EventType {
6916                         get {
6917                                 return event_type;
6918                         }
6919                 }
6920                 
6921                 public void SetUsed ()
6922                 {
6923                         if (my_event != null) {
6924 //                              my_event.SetAssigned ();
6925                                 my_event.SetMemberIsUsed ();
6926                         }
6927                 }
6928         }
6929         
6930         /// <summary>
6931         /// For case when event is declared like property (with add and remove accessors).
6932         /// </summary>
6933         public class EventProperty: Event {
6934                 abstract class AEventPropertyAccessor : AEventAccessor
6935                 {
6936                         public AEventPropertyAccessor (Event method, Accessor accessor, string prefix):
6937                                 base (method, accessor, prefix)
6938                         {
6939                         }
6940
6941                         public override MethodBuilder Define (DeclSpace ds)
6942                         {
6943                                 CheckAbstractAndExtern (block != null);
6944                                 return base.Define (ds);
6945                         }
6946                         
6947                         public override string GetSignatureForError ()
6948                         {
6949                                 return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
6950                         }
6951                 }
6952
6953                 sealed class AddDelegateMethod: AEventPropertyAccessor
6954                 {
6955                         public AddDelegateMethod (Event method, Accessor accessor):
6956                                 base (method, accessor, "add_")
6957                         {
6958                         }
6959
6960                         protected override MethodInfo DelegateMethodInfo {
6961                                 get {
6962                                         return TypeManager.delegate_combine_delegate_delegate;
6963                                 }
6964                         }
6965                 }
6966
6967                 sealed class RemoveDelegateMethod: AEventPropertyAccessor
6968                 {
6969                         public RemoveDelegateMethod (Event method, Accessor accessor):
6970                                 base (method, accessor, "remove_")
6971                         {
6972                         }
6973
6974                         protected override MethodInfo DelegateMethodInfo {
6975                                 get {
6976                                         return TypeManager.delegate_remove_delegate_delegate;
6977                                 }
6978                         }
6979                 }
6980
6981
6982                 static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
6983
6984                 public EventProperty (DeclSpace parent, FullNamedExpression type, int mod_flags,
6985                                       bool is_iface, MemberName name,
6986                                       Attributes attrs, Accessor add, Accessor remove)
6987                         : base (parent, type, mod_flags, is_iface, name, attrs)
6988                 {
6989                         Add = new AddDelegateMethod (this, add);
6990                         Remove = new RemoveDelegateMethod (this, remove);
6991                 }
6992
6993                 public override bool Define()
6994                 {
6995                         if (!base.Define ())
6996                                 return false;
6997
6998                         SetMemberIsUsed ();
6999                         return true;
7000                 }
7001
7002                 public override string[] ValidAttributeTargets {
7003                         get {
7004                                 return attribute_targets;
7005                         }
7006                 }
7007         }
7008
7009         /// <summary>
7010         /// Event is declared like field.
7011         /// </summary>
7012         public class EventField : Event {
7013                 abstract class EventFieldAccessor : AEventAccessor
7014                 {
7015                         protected EventFieldAccessor (Event method, string prefix)
7016                                 : base (method, prefix)
7017                         {
7018                         }
7019
7020                         protected override void EmitMethod(DeclSpace parent)
7021                         {
7022                                 if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7023                                         return;
7024
7025                                 MethodBuilder mb = method_data.MethodBuilder;
7026                                 ILGenerator ig = mb.GetILGenerator ();
7027
7028                                 // TODO: because we cannot use generics yet
7029                                 FieldInfo field_info = ((EventField)method).FieldBuilder;
7030
7031                                 if (parent is Class) {
7032                                         mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
7033                                 }
7034                                 
7035                                 if ((method.ModFlags & Modifiers.STATIC) != 0) {
7036                                         ig.Emit (OpCodes.Ldsfld, field_info);
7037                                         ig.Emit (OpCodes.Ldarg_0);
7038                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7039                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7040                                         ig.Emit (OpCodes.Stsfld, field_info);
7041                                 } else {
7042                                         ig.Emit (OpCodes.Ldarg_0);
7043                                         ig.Emit (OpCodes.Ldarg_0);
7044                                         ig.Emit (OpCodes.Ldfld, field_info);
7045                                         ig.Emit (OpCodes.Ldarg_1);
7046                                         ig.Emit (OpCodes.Call, DelegateMethodInfo);
7047                                         ig.Emit (OpCodes.Castclass, method.MemberType);
7048                                         ig.Emit (OpCodes.Stfld, field_info);
7049                                 }
7050                                 ig.Emit (OpCodes.Ret);
7051                         }
7052                 }
7053
7054                 sealed class AddDelegateMethod: EventFieldAccessor
7055                 {
7056                         public AddDelegateMethod (Event method):
7057                                 base (method, "add_")
7058                         {
7059                         }
7060
7061                         protected override MethodInfo DelegateMethodInfo {
7062                                 get {
7063                                         return TypeManager.delegate_combine_delegate_delegate;
7064                                 }
7065                         }
7066                 }
7067
7068                 sealed class RemoveDelegateMethod: EventFieldAccessor
7069                 {
7070                         public RemoveDelegateMethod (Event method):
7071                                 base (method, "remove_")
7072                         {
7073                         }
7074
7075                         protected override MethodInfo DelegateMethodInfo {
7076                                 get {
7077                                         return TypeManager.delegate_remove_delegate_delegate;
7078                                 }
7079                         }
7080                 }
7081
7082
7083                 static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
7084                 static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
7085
7086                 public FieldBuilder FieldBuilder;
7087                 public Expression Initializer;
7088
7089                 public EventField (DeclSpace parent, FullNamedExpression type, int mod_flags,
7090                                    bool is_iface, MemberName name,
7091                                    Attributes attrs)
7092                         : base (parent, type, mod_flags, is_iface, name, attrs)
7093                 {
7094                         Add = new AddDelegateMethod (this);
7095                         Remove = new RemoveDelegateMethod (this);
7096                 }
7097
7098                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7099                 {
7100                         if (a.Target == AttributeTargets.Field) {
7101                                 FieldBuilder.SetCustomAttribute (cb);
7102                                 return;
7103                         }
7104
7105                         if (a.Target == AttributeTargets.Method) {
7106                                 int errors = Report.Errors;
7107                                 Add.ApplyAttributeBuilder (a, cb);
7108                                 if (errors == Report.Errors)
7109                                         Remove.ApplyAttributeBuilder (a, cb);
7110                                 return;
7111                         }
7112
7113                         base.ApplyAttributeBuilder (a, cb);
7114                 }
7115
7116                 public override bool Define()
7117                 {
7118                         if (!base.Define ())
7119                                 return false;
7120
7121                         if (IsInterface)
7122                                 return true;
7123
7124                         // FIXME: We are unable to detect whether generic event is used because
7125                         // we are using FieldExpr instead of EventExpr for event access in that
7126                         // case.  When this issue will be fixed this hack can be removed.
7127                         if (TypeManager.IsGenericType (MemberType))
7128                                 SetMemberIsUsed();
7129
7130                         if (Add.IsInterfaceImplementation)
7131                                 SetMemberIsUsed ();
7132
7133                         FieldBuilder = Parent.TypeBuilder.DefineField (
7134                                 Name, MemberType,
7135                                 FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
7136                         TypeManager.RegisterEventField (EventBuilder, this);
7137
7138                         if (Initializer != null) {
7139                                 if (((ModFlags & Modifiers.ABSTRACT) != 0)) {
7140                                         Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
7141                                                 GetSignatureForError ());
7142                                         return false;
7143                                 }
7144
7145                                 ((TypeContainer) Parent).RegisterFieldForInitialization (this,
7146                                         new FieldInitializer (FieldBuilder, Initializer));
7147                         }
7148
7149                         return true;
7150                 }
7151
7152                 public override string[] ValidAttributeTargets 
7153                 {
7154                         get {
7155                                 return IsInterface ? attribute_targets_interface : attribute_targets;
7156                         }
7157                 }
7158         }
7159
7160         public abstract class Event : PropertyBasedMember {
7161                 public abstract class AEventAccessor : AbstractPropertyEventMethod
7162                 {
7163                         protected readonly Event method;
7164                         ImplicitParameter param_attr;
7165
7166                         static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
7167
7168                         protected AEventAccessor (Event method, string prefix)
7169                                 : base (method, prefix)
7170                         {
7171                                 this.method = method;
7172                                 this.ModFlags = method.ModFlags;
7173                         }
7174
7175                         protected AEventAccessor (Event method, Accessor accessor, string prefix)
7176                                 : base (method, accessor, prefix)
7177                         {
7178                                 this.method = method;
7179                                 this.ModFlags = method.ModFlags;
7180                         }
7181
7182                         public bool IsInterfaceImplementation {
7183                                 get { return method_data.implementing != null; }
7184                         }
7185
7186                         public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7187                         {
7188                                 if (a.IsInternalMethodImplAttribute) {
7189                                         method.is_external_implementation = true;
7190                                 }
7191
7192                                 base.ApplyAttributeBuilder (a, cb);
7193                         }
7194
7195                         protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
7196                         {
7197                                 if (a.Target == AttributeTargets.Parameter) {
7198                                         if (param_attr == null)
7199                                                 param_attr = new ImplicitParameter (method_data.MethodBuilder);
7200
7201                                         param_attr.ApplyAttributeBuilder (a, cb);
7202                                         return;
7203                                 }
7204
7205                                 base.ApplyAttributeBuilder (a, cb);
7206                         }
7207
7208                         public override AttributeTargets AttributeTargets {
7209                                 get {
7210                                         return AttributeTargets.Method;
7211                                 }
7212                         }
7213
7214                         public override bool IsClsComplianceRequired ()
7215                         {
7216                                 return method.IsClsComplianceRequired ();
7217                         }
7218
7219                         public virtual MethodBuilder Define (DeclSpace parent)
7220                         {
7221                                 method_data = new MethodData (method, method.ModFlags,
7222                                         method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
7223
7224                                 if (!method_data.Define (parent, method.GetFullName (MemberName)))
7225                                         return null;
7226
7227                                 MethodBuilder mb = method_data.MethodBuilder;
7228                                 ParameterInfo.ApplyAttributes (mb);
7229                                 return mb;
7230                         }
7231
7232                         protected abstract MethodInfo DelegateMethodInfo { get; }
7233
7234                         public override Type ReturnType {
7235                                 get {
7236                                         return TypeManager.void_type;
7237                                 }
7238                         }
7239
7240                         public override EmitContext CreateEmitContext (DeclSpace ds, ILGenerator ig)
7241                         {
7242                                 return new EmitContext (
7243                                         this, method.Parent, Location, ig, ReturnType,
7244                                         method.ModFlags, false);
7245                         }
7246
7247                         public override ObsoleteAttribute GetObsoleteAttribute ()
7248                         {
7249                                 return method.GetObsoleteAttribute ();
7250                         }
7251
7252                         public override string[] ValidAttributeTargets {
7253                                 get {
7254                                         return attribute_targets;
7255                                 }
7256                         }
7257
7258                         public override Parameters ParameterInfo {
7259                                 get {
7260                                         return method.parameters;
7261                                 }
7262                         }
7263                 }
7264
7265
7266                 const int AllowedModifiers =
7267                         Modifiers.NEW |
7268                         Modifiers.PUBLIC |
7269                         Modifiers.PROTECTED |
7270                         Modifiers.INTERNAL |
7271                         Modifiers.PRIVATE |
7272                         Modifiers.STATIC |
7273                         Modifiers.VIRTUAL |
7274                         Modifiers.SEALED |
7275                         Modifiers.OVERRIDE |
7276                         Modifiers.UNSAFE |
7277                         Modifiers.ABSTRACT |
7278                         Modifiers.EXTERN;
7279
7280                 const int AllowedInterfaceModifiers =
7281                         Modifiers.NEW;
7282
7283                 public AEventAccessor Add, Remove;
7284                 public MyEventBuilder     EventBuilder;
7285                 public MethodBuilder AddBuilder, RemoveBuilder;
7286
7287                 Parameters parameters;
7288
7289                 protected Event (DeclSpace parent, FullNamedExpression type, int mod_flags,
7290                               bool is_iface, MemberName name, Attributes attrs)
7291                         : base (parent, null, type, mod_flags,
7292                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers, is_iface,
7293                                 name, attrs)
7294                 {
7295                 }
7296
7297                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
7298                 {
7299                         if ((a.HasSecurityAttribute)) {
7300                                 a.Error_InvalidSecurityParent ();
7301                                 return;
7302                         }
7303                         
7304                         EventBuilder.SetCustomAttribute (cb);
7305                 }
7306
7307                 public bool AreAccessorsDuplicateImplementation (MethodCore mc)
7308                 {
7309                         return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
7310                 }
7311
7312                 public override AttributeTargets AttributeTargets {
7313                         get {
7314                                 return AttributeTargets.Event;
7315                         }
7316                 }
7317
7318                 public override bool Define ()
7319                 {
7320                         if (!DoDefineBase ())
7321                                 return false;
7322
7323                         if (!DoDefine ())
7324                                 return false;
7325
7326                         if (!TypeManager.IsDelegateType (MemberType)) {
7327                                 Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
7328                                 return false;
7329                         }
7330
7331                         parameters = Parameters.CreateFullyResolved (
7332                                 new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location));
7333
7334                         if (!CheckBase ())
7335                                 return false;
7336
7337                         if (TypeManager.delegate_combine_delegate_delegate == null) {
7338                                 TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
7339                                         TypeManager.delegate_type, "Combine", Location,
7340                                         TypeManager.delegate_type, TypeManager.delegate_type);
7341                         }
7342                         if (TypeManager.delegate_remove_delegate_delegate == null) {
7343                                 TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
7344                                         TypeManager.delegate_type, "Remove", Location,
7345                                         TypeManager.delegate_type, TypeManager.delegate_type);
7346                         }
7347
7348                         //
7349                         // Now define the accessors
7350                         //
7351
7352                         AddBuilder = Add.Define (Parent);
7353                         if (AddBuilder == null)
7354                                 return false;
7355
7356                         RemoveBuilder = Remove.Define (Parent);
7357                         if (RemoveBuilder == null)
7358                                 return false;
7359
7360                         EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
7361                         EventBuilder.SetAddOnMethod (AddBuilder);
7362                         EventBuilder.SetRemoveOnMethod (RemoveBuilder);
7363
7364                         Parent.MemberCache.AddMember (EventBuilder, this);
7365                         Parent.MemberCache.AddMember (AddBuilder, Add);
7366                         Parent.MemberCache.AddMember (RemoveBuilder, Remove);
7367                         
7368                         return true;
7369                 }
7370
7371                 public override void Emit ()
7372                 {
7373                         if (OptAttributes != null) {
7374                                 OptAttributes.Emit ();
7375                         }
7376
7377                         Add.Emit (Parent);
7378                         Remove.Emit (Parent);
7379
7380                         base.Emit ();
7381                 }
7382
7383                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7384                 {
7385                         MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
7386                                 Parent.TypeBuilder, Name);
7387
7388                         if (mi == null)
7389                                 return null;
7390
7391                         ParameterData pd = TypeManager.GetParameterData (mi);
7392                         base_ret_type = pd.ParameterType (0);
7393                         return mi;
7394                 }
7395
7396                 //
7397                 //   Represents header string for documentation comment.
7398                 //
7399                 public override string DocCommentHeader {
7400                         get { return "E:"; }
7401                 }
7402         }
7403
7404  
7405         public class Indexer : PropertyBase
7406         {
7407                 public class GetIndexerMethod : GetMethod
7408                 {
7409                         Parameters parameters;
7410
7411                         public GetIndexerMethod (PropertyBase method):
7412                                 base (method)
7413                         {
7414                         }
7415
7416                         public GetIndexerMethod (PropertyBase method, Accessor accessor):
7417                                 base (method, accessor)
7418                         {
7419                         }
7420
7421                         public override MethodBuilder Define (DeclSpace parent)
7422                         {
7423                                 //
7424                                 // Clone indexer accessor parameters for localized capturing
7425                                 //
7426                                 parameters = ((Indexer) method).parameters.Clone ();
7427                                 return base.Define (parent);
7428                         }
7429                         
7430                         public override bool EnableOverloadChecks (MemberCore overload)
7431                         {
7432                                 if (base.EnableOverloadChecks (overload)) {
7433                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7434                                         return true;
7435                                 }
7436
7437                                 return false;
7438                         }                       
7439
7440                         public override Parameters ParameterInfo {
7441                                 get {
7442                                         return parameters;
7443                                 }
7444                         }
7445                 }
7446
7447                 public class SetIndexerMethod: SetMethod
7448                 {
7449                         public SetIndexerMethod (PropertyBase method):
7450                                 base (method)
7451                         {
7452                         }
7453
7454                         public SetIndexerMethod (PropertyBase method, Accessor accessor):
7455                                 base (method, accessor)
7456                         {
7457                         }
7458
7459                         protected override void DefineParameters ()
7460                         {
7461                                 parameters = Parameters.MergeGenerated (((Indexer)method).parameters,
7462                                         new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, method.Location));
7463                         }
7464                         
7465                         public override bool EnableOverloadChecks (MemberCore overload)
7466                         {
7467                                 if (base.EnableOverloadChecks (overload)) {
7468                                         overload.caching_flags |= Flags.MethodOverloadsExist;
7469                                         return true;
7470                                 }
7471
7472                                 return false;
7473                         }                       
7474                 }
7475
7476                 const int AllowedModifiers =
7477                         Modifiers.NEW |
7478                         Modifiers.PUBLIC |
7479                         Modifiers.PROTECTED |
7480                         Modifiers.INTERNAL |
7481                         Modifiers.PRIVATE |
7482                         Modifiers.VIRTUAL |
7483                         Modifiers.SEALED |
7484                         Modifiers.OVERRIDE |
7485                         Modifiers.UNSAFE |
7486                         Modifiers.EXTERN |
7487                         Modifiers.ABSTRACT;
7488
7489                 const int AllowedInterfaceModifiers =
7490                         Modifiers.NEW;
7491
7492                 public readonly Parameters parameters;
7493
7494                 public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, int mod,
7495                                 bool is_iface, Parameters parameters, Attributes attrs,
7496                                 Accessor get_block, Accessor set_block, bool define_set_first)
7497                         : base (parent, type, mod,
7498                                 is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
7499                                 is_iface, name, attrs, define_set_first)
7500                 {
7501                         if (type == TypeManager.system_void_expr)
7502                                 Report.Error (620, name.Location, "An indexer return type cannot be `void'");
7503                         
7504                         this.parameters = parameters;
7505
7506                         if (get_block == null)
7507                                 Get = new GetIndexerMethod (this);
7508                         else
7509                                 Get = new GetIndexerMethod (this, get_block);
7510
7511                         if (set_block == null)
7512                                 Set = new SetIndexerMethod (this);
7513                         else
7514                                 Set = new SetIndexerMethod (this, set_block);
7515                 }
7516                 
7517                 public override bool Define ()
7518                 {
7519                         if (!DoDefineBase ())
7520                                 return false;
7521
7522                         if (!base.Define ())
7523                                 return false;
7524
7525                         if (!DefineParameters (parameters))
7526                                 return false;
7527
7528                         if (OptAttributes != null && TypeManager.indexer_name_type != null) {
7529                                 Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type);
7530                                 if (indexer_attr != null) {
7531                                         // Remove the attribute from the list because it is not emitted
7532                                         OptAttributes.Attrs.Remove (indexer_attr);
7533
7534                                         string name = indexer_attr.GetIndexerAttributeValue ();
7535                                         if (name == null)
7536                                                 return false;
7537
7538                                         ShortName = name;
7539
7540                                         if (IsExplicitImpl) {
7541                                                 Report.Error (415, indexer_attr.Location,
7542                                                               "The `IndexerName' attribute is valid only on an " +
7543                                                               "indexer that is not an explicit interface member declaration");
7544                                                 return false;
7545                                         }
7546
7547                                         if ((ModFlags & Modifiers.OVERRIDE) != 0) {
7548                                                 Report.Error (609, indexer_attr.Location,
7549                                                               "Cannot set the `IndexerName' attribute on an indexer marked override");
7550                                                 return false;
7551                                         }
7552                                 }
7553                         }
7554
7555                         if (InterfaceType != null) {
7556                                 string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
7557                                 if (base_IndexerName != Name)
7558                                         ShortName = base_IndexerName;
7559                         }
7560
7561                         if (!Parent.PartialContainer.AddMember (this) ||
7562                                 !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
7563                                 return false;
7564
7565                         if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
7566                                 if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, parameters))
7567                                         return false;
7568                         }
7569
7570                         flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
7571                         
7572                         if (!DefineAccessors ())
7573                                 return false;
7574
7575                         if (!CheckBase ())
7576                                 return false;
7577
7578                         //
7579                         // Now name the parameters
7580                         //
7581                         PropertyBuilder = Parent.TypeBuilder.DefineProperty (
7582                                 GetFullName (MemberName), PropertyAttributes.None, MemberType, parameters.Types);
7583
7584                         if (!Get.IsDummy) {
7585                                 PropertyBuilder.SetGetMethod (GetBuilder);
7586                                 Parent.MemberCache.AddMember (GetBuilder, Get);
7587                         }
7588
7589                         if (!Set.IsDummy) {
7590                                 PropertyBuilder.SetSetMethod (SetBuilder);
7591                                 Parent.MemberCache.AddMember (SetBuilder, Set);
7592                         }
7593                                 
7594                         TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, parameters.Types);
7595                         Parent.MemberCache.AddMember (PropertyBuilder, this);
7596                         return true;
7597                 }
7598
7599                 public override bool EnableOverloadChecks (MemberCore overload)
7600                 {
7601                         if (overload is Indexer) {
7602                                 caching_flags |= Flags.MethodOverloadsExist;
7603                                 return true;
7604                         }
7605
7606                         return false;
7607                 }
7608
7609                 public override string GetDocCommentName (DeclSpace ds)
7610                 {
7611                         return DocUtil.GetMethodDocCommentName (this, parameters, ds);
7612                 }
7613
7614                 public override string GetSignatureForError ()
7615                 {
7616                         StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
7617                         if (MemberName.Left != null) {
7618                                 sb.Append ('.');
7619                                 sb.Append (MemberName.Left.GetSignatureForError ());
7620                         }
7621
7622                         sb.Append (".this");
7623                         sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7624                         return sb.ToString ();
7625                 }
7626
7627                 protected override PropertyInfo ResolveBaseProperty ()
7628                 {
7629                         return Parent.PartialContainer.BaseCache.FindMemberToOverride (
7630                                 Parent.TypeBuilder, Name, parameters.Types, null, true) as PropertyInfo;
7631                 }
7632
7633                 protected override bool VerifyClsCompliance ()
7634                 {
7635                         if (!base.VerifyClsCompliance ())
7636                                 return false;
7637
7638                         parameters.VerifyClsCompliance ();
7639                         return true;
7640                 }
7641         }
7642
7643         public class Operator : MethodOrOperator {
7644
7645                 const int AllowedModifiers =
7646                         Modifiers.PUBLIC |
7647                         Modifiers.UNSAFE |
7648                         Modifiers.EXTERN |
7649                         Modifiers.STATIC;
7650
7651                 public enum OpType : byte {
7652
7653                         // Unary operators
7654                         LogicalNot,
7655                         OnesComplement,
7656                         Increment,
7657                         Decrement,
7658                         True,
7659                         False,
7660
7661                         // Unary and Binary operators
7662                         Addition,
7663                         Subtraction,
7664
7665                         UnaryPlus,
7666                         UnaryNegation,
7667                         
7668                         // Binary operators
7669                         Multiply,
7670                         Division,
7671                         Modulus,
7672                         BitwiseAnd,
7673                         BitwiseOr,
7674                         ExclusiveOr,
7675                         LeftShift,
7676                         RightShift,
7677                         Equality,
7678                         Inequality,
7679                         GreaterThan,
7680                         LessThan,
7681                         GreaterThanOrEqual,
7682                         LessThanOrEqual,
7683
7684                         // Implicit and Explicit
7685                         Implicit,
7686                         Explicit,
7687
7688                         // Just because of enum
7689                         TOP
7690                 };
7691
7692                 public readonly OpType OperatorType;
7693
7694                 static readonly string [] [] names;
7695
7696                 static Operator ()
7697                 {
7698                         names = new string[(int)OpType.TOP][];
7699                         names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
7700                         names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
7701                         names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
7702                         names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
7703                         names [(int) OpType.True] = new string [] { "true", "op_True" };
7704                         names [(int) OpType.False] = new string [] { "false", "op_False" };
7705                         names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
7706                         names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
7707                         names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
7708                         names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
7709                         names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
7710                         names [(int) OpType.Division] = new string [] { "/", "op_Division" };
7711                         names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
7712                         names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
7713                         names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
7714                         names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
7715                         names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
7716                         names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
7717                         names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
7718                         names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
7719                         names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
7720                         names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
7721                         names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
7722                         names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
7723                         names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
7724                         names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
7725                 }
7726                 
7727                 public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
7728                                  int mod_flags, Parameters parameters,
7729                                  ToplevelBlock block, Attributes attrs, Location loc)
7730                         : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
7731                                 new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
7732                 {
7733                         OperatorType = type;
7734                         Block = block;
7735                 }
7736
7737                 public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
7738                 {
7739                         if (a.Type == TypeManager.conditional_attribute_type) {
7740                                 Error_ConditionalAttributeIsNotValid ();
7741                                 return;
7742                         }
7743
7744                         base.ApplyAttributeBuilder (a, cb);
7745                 }
7746                 
7747                 public override bool Define ()
7748                 {
7749                         const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
7750                         if ((ModFlags & RequiredModifiers) != RequiredModifiers){
7751                                 Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7752                                 return false;
7753                         }
7754
7755                         if (!base.Define ())
7756                                 return false;
7757
7758                         // imlicit and explicit operator of same types are not allowed
7759                         if (OperatorType == OpType.Explicit)
7760                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), Parameters);
7761                         else if (OperatorType == OpType.Implicit)
7762                                 Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters);
7763
7764                         if (MemberType == TypeManager.void_type) {
7765                                 Report.Error (590, Location, "User-defined operators cannot return void");
7766                                 return false;
7767                         }
7768
7769                         Type declaring_type = MethodData.DeclaringType;
7770                         Type return_type = MemberType;
7771                         Type first_arg_type = ParameterTypes [0];
7772                         
7773                         Type first_arg_type_unwrap = first_arg_type;
7774                         if (TypeManager.IsNullableType (first_arg_type))
7775                                 first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0];
7776                         
7777                         Type return_type_unwrap = return_type;
7778                         if (TypeManager.IsNullableType (return_type))
7779                                 return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];                    
7780
7781                         //
7782                         // Rules for conversion operators
7783                         //
7784                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7785                                 if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type){
7786                                         Report.Error (555, Location,
7787                                                 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7788                                         return false;
7789                                 }
7790                                 
7791                                 Type conv_type;
7792                                 if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
7793                                         conv_type = first_arg_type;
7794                                 } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
7795                                         conv_type = return_type;
7796                                 } else {
7797                                         Report.Error (556, Location, 
7798                                                 "User-defined conversion must convert to or from the enclosing type");
7799                                         return false;
7800                                 }
7801
7802                                 //
7803                                 // Because IsInterface and IsClass are not supported
7804                                 //
7805                                 if (!TypeManager.IsGenericParameter (conv_type)) {
7806                                         if (conv_type.IsInterface) {
7807                                                 Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
7808                                                         GetSignatureForError ());
7809                                                 return false;
7810                                         }
7811
7812                                         if (conv_type.IsClass) {
7813                                                 if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
7814                                                         Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
7815                                                                 GetSignatureForError ());
7816                                                         return false;
7817                                                 }
7818
7819                                                 if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
7820                                                         Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
7821                                                                 GetSignatureForError ());
7822                                                         return false;
7823                                                 }
7824                                         }
7825                                 }
7826                         } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
7827                                 if (first_arg_type != declaring_type || ParameterTypes [1] != TypeManager.int32_type) {
7828                                         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");
7829                                         return false;
7830                                 }
7831                         } else if (Parameters.Count == 1) {
7832                                 // Checks for Unary operators
7833
7834                                 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
7835                                         if (return_type != declaring_type && !TypeManager.IsSubclassOf (return_type, declaring_type)) {
7836                                                 Report.Error (448, Location,
7837                                                         "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7838                                                 return false;
7839                                         }
7840                                         if (first_arg_type != declaring_type) {
7841                                                 Report.Error (
7842                                                         559, Location, "The parameter type for ++ or -- operator must be the containing type");
7843                                                 return false;
7844                                         }
7845                                 }
7846                                 
7847                                 if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)){
7848                                         Report.Error (562, Location,
7849                                                 "The parameter type of a unary operator must be the containing type");
7850                                         return false;
7851                                 }
7852                                 
7853                                 if (OperatorType == OpType.True || OperatorType == OpType.False) {
7854                                         if (return_type != TypeManager.bool_type){
7855                                                 Report.Error (
7856                                                         215, Location,
7857                                                         "The return type of operator True or False " +
7858                                                         "must be bool");
7859                                                 return false;
7860                                         }
7861                                 }
7862                                 
7863                         } else {
7864                                 // Checks for Binary operators
7865                                 
7866                                 if (first_arg_type != declaring_type &&
7867                                     ParameterTypes [1] != declaring_type){
7868                                         Report.Error (
7869                                                 563, Location,
7870                                                 "One of the parameters of a binary operator must " +
7871                                                 "be the containing type");
7872                                         return false;
7873                                 }
7874                         }
7875
7876                         return true;
7877                 }
7878
7879                 protected override bool DoDefine ()
7880                 {
7881                         if (!base.DoDefine ())
7882                                 return false;
7883
7884                         flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
7885                         return true;
7886                 }
7887                 
7888                 public override void Emit ()
7889                 {
7890                         base.Emit ();
7891
7892                         Parameters.ApplyAttributes (MethodBuilder);
7893
7894                         //
7895                         // abstract or extern methods have no bodies
7896                         //
7897                         if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
7898                                 return;
7899                         
7900                         EmitContext ec;
7901                         if ((flags & MethodAttributes.PinvokeImpl) == 0)
7902                                 ec = CreateEmitContext (Parent, MethodBuilder.GetILGenerator ());
7903                         else
7904                                 ec = CreateEmitContext (Parent, null);
7905                         
7906                         SourceMethod source = SourceMethod.Create (Parent, MethodBuilder, Block);
7907                         ec.EmitTopBlock (this, Block);
7908
7909                         if (source != null)
7910                                 source.CloseMethod ();
7911
7912                         Block = null;
7913                 }
7914
7915                 // Operator cannot be override
7916                 protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
7917                 {
7918                         return null;
7919                 }
7920
7921                 public static string GetName (OpType ot)
7922                 {
7923                         return names [(int) ot] [0];
7924                 }
7925
7926                 public static string GetName (string metadata_name)
7927                 {
7928                         for (int i = 0; i < names.Length; ++i) {
7929                                 if (names [i] [1] == metadata_name)
7930                                         return names [i] [0];
7931                         }
7932                         return null;
7933                 }
7934
7935                 public static string GetMetadataName (OpType ot)
7936                 {
7937                         return names [(int) ot] [1];
7938                 }
7939
7940                 public static string GetMetadataName (string name)
7941                 {
7942                         for (int i = 0; i < names.Length; ++i) {
7943                                 if (names [i] [0] == name)
7944                                         return names [i] [1];
7945                         }
7946                         return null;
7947                 }
7948
7949                 public OpType GetMatchingOperator ()
7950                 {
7951                         switch (OperatorType) {
7952                                 case OpType.Equality:
7953                                         return OpType.Inequality;
7954                                 case OpType.Inequality:
7955                                         return OpType.Equality;
7956                                 case OpType.True:
7957                                         return OpType.False;
7958                                 case OpType.False:
7959                                         return OpType.True;
7960                                 case OpType.GreaterThan:
7961                                         return OpType.LessThan;
7962                                 case OpType.LessThan:
7963                                         return OpType.GreaterThan;
7964                                 case OpType.GreaterThanOrEqual:
7965                                         return OpType.LessThanOrEqual;
7966                                 case OpType.LessThanOrEqual:
7967                                         return OpType.GreaterThanOrEqual;
7968                                 default:
7969                                         return OpType.TOP;
7970                         }
7971                 }
7972
7973                 public override string GetSignatureForError ()
7974                 {
7975                         StringBuilder sb = new StringBuilder ();
7976                         if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
7977                                 sb.AppendFormat ("{0}.{1} operator {2}",
7978                                         Parent.GetSignatureForError (), GetName (OperatorType), type_name.GetSignatureForError ());
7979                         }
7980                         else {
7981                                 sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
7982                         }
7983
7984                         sb.Append (Parameters.GetSignatureForError ());
7985                         return sb.ToString ();
7986                 }
7987         }
7988
7989         //
7990         // This is used to compare method signatures
7991         //
7992         struct MethodSignature {
7993                 public string Name;
7994                 public Type RetType;
7995                 public Type [] Parameters;
7996                 
7997                 /// <summary>
7998                 ///    This delegate is used to extract methods which have the
7999                 ///    same signature as the argument
8000                 /// </summary>
8001                 public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
8002                 
8003                 public MethodSignature (string name, Type ret_type, Type [] parameters)
8004                 {
8005                         Name = name;
8006                         RetType = ret_type;
8007
8008                         if (parameters == null)
8009                                 Parameters = Type.EmptyTypes;
8010                         else
8011                                 Parameters = parameters;
8012                 }
8013
8014                 public override string ToString ()
8015                 {
8016                         string pars = "";
8017                         if (Parameters.Length != 0){
8018                                 System.Text.StringBuilder sb = new System.Text.StringBuilder ();
8019                                 for (int i = 0; i < Parameters.Length; i++){
8020                                         sb.Append (Parameters [i]);
8021                                         if (i+1 < Parameters.Length)
8022                                                 sb.Append (", ");
8023                                 }
8024                                 pars = sb.ToString ();
8025                         }
8026
8027                         return String.Format ("{0} {1} ({2})", RetType, Name, pars);
8028                 }
8029                 
8030                 public override int GetHashCode ()
8031                 {
8032                         return Name.GetHashCode ();
8033                 }
8034
8035                 public override bool Equals (Object o)
8036                 {
8037                         MethodSignature other = (MethodSignature) o;
8038
8039                         if (other.Name != Name)
8040                                 return false;
8041
8042                         if (other.RetType != RetType)
8043                                 return false;
8044                         
8045                         if (Parameters == null){
8046                                 if (other.Parameters == null)
8047                                         return true;
8048                                 return false;
8049                         }
8050
8051                         if (other.Parameters == null)
8052                                 return false;
8053                         
8054                         int c = Parameters.Length;
8055                         if (other.Parameters.Length != c)
8056                                 return false;
8057
8058                         for (int i = 0; i < c; i++)
8059                                 if (other.Parameters [i] != Parameters [i])
8060                                         return false;
8061
8062                         return true;
8063                 }
8064
8065                 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
8066                 {
8067                         MethodSignature sig = (MethodSignature) filter_criteria;
8068
8069                         if (m.Name != sig.Name)
8070                                 return false;
8071
8072                         Type ReturnType;
8073                         MethodInfo mi = m as MethodInfo;
8074                         PropertyInfo pi = m as PropertyInfo;
8075
8076                         if (mi != null)
8077                                 ReturnType = mi.ReturnType;
8078                         else if (pi != null)
8079                                 ReturnType = pi.PropertyType;
8080                         else
8081                                 return false;
8082
8083                         //
8084                         // we use sig.RetType == null to mean `do not check the
8085                         // method return value.  
8086                         //
8087                         if (sig.RetType != null) {
8088                                 if (!TypeManager.IsEqual (ReturnType, sig.RetType))
8089                                         return false;
8090                         }
8091
8092                         Type [] args;
8093                         if (mi != null)
8094                                 args = TypeManager.GetParameterData (mi).Types;
8095                         else
8096                                 args = TypeManager.GetArgumentTypes (pi);
8097                         Type [] sigp = sig.Parameters;
8098
8099                         if (args.Length != sigp.Length)
8100                                 return false;
8101
8102                         for (int i = args.Length - 1; i >= 0; i--)
8103                                 if (!TypeManager.IsEqual (args [i], sigp [i]))
8104                                         return false;
8105
8106                         return true;
8107                 }
8108         }
8109 }
8110