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