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