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