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