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