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