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