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