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